Skip to content
WIP

This guide is a work in progress. Barry is also a work in progress.

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.

Every key action.yaml accepts, with its type. Each key has its own section under Fields.

version: string | number
name: string # required
description: string # required
prompt: string | object
format: string # required
content: string
path: string
run: string | object
entry: string
command: string
args: list of string
working-directory: string
job: string
agent: object
agent: string
model: string
instructions: list of string
steps: list of object
action: string # required
slash_command: boolean # default false
command_description: string
command_hint: string
requires: object
tools: list of string
secrets: list of string
bins: list of string
preflight: object
command: string # required
timeout: integer # default 15
hint: string
validate: object
files_exist: list of string
command: string
timeout: integer # default 60
input_schema: object
output_schema: object
timeout: integer | string
context: string # default session
env: list of string
secrets: list of string
  • 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-triage
  • 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.
  • 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.
  • Type: string
  • Required: yes
  • Values: markdown, file

Which object form the prompt uses.

  • Type: string
  • Required: no

The prompt text, as Markdown. Required with format: markdown.

  • 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.

  • 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.

  • 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.

  • Type: list of string
  • Required: no

Arguments passed after entry or command.

  • 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-5
  • Type: string
  • Required: no

A harness id: lowercase letters, digits, and dashes.

  • 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.

  • 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-inbox
  • Type: string
  • Required: yes

The child action, as name or bag:name.

  • 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: true
  • 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: true
command_description: Triage today's mail and calendar
  • Type: string
  • Required: no

The argument hint shown during / autocomplete, at most 120 characters.

slash_command: true
command_hint: "[--since=DATE]"
  • 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]
  • Type: list of string
  • Required: no

Tool names the prompt tells the agent to call.

  • Type: list of string
  • Required: no

Environment keys a script the action ships needs, in upper case with digits and underscores, each listed once.

  • Type: list of string
  • Required: no

Host binaries a script the action ships needs.

  • 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`.
  • Type: string
  • Required: yes

The probe. Exit 0 means it passed.

  • 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.

  • Type: string
  • Required: no

What to do about a failure, at most 500 characters. Barry shows it verbatim in the warning.

  • 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.md
  • Type: list of string
  • Required: no

Paths that must exist afterward. A relative path resolves against the action directory.

  • Type: string
  • Required: no

A shell command that must exit 0. It runs in the action directory.

  • 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.

  • 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]
  • 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.
  • 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: 10m
  • 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.

  • 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.

version: 1
name: release-notes
description: Draft release notes from the commits since the last tag. Use when the user asks for release notes or a changelog entry.
slash_command: true
command_description: Draft release notes since the last tag
command_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 --quiet
timeout: 15m
prompt:
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.
name: disk-report
description: Report disk usage under the Barry home directory.
run:
entry: scripts/disk-report.ts
args: [--json]
env:
- REPORT_DEPTH=2
secrets: [BARRY_SECRET]
input_schema:
type: object
properties:
path: { type: string }
output_schema:
type: object
properties:
bytes: { type: number }
required: [bytes]
timeout: 2m
name: prune-worktrees
description: Prune the worktrees of sessions that ended. Use when disk space runs low.
job: sessions:disk-retention