Skip to contentSkip to Content
ReferenceCLI reference

CLI reference

folio-agents board is a command group of the folio-agents binary; Folio Docs’ own folio has no board command. folio-agents --version prints both releases, as folio-agents <version> (folio <Docs version>), and folio-agents --update refuses, because Folio Docs’ updater would install folio; reinstall the way Quickstart does. A bare folio-agents board is a read-only table; the write subcommands (add, move, update, trail, comment, attach) operate boards: one logical operation, one targeted file edit, optionally one conventional commit. fmt rewrites the prose of every card at once. The browser edits the same files through the board server: Edit the board in the browser.

These commands operate the Markdown directory named by board.source. They do not call the HTTP API or edit a SQLite database. folio-board-server api starts the SQLite backend; scripts use its HTTP routes. Data storage compares tool support.

Shared behavior

OptionMeaning
--project-dir PATHProject directory. Defaults to the current directory.
--config, -cConfig file path. Defaults to agents.yaml.
--commitOn any write command, wraps the operation in one conventional commit scoped to the board directory.
What happenedOutputExit code
Validation or write errorError: <message>1
Usage error (missing argument, bad option)usage panel2
Warning onlywarning: <message>0
Failure upstream of the validatorinternal error, no Error: prefixnonzero

Scripts should treat any nonzero exit as failure rather than parsing for the Error: prefix.

Write commands and check require a board directory. When the config has no board.source, when the source names a file or missing path, or when a columns: key is present, the commands exit 1 and nothing is written. Edits are targeted line surgery, never a YAML round-trip, so hand formatting and comments survive. Structurally unusual files (block scalars, multiline values, flow-style artifacts:) get a loud refusal (“edit the file manually”) with the file left untouched.

Each write is checked before it is allowed to stand:

CommandAfter the edit
move, update, attachThe whole board is silently reloaded. If the edit made it invalid, the original file bytes are restored — a file attach also deletes the copy, or moves it back — and the command errors with “the edit was rolled back”.
addThe whole board is reloaded, and a rejected card has its new file deleted: a rejected card must never survive to break the next build.
trail, commentOnly the written line is validated, with no full reload. A prose line can warn, but it cannot break board topology.

init

folio-agents board init

Creates a board and wires it into the config:

board
board.yaml
cards
├── read-me-first.md
└── _TEMPLATE.md
SKILL.md
agents.yaml

board.yaml declares three columns, cards/ holds one starter card and the copy-me template, SKILL.md is the in-repo operating protocol, and a board: section is appended to agents.yaml so the standalone CLI can find it.

FlagMeaning
--pathBoard directory to create (default board)
--branchBranch to create the board on (default board)
--no-branchScaffold on the current branch instead
--commitCommit the new board and the config change together

Refuses rather than overwrites; the four refusal conditions are listed in Quickstart. The config is appended to as text, never round-tripped, so comments and hand formatting survive. The generated board is loaded and validated before the command reports success.

This is the only command that writes agents.yaml, and it runs before a board exists; see the rules in Operating a board.

show

folio-agents board [--project-dir PATH] folio-agents board show [DIRECTORY]

The board as a table: column (with n/limit counts), card id, title, track, type, size, assignee, tags. The title: of board.yaml, when set, heads the table; init sets none. Blocked cards are marked with the blocking ids. show accepts the project directory as a positional argument as an alternative to --project-dir; passing both (with different paths) is an error.

A board straight out of init, with three cards added and one moved:

folio-agents board add "Fix flaky test" folio-agents board add "Ship browser canvas" folio-agents board add "Write release notes" folio-agents board move fix-flaky-test in-progress
┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━┳━━━━━━┳━━━━━━━━━━┳━━━━━━━━━┓ ┃ Column ┃ Id ┃ Card ┃ Track ┃ Type ┃ Size ┃ Assignee ┃ Tags ┃ ┡━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━╇━━━━━━╇━━━━━━━━━━╇━━━━━━━━━┩ │ Backlog (3) │ read-me-first │ Read me first │ │ │ │ │ example │ │ │ ship-browser-canvas │ Ship browser canvas │ │ │ │ │ │ │ │ write-release-notes │ Write release notes │ │ │ │ │ │ ├───────────────────┼─────────────────────┼─────────────────────┼───────┼──────┼──────┼──────────┼─────────┤ │ In progress (1/3) │ fix-flaky-test │ Fix flaky test │ │ │ │ │ │ ├───────────────────┼─────────────────────┼─────────────────────┼───────┼──────┼──────┼──────────┼─────────┤ │ Done (0) │ │ - │ │ │ │ │ │ └───────────────────┴─────────────────────┴─────────────────────┴───────┴──────┴──────┴──────────┴─────────┘

check

folio-agents board check

Validates the cardfile board — the pre-commit and CI gate. Runs the exact normalization the build runs, prints every warning, and exits 1 on the first topology error (the fail list in Board formats). On success:

Board OK: 4 cards across 3 columns

add

folio-agents board add TITLE [--status ID] [--description TEXT] [--tags LIST] [--assignee LIST] [--priority LEVEL] [--track NAME] [--milestone ID] [--parent ID] [--commit]

Creates cards/<slug-of-title>.md.

FlagMeaning
--status, -sTarget column id; defaults to the first column.
--description, -dInitial body text.
--tagsComma-separated tags.
--assigneeComma-separated assignees. One name is written scalar, several as a list.
--prioritylow, normal, or high.
--trackOptional workstream inside this product.
--milestoneRelease id for this product, such as 0.2.
--parentParent card id; must exist on the board.

The card id is the slugified title. An existing cards/<id>.md is an error (“already exists”), as is an unknown --status or --parent. created is set to today. This is the one place the CLI uses a YAML dumper: a brand-new file has no hand formatting to preserve, and the dumper safely quotes titles and tags containing YAML metacharacters.

folio-agents board add "Fix flaky test" --status backlog --tags ci,tests --priority high --commit

move

folio-agents board move CARD_ID STATUS [--after CARD] [--commit]

A one-line status edit. An unknown card or target column errors before anything is written.

FlagMeaning
--after CARDPlace the card after an anchor by writing an order rank.
--commitCommit the move.

Two conditions warn instead of refusing, at exit 0 with the move applied:

WarningCondition
WIP limitThe destination column is at or over its limit.
Open blockersThe card has blocked_by entries whose card is not in the terminal (last-listed) column.

The --after anchor must be in the destination column and must itself carry a numeric order; ranks are the explicit-ordering exception, so the CLI refuses to invent one for the anchor. The new rank is the midpoint between the anchor and the next-higher rank, or anchor + 100 if the anchor is the highest-ranked:

  • Anchor at order: 200, next rank 300 → the moved card gets 250.
  • Anchor highest at 200 → it gets 300.

All --after validation and math run before any write, so a bad anchor leaves the file untouched. See Ordering for the sort rules.

folio-agents board move fix-flaky-test in-progress --commit folio-agents board move fix-flaky-test in-progress --after other-card

update

folio-agents board update CARD_ID --set field=value [--set field=value ...] [--commit]
FlagMeaning
--set field=valueRepeatable. Only the twelve fields below are accepted.
--commitCommit the update.

The priority, order, and created warnings below print when the board is next loaded, by check, build, or the next CLI command, rather than at update time: the update’s own revalidation runs with warnings suppressed.

FieldRule
titleAny string.
assignee--set assignee=ana,bo writes the list form assignee: [ana, bo]; a single name stays scalar.
prioritylow, normal, or high. Any other value warns and sorts as normal.
sizeValidated against the scale S, M, L, XL: any case in, uppercase written.
orderThe explicit rank. A non-numeric value warns and is ignored.
parentMust name an existing card, not the card itself and not one of its descendants; anything else rolls the edit back.
createdYYYY-MM-DD. Any other shape warns, and the card stops ordering and filtering by date.
typeAny string.
trackAny string naming a workstream inside this product.
milestoneAny string.
sourceAny string.
source_titleAny string.

Status changes go through move; tags, blocked_by, and artifacts stay one-line hand edits by design. A multi---set is atomic: if any pair fails, the whole file is restored.

folio-agents board update fix-flaky-test --set assignee=ana --set type=bug folio-agents board update fix-flaky-test --set size=M --set source=folio#fix-flaky

trail

folio-agents board trail CARD_ID --note TEXT [--ref REF] [--actor NAME] [--commit]
FlagMeaning
--note, -nRequired. Whitespace is collapsed and the result must be non-empty.
--refCommit sha or PR #n. Must not contain parentheses or newlines.
--actorDefaults to the slugified git user.name, falling back to local.
--commitCommit the trail line.

Appends one session-trail line at the end of the ## Trail section, creating the section at the end of the file if missing. The date is always today.

folio-agents board trail fix-flaky-test --note "root cause found" --ref abc1234

comment

folio-agents board comment CARD_ID TEXT [--by NAME] [--commit]
FlagMeaning
--byAuthor name. Defaults to the slugified git user.name.
--commitCommit the comment.

Appends one comment at the end of the ## Comments section, creating the section at the end of the file if missing. The date is always today; the text has its whitespace collapsed and must be non-empty.

folio-agents board comment fix-flaky-test "the retry masks the race — see the trail ref" --by peter

attach

folio-agents board attach CARD_ID [PATH] [--move] [--label TEXT] [--commit] folio-agents board attach CARD_ID (--doc PATH | --api SYMBOL | --file PATH | --pr N_OR_URL | --url URL) [--label TEXT] [--commit]

Two forms, one at a time: a file path, or exactly one artifact flag.

A file path copies the file into cards/<id>/, creating the directory if needed — that alone is the attach, since artifacts: derives from the directory. The card file stays untouched unless --label is given, which also appends one line naming the sibling by its bare name (doc for .md/.mdx, file otherwise) so the label lands on the derived entry. --move moves the file instead of copying it.

FlagMeaning
--moveMove PATH instead of copying it.
--labelAlso write the bare-name label carrier line.
--commitCommit the file, and the card when --label was given. A moved tracked source’s deletion rides the same commit.

Refused: a PATH that is missing or not a regular file; a filename already present in the card’s directory (remove or rename first — labelling an existing sibling is the --file form’s job); a name starting with . or _, which derivation skips, so nothing would publish. After the write the whole board is revalidated; on failure the copy is deleted — or moved back to its source — and the card file restored.

folio-agents board attach fix-flaky-test .artifacts/flaky-analysis.md --label "Flaky analysis" folio-agents board attach fix-flaky-test /tmp/repro.sh --move

An artifact flag appends one line to the artifacts: block, creating the block if missing — the form for what is not a file, and for labels.

FlagTarget
--docProject-relative Markdown path.
--apiAPI symbol; any non-empty string.
--fileProject-relative path, optionally with an #L12 fragment.
--prPositive pull request number, or its full http(s) URL. A full URL makes the card artifact clickable without Folio guessing a repository.
--urlURL, subject to the href scheme policy.
--labelOptional display label, valid on any kind.
--commitCommit the artifact line.

Shape is validated before the write; target validation runs through the full-board revalidation, so a javascript: URL or an escaping path is rolled back. A --doc/--file path that resolves to no file lands and warns at check and build time instead — a stale path is prose, not topology. For a file already in the card’s directory, attaching by its bare name adds a label to the derived artifact rather than a second entry. A flow-style artifacts: [...] block is refused with “edit the file manually”.

folio-agents board attach fix-flaky-test --doc docs/research/analysis.md folio-agents board attach fix-flaky-test --pr https://github.com/acme/widgets/pull/42 folio-agents board attach fix-flaky-test --url https://example.com/spec --label Spec

fmt

folio-agents board fmt [--check] [--commit]

Puts every card’s prose on one line per paragraph: the description, the criteria, the comments and the trail. Lines are joined with one space, inside block quotes and list items too. Code, tables, headings, HTML and component blocks, link definitions, hard breaks and the frontmatter stay byte for byte, so a second run changes nothing.

FlagMeaning
--checkList the cards that would change and exit 1 if any would; write nothing.
--commitCommit the changed cards as one commit, board: unwrap card prose.

After the rewrite the whole board is reloaded; if it no longer loads, every card is restored and the command exits 1. --check and --commit together are refused.

$ folio-agents board fmt --check would unwrap: cards/fix-flaky-test.md Error: 1 of 4 cards have wrapped prose; run `folio-agents board fmt` $ folio-agents board fmt --commit unwrapped: cards/fix-flaky-test.md committed: board: unwrap card prose

init writes read-me-first.md with wrapped prose, so a new board fails fmt --check until fmt runs once. Run folio-agents board fmt once after init, then fmt --check beside check in CI to keep every card in this form.

--commit

One operation, one commit, scoped to the board directory:

  1. git add -- <board-dir>
  2. If the board directory has no changes: prints “nothing to commit (the board was already in this state)” and exits 0 without committing.
  3. git commit -m "<message>" -- <board-dir>

Only files under the board directory are ever staged or committed, so a board commit never carries unrelated project changes. Two exceptions stage what the operation itself touched outside the board: folio-agents board init stages the board: section it appended to agents.yaml, because a board without its config entry is not yet loadable; and attach --move of a git-tracked source stages the source’s deletion, because the deletion is the other half of the move. A git failure is an error (exit 1).

CommandCommit message
initboard: init
addboard: add <id>
moveboard: <id> <from> -> <to>
updateboard: update <id>
trailboard: trail <id>
commentboard: comment on <id>
attach (typed flag)board: attach <kind> to <id>
attach (file)board: attach <id> <filename>
fmtboard: unwrap card prose

Remote boards

folio-agents board edits Markdown files. The network CLI, folio-board, uses a source-bound token and the HTTP API for GitHub or SQLite. See remote CLI setup and commands.