Symbols
Caret ships ten glyphs that carry brand identity across every component. The manifesto lists them as one of the seven hard rules: "Never customize Caret symbols. They are the brand." A user who has seen ^ and ▸ and ✓ in one Caret CLI should recognize them in every other Caret CLI.
Brand mark
| Glyph | Token | Where used |
|---|---|---|
| ^ | symbols.anchor | Banner heads, prompt frames, splash logos. The mark. |
State indicators
| Glyph | Token | Meaning |
|---|---|---|
| ✓ | symbols.state.success | Operation completed successfully |
| ✗ | symbols.state.failure | Operation failed |
| ⚠ | symbols.state.warning | Soft problem — attention but not error |
| ℹ | symbols.state.info | Informational message |
| — | symbols.state.cancelled | User cancelled (Esc on a prompt) |
Selection markers
| Glyph | Token | Meaning |
|---|---|---|
| ● | symbols.marker.selected | Selected radio / multi-select item |
| ○ | symbols.marker.unselected | Unselected radio / multi-select item |
| ▸ | symbols.progress.arrow | Focus indicator, list arrow variant |
Structure
| Glyph | Token | Where used |
|---|---|---|
| │ | symbols.structure.gutter | Quote, error, alert left gutter |
| ─ | symbols.ruler | Banner rule, divider, section separator |
Why "do not customize"
Two reasons. First, recognizability: a CLI users identify as "Caret-built" gives them confidence about the rest of the interaction — they know ✓ means done, ✗ means failed, no need to relearn.
Second, spec portability: the spec for error says "prefix with symbols.state.failure". A Go port reads the spec, renders the same glyph, and the result feels like the same product. If symbols were customizable, the spec would have to say "the concept of failure", and ports would diverge.
symbols via setTheme. Caret won't stop you. But it stops being a Caret CLI at that point — that's the point of the rule.ASCII fallback
On dumb terminals or when NO_COLOR is set, glyphs that rely on Unicode (✓ ✗ ⚠ ℹ ● ○ ▸ ─ │) fall back to ASCII equivalents (+ x ! i [x] [ ] > - |) automatically. The capability layer makes this decision; you don't opt in. See Capability detection.