PATTERNS
cathode_suggest_component tool so AI
agents can route from intent to composition.
1. Dashboard readout
Use when you need to surface a snapshot of live system state at a
glance — a TerminalFrame groups the values, DotLeader renders
each labelled row, PulsingDot marks live status, and
PixelBar / ActivityBar animate rolling metrics.
<TerminalFrame title="TELEMETRY" accent="info">
<Stack gap={6}>
<Stack direction="row" gap={8} align="center">
<PulsingDot color="var(--cathode-color-success)" />
<span>LIVE</span>
</Stack>
<DotLeader label="LATENCY" value="42 MS" />
<DotLeader label="STATE" value="HEALTHY" valueColor="var(--cathode-color-success)" />
<PixelBar level={0.68} cells={28} fill="var(--cathode-color-info)" />
<ActivityBar intensity={0.55} seed={tick} cells={28} />
</Stack>
</TerminalFrame> 2. Settings panel
Each input gets wrapped in a FormField so labels, hints,
and errors stay consistent. The inputs themselves are all
controlled (value/onChange), which keeps
validation and submission logic simple.
<Stack gap={16} fullWidth>
<FormField label="CALLSIGN" hint="4 chars, alphanumeric." required>
<TextField value={callsign} onChange={setCallsign} />
</FormField>
<FormField label="TRANSMIT SPEED">
<Counter value={wpm} onChange={setWpm} min={5} max={40} label="WPM" />
</FormField>
<FormField label="THEME">
<Select value={theme} onChange={setTheme} options={themeOptions} />
</FormField>
<Stack direction="row" gap={24} wrap>
<Toggle value={notify} onChange={setNotify} label="NOTIFICATIONS" />
<Toggle value={danger} onChange={setDanger} label="DANGER MODE" accent="danger" />
</Stack>
<Button variant="primary" onClick={save}>SAVE</Button>
</Stack> 3. Destructive flow
Button variant="danger" opens a Dialog with matching
accent. A Toggle arms the destructive action; only then does
HazardStripes reveal the real confirm button. The user
has to cross three deliberate gates, so accidents don't happen.
<Button variant="danger" onClick={() => setOpen(true)}>
DELETE ACCOUNT
</Button>
<Dialog open={open} onClose={close} title="DELETE ACCOUNT?" accent="danger">
<p>Permanently removes callsign, history, presets. No undo.</p>
<Toggle value={armed} onChange={setArmed} label="I UNDERSTAND" accent="danger" />
{armed ? (
<HazardStripes intensity={0.16}>
<Button variant="danger" onClick={confirmDelete}>CONFIRM DELETE</Button>
</HazardStripes>
) : (
<Button variant="danger" disabled>CONFIRM DELETE</Button>
)}
</Dialog> 4. Loading states
Three flavours of "waiting" — each has a specific fit:
Skeletonwhen you know the shape of the content that's coming and want the page to stop jumping.Loaderwhen you're waiting on something with unknown duration — a connection, a retry, a handshake.ProgressBarwhen you know the percentage — downloads, uploads, multi-step tasks.
<Skeleton variant="text" width={180} />
<Skeleton variant="block" height={60} />
<Loader size="md" /> <span>CONNECTING…</span>
<ProgressBar value={uploadPct} showValue /> How patterns support AI agents
Agents using Cathode via the MCP server can call
cathode_suggest_component(intent) with natural-language
intents ("I need to show a confirmation before deleting"),
and the ranked results lead them straight to the right primitives.
The patterns here then show how to compose those primitives into a
real screen — canonical call sites with full props.
Long-form guidance for agents lives in
CATHODE.md at repo root, which is auto-generated from cathode.manifest.json and regenerated on every npm run gen.