Skip to content

Commit 262a200

Browse files
dvdksnclaudecodex
authored
docs: fix kit agent settings guidance (#25749)
## Summary Replace the racy startup-based agent settings override with sandbox-local, additive configuration examples. The Claude example extends the built-in agent and loads an additional home settings file with `--settings`; the OpenCode example uses `OPENCODE_CONFIG`. Clarify that startup commands do not gate agent initialization. @netlify /ai/sandboxes/customize/kit-examples/ - [Preview the kit examples](https://deploy-preview-25749--docsdocker.netlify.app/ai/sandboxes/customize/kit-examples/) - [Preview the kits overview](https://deploy-preview-25749--docsdocker.netlify.app/ai/sandboxes/customize/kits/) - [Preview the kit spec reference](https://deploy-preview-25749--docsdocker.netlify.app/ai/sandboxes/customize/kit-reference/) Closes docker/sbx-releases#408 Generated by Codex --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Codex <noreply@openai.com>
1 parent fb04f81 commit 262a200

3 files changed

Lines changed: 122 additions & 35 deletions

File tree

content/manuals/ai/sandboxes/customize/kit-examples.md

Lines changed: 87 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -316,32 +316,97 @@ See the
316316
[FAQ](../faq.md#why-doesnt-the-sandbox-use-my-user-level-agent-configuration)
317317
for details.
318318

319-
## Override agent settings
319+
## Customize agent settings
320320

321-
Sandboxes seed settings files for some built-in agents during setup.
322-
For example, the sandbox writes `/home/agent/.claude/settings.json`
323-
for the `claude` agent. This happens after the kit's static files and
324-
`setup.files`, so a kit can't override those paths with either mechanism.
325-
Use `setup.startup` instead, which runs after the sandbox seeds its
326-
files:
321+
Some agents combine settings from several files. When the agent supports it,
322+
place kit settings in a separate file instead of replacing
323+
[sandbox-managed agent configuration](kits.md#sandbox-managed-agent-configuration).
327324

328-
```yaml
329-
setup:
330-
startup:
331-
- command:
332-
- sh
333-
- -c
334-
- |
335-
mkdir -p /home/agent/.claude
336-
cat > /home/agent/.claude/settings.json <<'JSON'
337-
{"permissions": {"allow": ["Bash(echo:*)"]}}
338-
JSON
339-
user: "1000"
340-
description: Write user-scope claude settings
325+
Claude Code's `--settings` option loads an additional settings file. Extend the
326+
built-in `claude` kit to add the option without reproducing its configuration,
327+
and place the additional file outside the path the sandbox manages:
328+
329+
```text
330+
claude-sonnet/
331+
├── spec.yaml
332+
└── files/
333+
└── home/
334+
└── .config/
335+
└── claude/
336+
└── sonnet.json
337+
```
338+
339+
```yaml {title="claude-sonnet/spec.yaml"}
340+
schemaVersion: "2"
341+
kind: sandbox
342+
name: claude-sonnet
343+
extends: claude
344+
345+
sandbox:
346+
command:
347+
- --dangerously-skip-permissions
348+
- --settings
349+
- /home/agent/.config/claude/sonnet.json
350+
```
351+
352+
```json {title="claude-sonnet/files/home/.config/claude/sonnet.json"}
353+
{
354+
"model": "sonnet"
355+
}
356+
```
357+
358+
Claude Code merges the additional file with the sandbox-managed user settings.
359+
Because the file is under `files/home/`, it stays inside the sandbox instead of
360+
being written into a directly mounted host workspace. Launch the sandbox with
361+
the child kit's name:
362+
363+
```console
364+
$ sbx run claude-sonnet --kit ./claude-sonnet
365+
```
366+
367+
OpenCode supports an additional config file through `OPENCODE_CONFIG`. Keep the
368+
kit's config separate from the sandbox-managed
369+
`/home/agent/.config/opencode/opencode.json`, for example at
370+
`/home/agent/.config/opencode/team.json`:
371+
372+
```text
373+
opencode-team/
374+
├── spec.yaml
375+
└── files/
376+
└── home/
377+
└── .config/
378+
└── opencode/
379+
└── team.json
380+
```
381+
382+
```yaml {title="opencode-team/spec.yaml"}
383+
schemaVersion: "2"
384+
kind: mixin
385+
name: opencode-team
386+
requires:
387+
agent: opencode
388+
389+
environment:
390+
variables:
391+
OPENCODE_CONFIG: /home/agent/.config/opencode/team.json
341392
```
342393
343-
Startup commands replay on every sandbox start, so the script must be
344-
idempotent. The heredoc pattern overwrites cleanly each time.
394+
```json {title="opencode-team/files/home/.config/opencode/team.json"}
395+
{
396+
"$schema": "https://opencode.ai/config.json",
397+
"autoupdate": false
398+
}
399+
```
400+
401+
OpenCode merges the custom file with its global and project config files. See
402+
the OpenCode [config precedence](https://opencode.ai/docs/config/#precedence-order)
403+
for the complete order.
404+
405+
Agent settings mechanisms differ. If an agent doesn't support an additional
406+
config file, launch option, or environment variable for the setting, kits can't
407+
replace the sandbox-managed user settings before the agent launches.
408+
`setup.startup` doesn't gate the agent entrypoint, so don't use it for settings
409+
the agent must read during initialization.
345410

346411
## Fork an existing agent
347412

content/manuals/ai/sandboxes/customize/kit-reference.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ sandbox:
167167

168168
| Field | Required | Description |
169169
| -------------------- | -------- | --------------------------------------------------------------------------------------------------------------- |
170-
| `sandbox.image` | Yes | Docker image reference. A sandbox that sets `extends:` can inherit this from its parent. |
170+
| `sandbox.image` | When `extends:` is omitted | Docker image reference. |
171171
| `sandbox.build` | No | Build configuration. Runtime support is pending, so a kit with `build:` must also set `image:`. |
172172
| `sandbox.entrypoint` | No | Fixed process prefix as a string array. The first element is the agent binary. |
173173
| `sandbox.command` | No | Mode-specific argument tail. Use a list shorthand for `default`, or a mapping with `default` and `interactive`. |
@@ -177,6 +177,12 @@ The effective command is `entrypoint` plus `command.default` for non-interactive
177177
launches, and `entrypoint` plus `command.interactive` for TTY sessions. If
178178
`interactive` is omitted, it falls back to `default`.
179179

180+
For a kit that uses `extends:`, `sandbox.command` replaces the full inherited
181+
argument tail, including flags after the binary in the parent's
182+
`sandbox.entrypoint`. It doesn't append to that tail. Define every argument the
183+
child needs. For example, a child of `claude` that adds `--settings` must also
184+
include `--dangerously-skip-permissions` to preserve that behavior.
185+
180186
The agent's container image must provide:
181187

182188
- A non-root `agent` user at UID 1000 with passwordless sudo.
@@ -434,14 +440,16 @@ Runs at every sandbox start. String array, not interpreted by a shell.
434440
| ------------- | -------- | ----------------------------------- |
435441
| `command` | — | Command and args as a string array. |
436442
| `user` | `"1000"` | User to run as. `"1000"` = agent. |
437-
| `background` | `false` | Run in background. |
443+
| `background` | `false` | Block later startup commands until this command finishes. Set to `true` to let later commands run without waiting. |
438444
| `description` | — | Human-readable description. |
439445

440446
Startup commands are non-interactive. They run before the agent
441447
attaches, with no terminal connected, so they can't prompt the user
442448
(for example, an interactive `aws login` will hang or fail). They also
443449
don't gate the agent's entrypoint: the agent launches once startup
444-
commands have been dispatched, regardless of `background`. Use them
450+
commands have been dispatched, regardless of `background`. A value of
451+
`false` waits within the startup dispatcher before it runs the next command;
452+
it doesn't delay the agent entrypoint. Use startup commands
445453
for non-interactive prep — launching daemons, warming caches,
446454
refreshing config — and use `setup.files` for any value that
447455
needs to land on disk before the agent runs.

content/manuals/ai/sandboxes/customize/kits.md

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -99,16 +99,30 @@ setup:
9999
See [`setup.files`](kit-reference.md#files) in the spec reference for all
100100
fields.
101101

102-
Sandboxes seed settings files for some built-in agents during setup.
103-
For example, the sandbox writes `/home/agent/.claude/settings.json`
104-
for the `claude` agent. This happens after the kit's static files and
105-
`setup.files`, so kit-injected files at those paths get overwritten.
106-
Workspace files (such as `<workspace>/.claude/settings.local.json`)
107-
aren't affected, and you can ship them under `files/workspace/` as
108-
usual. To override a path the sandbox writes to, use a
109-
[`setup.startup`](kit-reference.md#startup) script instead. See
110-
[Override agent settings](kit-examples.md#override-agent-settings) for
111-
an example.
102+
#### Sandbox-managed agent configuration
103+
104+
Built-in agent kits reserve the following paths for sandbox setup. Treat these
105+
paths as sandbox-managed, even if a file is only needed for a particular
106+
feature. Don't target them with static files, `setup.files`, or install
107+
commands. Later setup can replace your content or depend on settings that your
108+
file removes. In this table, `~` is `/home/agent`.
109+
110+
| Built-in agent kit | Managed configuration paths |
111+
| ------------------ | --------------------------- |
112+
| `claude` | `~/.claude.json`, `~/.claude/settings.json`, `~/.claude/.config.json` |
113+
| `codex` | `~/.codex/config.toml` |
114+
| `copilot` | `~/.copilot/config.json` |
115+
| `cursor` | `~/.cursor/cli-config.json` |
116+
| `gemini` | `~/.gemini/settings.json` |
117+
| `kiro` | `~/.kiro/settings/mcp.json` |
118+
| `opencode` | `~/.config/opencode/opencode.json` |
119+
120+
Use a separate settings layer when the agent supports one. For example, Claude
121+
Code can load an additional settings file with `--settings`, and OpenCode can
122+
load one from the path in `OPENCODE_CONFIG`. See
123+
[Customize agent settings](kit-examples.md#customize-agent-settings) for
124+
examples. Don't use `setup.startup` for settings the agent must read during
125+
initialization because startup commands don't gate the agent entrypoint.
112126

113127
### Set environment variables
114128

0 commit comments

Comments
 (0)