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.
./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.
Arguments
Section titled “Arguments”| Argument | Description | Required |
|---|---|---|
[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 |
Options
Section titled “Options”| 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, --note <text> | Note text. Replaces any existing note. Cannot be empty — use --clear to remove a note. | |
--clear | Remove 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-run | Report what the note would become without writing anything (long form only — -n is --note) | false |
--output <format> | Output format: text, json, or ndjson | text |
--quiet | Suppress non-essential output | false |
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: …).
Examples
Section titled “Examples”Fully interactive (prompts for everything):
./ritual noteSet a note on a deck card (name resolved across all list types):
./ritual note "My Deck" Sol Ring --note "starts the engine"Pin the list type when a name is ambiguous, or to be explicit:
./ritual note --deck "My Deck" --card-id 17 --note "alpha printing"Replace an existing note — setting always overwrites:
./ritual note --collection "Main" "Mana Crypt" --note "tutor target"Remove a note:
./ritual note --collection "Main" "Mana Crypt" --clearPipe a JSON record for scripting:
./ritual note --collection main "Sol Ring" --note "first edition" --output jsonBehavior
Section titled “Behavior”Setting Replaces
Section titled “Setting Replaces”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"}Clearing Is Idempotent
Section titled “Clearing Is Idempotent”--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"}List Resolution
Section titled “List Resolution”[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.
Card Resolution
Section titled “Card Resolution”- By name: the input is fuzzy-matched against the cards in the list. Punctuation, case, and accents are ignored (so
seancematchesSéance); substring matches are accepted. If multiple cards match (e.g. two different printings of “Lightning Bolt”), the command exits with ausage_errorlisting each match. Disambiguate with--card-idor run interactively. - By card ID: pass
--card-id <N>to target an entry by its persistent&Nsuffix. 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 Runs
Section titled “Dry Runs”--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.
Quantity Behavior
Section titled “Quantity Behavior”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.
Note Validation
Section titled “Note Validation”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.
Change Tracking
Section titled “Change Tracking”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.
Exit Codes
Section titled “Exit Codes”| Code | Meaning |
|---|---|
0 | Success (note set or cleared, or no-op --clear when no note existed) |
2 | Usage 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) |
3 | Not found (missing list file, missing card, missing card ID) |
1 | Runtime error (file changed concurrently, etc.) |