Custom agents
How to write agent templates for spens
You can add your own agent templates the same way you add environment templates: in a templates/ directory inside your workspace, or by passing a .json file path directly on the command line.
Agent template format
An agent template is a JSON file with "template_type": "agent". It defines how to install and configure a specific coding agent.
| Field | Required | Description |
|---|---|---|
template_type | yes | Must be "agent" |
name | yes | Name used on the command line. It is also the command used to start the agent |
installation_command | yes | Shell command that installs the agent binary. Runs as the unprivileged agent user, installing into its home |
dependencies | no | Shell commands to run before installation (e.g. installing prerequisites). Runs as root during build, with HOME pinned to the agent user's home |
nono_base_config | no | nono.sh base profile to pull and extend |
relocate_binary | no | Moves the installed binary to a standard location and cleans up install artifacts: {"from", "to", "cleanup"}. cleanup is a path or list of paths to remove |
config_files | no | Static files written into the image at build time. A map of container path to file content |
configuration | no | Ordered list of host config mounts. Each entry has a source, a destination, an optional include glob list, and an optional exclude glob list. Only existing sources and matching files are mounted. source accepts the {workspace} token and the {spens_dir} token. destination paths starting with ~ expand to the agent user's home. When multiple entries target the same container file, the entry listed first wins |
allow_folders | no | Directories the agent is allowed to access |
env | no | Environment variables to set in the container, in KEY=value format |
packages | no | Additional system packages to install in the image |
yolo_command | no | Command template with a {prompt} placeholder, used to run the agent non-interactively when a prompt is passed on the CLI. The placeholder is filled at runtime, so the image is not rebuilt per prompt. If omitted, passing a prompt is an error |
Yolo commands
The built-in agents use these yolo commands:
| Agent | Yolo command |
|---|---|
opencode | opencode run --auto {prompt} |
codex | codex exec --sandbox danger-full-access {prompt} |
claude | claude -p {prompt} --dangerously-skip-permissions |
pi | pi -p {prompt} |
Worked example
Create templates/my-agent.json:
{
"template_type": "agent",
"name": "my-agent",
"installation_command": "curl -fsSL https://example.com/install | sh",
"dependencies": [],
"nono_base_config": "nolabs-ai/my-agent",
"relocate_binary": {
"from": "~/.local/bin/my-agent",
"to": "/usr/local/bin/my-agent",
"cleanup": ["~/.my-agent", "~/.local/bin/my-agent"]
},
"config_files": {
"~/.my-agent/config.toml": "setting = true\n"
},
"configuration": [
{
"source": "~/.config/my-agent",
"destination": "~/.config/my-agent",
"include": ["config.json", "*.toml"],
"exclude": ["secrets.*"]
}
],
"allow_folders": ["~/.cache/my-agent"],
"env": ["MY_AGENT_CERT=/certs/mitmproxy-ca-cert.pem"],
"packages": ["ripgrep"],
"yolo_command": "my-agent run --yes {prompt}"
}Then run it:
spens node-24 my-agent .
Spens