| title |
Environment helpers reference |
| description |
An environment spec sets what the agent starts with, built from the git, file, directory, skill, mcp, plugin, and secret helpers. |
defineEnvironment() and extend() take a spec or a callback with git, file, directory, skill, mcp, plugin, and secret. Relative host paths passed to those helpers resolve against the calling file. The return is synchronous, and a Promise stops the run with exit code 2.
A child merges env, files, and mcp by name, skills by skill name, and plugins by plugin name, and its value wins. setup appends. sandbox, workspace, egress, and rules replace when set. An omitted sandbox keeps the parent's, and a set sandbox keeps none of the parent's install steps.
For more information about defining an environment, see Environments.
import { defineEnvironment } from '{{ pkg }}'
export const chatbot = defineEnvironment('chatbot', ({
git, file, secret, skill, mcp,
}) => ({
workspace: git('github:vercel/ai-chatbot', { ref: 'v3.1.0' }),
files: {
'src/agent.ts': file('./fixtures/agent.ts'),
},
env: {
SDK_API_KEY: secret.fromEnv('SDK_API_KEY'),
},
skills: [skill.local('./skills/review')],
mcp: {
docs: mcp.stdio('npx', [
'-y',
'@modelcontextprotocol/server-filesystem',
]),
},
setup: ['pnpm install --frozen-lockfile'],
}))
Where the attempt runs. Omitted on a root environment, the cascaded sandbox or the default sandbox is used, and putting `image`, `from`, `dockerfile`, or `install` beside `sandbox` in the environment spec stops the run with exit code 2.
The tree the attempt starts from, before `files`, `rules`, and `setup`.
A sandbox string or secret. The name is letters, digits, and `_`, starting with a letter or `_`, and a literal whose name contains `KEY`, `TOKEN`, `SECRET`, `PASSWORD`, or `CREDENTIAL` stops the run with exit code 2.
Where the sandbox may connect. The default is the inherited policy: `'proxy'` permits any host over HTTP and HTTPS through the egress gateway, `'allow-all'` also permits raw TCP and UDP, `'deny-all'` the automatic hosts, and `{ allow }` extra hosts, with `*.example.com` for subdomains.
Workspace paths, or `~/` paths in the home directory. A string is the contents, `file()` is read at attempt start, and `..` or a backslash stops the run with exit code 2.
Instructions for the harness rules file, written after `files`. A string is copied, `file()` is read at attempt start, and a missing file ends the attempt as an infrastructure error. For more information about the file each harness reads, see [Rules and skills](/reference/options#rules-and-skills).
A string or an object after `files`, before the agent. `timeout` defaults to `5m`, `cwd` defaults to the workspace, and a non-zero exit or a timeout is an infrastructure error.
Skills for the agent, from `skill`.
MCP servers by name, from `mcp`.
Claude Code layout plugins from `plugin`. A child replaces a parent plugin of the same name.
git() supplies workspace, fetched on the host with credentials kept there. A fetch that cannot complete fails the attempts.
A URL, `github:owner/repo`, a GitHub `/tree//` URL, or a local path. A `/tree/` URL sets `ref` and `path`, and a password or token in the URL stops the run with exit code 2.
A branch, tag, or commit SHA, defaulting to the remote `HEAD`. A ref other than a commit SHA or a version tag such as `v1.2.0` warns that results are not comparable over time.
The directory that becomes the workspace. It is relative, with forward slashes and no `.` or `..`, and any other path stops the run with exit code 2.
`true` writes one commit and no remote. The default omits the `.git` directory.
The host variable for an `https://` fetch. The token text, or `token` on SSH or a local path, stops the run with exit code 2.
file() is one host file for files or rules.
A path relative to the calling file, or absolute, read at attempt start. A missing file ends the attempt as an infrastructure error, and an owner execute bit stays executable.
directory() walks a host directory at the call, reads those files at attempt start, and skips empty directories. A missing path, a non-directory, no match, or a broken or cyclic symlink stops the run with exit code 2.
The host directory, relative to the calling file or absolute.
A directory relative to the workspace, or a home-directory path starting with `~/`. Forward slashes only, and no `..`.
Ordered gitignore-style patterns. The last match wins; `!` excludes; a slash other than a trailing `/` anchors the pattern; a pattern with no other slash matches a name at any depth; a trailing `/` matches a directory; with no including pattern, every file starts included; and the default ignores win.
Defaults to `true` and skips paths such as the `node_modules/` directory and the top-level `/build/` and `/target/` directories. `false` walks those paths; the `vendor/` directory is copied either way; and the `.git` directory stays out. The list is `DEFAULT_DIRECTORY_IGNORES` from `{{ pkg }}`.
A host directory with a SKILL.md file, or one whose immediate child directories have one. name defaults to the directory name and must be kebab-case; a missing description or a non-kebab-case name ends the attempt as an infrastructure error.
The host directory, relative to the calling file or absolute. A missing path ends the attempt as an infrastructure error.
Names to keep. The default is every skill, and a missing name ends the attempt as an infrastructure error whose message lists the skills found.
Paths left out of each skill. Setting `exclude` replaces the default path patterns: `/evals/`, `.history/`, and `*.eval.ts`; `*` matches within one name; a leading or inner `/` anchors to the skill root; a trailing `/` matches directories; any other pattern matches a name at any depth; and the `.git` directory is always left out. Import `DEFAULT_SKILL_EXCLUDE` from `{{ pkg }}` and spread it to add patterns.
`harness`, the default, places the skill through the harness. `workspace` places it in the repository's skill directory.
A Git repository of skills. only, exclude, placement, and the rules for the SKILL.md file match skill.local().
An `https://` URL, an SSH URL, `github:owner/repo`, or a GitHub `/tree//` URL. A `/tree/` URL sets `ref` and `path` when they are omitted.
A branch, tag, or commit SHA. The default and the warning match `ref` on `git()`.
One skill, or a directory of them. With no `path`, the `skills/` directory is read when it exists and the root has no `SKILL.md` file, and the root is read otherwise.
An npm package of skills. only, exclude, and placement match skill.local().
A package spec pinned to a version. A relative path or a `file:` URL resolves against the calling file, and any other spec is passed to `npm pack`.
The directory to read. The default is the `skills` directory.
One skills.sh skill. reeval clones the repository at https://github.com/<owner>/<repo>.git and reads the skills/ directory when present, otherwise the repository root. placement matches skill.local().
`owner/repo@skill`, the name after `@`. Any other id stops the run with exit code 2.
A Git ref. Omitting it warns that results are not comparable over time.
A skill written in the spec. A missing description, or a name other than kebab-case, ends the attempt as an infrastructure error, and placement matches skill.local().
The skill name.
The description.
The body of the `SKILL.md` file.
Extra files by relative path. The default is none.
A sandbox command on stdin and stdout. The mcp key is the server name.
The command. An empty command stops the run with exit code 2.
Arguments before the options. The default is none.
Process variables. A secret with `hosts` is brokered, and one without `hosts` is the process value.
An MCP server over streamable HTTP. The mcp key is the server name.
The server URL. Any other value stops the run with exit code 2.
Request headers. A secret with `hosts` is brokered to them, one without is brokered to an `https` host and sent raw on `http`, and `secret.template()` fills a header from host variables.
An MCP server over SSE. url, headers, and the mcp key match mcp.http().
A host directory with .claude-plugin/plugin.json.
The plugin directory, relative to the calling file or absolute.
Parts to place: `skills`, `agents`, `commands`, `hooks`, `mcp`, `rules`. Default: every part the plugin has.
Commands baked into a Docker image layer from the plugin directory (or `cwd` relative to the source root).
Same only and build as plugin.local().
An `https://` URL, SSH URL, `github:owner/repo`, or GitHub `/tree//` URL.
A branch, tag, or commit SHA, defaulting to the remote `HEAD`.
Plugin directory in the repository. Default: repository root.
Same only and build as plugin.local().
A pinned package spec. Relative and `file:` paths resolve against the calling file.
Plugin directory in the package. Default: package root.
'name@source' in a Claude Code marketplace. Same only and build as plugin.local().
`name@` followed by a git URL, `github:owner/repo`, or `npm:`. Any other entry stops the run with exit code 2.
Commit of a git marketplace. Pin an npm marketplace in its spec.
secret() reads the host variable named by its env key, so env: { API_KEY: secret() } reads API_KEY. Options match secret.fromEnv().
A named host variable for env or an MCP header. The record keeps the name and redacts the value.
Letters, digits, and `_`, starting with a letter or `_`. Any other name stops the run with exit code 2.
`true` skips the entry when the host variable is unset, and the record says so. The default ends the attempt as an infrastructure error.
`agent`, the default, sets the sandbox variable. `checks` limits it to `setup` and `c.exec()`.
Hosts the value is brokered to, with `*.example.com` for subdomains and `secret.hosts` for presets; a brokering sandbox gets a placeholder that its egress gateway fills on HTTPS. Without `hosts`, the value passes through except in an HTTPS MCP header, which brokers it to the server's host.
Where the value is substituted, defaulting to `['header']`. `in` requires `hosts`, and whitespace or a line break in a header value ends the attempt as an infrastructure error.
One MCP header built from host variables.
A string of `${NAME}` host variables. An unset name ends the attempt as an infrastructure error, an `https` URL brokers the result to that host, and any other URL uses the host value.
Host lists for hosts on secret() and secret.fromEnv().
`generativelanguage.googleapis.com`.
`api.openai.com`.
`api.anthropic.com`.
`api.github.com` and `uploads.github.com`.
extend() is extendEnvironment() on a defineEnvironment() parent. compare runs the baseline and each variant as its own environment, so shared fields are an extend() chain. Merging is described under Environment fields.
The cell-key name. It starts with a letter or a digit, then letters, digits, `.`, `_`, `@`, `+`, or `-`, and any other name stops the run with exit code 2.
The child fields, or a synchronous callback. A returned `Promise` stops the run with exit code 2.