From d5799d8e59af41e0c4890988e0deff1227341dcb Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Fri, 12 Jun 2026 10:25:23 +0200 Subject: [PATCH 1/7] docs: split kits spec reference into its own page Move the spec.yaml field reference out of the Kits overview page into a new Kit spec reference page, keeping the overview focused on concepts and usage. Rewire cross-page links accordingly. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../ai/sandboxes/customize/build-an-agent.md | 6 +- .../ai/sandboxes/customize/kit-examples.md | 2 +- .../ai/sandboxes/customize/kit-reference.md | 330 ++++++++++++++++++ .../manuals/ai/sandboxes/customize/kits.md | 326 +---------------- 4 files changed, 343 insertions(+), 321 deletions(-) create mode 100644 content/manuals/ai/sandboxes/customize/kit-reference.md diff --git a/content/manuals/ai/sandboxes/customize/build-an-agent.md b/content/manuals/ai/sandboxes/customize/build-an-agent.md index 237e25e209e..840f0cf3e25 100644 --- a/content/manuals/ai/sandboxes/customize/build-an-agent.md +++ b/content/manuals/ai/sandboxes/customize/build-an-agent.md @@ -18,8 +18,8 @@ This tutorial walks through building an agent kit for the [Amp](https://ampcode.com/) coding agent. Each step explains the decision behind a part of the spec, so you can apply the same reasoning to other agents. -For reference on every field, see the [Kits](kits.md) page. This tutorial -focuses on the journey. +For reference on every field, see the [Kit spec reference](kit-reference.md). +This tutorial focuses on the journey. The finished kit is also published as a runnable sample at [docker/sbx-kits-contrib](https://github.com/docker/sbx-kits-contrib/tree/main/amp) — @@ -28,7 +28,7 @@ useful as a reference while you follow along. ## Choose a base image An agent kit needs a container image that satisfies the -[base image requirements](kits.md#base-image-requirements): non-root +[base image requirements](kit-reference.md#base-image-requirements): non-root `agent` user at UID 1000, passwordless sudo, `/home/agent/` home, and HTTP proxy environment variable forwarding. diff --git a/content/manuals/ai/sandboxes/customize/kit-examples.md b/content/manuals/ai/sandboxes/customize/kit-examples.md index 9bf728e64e3..d7aa96f6440 100644 --- a/content/manuals/ai/sandboxes/customize/kit-examples.md +++ b/content/manuals/ai/sandboxes/customize/kit-examples.md @@ -17,7 +17,7 @@ weight: 25 Each section below shows one `spec.yaml` snippet that demonstrates a single kit pattern. These aren't complete, distributable kits — they're small, focused examples you can lift into your own kit. For the full -spec reference, see [Kits](kits.md). +spec reference, see [Kit spec reference](kit-reference.md). ## Drop a shared config file diff --git a/content/manuals/ai/sandboxes/customize/kit-reference.md b/content/manuals/ai/sandboxes/customize/kit-reference.md new file mode 100644 index 00000000000..582f7cc55d9 --- /dev/null +++ b/content/manuals/ai/sandboxes/customize/kit-reference.md @@ -0,0 +1,330 @@ +--- +title: Kit spec reference +linkTitle: Spec reference +description: Field-by-field reference for a kit's spec.yaml — credentials, network rules, environment, commands, files, memory, and the agent block. +keywords: sandboxes, sbx, kits, spec.yaml, reference, schema, fields +weight: 22 +--- + +{{< summary-bar feature_name="Docker Sandboxes sbx" >}} + +> [!NOTE] +> Kits are experimental. The kit file format, CLI commands, and experience +> for creating, loading, and managing kits are subject to change as the +> feature evolves. Share feedback and bug reports in the +> [docker/sbx-releases](https://github.com/docker/sbx-releases) repository. + +This page documents every field in a kit's `spec.yaml`. For an overview of +what kits are and how to use them, see [Kits](kits.md). + +A kit directory has a required `spec.yaml` and an optional `files/` tree: + +```text +my-kit/ +├── spec.yaml # required +└── files/ # optional — static files to inject + ├── home/ + └── workspace/ +``` + +## Top-level fields + +```yaml +schemaVersion: "1" +kind: +name: +displayName: +description: +``` + +| Field | Required | Description | +| --------------- | -------- | ------------------------------------------------------------------------ | +| `schemaVersion` | Yes | Spec schema version. Set to `"1"`. | +| `kind` | Yes | `mixin` for kits that extend an agent; `agent` for kits that define one. | +| `name` | Yes | Unique identifier. Lowercase, alphanumeric, hyphens. | +| `displayName` | No | Human-readable name. | +| `description` | No | Short description. | + +The sections below apply to both kinds. Agent kits also declare an +[`agent:` block](#agent-block). + +## Credentials + +```yaml +credentials: + sources: + : + env: [, ...] + file: + path: + parser: + priority: +``` + +| Field | Description | +| -------------------------- | ------------------------------------------------------------- | +| `sources` | Map of service identifier to credential source. | +| `sources..env` | Environment variables to read on the host, in priority order. | +| `sources..file.path` | Path on host. `~` expands to home directory. | +| `sources..file.parser` | How to extract the credential value from the file. | +| `sources..priority` | `env-first` (default) or `file-first`. | + +Service identifiers link credentials to [network rules](#network). + +### file.parser + +`file.parser` tells the proxy how to extract a credential from the file at `file.path`. +Omit it for plain-text files; set it to `json:` to extract a field from a JSON file. + +| Value | Behavior | +| ----------------- | ------------------------------------------------------------------------------------ | +| omitted or empty | Reads the entire file as the credential. Leading and trailing whitespace is trimmed. | +| `json:` | Parses the file as JSON and returns the value at the dot-separated path. | +| any other value | Rejected — `unsupported parser: `. | + +For `json:` paths, segments are separated by `.` (for example, `json:credentials.github.token`). +Only object keys can be navigated — arrays are not supported and there is no `[0]`-style indexing. +Keys that contain a literal `.` cannot be referenced. The resolved value must be a string, number, +or boolean; numbers and booleans are converted to strings. Objects, arrays, and null are rejected. + +When a source has both `env` and `file` defined, `priority` controls which is tried first. The +preferred source is used when it exists — the environment variable is set, or the file is +present on disk. If it doesn't, the other source is used instead. The choice is made once at +discovery time, so parser errors (missing JSON field, wrong value type, invalid JSON) surface +as errors rather than triggering a fallback. + +Plain-text token file: + +```yaml +credentials: + sources: + openai: + file: + path: "~/.openai/token" +``` + +Nested JSON field, with an environment variable as fallback: + +```yaml +credentials: + sources: + github: + env: + - GH_TOKEN + file: + path: "~/.config/myapp/creds.json" + parser: "json:credentials.github.token" + priority: file-first +``` + +Given `~/.config/myapp/creds.json`: + +```json +{ + "credentials": { + "github": { "token": "ghp_xyz", "expires": "2026-12-31" } + } +} +``` + +The proxy resolves the credential to `ghp_xyz`, falling back to `GH_TOKEN` if the file is +missing. If the file exists but the JSON path doesn't resolve, the request fails with the +parser error below instead of falling back. + +Common errors when using `json:` parsers: + +| Error message | Cause | +| --------------------------------------------- | ------------------------------------------------------------------- | +| `field 'X' not found in JSON` | The path doesn't exist in the file. | +| `cannot navigate to field 'X': not an object` | A path segment hit a string, array, or scalar instead of an object. | +| `field 'X' is not a string value` | The resolved value is an object, array, or null. | +| `failed to parse JSON: ...` | The file is not valid JSON. | + +## Network + +```yaml +network: + allowedDomains: [, ...] + deniedDomains: [, ...] + serviceDomains: + : + serviceAuth: + : + headerName:
+ valueFormat: +``` + +| Field | Description | +| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| `allowedDomains` | Domains the sandbox can reach. Wildcards supported. | +| `deniedDomains` | Domains the sandbox is blocked from reaching. Deny rules take precedence over allow rules, including those from other composed kits. | +| `serviceDomains` | Map of domain to service identifier from `credentials.sources`. | +| `serviceAuth.headerName` | HTTP header the proxy sets (for example, `Authorization`). | +| `serviceAuth.valueFormat` | Format string for the header value (for example, `"Bearer %s"`). | + +## Environment + +```yaml +environment: + variables: + : + proxyManaged: [, ...] +``` + +| Field | Description | +| -------------- | ------------------------------------------------------------------------------------------------------------------- | +| `variables` | Key-value pairs set directly in the container. | +| `proxyManaged` | Environment variable names populated by the proxy at request time. Pair with [`credentials.sources`](#credentials). | + +Variable names must be valid shell identifiers (`[A-Za-z_][A-Za-z0-9_]*`). + +## Commands + +```yaml +commands: + install: + - command: + user: + description: + startup: + - command: [, ...] + user: + background: + description: + initFiles: + - path: + content: + mode: + onlyIfMissing: + description: +``` + +### install + +Runs once during sandbox creation. Shell strings passed to `sh -c`. + +| Field | Default | Description | +| ------------- | ------- | ----------------------------- | +| `command` | — | Shell command string. | +| `user` | `"0"` | User to run as. `"0"` = root. | +| `description` | — | Human-readable description. | + +### startup + +Runs at every sandbox start. String array, not interpreted by a shell. + +| Field | Default | Description | +| ------------- | -------- | ----------------------------------- | +| `command` | — | Command and args as a string array. | +| `user` | `"1000"` | User to run as. `"1000"` = agent. | +| `background` | `false` | Run in background. | +| `description` | — | Human-readable description. | + +Startup commands are non-interactive. They run before the agent +attaches, with no terminal connected, so they can't prompt the user +(for example, an interactive `aws login` will hang or fail). They also +don't gate the agent's entrypoint: the agent launches once startup +commands have been dispatched, regardless of `background`. Use them +for non-interactive prep — launching daemons, warming caches, +refreshing config — and use `commands.initFiles` for any value that +needs to land on disk before the agent runs. + +Startup commands must be idempotent. They run on every sandbox start +and replay on container restarts, so a command that fails or +misbehaves on a second invocation breaks the restart path. Guard +work with existence checks, use upserts instead of inserts, and +prefer commands that converge to the same end state regardless of +how many times they run. + +### initFiles + +Files written at sandbox start, with runtime substitution. + +| Field | Default | Description | +| --------------- | -------- | --------------------------------------------------------- | +| `path` | — | Absolute container path. | +| `content` | — | File content. `${WORKDIR}` expands to the workspace path. | +| `mode` | `"0644"` | File permissions in octal. | +| `onlyIfMissing` | `false` | Skip if the file already exists. | + +## Static files + +```text +my-kit/files/ +├── home/ → /home/agent/ +└── workspace/ → primary workspace path +``` + +| Kit path | Container destination | +| ------------------ | --------------------------------------- | +| `files/home/` | `/home/agent/` (config files, dotfiles) | +| `files/workspace/` | The primary workspace path | + +Parent directories are created automatically. Existing files are +overwritten. Absolute paths and path-traversal sequences (`../../`) are +rejected. + +## Memory + +```yaml +memory: | + +``` + +Top-level field. Available in both mixin and agent kits. Markdown +appended to the agent's memory file at sandbox creation. The agent reads +this content at startup. Write it as instructions or notes the agent +should follow when working in the sandbox. Applied only when the active +agent kit sets [`agent.aiFilename`](#agent-block). + +The file is written to the parent of the workspace path inside the +sandbox, not to the workspace itself. For a workspace mounted at +`/Users/you/myproject`, the memory file lands at +`/Users/you/AGENTS.md` (or whatever `aiFilename` is set to). It exists +only inside the sandbox. Nothing is written to the host. + +When several loaded kits declare `memory:` blocks, the content is split +across files instead of being concatenated into the main one: + +- Each kit's memory is written to `.md` in a sibling + `kits-memory/` directory next to the main memory file. +- The main memory file gets a `## Kits` section listing every kit with + a pointer to its file. The section is delimited by + `` and `` + markers so it can be regenerated when kits are added or removed. + +## Agent block + +Required for `kind: agent`. + +```yaml +agent: + image: + aiFilename: + persistence: + entrypoint: + run: [, ...] + args: [, ...] +``` + +| Field | Required | Description | +| ----------------------- | -------- | ---------------------------------------------------------------------------------------------- | +| `agent.image` | Yes | Docker image reference. See [Base image requirements](#base-image-requirements). | +| `agent.aiFilename` | No | Memory filename (for example, `AGENTS.md`). Appends top-level [`memory`](#memory) at creation. | +| `agent.persistence` | No | `persistent` (named volume across restarts) or `ephemeral` (default). | +| `agent.entrypoint.run` | No | Command and args as a string array. Replaces the image's entrypoint. | +| `agent.entrypoint.args` | No | Args appended to the image's existing entrypoint. | + +### Base image requirements + +The agent's container image must provide: + +- A non-root `agent` user at UID 1000 with passwordless sudo. +- A `/home/agent/` home directory owned by `agent`. +- HTTP proxy environment variables (`HTTP_PROXY`, `HTTPS_PROXY`, + `NO_PROXY`) preserved across sudo. +- The agent binary (baked in, or installed via + [`commands.install`](#commands)). + +Build on top of `docker/sandbox-templates:shell-docker` to get these for +free. diff --git a/content/manuals/ai/sandboxes/customize/kits.md b/content/manuals/ai/sandboxes/customize/kits.md index 59b0cec6cab..22ac78760b3 100644 --- a/content/manuals/ai/sandboxes/customize/kits.md +++ b/content/manuals/ai/sandboxes/customize/kits.md @@ -55,7 +55,7 @@ commands: Startup commands cover things like launching background services, warming caches, or refreshing config on each start. They must be -idempotent — see the [`startup`](#startup) spec reference: +idempotent — see the [`startup`](kit-reference.md#startup) spec reference: ```yaml commands: @@ -96,7 +96,7 @@ commands: onlyIfMissing: true ``` -See [`initFiles`](#initfiles) in the spec reference for all fields. +See [`initFiles`](kit-reference.md#initfiles) in the spec reference for all fields. Sandboxes seed settings files for some built-in agents during setup. For example, the sandbox writes `/home/agent/.claude/settings.json` @@ -105,7 +105,7 @@ for the `claude` agent. This happens after the kit's static files and Workspace files (such as `/.claude/settings.local.json`) aren't affected, and you can ship them under `files/workspace/` as usual. To override a path the sandbox writes to, use a -[`commands.startup`](#startup) script instead. See +[`commands.startup`](kit-reference.md#startup) script instead. See [Override agent settings](kit-examples.md#override-agent-settings) for an example. @@ -209,7 +209,7 @@ memory: | ``` Both mixin and agent kits can declare `memory:`. The content is written -only when the active agent kit sets [`agent.aiFilename`](#agent-block), +only when the active agent kit sets [`agent.aiFilename`](kit-reference.md#agent-block), which determines the memory file's name. When more than one loaded kit declares a `memory:` block, each kit's @@ -227,7 +227,7 @@ that points to each kit file: └── git-ssh-sign.md ``` -See [`memory`](#memory) in the spec reference for the full field schema. +See [`memory`](kit-reference.md#memory) in the spec reference for the full field schema. ### Define an agent @@ -318,7 +318,7 @@ everything the agent needs. Common use cases: - Prototype a new agent integration Agent kits declare everything a mixin kit can, plus an -[`agent:` block](#agent-block) that tells the sandbox how to launch the +[`agent:` block](kit-reference.md#agent-block) that tells the sandbox how to launch the agent. For a step-by-step walkthrough, see [Build your own agent kit](build-an-agent.md). @@ -459,317 +459,9 @@ Docker credential store, so pushing to a private registry requires a prior ## Spec reference -A kit directory has a required `spec.yaml` and an optional `files/` tree: - -```text -my-kit/ -├── spec.yaml # required -└── files/ # optional — static files to inject - ├── home/ - └── workspace/ -``` - -### Top-level fields - -```yaml -schemaVersion: "1" -kind: -name: -displayName: -description: -``` - -| Field | Required | Description | -| --------------- | -------- | ------------------------------------------------------------------------ | -| `schemaVersion` | Yes | Spec schema version. Set to `"1"`. | -| `kind` | Yes | `mixin` for kits that extend an agent; `agent` for kits that define one. | -| `name` | Yes | Unique identifier. Lowercase, alphanumeric, hyphens. | -| `displayName` | No | Human-readable name. | -| `description` | No | Short description. | - -The sections below apply to both kinds. Agent kits also declare an -[`agent:` block](#agent-block). - -### Credentials - -```yaml -credentials: - sources: - : - env: [, ...] - file: - path: - parser: - priority: -``` - -| Field | Description | -| -------------------------- | ------------------------------------------------------------- | -| `sources` | Map of service identifier to credential source. | -| `sources..env` | Environment variables to read on the host, in priority order. | -| `sources..file.path` | Path on host. `~` expands to home directory. | -| `sources..file.parser` | How to extract the credential value from the file. | -| `sources..priority` | `env-first` (default) or `file-first`. | - -Service identifiers link credentials to [network rules](#network). - -#### file.parser - -`file.parser` tells the proxy how to extract a credential from the file at `file.path`. -Omit it for plain-text files; set it to `json:` to extract a field from a JSON file. - -| Value | Behavior | -| ----------------- | ------------------------------------------------------------------------------------ | -| omitted or empty | Reads the entire file as the credential. Leading and trailing whitespace is trimmed. | -| `json:` | Parses the file as JSON and returns the value at the dot-separated path. | -| any other value | Rejected — `unsupported parser: `. | - -For `json:` paths, segments are separated by `.` (for example, `json:credentials.github.token`). -Only object keys can be navigated — arrays are not supported and there is no `[0]`-style indexing. -Keys that contain a literal `.` cannot be referenced. The resolved value must be a string, number, -or boolean; numbers and booleans are converted to strings. Objects, arrays, and null are rejected. - -When a source has both `env` and `file` defined, `priority` controls which is tried first. The -preferred source is used when it exists — the environment variable is set, or the file is -present on disk. If it doesn't, the other source is used instead. The choice is made once at -discovery time, so parser errors (missing JSON field, wrong value type, invalid JSON) surface -as errors rather than triggering a fallback. - -Plain-text token file: - -```yaml -credentials: - sources: - openai: - file: - path: "~/.openai/token" -``` - -Nested JSON field, with an environment variable as fallback: - -```yaml -credentials: - sources: - github: - env: - - GH_TOKEN - file: - path: "~/.config/myapp/creds.json" - parser: "json:credentials.github.token" - priority: file-first -``` - -Given `~/.config/myapp/creds.json`: - -```json -{ - "credentials": { - "github": { "token": "ghp_xyz", "expires": "2026-12-31" } - } -} -``` - -The proxy resolves the credential to `ghp_xyz`, falling back to `GH_TOKEN` if the file is -missing. If the file exists but the JSON path doesn't resolve, the request fails with the -parser error below instead of falling back. - -Common errors when using `json:` parsers: - -| Error message | Cause | -| --------------------------------------------- | ------------------------------------------------------------------- | -| `field 'X' not found in JSON` | The path doesn't exist in the file. | -| `cannot navigate to field 'X': not an object` | A path segment hit a string, array, or scalar instead of an object. | -| `field 'X' is not a string value` | The resolved value is an object, array, or null. | -| `failed to parse JSON: ...` | The file is not valid JSON. | - -### Network - -```yaml -network: - allowedDomains: [, ...] - deniedDomains: [, ...] - serviceDomains: - : - serviceAuth: - : - headerName:
- valueFormat: -``` - -| Field | Description | -| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | -| `allowedDomains` | Domains the sandbox can reach. Wildcards supported. | -| `deniedDomains` | Domains the sandbox is blocked from reaching. Deny rules take precedence over allow rules, including those from other composed kits. | -| `serviceDomains` | Map of domain to service identifier from `credentials.sources`. | -| `serviceAuth.headerName` | HTTP header the proxy sets (for example, `Authorization`). | -| `serviceAuth.valueFormat` | Format string for the header value (for example, `"Bearer %s"`). | - -### Environment - -```yaml -environment: - variables: - : - proxyManaged: [, ...] -``` - -| Field | Description | -| -------------- | ------------------------------------------------------------------------------------------------------------------- | -| `variables` | Key-value pairs set directly in the container. | -| `proxyManaged` | Environment variable names populated by the proxy at request time. Pair with [`credentials.sources`](#credentials). | - -Variable names must be valid shell identifiers (`[A-Za-z_][A-Za-z0-9_]*`). - -### Commands - -```yaml -commands: - install: - - command: - user: - description: - startup: - - command: [, ...] - user: - background: - description: - initFiles: - - path: - content: - mode: - onlyIfMissing: - description: -``` - -#### `install` - -Runs once during sandbox creation. Shell strings passed to `sh -c`. - -| Field | Default | Description | -| ------------- | ------- | ----------------------------- | -| `command` | — | Shell command string. | -| `user` | `"0"` | User to run as. `"0"` = root. | -| `description` | — | Human-readable description. | - -#### `startup` - -Runs at every sandbox start. String array, not interpreted by a shell. - -| Field | Default | Description | -| ------------- | -------- | ----------------------------------- | -| `command` | — | Command and args as a string array. | -| `user` | `"1000"` | User to run as. `"1000"` = agent. | -| `background` | `false` | Run in background. | -| `description` | — | Human-readable description. | - -Startup commands are non-interactive. They run before the agent -attaches, with no terminal connected, so they can't prompt the user -(for example, an interactive `aws login` will hang or fail). They also -don't gate the agent's entrypoint: the agent launches once startup -commands have been dispatched, regardless of `background`. Use them -for non-interactive prep — launching daemons, warming caches, -refreshing config — and use `commands.initFiles` for any value that -needs to land on disk before the agent runs. - -Startup commands must be idempotent. They run on every sandbox start -and replay on container restarts, so a command that fails or -misbehaves on a second invocation breaks the restart path. Guard -work with existence checks, use upserts instead of inserts, and -prefer commands that converge to the same end state regardless of -how many times they run. - -#### `initFiles` - -Files written at sandbox start, with runtime substitution. - -| Field | Default | Description | -| --------------- | -------- | --------------------------------------------------------- | -| `path` | — | Absolute container path. | -| `content` | — | File content. `${WORKDIR}` expands to the workspace path. | -| `mode` | `"0644"` | File permissions in octal. | -| `onlyIfMissing` | `false` | Skip if the file already exists. | - -### Static files - -```text -my-kit/files/ -├── home/ → /home/agent/ -└── workspace/ → primary workspace path -``` - -| Kit path | Container destination | -| ------------------ | --------------------------------------- | -| `files/home/` | `/home/agent/` (config files, dotfiles) | -| `files/workspace/` | The primary workspace path | - -Parent directories are created automatically. Existing files are -overwritten. Absolute paths and path-traversal sequences (`../../`) are -rejected. - -### Memory - -```yaml -memory: | - -``` - -Top-level field. Available in both mixin and agent kits. Markdown -appended to the agent's memory file at sandbox creation. The agent reads -this content at startup. Write it as instructions or notes the agent -should follow when working in the sandbox. Applied only when the active -agent kit sets [`agent.aiFilename`](#agent-block). - -The file is written to the parent of the workspace path inside the -sandbox, not to the workspace itself. For a workspace mounted at -`/Users/you/myproject`, the memory file lands at -`/Users/you/AGENTS.md` (or whatever `aiFilename` is set to). It exists -only inside the sandbox. Nothing is written to the host. - -When several loaded kits declare `memory:` blocks, the content is split -across files instead of being concatenated into the main one: - -- Each kit's memory is written to `.md` in a sibling - `kits-memory/` directory next to the main memory file. -- The main memory file gets a `## Kits` section listing every kit with - a pointer to its file. The section is delimited by - `` and `` - markers so it can be regenerated when kits are added or removed. - -### Agent block - -Required for `kind: agent`. - -```yaml -agent: - image: - aiFilename: - persistence: - entrypoint: - run: [, ...] - args: [, ...] -``` - -| Field | Required | Description | -| ----------------------- | -------- | ---------------------------------------------------------------------------------------------- | -| `agent.image` | Yes | Docker image reference. See [Base image requirements](#base-image-requirements). | -| `agent.aiFilename` | No | Memory filename (for example, `AGENTS.md`). Appends top-level [`memory`](#memory) at creation. | -| `agent.persistence` | No | `persistent` (named volume across restarts) or `ephemeral` (default). | -| `agent.entrypoint.run` | No | Command and args as a string array. Replaces the image's entrypoint. | -| `agent.entrypoint.args` | No | Args appended to the image's existing entrypoint. | - -#### Base image requirements - -The agent's container image must provide: - -- A non-root `agent` user at UID 1000 with passwordless sudo. -- A `/home/agent/` home directory owned by `agent`. -- HTTP proxy environment variables (`HTTP_PROXY`, `HTTPS_PROXY`, - `NO_PROXY`) preserved across sudo. -- The agent binary (baked in, or installed via - [`commands.install`](#commands)). - -Build on top of `docker/sandbox-templates:shell-docker` to get these for -free. +For a field-by-field reference of every `spec.yaml` block — top-level +fields, credentials, network, environment, commands, static files, +memory, and the agent block — see [Kit spec reference](kit-reference.md). ## Debugging From adcb2a26ee0457e7f8501944650751a861039d55 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Fri, 12 Jun 2026 10:25:55 +0200 Subject: [PATCH 2/7] docs: fix broken anchor to the Define an agent section The links pointed to #defining-an-agent, but the heading "Define an agent" slugifies to #define-an-agent. Co-Authored-By: Claude Opus 4.8 (1M context) --- content/manuals/ai/sandboxes/customize/_index.md | 2 +- content/manuals/ai/sandboxes/customize/templates.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/manuals/ai/sandboxes/customize/_index.md b/content/manuals/ai/sandboxes/customize/_index.md index 5d1b7a30d82..6534c169e98 100644 --- a/content/manuals/ai/sandboxes/customize/_index.md +++ b/content/manuals/ai/sandboxes/customize/_index.md @@ -58,7 +58,7 @@ each time something changes. | Pre-install tools and packages into a reusable base image | [Template](templates.md) | | Capture a configured running sandbox for reuse | [Saved template](templates.md#saving-a-sandbox-as-a-template) | | Add a tool, credential, or config to agent runs via YAML | [Kit (mixin)](kits.md) | -| Define a new agent from scratch | [Kit (agent)](kits.md#defining-an-agent) | +| Define a new agent from scratch | [Kit (agent)](kits.md#define-an-agent) | Templates and kits can be used together. A template bakes heavy tools into the image for fast sandbox startup; a kit layered on top adds per-run diff --git a/content/manuals/ai/sandboxes/customize/templates.md b/content/manuals/ai/sandboxes/customize/templates.md index da4410bb740..5e5f1f21e53 100644 --- a/content/manuals/ai/sandboxes/customize/templates.md +++ b/content/manuals/ai/sandboxes/customize/templates.md @@ -29,7 +29,7 @@ ask the agent to install what's needed. > create new agent runtimes. The agent that launches inside the sandbox is > determined by the base image variant you extend and the agent you specify > in the `sbx run` command, not by binaries installed in the template. To -> define a new agent from scratch, see [Kits](kits.md#defining-an-agent). +> define a new agent from scratch, see [Kits](kits.md#define-an-agent). ### Base images From 393c83854eb276b3021908f117b1a0b7081849bf Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Fri, 12 Jun 2026 10:28:15 +0200 Subject: [PATCH 3/7] docs: remove the agent.persistence field The agent.persistence field was removed from kits, so drop it from the spec reference, the agent block examples, and the build-an-agent tutorial. Co-Authored-By: Claude Opus 4.8 (1M context) --- content/manuals/ai/sandboxes/customize/build-an-agent.md | 5 ----- content/manuals/ai/sandboxes/customize/kit-examples.md | 1 - content/manuals/ai/sandboxes/customize/kit-reference.md | 2 -- content/manuals/ai/sandboxes/customize/kits.md | 1 - 4 files changed, 9 deletions(-) diff --git a/content/manuals/ai/sandboxes/customize/build-an-agent.md b/content/manuals/ai/sandboxes/customize/build-an-agent.md index 840f0cf3e25..0b0411fd06e 100644 --- a/content/manuals/ai/sandboxes/customize/build-an-agent.md +++ b/content/manuals/ai/sandboxes/customize/build-an-agent.md @@ -80,7 +80,6 @@ description: The frontier coding agent. agent: image: "docker/sandbox-templates:shell-docker" aiFilename: AGENTS.md - persistence: persistent entrypoint: run: [amp, --dangerously-allow-all] ``` @@ -88,9 +87,6 @@ agent: - `aiFilename: AGENTS.md` tells the sandbox to create `AGENTS.md` at launch and append the [`memory`](#prime-amp-with-memory) block to it. Amp reads this file for instructions. -- `persistence: persistent` keeps Amp's state (auth tokens, history) in a - named volume across sandbox restarts. Without it, you re-authenticate - every time. - `entrypoint.run` runs `amp` in "YOLO-mode" when the sandbox starts. Adjust if you want to pass different args on startup. @@ -188,7 +184,6 @@ description: The frontier coding agent. agent: image: "docker/sandbox-templates:shell-docker" aiFilename: AGENTS.md - persistence: persistent entrypoint: run: [amp, --dangerously-allow-all] diff --git a/content/manuals/ai/sandboxes/customize/kit-examples.md b/content/manuals/ai/sandboxes/customize/kit-examples.md index d7aa96f6440..62dbd2d344f 100644 --- a/content/manuals/ai/sandboxes/customize/kit-examples.md +++ b/content/manuals/ai/sandboxes/customize/kit-examples.md @@ -269,7 +269,6 @@ description: Claude Code without --dangerously-skip-permissions agent: image: "docker/sandbox-templates:claude-code-docker" aiFilename: CLAUDE.md - persistence: persistent entrypoint: run: [claude] diff --git a/content/manuals/ai/sandboxes/customize/kit-reference.md b/content/manuals/ai/sandboxes/customize/kit-reference.md index 582f7cc55d9..163a139a576 100644 --- a/content/manuals/ai/sandboxes/customize/kit-reference.md +++ b/content/manuals/ai/sandboxes/customize/kit-reference.md @@ -301,7 +301,6 @@ Required for `kind: agent`. agent: image: aiFilename: - persistence: entrypoint: run: [, ...] args: [, ...] @@ -311,7 +310,6 @@ agent: | ----------------------- | -------- | ---------------------------------------------------------------------------------------------- | | `agent.image` | Yes | Docker image reference. See [Base image requirements](#base-image-requirements). | | `agent.aiFilename` | No | Memory filename (for example, `AGENTS.md`). Appends top-level [`memory`](#memory) at creation. | -| `agent.persistence` | No | `persistent` (named volume across restarts) or `ephemeral` (default). | | `agent.entrypoint.run` | No | Command and args as a string array. Replaces the image's entrypoint. | | `agent.entrypoint.args` | No | Args appended to the image's existing entrypoint. | diff --git a/content/manuals/ai/sandboxes/customize/kits.md b/content/manuals/ai/sandboxes/customize/kits.md index 22ac78760b3..857f340cb88 100644 --- a/content/manuals/ai/sandboxes/customize/kits.md +++ b/content/manuals/ai/sandboxes/customize/kits.md @@ -335,7 +335,6 @@ name: claude agent: image: "docker/sandbox-templates:claude-code-docker" aiFilename: CLAUDE.md - persistence: persistent entrypoint: run: [claude, "--dangerously-skip-permissions"] From 87168bd2c2fb7ca5c422158c4d123577a806f0f5 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Fri, 12 Jun 2026 10:33:59 +0200 Subject: [PATCH 4/7] docs: rename the memory kit field to agentContext Rename the spec.yaml memory: field to agentContext: across the spec reference, overview, and tutorial, and update the section heading, anchor, and cross-links. The memory file artifact and kits-memory/ directory keep their names. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../ai/sandboxes/customize/build-an-agent.md | 12 +++++----- .../ai/sandboxes/customize/kit-reference.md | 22 +++++++++---------- .../manuals/ai/sandboxes/customize/kits.md | 10 ++++----- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/content/manuals/ai/sandboxes/customize/build-an-agent.md b/content/manuals/ai/sandboxes/customize/build-an-agent.md index 0b0411fd06e..71ba5ab24cd 100644 --- a/content/manuals/ai/sandboxes/customize/build-an-agent.md +++ b/content/manuals/ai/sandboxes/customize/build-an-agent.md @@ -85,7 +85,7 @@ agent: ``` - `aiFilename: AGENTS.md` tells the sandbox to create `AGENTS.md` at launch - and append the [`memory`](#prime-amp-with-memory) block to it. Amp reads + and append the [`agentContext`](#prime-amp-with-memory) block to it. Amp reads this file for instructions. - `entrypoint.run` runs `amp` in "YOLO-mode" when the sandbox starts. Adjust if you want to pass different args on startup. @@ -153,12 +153,12 @@ pick any name. ## Prime Amp with memory -The `memory` field appends markdown to `AGENTS.md` at sandbox creation. +The `agentContext` field appends markdown to `AGENTS.md` at sandbox creation. Use it to tell Amp about the sandbox environment so it knows the conventions when it starts. ```yaml -memory: | +agentContext: | ## Sandbox environment You are running inside a Docker sandbox. The workspace is mounted at @@ -204,7 +204,7 @@ commands: user: "1000" description: Install Amp -memory: | +agentContext: | ## Sandbox environment You are running inside a Docker sandbox. The workspace is mounted at @@ -282,7 +282,7 @@ Two loops help: - Edit the spec and re-run `sbx run --kit ./amp/ amp` to pick up changes. Remove the sandbox first (`sbx rm `) for a clean start. -Flesh out the `memory` block as you refine how Amp should behave in the +Flesh out the `agentContext` block as you refine how Amp should behave in the sandbox. ## Publish @@ -311,7 +311,7 @@ the same decisions for your agent: placeholder. If it accepts the env var as-is, declare `environment.proxyManaged` in the kit and skip the user-side step. -The rest — memory block, network-policy iteration, packaging — is the +The rest — agent-context block, network-policy iteration, packaging — is the same regardless of agent. ## Remove the stored secret diff --git a/content/manuals/ai/sandboxes/customize/kit-reference.md b/content/manuals/ai/sandboxes/customize/kit-reference.md index 163a139a576..1fef19ace9c 100644 --- a/content/manuals/ai/sandboxes/customize/kit-reference.md +++ b/content/manuals/ai/sandboxes/customize/kit-reference.md @@ -1,7 +1,7 @@ --- title: Kit spec reference linkTitle: Spec reference -description: Field-by-field reference for a kit's spec.yaml — credentials, network rules, environment, commands, files, memory, and the agent block. +description: Field-by-field reference for a kit's spec.yaml — credentials, network rules, environment, commands, files, agent context, and the agent block. keywords: sandboxes, sbx, kits, spec.yaml, reference, schema, fields weight: 22 --- @@ -264,10 +264,10 @@ Parent directories are created automatically. Existing files are overwritten. Absolute paths and path-traversal sequences (`../../`) are rejected. -## Memory +## Agent context ```yaml -memory: | +agentContext: | ``` @@ -283,10 +283,10 @@ sandbox, not to the workspace itself. For a workspace mounted at `/Users/you/AGENTS.md` (or whatever `aiFilename` is set to). It exists only inside the sandbox. Nothing is written to the host. -When several loaded kits declare `memory:` blocks, the content is split +When several loaded kits declare `agentContext:` blocks, the content is split across files instead of being concatenated into the main one: -- Each kit's memory is written to `.md` in a sibling +- Each kit's agent context is written to `.md` in a sibling `kits-memory/` directory next to the main memory file. - The main memory file gets a `## Kits` section listing every kit with a pointer to its file. The section is delimited by @@ -306,12 +306,12 @@ agent: args: [, ...] ``` -| Field | Required | Description | -| ----------------------- | -------- | ---------------------------------------------------------------------------------------------- | -| `agent.image` | Yes | Docker image reference. See [Base image requirements](#base-image-requirements). | -| `agent.aiFilename` | No | Memory filename (for example, `AGENTS.md`). Appends top-level [`memory`](#memory) at creation. | -| `agent.entrypoint.run` | No | Command and args as a string array. Replaces the image's entrypoint. | -| `agent.entrypoint.args` | No | Args appended to the image's existing entrypoint. | +| Field | Required | Description | +| ----------------------- | -------- | ----------------------------------------------------------------------------------------------------------- | +| `agent.image` | Yes | Docker image reference. See [Base image requirements](#base-image-requirements). | +| `agent.aiFilename` | No | Memory filename (for example, `AGENTS.md`). Appends top-level [`agentContext`](#agent-context) at creation. | +| `agent.entrypoint.run` | No | Command and args as a string array. Replaces the image's entrypoint. | +| `agent.entrypoint.args` | No | Args appended to the image's existing entrypoint. | ### Base image requirements diff --git a/content/manuals/ai/sandboxes/customize/kits.md b/content/manuals/ai/sandboxes/customize/kits.md index 857f340cb88..815b4af9a53 100644 --- a/content/manuals/ai/sandboxes/customize/kits.md +++ b/content/manuals/ai/sandboxes/customize/kits.md @@ -203,16 +203,16 @@ the agent project conventions, usage tips for a tool the kit installs, or other guidance that should be in scope when the sandbox runs. ```yaml -memory: | +agentContext: | Ruff is installed. Run `ruff check` before committing. Shared config lives at `/workspace/ruff.toml`. ``` -Both mixin and agent kits can declare `memory:`. The content is written +Both mixin and agent kits can declare `agentContext:`. The content is written only when the active agent kit sets [`agent.aiFilename`](kit-reference.md#agent-block), which determines the memory file's name. -When more than one loaded kit declares a `memory:` block, each kit's +When more than one loaded kit declares an `agentContext:` block, each kit's content is written to its own `.md` file under a sibling `kits-memory/` directory. The main memory file gets a `## Kits` section that points to each kit file: @@ -227,7 +227,7 @@ that points to each kit file: └── git-ssh-sign.md ``` -See [`memory`](kit-reference.md#memory) in the spec reference for the full field schema. +See [`agentContext`](kit-reference.md#agent-context) in the spec reference for the full field schema. ### Define an agent @@ -460,7 +460,7 @@ Docker credential store, so pushing to a private registry requires a prior For a field-by-field reference of every `spec.yaml` block — top-level fields, credentials, network, environment, commands, static files, -memory, and the agent block — see [Kit spec reference](kit-reference.md). +agent context, and the agent block — see [Kit spec reference](kit-reference.md). ## Debugging From dd55b6601d98e779309735aef0dc8ea97dbb9f5d Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Fri, 12 Jun 2026 10:40:44 +0200 Subject: [PATCH 5/7] docs: rename the agent kit kind to sandbox Rename the spec.yaml kind: agent value to kind: sandbox and the "agent kit" concept to "sandbox kit" across the overview, spec reference, examples, index, and FAQ. Update the "Agent kits" heading and its #agent-kits anchor to "Sandbox kits"/#sandbox-kits, and repoint inbound links. The agent: block and the build-an-agent.md tutorial keep their existing names. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../manuals/ai/sandboxes/customize/_index.md | 8 +++---- .../ai/sandboxes/customize/build-an-agent.md | 4 ++-- .../ai/sandboxes/customize/kit-examples.md | 8 +++---- .../ai/sandboxes/customize/kit-reference.md | 24 +++++++++---------- .../manuals/ai/sandboxes/customize/kits.md | 20 ++++++++-------- content/manuals/ai/sandboxes/faq.md | 6 ++--- 6 files changed, 35 insertions(+), 35 deletions(-) diff --git a/content/manuals/ai/sandboxes/customize/_index.md b/content/manuals/ai/sandboxes/customize/_index.md index 6534c169e98..29e55925189 100644 --- a/content/manuals/ai/sandboxes/customize/_index.md +++ b/content/manuals/ai/sandboxes/customize/_index.md @@ -40,12 +40,12 @@ dependencies — anything you'd rather not reinstall on every sandbox start. A kit is a YAML artifact applied at sandbox creation. The kit can run install commands, drop files into the sandbox, declare network and -credential rules, and (for agent kits) define which template image the +credential rules, and (for sandbox kits) define which template image the agent runs in. Use kits for things that vary per agent or per team: shared linter config, project-specific install steps, credential injection for a service the agent talks to. -Templates and kits work together. An agent kit's `agent.image` field +Templates and kits work together. A sandbox kit's `agent.image` field points at a template: the template provides the base environment, the kit layers config, secrets, and runtime behavior on top. A team can ship one heavy template and several thin kits without rebuilding the image @@ -58,7 +58,7 @@ each time something changes. | Pre-install tools and packages into a reusable base image | [Template](templates.md) | | Capture a configured running sandbox for reuse | [Saved template](templates.md#saving-a-sandbox-as-a-template) | | Add a tool, credential, or config to agent runs via YAML | [Kit (mixin)](kits.md) | -| Define a new agent from scratch | [Kit (agent)](kits.md#define-an-agent) | +| Define a new agent from scratch | [Kit (sandbox)](kits.md#define-an-agent) | Templates and kits can be used together. A template bakes heavy tools into the image for fast sandbox startup; a kit layered on top adds per-run @@ -67,4 +67,4 @@ credentials, config, or extra capabilities. ## Tutorials - [Build your own agent kit](build-an-agent.md) — step-by-step walkthrough - for packaging [Amp](https://ampcode.com/) as an agent kit. + for packaging [Amp](https://ampcode.com/) as a sandbox kit. diff --git a/content/manuals/ai/sandboxes/customize/build-an-agent.md b/content/manuals/ai/sandboxes/customize/build-an-agent.md index 71ba5ab24cd..254c4d400a4 100644 --- a/content/manuals/ai/sandboxes/customize/build-an-agent.md +++ b/content/manuals/ai/sandboxes/customize/build-an-agent.md @@ -72,7 +72,7 @@ attaches. ```yaml {title="amp/spec.yaml"} schemaVersion: "1" -kind: agent +kind: sandbox name: amp displayName: Amp description: The frontier coding agent. @@ -176,7 +176,7 @@ Putting it all together: ```yaml {title="amp/spec.yaml"} schemaVersion: "1" -kind: agent +kind: sandbox name: amp displayName: Amp description: The frontier coding agent. diff --git a/content/manuals/ai/sandboxes/customize/kit-examples.md b/content/manuals/ai/sandboxes/customize/kit-examples.md index 62dbd2d344f..b3c2ce27672 100644 --- a/content/manuals/ai/sandboxes/customize/kit-examples.md +++ b/content/manuals/ai/sandboxes/customize/kit-examples.md @@ -1,7 +1,7 @@ --- title: Kit examples linkTitle: Examples -description: Copy-and-adapt spec.yaml snippets for common mixin and agent kit patterns — static files, install commands, background services, initFiles, Claude Code skills, and agent forks. +description: Copy-and-adapt spec.yaml snippets for common mixin and sandbox kit patterns — static files, install commands, background services, initFiles, Claude Code skills, and agent forks. keywords: sandboxes, sbx, kits, mixins, examples, patterns, skills weight: 25 --- @@ -253,7 +253,7 @@ idempotent. The heredoc pattern overwrites cleanly each time. ## Fork an existing agent -Agent kits (`kind: agent`) define a full agent from scratch. The most +Sandbox kits (`kind: sandbox`) define a full agent from scratch. The most common variant is a fork of a built-in agent — same image and credentials, but a different entrypoint. This example reproduces the built-in `claude` agent but drops `--dangerously-skip-permissions` so @@ -261,7 +261,7 @@ every tool call prompts for approval: ```yaml {title="claude-safe/spec.yaml"} schemaVersion: "1" -kind: agent +kind: sandbox name: claude-safe displayName: Claude Code (with approval prompts) description: Claude Code without --dangerously-skip-permissions @@ -296,7 +296,7 @@ Launch with the kit's `name:` as the agent argument to `sbx run`: $ sbx run claude-safe --kit ./claude-safe ``` -For a step-by-step walkthrough of building a new agent kit from +For a step-by-step walkthrough of building a new sandbox kit from scratch, see [Build an agent](build-an-agent.md). ## More examples diff --git a/content/manuals/ai/sandboxes/customize/kit-reference.md b/content/manuals/ai/sandboxes/customize/kit-reference.md index 1fef19ace9c..b989670d8de 100644 --- a/content/manuals/ai/sandboxes/customize/kit-reference.md +++ b/content/manuals/ai/sandboxes/customize/kit-reference.md @@ -31,21 +31,21 @@ my-kit/ ```yaml schemaVersion: "1" -kind: +kind: name: displayName: description: ``` -| Field | Required | Description | -| --------------- | -------- | ------------------------------------------------------------------------ | -| `schemaVersion` | Yes | Spec schema version. Set to `"1"`. | -| `kind` | Yes | `mixin` for kits that extend an agent; `agent` for kits that define one. | -| `name` | Yes | Unique identifier. Lowercase, alphanumeric, hyphens. | -| `displayName` | No | Human-readable name. | -| `description` | No | Short description. | +| Field | Required | Description | +| --------------- | -------- | -------------------------------------------------------------------------- | +| `schemaVersion` | Yes | Spec schema version. Set to `"1"`. | +| `kind` | Yes | `mixin` for kits that extend an agent; `sandbox` for kits that define one. | +| `name` | Yes | Unique identifier. Lowercase, alphanumeric, hyphens. | +| `displayName` | No | Human-readable name. | +| `description` | No | Short description. | -The sections below apply to both kinds. Agent kits also declare an +The sections below apply to both kinds. Sandbox kits also declare an [`agent:` block](#agent-block). ## Credentials @@ -271,11 +271,11 @@ agentContext: | ``` -Top-level field. Available in both mixin and agent kits. Markdown +Top-level field. Available in both mixin and sandbox kits. Markdown appended to the agent's memory file at sandbox creation. The agent reads this content at startup. Write it as instructions or notes the agent should follow when working in the sandbox. Applied only when the active -agent kit sets [`agent.aiFilename`](#agent-block). +sandbox kit sets [`agent.aiFilename`](#agent-block). The file is written to the parent of the workspace path inside the sandbox, not to the workspace itself. For a workspace mounted at @@ -295,7 +295,7 @@ across files instead of being concatenated into the main one: ## Agent block -Required for `kind: agent`. +Required for `kind: sandbox`. ```yaml agent: diff --git a/content/manuals/ai/sandboxes/customize/kits.md b/content/manuals/ai/sandboxes/customize/kits.md index 815b4af9a53..13716e81531 100644 --- a/content/manuals/ai/sandboxes/customize/kits.md +++ b/content/manuals/ai/sandboxes/customize/kits.md @@ -29,11 +29,11 @@ and enforces them at runtime. Credentials stay on the host and go through a proxy instead of entering the VM, and outbound traffic is restricted to the domains permitted by the kit's network rules. -A kit is either a mixin or an agent: +A kit is either a mixin or a sandbox: - Mixin kits (`kind: mixin`) extend an existing agent with extra capabilities. Stack several on the same sandbox. -- Agent kits (`kind: agent`) define a full agent from scratch: its image, +- Sandbox kits (`kind: sandbox`) define a full agent from scratch: its image, entrypoint, network policies, and everything else the agent needs. ## What kits can do @@ -208,8 +208,8 @@ agentContext: | Shared config lives at `/workspace/ruff.toml`. ``` -Both mixin and agent kits can declare `agentContext:`. The content is written -only when the active agent kit sets [`agent.aiFilename`](kit-reference.md#agent-block), +Both mixin and sandbox kits can declare `agentContext:`. The content is written +only when the active sandbox kit sets [`agent.aiFilename`](kit-reference.md#agent-block), which determines the memory file's name. When more than one loaded kit declares an `agentContext:` block, each kit's @@ -231,7 +231,7 @@ See [`agentContext`](kit-reference.md#agent-context) in the spec reference for t ### Define an agent -Agent kits declare an `agent:` block with the image the agent runs in and +Sandbox kits declare an `agent:` block with the image the agent runs in and the command the user attaches to when they launch the sandbox: ```yaml @@ -241,7 +241,7 @@ agent: run: [my-agent, "--yolo"] ``` -See [Agent kits](#agent-kits) for use cases and an example. +See [Sandbox kits](#sandbox-kits) for use cases and an example. ## Mixin kits @@ -307,9 +307,9 @@ To apply the mixin to a sandbox that's already running, use [`sbx kit add`](#local) instead. The `--kit` flag only takes effect when a sandbox is created. -## Agent kits +## Sandbox kits -An agent kit defines a full agent from scratch — image, entrypoint, and +A sandbox kit defines a full agent from scratch — image, entrypoint, and everything the agent needs. Common use cases: - Package a custom agent you've built so others can run it @@ -317,7 +317,7 @@ everything the agent needs. Common use cases: - Run a fork of an existing agent with your own config - Prototype a new agent integration -Agent kits declare everything a mixin kit can, plus an +Sandbox kits declare everything a mixin kit can, plus an [`agent:` block](kit-reference.md#agent-block) that tells the sandbox how to launch the agent. For a step-by-step walkthrough, see [Build your own agent kit](build-an-agent.md). @@ -330,7 +330,7 @@ with network, credentials, environment, and commands: ```yaml {title="claude/spec.yaml"} schemaVersion: "1" -kind: agent +kind: sandbox name: claude agent: image: "docker/sandbox-templates:claude-code-docker" diff --git a/content/manuals/ai/sandboxes/faq.md b/content/manuals/ai/sandboxes/faq.md index 79a2c94652d..be21be1fbbf 100644 --- a/content/manuals/ai/sandboxes/faq.md +++ b/content/manuals/ai/sandboxes/faq.md @@ -111,13 +111,13 @@ startup. In Claude Code, use the `/permissions` command to change the mode interactively. To make approval prompts the default for every session, define a custom -agent kit that overrides the agent's entrypoint to drop the +sandbox kit that overrides the agent's entrypoint to drop the permission-skipping flag. For example, a kit that launches Claude Code without `--dangerously-skip-permissions`: ```yaml {title="claude-safe/spec.yaml"} schemaVersion: "1" -kind: agent +kind: sandbox name: claude-safe agent: image: "docker/sandbox-templates:claude-code-docker" @@ -126,7 +126,7 @@ agent: ``` Run it with `sbx run claude-safe --kit ./claude-safe/`. See -[Agent kits](customize/kits.md#agent-kits) for the full pattern. +[Sandbox kits](customize/kits.md#sandbox-kits) for the full pattern. ## How do I know if my agent is running in a sandbox? From 2167dc4e22de8b75f956c8f7794a25aa2448e48e Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Fri, 12 Jun 2026 10:45:02 +0200 Subject: [PATCH 6/7] docs: rename the agent kit block to sandbox Rename the spec.yaml agent: block to sandbox: and its field paths (agent.image, agent.aiFilename, agent.entrypoint) to sandbox.*. Update the "Agent block" reference heading and its #agent-block anchor to "Sandbox block"/#sandbox-block, repoint cross-links, and rename the tutorial's "Write the agent block" section. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../manuals/ai/sandboxes/customize/_index.md | 2 +- .../ai/sandboxes/customize/build-an-agent.md | 8 +++---- .../ai/sandboxes/customize/kit-examples.md | 2 +- .../ai/sandboxes/customize/kit-reference.md | 24 +++++++++---------- .../manuals/ai/sandboxes/customize/kits.md | 14 +++++------ content/manuals/ai/sandboxes/faq.md | 2 +- 6 files changed, 26 insertions(+), 26 deletions(-) diff --git a/content/manuals/ai/sandboxes/customize/_index.md b/content/manuals/ai/sandboxes/customize/_index.md index 29e55925189..d5df8e2365a 100644 --- a/content/manuals/ai/sandboxes/customize/_index.md +++ b/content/manuals/ai/sandboxes/customize/_index.md @@ -45,7 +45,7 @@ agent runs in. Use kits for things that vary per agent or per team: shared linter config, project-specific install steps, credential injection for a service the agent talks to. -Templates and kits work together. A sandbox kit's `agent.image` field +Templates and kits work together. A sandbox kit's `sandbox.image` field points at a template: the template provides the base environment, the kit layers config, secrets, and runtime behavior on top. A team can ship one heavy template and several thin kits without rebuilding the image diff --git a/content/manuals/ai/sandboxes/customize/build-an-agent.md b/content/manuals/ai/sandboxes/customize/build-an-agent.md index 254c4d400a4..98aec4206f0 100644 --- a/content/manuals/ai/sandboxes/customize/build-an-agent.md +++ b/content/manuals/ai/sandboxes/customize/build-an-agent.md @@ -65,9 +65,9 @@ substitutes the real key on outbound requests to the API host, so the secret never enters the sandbox. A later section walks through the specific command for storing the key. -## Write the agent block +## Write the sandbox block -The `agent:` block tells the sandbox how to launch Amp when the user +The `sandbox:` block tells the sandbox how to launch Amp when the user attaches. ```yaml {title="amp/spec.yaml"} @@ -77,7 +77,7 @@ name: amp displayName: Amp description: The frontier coding agent. -agent: +sandbox: image: "docker/sandbox-templates:shell-docker" aiFilename: AGENTS.md entrypoint: @@ -181,7 +181,7 @@ name: amp displayName: Amp description: The frontier coding agent. -agent: +sandbox: image: "docker/sandbox-templates:shell-docker" aiFilename: AGENTS.md entrypoint: diff --git a/content/manuals/ai/sandboxes/customize/kit-examples.md b/content/manuals/ai/sandboxes/customize/kit-examples.md index b3c2ce27672..2d67dd7bf81 100644 --- a/content/manuals/ai/sandboxes/customize/kit-examples.md +++ b/content/manuals/ai/sandboxes/customize/kit-examples.md @@ -266,7 +266,7 @@ name: claude-safe displayName: Claude Code (with approval prompts) description: Claude Code without --dangerously-skip-permissions -agent: +sandbox: image: "docker/sandbox-templates:claude-code-docker" aiFilename: CLAUDE.md entrypoint: diff --git a/content/manuals/ai/sandboxes/customize/kit-reference.md b/content/manuals/ai/sandboxes/customize/kit-reference.md index b989670d8de..2300e598b1c 100644 --- a/content/manuals/ai/sandboxes/customize/kit-reference.md +++ b/content/manuals/ai/sandboxes/customize/kit-reference.md @@ -1,7 +1,7 @@ --- title: Kit spec reference linkTitle: Spec reference -description: Field-by-field reference for a kit's spec.yaml — credentials, network rules, environment, commands, files, agent context, and the agent block. +description: Field-by-field reference for a kit's spec.yaml — credentials, network rules, environment, commands, files, agent context, and the sandbox block. keywords: sandboxes, sbx, kits, spec.yaml, reference, schema, fields weight: 22 --- @@ -45,8 +45,8 @@ description: | `displayName` | No | Human-readable name. | | `description` | No | Short description. | -The sections below apply to both kinds. Sandbox kits also declare an -[`agent:` block](#agent-block). +The sections below apply to both kinds. Sandbox kits also declare a +[`sandbox:` block](#sandbox-block). ## Credentials @@ -275,7 +275,7 @@ Top-level field. Available in both mixin and sandbox kits. Markdown appended to the agent's memory file at sandbox creation. The agent reads this content at startup. Write it as instructions or notes the agent should follow when working in the sandbox. Applied only when the active -sandbox kit sets [`agent.aiFilename`](#agent-block). +sandbox kit sets [`sandbox.aiFilename`](#sandbox-block). The file is written to the parent of the workspace path inside the sandbox, not to the workspace itself. For a workspace mounted at @@ -293,12 +293,12 @@ across files instead of being concatenated into the main one: `` and `` markers so it can be regenerated when kits are added or removed. -## Agent block +## Sandbox block Required for `kind: sandbox`. ```yaml -agent: +sandbox: image: aiFilename: entrypoint: @@ -306,12 +306,12 @@ agent: args: [, ...] ``` -| Field | Required | Description | -| ----------------------- | -------- | ----------------------------------------------------------------------------------------------------------- | -| `agent.image` | Yes | Docker image reference. See [Base image requirements](#base-image-requirements). | -| `agent.aiFilename` | No | Memory filename (for example, `AGENTS.md`). Appends top-level [`agentContext`](#agent-context) at creation. | -| `agent.entrypoint.run` | No | Command and args as a string array. Replaces the image's entrypoint. | -| `agent.entrypoint.args` | No | Args appended to the image's existing entrypoint. | +| Field | Required | Description | +| ------------------------- | -------- | ----------------------------------------------------------------------------------------------------------- | +| `sandbox.image` | Yes | Docker image reference. See [Base image requirements](#base-image-requirements). | +| `sandbox.aiFilename` | No | Memory filename (for example, `AGENTS.md`). Appends top-level [`agentContext`](#agent-context) at creation. | +| `sandbox.entrypoint.run` | No | Command and args as a string array. Replaces the image's entrypoint. | +| `sandbox.entrypoint.args` | No | Args appended to the image's existing entrypoint. | ### Base image requirements diff --git a/content/manuals/ai/sandboxes/customize/kits.md b/content/manuals/ai/sandboxes/customize/kits.md index 13716e81531..9b40e4955cc 100644 --- a/content/manuals/ai/sandboxes/customize/kits.md +++ b/content/manuals/ai/sandboxes/customize/kits.md @@ -209,7 +209,7 @@ agentContext: | ``` Both mixin and sandbox kits can declare `agentContext:`. The content is written -only when the active sandbox kit sets [`agent.aiFilename`](kit-reference.md#agent-block), +only when the active sandbox kit sets [`sandbox.aiFilename`](kit-reference.md#sandbox-block), which determines the memory file's name. When more than one loaded kit declares an `agentContext:` block, each kit's @@ -231,11 +231,11 @@ See [`agentContext`](kit-reference.md#agent-context) in the spec reference for t ### Define an agent -Sandbox kits declare an `agent:` block with the image the agent runs in and +Sandbox kits declare a `sandbox:` block with the image the agent runs in and the command the user attaches to when they launch the sandbox: ```yaml -agent: +sandbox: image: "my-registry/my-agent:latest" entrypoint: run: [my-agent, "--yolo"] @@ -318,21 +318,21 @@ everything the agent needs. Common use cases: - Prototype a new agent integration Sandbox kits declare everything a mixin kit can, plus an -[`agent:` block](kit-reference.md#agent-block) that tells the sandbox how to launch the +[`sandbox:` block](kit-reference.md#sandbox-block) that tells the sandbox how to launch the agent. For a step-by-step walkthrough, see [Build your own agent kit](build-an-agent.md). ### Example: the built-in `claude` agent The `claude` agent you get from `sbx run claude` is defined as a kit. Here -is an abbreviated version of its spec, showing how the agent block combines +is an abbreviated version of its spec, showing how the sandbox block combines with network, credentials, environment, and commands: ```yaml {title="claude/spec.yaml"} schemaVersion: "1" kind: sandbox name: claude -agent: +sandbox: image: "docker/sandbox-templates:claude-code-docker" aiFilename: CLAUDE.md entrypoint: @@ -460,7 +460,7 @@ Docker credential store, so pushing to a private registry requires a prior For a field-by-field reference of every `spec.yaml` block — top-level fields, credentials, network, environment, commands, static files, -agent context, and the agent block — see [Kit spec reference](kit-reference.md). +agent context, and the sandbox block — see [Kit spec reference](kit-reference.md). ## Debugging diff --git a/content/manuals/ai/sandboxes/faq.md b/content/manuals/ai/sandboxes/faq.md index be21be1fbbf..4f83d2ce515 100644 --- a/content/manuals/ai/sandboxes/faq.md +++ b/content/manuals/ai/sandboxes/faq.md @@ -119,7 +119,7 @@ without `--dangerously-skip-permissions`: schemaVersion: "1" kind: sandbox name: claude-safe -agent: +sandbox: image: "docker/sandbox-templates:claude-code-docker" entrypoint: run: [claude] From e593c74762c11b4dabd2c69ea0ea65deecc21063 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Fri, 12 Jun 2026 11:31:47 +0200 Subject: [PATCH 7/7] docs: add kit spec changelog and fix kits-memory directory name Add a Changelog section at the top of the kit spec reference noting the v0.32.0 field renames (memory -> agentContext, kind: agent -> kind: sandbox, agent: block -> sandbox: block), which are deprecated aliases that sbx kit validate warns on. Also fix the per-kit directory name: v0.32.0 renamed kits-memory/ to kits-agent-context/ (with automatic migration), which the docs had not been updated to reflect. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../ai/sandboxes/customize/kit-reference.md | 22 ++++++++++++++++++- .../manuals/ai/sandboxes/customize/kits.md | 10 ++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/content/manuals/ai/sandboxes/customize/kit-reference.md b/content/manuals/ai/sandboxes/customize/kit-reference.md index 2300e598b1c..fd8d6cde247 100644 --- a/content/manuals/ai/sandboxes/customize/kit-reference.md +++ b/content/manuals/ai/sandboxes/customize/kit-reference.md @@ -27,6 +27,26 @@ my-kit/ └── workspace/ ``` +## Changelog + +Renamed fields are still accepted for backward compatibility, but +`sbx kit validate` reports a deprecation warning for each, and a future +release may stop accepting them. Update kits to the current names. + +### v0.32.0 + +The following `spec.yaml` fields were renamed: + +| Previous | Current | +| -------------- | ---------------- | +| `memory` | `agentContext` | +| `kind: agent` | `kind: sandbox` | +| `agent:` block | `sandbox:` block | + +The per-kit directory was also renamed from `kits-memory/` to +`kits-agent-context/`. An existing `kits-memory/` directory is migrated +automatically the next time the sandbox starts. + ## Top-level fields ```yaml @@ -287,7 +307,7 @@ When several loaded kits declare `agentContext:` blocks, the content is split across files instead of being concatenated into the main one: - Each kit's agent context is written to `.md` in a sibling - `kits-memory/` directory next to the main memory file. + `kits-agent-context/` directory next to the main memory file. - The main memory file gets a `## Kits` section listing every kit with a pointer to its file. The section is delimited by `` and `` diff --git a/content/manuals/ai/sandboxes/customize/kits.md b/content/manuals/ai/sandboxes/customize/kits.md index 9b40e4955cc..c19552ed647 100644 --- a/content/manuals/ai/sandboxes/customize/kits.md +++ b/content/manuals/ai/sandboxes/customize/kits.md @@ -214,14 +214,14 @@ which determines the memory file's name. When more than one loaded kit declares an `agentContext:` block, each kit's content is written to its own `.md` file under a sibling -`kits-memory/` directory. The main memory file gets a `## Kits` section -that points to each kit file: +`kits-agent-context/` directory. The main memory file gets a `## Kits` +section that points to each kit file: ```text /Users/you/ -├── myproject/ # workspace -├── AGENTS.md # main memory file with a "## Kits" index -└── kits-memory/ +├── myproject/ # workspace +├── AGENTS.md # main memory file with a "## Kits" index +└── kits-agent-context/ ├── ruff-lint.md ├── vale.md └── git-ssh-sign.md