Home provisioning & startup hooks
In addition to the agent config, the home: key provisions arbitrary files into the VM home directory (/home/dev). It is an optional YAML map from a VM-home-relative target path to a host source string, nested under the home: key in a config file:
| Config location | Purpose |
|---|---|
~/.config/agents-sandbox/config.yaml (home:) | User-level home-file mappings |
.agents-sandbox/config.yaml (home:) | Project-level home-file mappings |
Keys (targets) are relative paths within the VM home, e.g. .config/opencode/opencode.json. The host source value is resolved as follows:
- empty — read host
$HOME/<target> /-prefixed — an absolute host path~/-prefixed — host$HOME/<rest>- otherwise — relative to the config file that declares it
Layering: the project config overrides the user config per target. Targets must stay within the VM home (.. traversal, absolute paths, and ~-prefixed targets are rejected — targets are already relative to the home directory, so ~/fdsa should simply be written as fdsa), and the active agent’s merged-config path is reserved (for opencode, .config/opencode/opencode.jsonc) — it cannot be provisioned via home:.
Example project-level home: block in .agents-sandbox/config.yaml:
home:
# Relative source resolves against .agents-sandbox/
.ssh/config: ssh_config
# Absolute host path
.config/tooling/rc: /abs/path/to/rc
# Host $HOME
.gitconfig: ~/.gitconfig
# Empty source reads host $HOME/.inputrc
.inputrc:
In addition to the plain string form, a value may be a mapping that provisions the file and optionally runs it at VM startup as a startup hook:
home:
# provision AND run at startup, as root
.vpn/connect.sh:
source: vpn/connect.sh # resolved exactly like the plain string form
hook: startup # optional; the only supported value is `startup`
root: true # optional; true runs as root, the default (dev) otherwise
Rules:
hook: startupruns the provisioned script after home files are provisioned and before the agent session starts, using the interpreter named by the script’s shebang (#!/bin/sh,#!/bin/bash,#!/usr/bin/env python3, …). A script with no shebang falls back to/bin/sh. Any other non-emptyhookvalue is rejected as a parse error.- The hook runs only when the VM is started — freshly created, recreated, or booted from a stopped/crashed state. It is not re-run when you attach to an already-running VM.
- The hook runs interactively: it may read from user input (e.g. prompt for passwords or MFA), and startup blocks until the script finishes. A hook that must keep running for the VM’s lifetime (e.g. a VPN client) must daemonize itself (e.g.
nohup openfortivpn ... &) so it survives the attach; it stops when the VM stops. - The script runs as the sandbox user (
dev) by default; setroot: trueto run it as root.
Example: bring up a VPN with a vpn client (installed via your .agents-sandbox/Dockerfile), with its config (host, port, username, trusted cert) provisioned as a plain entry:
home:
.vpn/connect.sh:
source: vpn/connect.sh
hook: startup
root: true
.vpn/config: .vpn/config
Any credentials (passwords, MFA) the VPN needs should be interactively read from user input by the script.
Run agents-sandbox config home to list the resolved VM target → host source mappings.