Skip to content

note

Set, replace, or clear the note on a card that already exists in a deck, collection, or wanted list.

Notes are stored in list files as {note text} between the bracketed metadata and the &N card ID.

The edit is line-preserving: only the targeted card’s line is rewritten. Everything else in the file — prose, comments, lines the parser cannot read — stays byte-for-byte intact.

Terminal window
./ritual note [listName] [cardName...] [options]

[listName] is resolved across all three list types (see List Resolution); pass a --deck, --collection, or --wanted flag (or a deck:/collection:/wanted: prefix on the name) to pin the type or disambiguate; a prefix that contradicts the flag is a usage error. If invoked with no list name, the command runs interactively, prompting you to pick a list (filtered by the type flag if given), then the card and note text. Any argument or option you supply skips the corresponding prompt — fully scripting-friendly. The list and card prompts require a terminal with prompts enabled too — with piped stdin or --no-input, a missing [listName] or card selector ([cardName...]/--card-id) exits with a usage error (code 2) instead of prompting.

ArgumentDescriptionRequired
[listName]Name of the deck, collection, or wanted list (case- and accent-insensitive, no extension)No
[cardName...]Card name whose note to set or clear (fuzzy match)No
OptionDescriptionDefault
--deckResolve the name as a deck
--collectionResolve the name as a collection
--wantedResolve the name as a wanted list
-n, --note <text>Note text. Replaces any existing note. Cannot be empty — use --clear to remove a note.
--clearRemove the note from the card. Cannot be combined with --note.
--card-id <id>Disambiguate by card ID (the &N suffix in list files). Required when name search hits multiple printings.
--dry-runReport what the note would become without writing anything (long form only — -n is --note)false
--output <format>Output format: text, json, or ndjsontext
--quietSuppress non-essential outputfalse

If neither --note nor --clear is given, the command prompts for the note text (prefilled with the card’s current note). When prompts are unavailable (stdin is not a terminal, or --no-input / RITUAL_NO_INPUT is in force), one of the two flags is required — instead of prompting, the command exits with code 2 (Input required: …).

Fully interactive (prompts for everything):

Terminal window
./ritual note

Set a note on a deck card (name resolved across all list types):

Terminal window
./ritual note "My Deck" Sol Ring --note "starts the engine"

Pin the list type when a name is ambiguous, or to be explicit:

Terminal window
./ritual note --deck "My Deck" --card-id 17 --note "alpha printing"

Replace an existing note — setting always overwrites:

Terminal window
./ritual note --collection "Main" "Mana Crypt" --note "tutor target"

Remove a note:

Terminal window
./ritual note --collection "Main" "Mana Crypt" --clear

Pipe a JSON record for scripting:

Terminal window
./ritual note --collection main "Sol Ring" --note "first edition" --output json

Setting a note unconditionally replaces any existing note — there is no overwrite guard or confirmation. The previous text is reported back (previousNote in JSON output), so scripts can detect that a replacement happened.

{
"type": "deck",
"list": "my-deck",
"cardName": "Sol Ring",
"cardId": 17,
"note": "second",
"previousNote": "first"
}

--clear on a card that has no note is a successful no-op. The file is not rewritten, and no changelog entry is appended. JSON output reports { "cleared": false, "previousNote": null } for this case so scripts can distinguish a real clear from an idempotent run.

When a note is removed, the response includes the removed text:

{
"type": "deck",
"list": "my-deck",
"cardName": "Sol Ring",
"cardId": 17,
"cleared": true,
"previousNote": "starts the engine"
}

[listName] is matched case- and accent-insensitively across all list types (exact name first, then a unique substring), and a name that exists in more than one type is rejected unless you pin it with --deck, --collection, or --wanted. See List Resolution for the full rules.

  • By name: the input is fuzzy-matched against the cards in the list. Punctuation, case, and accents are ignored (so seance matches Séance); substring matches are accepted. If multiple cards match (e.g. two different printings of “Lightning Bolt”), the command exits with a usage_error listing each match. Disambiguate with --card-id or run interactively.
  • By card ID: pass --card-id <N> to target an entry by its persistent &N suffix. Card IDs are unique within each list file, and must be positive integers.

When a card name and --card-id are both given they must agree: the ID’s entry has to match the name by the same rule the name-only path uses. A disagreement is a usage error naming both (--card-id 3 is 'Demonic Tutor', which does not match 'Lightning Bolt'.) — IDs are reused from a pool after a removal, so a stale ID paired with a name is a strong signal the wrong card is about to be touched. ID-only and name-only invocations are unaffected.

--dry-run resolves the list, the card, and the note text, then reports what the note would become and stops — nothing is written (list file, changelog, .sha256 sidecar, or the card-ID backfill). The short -n is not available here: it is already --note. Text output is prefixed [dry-run]; JSON output carries "dryRun": true — including on the idempotent --clear no-op, which reports cleared: false and previousNote: null whether or not it is a dry run.

For deck lists with more than one quantity of any card not separated by printing (e.g. 4 Lightning Bolt), all copies share a single line and a single &N ID, so a single note attaches to all of them. To give one copy a different note, split the line into multiple entries first.

Notes are single-line text. The command trims surrounding whitespace and rejects any control characters (newlines, tabs, NUL, DEL, escape sequences). Quotes and other printable punctuation are allowed. The same validation applies to notes coming from the admin UI. An empty or whitespace-only --note value is rejected — clearing is an explicit action via --clear, never an empty set.

A set is recorded in the list’s .changes.md changelog as Set note on "<Card>" &N to "<text>"; a clear as Cleared note on "<Card>" &N. An idempotent --clear records nothing.

CodeMeaning
0Success (note set or cleared, or no-op --clear when no note existed)
2Usage error (conflicting type flags, a type prefix contradicting a type flag, a --card-id that disagrees with the card name, ambiguous list name, ambiguous card match, empty note, no --note/--clear when prompts are unavailable, prompts unavailable for interactive list/card selection)
3Not found (missing list file, missing card, missing card ID)
1Runtime error (file changed concurrently, etc.)