action.yaml
action.yaml defines one action: a prompt an agent follows, a command Barry
runs itself, or one of a bag’s jobs offered to agents, plus the contract
around it. Put each action in its own directory under a bag’s actions/ or
skills/ directory. Barry discovers it there, so bag.yaml needs no entry
for it. The directory is the action: prompt files, run: scripts, and
validate paths resolve inside it, and a path that leaves it fails.
Barry parses the file strictly, so an unknown key fails the manifest. Every
action sets name and description, plus exactly one of prompt, run, or
job. Run barry bag check to parse every action in the installed bags.
Using actions walks through finding, running,
and writing actions, and
action-manifest.ts
holds the schema.
Overview
Section titled “Overview”Every key action.yaml accepts, with its type. Each key has its own section under Fields.
version: string | numbername: string # requireddescription: string # requiredprompt: string | object format: string # required content: string path: stringrun: string | object entry: string command: string args: list of string working-directory: stringjob: stringagent: object agent: string model: stringinstructions: list of stringsteps: list of object action: string # requiredslash_command: boolean # default falsecommand_description: stringcommand_hint: stringrequires: object tools: list of string secrets: list of string bins: list of stringpreflight: object command: string # required timeout: integer # default 15 hint: stringvalidate: object files_exist: list of string command: string timeout: integer # default 60input_schema: objectoutput_schema: objecttimeout: integer | stringcontext: string # default sessionenv: list of stringsecrets: list of stringFields
Section titled “Fields”version
Section titled “version”- Type:
string | number - Required: no
The action’s version. Barry accepts a string or a number and stores it as a string.
version: 1- Type:
string - Required: yes
The action’s name, in kebab-case: lowercase letters and digits joined by
single dashes. Other actions and schedules refer to it as name within
the same bag or as bag:name from anywhere.
name: morning-triagedescription
Section titled “description”- Type:
string - Required: yes
What the action does and when to use it, at most 1,024 characters. The
actions index in every session prompt carries it, and find_actions
searches it, so phrase it for matching: name the requests the action
answers.
description: Triage the inbox and calendar each morning. Use when the user asks what needs attention today.prompt
Section titled “prompt”- Type:
string | object - Required: no
The instructions an agent follows. A string is inline Markdown. The
object form names a format: markdown with inline content, or file
with a path relative to the action directory. A file prompt drops any
leading YAML frontmatter, so path can point at an existing SKILL.md
unchanged. Barry replaces ${ACTION_DIR} (or ${CLAUDE_SKILL_ROOT}) with
the action directory and ${INPUT.name} with that input’s value, and
appends any input without a placeholder.
prompt: format: markdown content: | Read today's calendar and unread mail. List what needs a reply first.prompt.format
Section titled “prompt.format”- Type:
string - Required: yes
- Values:
markdown,file
Which object form the prompt uses.
prompt.content
Section titled “prompt.content”- Type:
string - Required: no
The prompt text, as Markdown. Required with format: markdown.
prompt.path
Section titled “prompt.path”- Type:
string - Required: no
A file inside the action directory that holds the prompt. Required
with format: file. An absolute path or one that starts with ..
fails, and so does a missing file.
- Type:
string | object - Required: no
The command Barry runs for this action, in place of a prompt. A string
names a script inside the action directory: Barry runs a .js, .mjs,
.cjs, .ts, .mts, .cts, or .tsx file with Node.js, a TypeScript
one through tsx as entry describes, a .sh file with bash, and any
other file as an executable. The object form takes
exactly one of entry or command. Inputs arrive as JSON on stdin and in
BARRY_ACTION_INPUTS. Exit 0 completes the run, and with an
output_schema, stdout must hold JSON that matches it. A run: action
takes no steps, instructions, or agent, and its context is always
none.
An inline action under a schedule in bag.yaml has no action directory
of its own, so its paths, entry and working-directory among them,
resolve against the bag’s directory instead.
run.entry
Section titled “run.entry”- Type:
string - Required: no
A JavaScript or TypeScript file inside the action directory, run with
Node.js. Barry runs a TypeScript file (.ts, .mts, .cts, or
.tsx) through tsx’s loader, which it looks for in the node_modules
of the file’s directory or of its closest parent directory that has
one, so a bag with a TypeScript entry lists tsx in its
package.json.
run.command
Section titled “run.command”- Type:
string - Required: no
A program to run. A relative path containing / resolves against the
action directory, and an absolute path names a host binary.
run.args
Section titled “run.args”- Type:
list of string - Required: no
Arguments passed after entry or command.
run.working-directory
Section titled “run.working-directory”- Type:
string - Required: no
The process’s working directory, relative to the action directory. It defaults to the action directory.
- Type:
string - Required: no
A job from jobs: in a bag.yaml, offered to agents as this action:
name for this bag’s job, or bag:name[@version]. The job owns the
contract, so a job: action sets none of steps, instructions,
agent, env, secrets, requires, input_schema, output_schema,
timeout, preflight, or validate, and its context is always
none. It must name a node or process job; barry bag check reports
one that runs an action.
- Type:
object - Required: no
The coding agent and model a detached run of this action prefers. A
request can override either half, and an inline run stays on the calling
session’s agent. Barry checks agent.agent for shape here and for an
installed harness when the run starts.
agent: agent: codex model: gpt-5agent.agent
Section titled “agent.agent”- Type:
string - Required: no
A harness id: lowercase letters, digits, and dashes.
agent.model
Section titled “agent.model”- Type:
string - Required: no
A model id. Barry leaves model ids unvalidated, warns at spawn about an unknown one, and derives the model’s vendor from the id.
instructions
Section titled “instructions”- Type:
list of string - Required: no
Shared instructions, by name, that Barry prepends to the prompt in the listed order. A missing name produces a warning, not an error.
instructions: [house-style]- Type:
list of object - Required: no
Child actions that make this action a composite, in run order. The
prompt then explains how to combine the children’s results. A step
that names the action itself, or a child listed twice, fails parsing.
Barry resolves child names against the catalog, so a missing child
appears as a catalog problem instead of a parse error.
steps: - action: check-calendar - action: mail:check-inboxsteps.action
Section titled “steps.action”- Type:
string - Required: yes
The child action, as name or bag:name.
slash_command
Section titled “slash_command”- Type:
boolean - Required: no
- Default:
false
Expose the action as a /name command in harnesses that have a command
menu. The generated command calls begin_action, so the run records,
composes instructions, and validates the same way as any other run.
slash_command: truecommand_description
Section titled “command_description”- Type:
string - Required: no
A shorter menu subtitle for the slash command, at most 200 characters.
Without it, the menu shows description. Barry ignores it unless
slash_command is true.
slash_command: truecommand_description: Triage today's mail and calendarcommand_hint
Section titled “command_hint”- Type:
string - Required: no
The argument hint shown during / autocomplete, at most 120 characters.
slash_command: truecommand_hint: "[--since=DATE]"requires
Section titled “requires”- Type:
object - Required: no
What the action expects to exist. Barry warns about a missing tool, secret, or binary before the work starts. It never grants access or blocks the run.
requires: tools: [Bash] bins: [gh]requires.tools
Section titled “requires.tools”- Type:
list of string - Required: no
Tool names the prompt tells the agent to call.
requires.secrets
Section titled “requires.secrets”- Type:
list of string - Required: no
Environment keys a script the action ships needs, in upper case with digits and underscores, each listed once.
requires.bins
Section titled “requires.bins”- Type:
list of string - Required: no
Host binaries a script the action ships needs.
preflight
Section titled “preflight”- Type:
object - Required: no
A probe Barry runs before the work starts, to check that the action can
work here and now. It runs as a shell command in the action directory,
with ${ACTION_DIR} substituted. The result is advisory: Barry reports
passed, failed, or unknown, and the agent decides. Write the probe so it
can fail; a pipe reports the exit status of its last command.
preflight: command: gh auth status timeout: 10 hint: Sign in with `gh auth login`.preflight.command
Section titled “preflight.command”- Type:
string - Required: yes
The probe. Exit 0 means it passed.
preflight.timeout
Section titled “preflight.timeout”- Type:
integer - Required: no
- Default:
15
The probe’s time limit in seconds, at most 60. Past it, Barry stops the probe and reports the result as unknown.
preflight.hint
Section titled “preflight.hint”- Type:
string - Required: no
What to do about a failure, at most 500 characters. Barry shows it verbatim in the warning.
validate
Section titled “validate”- Type:
object - Required: no
Checks Barry runs when the run completes. Set files_exist, command, or
both. A failed check closes the run as failed with the reason; it doesn’t
undo the work.
validate: files_exist: [report.md] command: test -s report.mdvalidate.files_exist
Section titled “validate.files_exist”- Type:
list of string - Required: no
Paths that must exist afterward. A relative path resolves against the action directory.
validate.command
Section titled “validate.command”- Type:
string - Required: no
A shell command that must exit 0. It runs in the action directory.
validate.timeout
Section titled “validate.timeout”- Type:
integer - Required: no
- Default:
60
The command’s time limit in seconds, at most 600. Past it, Barry stops the command and fails the check.
input_schema
Section titled “input_schema”- Type:
object - Required: no
A JSON Schema for the inputs a caller passes. The root must have
type: object, because inputs have names, and the schema must compile.
Barry rejects malformed input before it creates a run. A property’s
x-barry-infer holds prose that explains how to infer an unset value.
input_schema: type: object properties: since: type: string description: Only mail newer than this date. required: [since]output_schema
Section titled “output_schema”- Type:
object - Required: no
A JSON Schema for what the run produces. Any root type works, and the schema must compile. Barry captures it when the run begins, so editing the manifest mid-run leaves that run’s contract unchanged.
output_schema: type: string description: The triage report as Markdown.timeout
Section titled “timeout”- Type:
integer | string - Required: no
How long a run may take before Barry stops it and records it as failed:
whole seconds, or a number with s, m, h, or d. It bounds a run:
process, which otherwise stops at 600 seconds, and a detached agent run.
timeout: 10mcontext
Section titled “context”- Type:
string - Required: no
- Default:
session - Values:
session,none
What the action needs from its caller. session means the prompt refers
to the calling conversation, so the action runs inline. none marks it
self-contained, so a fresh agent can run it detached. The default is
session for a prompt action and none for a run: or job: action,
which reject session.
context: none- Type:
list of string - Required: no
Non-secret KEY=VALUE literals for a run: process. Each key starts with
an upper-case letter followed by upper-case letters, digits, or
underscores, and appears once. A prompt action has no process, so it
rejects env.
secrets
Section titled “secrets”- Type:
list of string - Required: no
Names of secrets to pass to a run: process as environment variables,
each listed once. Barry reads them from the run’s secret owner, the
identity the run acts for or the installation, and the run fails to
start when one is unavailable. A prompt action rejects secrets.
Examples
Section titled “Examples”A prompt action with inputs and checks
Section titled “A prompt action with inputs and checks”version: 1name: release-notesdescription: Draft release notes from the commits since the last tag. Use when the user asks for release notes or a changelog entry.slash_command: truecommand_description: Draft release notes since the last tagcommand_hint: "[--since=TAG]"requires: tools: [Bash] bins: [git]preflight: command: git describe --tags --abbrev=0 hint: Tag a release first with `git tag`.input_schema: type: object properties: since: type: string description: The tag to start from. x-barry-infer: The most recent tag, from `git describe --tags --abbrev=0`.output_schema: type: string description: The release notes as Markdown.validate: command: git diff --quiettimeout: 15mprompt: format: markdown content: | List the commits since ${INPUT.since} with `git log`. Group them into features, fixes, and internal changes, and write the notes as Markdown.An action Barry runs itself
Section titled “An action Barry runs itself”name: disk-reportdescription: Report disk usage under the Barry home directory.run: entry: scripts/disk-report.ts args: [--json]env: - REPORT_DEPTH=2secrets: [BARRY_SECRET]input_schema: type: object properties: path: { type: string }output_schema: type: object properties: bytes: { type: number } required: [bytes]timeout: 2mA job offered as an action
Section titled “A job offered as an action”name: prune-worktreesdescription: Prune the worktrees of sessions that ended. Use when disk space runs low.job: sessions:disk-retention