Skip to content

categories

Inspect and edit a list’s card categories: a card’s role in that one list, such as Ramp, Removal, or Board Wipes. It is what Archidekt calls a category and Moxfield a tag. Categories are not Ritual’s tags or labels; see Labels, tags, and categories for how the three differ.

A category belongs to a card name, not to a card line. One assignment covers every line of that name in the list, whatever its printing, section, or quantity. It is never written on the line, and it never follows a move. A card’s categories are ordered, and the first one is its primary category, which is what the site groups by. Categories are stored in a <list>.categories.json file beside the list; see Categories in the list format.

Terminal window
ritual categories list [listName]
ritual categories rename [listName] <from> <to>
ritual categories order [listName] <value>
ritual categories remove [listName] <name>

listName names a list of any type unless a type flag narrows it; see List Names. Omit it to pick a list interactively.

Print the list’s category vocabulary in display order, each with how many cards carry it, followed by one line per categorized card.

Argument Description
[listName] The list to read (prompted when omitted)

Read-only: it takes no --dry-run, never writes, and never prunes. It does report stale entries (see Stale names).

Rename a category throughout the list: in the vocabulary and on every card carrying it, with each card’s own order preserved.

Argument Description
[listName] The list to edit
<from> The category to rename
<to> The new name for the category

A <from> the list does not use (neither in order nor on any card, compared case-insensitively) is a not_found (exit 3).

Set the display order of the list’s vocabulary.

Argument Description
[listName] The list to edit
<value> The categories in their new order, comma-separated

Names the list does not use yet are accepted: order declares a vocabulary. An empty value is a usage error (exit 2); use remove to drop a name.

Remove a category from the list’s vocabulary and from every card that uses it. A card left with no categories loses its entry in the categories file.

Argument Description
[listName] The list to edit
<name> The category to remove
Option Description Default
--deck Resolve the name as a deck
--collection Resolve the name as a collection
--wanted Resolve the name as a wanted list
-n, --dry-run Report what would change without writing anything (not on list) false
--output <format> Output format: text, json, or ndjson text
--quiet Suppress non-essential output false
Terminal window
ritual categories list --deck "Winota Stax"
ritual categories list --deck "Winota Stax" --output json
ritual categories rename --deck "Winota Stax" Draw "Card Draw"
ritual categories order --deck "Winota Stax" "Ramp, Card Draw, Removal"
ritual categories remove --collection main Ramp --dry-run

Every mutating subcommand writes the list’s <list>.categories.json and <list>.categories.json.sha256 when the edit changes them, then appends one entry to the list’s .changes.md changelog. Those paths come back in writtenFiles. The list .md file is never rewritten. This command writes no card lines and reads no &N, so it does not trigger the card-ID backfill.

An edit that changes nothing (rename Draw Draw, or an order equal to the one on disk) reports wouldWrite: false, writes no file and no changelog entry, and returns an empty writtenFiles. A real run and its --dry-run preview always agree about whether the command touches disk.

A categories file left with no vocabulary and no cards is deleted rather than written as {}, and its .sha256 goes with it.

The .sha256 is refreshed only when it matched the categories file before the write. A hand-edited file therefore keeps its stale hash (its .sha256 is not in writtenFiles), so detect-changes still records the hand edit.

The changelog records:

  • Renamed category "Draw" to "Card Draw"
  • Set category order to Ramp, Draw, Removal (or Clear category order)
  • Set categories of "Sol Ring" to Ramp, Artifacts / Cleared categories of "Sol Ring"

remove has no event of its own. It is recorded as a set-category-order without the name plus one set-categories per affected card.

An entry naming a card the list no longer holds is kept. categories list reports it on stderr:

Categories are recorded for cards this list no longer holds: Sol Ring. They are kept until the list is saved or cleaned up.

--quiet does not hide it, because the next save will drop that data. The check needs a complete read of the list. When the file holds a body line the card-line parser cannot read, categories list reports that instead and names no entry stale, since a card it could not see is not a card that is gone.

Nothing in this command prunes. Pruning happens on the list’s own save (an editor session, an admin save), on a cross-list move that rewrites the list from a clean parse, and in ritual cleanup.

-n / --dry-run resolves the list, validates the arguments, computes the edit, reports it, and stops. Nothing is written: no categories file, no .sha256, no changelog. wouldWrite says whether a real run would touch the categories file. It is false for a no-op edit, in which case a real run writes nothing at all, changelog included. Text output is prefixed [dry-run]; JSON output carries "dryRun": true alongside the usual fields.

categories list:

{
"type": "deck",
"list": "Winota Stax",
"order": ["Ramp", "Draw", "Removal"],
"cards": [{ "name": "Sol Ring", "categories": ["Ramp", "Artifacts"] }],
"warnings": []
}

categories rename / order / remove:

{
"type": "deck",
"list": "Winota Stax",
"action": "rename",
"order": ["Ramp", "Card Draw", "Removal"],
"cardsChanged": ["Rhystic Study"],
"wouldWrite": true,
"writtenFiles": [
"/decks/Winota Stax.categories.json",
"/decks/Winota Stax.categories.json.sha256",
"/decks/Winota Stax.changes.md"
]
}

cardsChanged lists the cards whose recorded categories differ after the edit, so a rename reports every card that carried the old name.

The built site reads the same categories file. On any single list view, Group: Category puts each card under its primary category, Group: Categories shows it under every category it holds (non-primary appearances dimmed and badged), Sort: Category orders by primary, and a Categories filter row narrows the list. All of this is shareable in the view URL. On a deck the two groupings nest inside every board, so headings read Main › Ramp and Sideboard › Draw. See Grouping, sorting and filtering by category.

Both the admin and the public in-browser editors edit categories directly: an Edit Categories… row in a card’s ⋯ menu, and a Categories (Manage categories) dialog for renaming, reordering, and removing. See Card Categories in the editors.

Code Meaning
0 Success
1 Runtime error (the <list>.categories.json file could not be read — the command refuses rather than overwriting it)
2 Usage error (a malformed category name, an empty order value, an ambiguous list name, prompts unavailable for the interactive list picker)
3 Not found (missing list file, or a category the list does not use given to rename/remove)