list-all-cards
Print a deduplicated, alphabetically sorted manifest of every card known to your decks, collections, and wanted lists. Designed primarily as a deterministic cache key input for CI builds — its output changes only when the set of unique (name, set, collector number) tuples in your lists changes.
The manifest excludes quantities, finishes, conditions, notes, and card IDs. If a card appears in multiple lists or with the same printing in different decks, it is collapsed into a single entry.
The command is strictly read-only: it never writes to list files (it is exempt from the card-ID backfill), so running it in CI never dirties the checkout.
./ritual list-all-cards [options]Options
Section titled “Options”| Option | Description | Default |
|---|---|---|
--out <file> | Write the manifest to this file instead of stdout (- means stdout) | (stdout) |
--output <format> | Output format: text, json, or ndjson | text |
--quiet | Suppress the Wrote N cards to <path> confirmation | false |
Without --out, the manifest is the command’s stdout — pipe or redirect it wherever you like. With --out, the file is written (parent directories are created as needed) and a Wrote N cards to <path> confirmation is printed instead; a relative path is resolved against the base directory.
Output format
Section titled “Output format”text (the default) is the markdown manifest:
# All cards
- Black Lotus (LEA:232)- Lightning Bolt- Lightning Bolt (LEA:161)- Sol Ring (CMR:472)- Sol Ring (ECC:57)Each line is a - name (SET:CN) entry, with the parenthesized printing omitted when a card has no set/collector number.
json emits the raw entry array (set codes lowercase, as stored internally; absent fields are omitted):
./ritual list-all-cards --output json[ { "name": "Black Lotus", "set": "lea", "collectorNumber": "232" }, { "name": "Lightning Bolt" }, { "name": "Sol Ring", "set": "cmr", "collectorNumber": "472" }]ndjson emits the same entries one JSON object per line. --out writes whichever format was selected to the file.
Diagnostics
Section titled “Diagnostics”A list file that cannot be read or parsed (for example a deck with broken YAML front matter) does not abort the run: the file is skipped, a warning: skipped <file>: <reason> line goes to stderr, the manifest is still emitted from the remaining files, and the command exits 1 so CI can tell the manifest is incomplete.
Non-fatal parser warnings (a malformed card line, prose, or a comment inside an otherwise readable file) are also printed to stderr but do not affect the exit code — the manifest is still deterministic over the lines that did parse.
Exit Codes
Section titled “Exit Codes”| Code | Meaning |
|---|---|
0 | Success |
1 | One or more files were skipped (manifest incomplete), or the write failed |
2 | Usage error (e.g. an invalid --output format) |
Why this exists
Section titled “Why this exists”The generated GitHub Actions workflow uses this file as the cache key for the Scryfall data cache:
- name: Generate card manifest run: ./ritual list-all-cards --out all-cards.md
- name: Restore Scryfall cache uses: actions/cache@v5 with: path: cache/ key: ritual-cache-${{ hashFiles('all-cards.md') }}This means the cache is reused across builds whenever the set of cards in your lists hasn’t changed — even if you tweak finishes, conditions, notes, or quantities, or rearrange existing cards across files.
all-cards.md is added to the .gitignore generated by ritual init-site. You don’t need to commit it.
Examples
Section titled “Examples”Print the manifest to stdout:
./ritual list-all-cardsWrite the CI cache-key file:
./ritual list-all-cards --out all-cards.mdFeed the unique cards to a script:
./ritual list-all-cards --output ndjson | jq -r .name | sort -uUse with --base-dir:
./ritual --base-dir ~/mtg list-all-cards