The CLI
The terminal ships two commands, split by what they act on:
brain— brAIn’s own faculties: memory, findings, learning, undo, file ownership, diagnostics.ha— Home Assistant operations: logs, reloads, entities, services, add-ons.
The split exists so that “which log?” is never a question anyone has to ask. brain help and ha help list everything; typing a subcommand into the wrong dispatcher tells you which one it belongs to rather than failing quietly.
These cover the file-and-workflow side that live APIs don’t; the live home belongs to the MCP tools, and admin changes to Power Tools — see how the layers fit.
brain — its own faculties
| Command | What it does |
|---|---|
brain memory <action> |
The home memory: add, list, forget, edit, inbox, hypotheses (alias guesses), confirm, reject, log (--show <n> prints one entry in full), undo, consolidate, clear, export, import |
brain findings <action> |
The findings work list: list (default), fix <id>, done <id> ["note"], wrong <id> ["note"], ack <id>, snooze <id> [hour|tomorrow|week|month|now] |
brain learn [topic] |
Run a study session. With a topic, on that topic; without one, on whatever has gone stalest |
brain ask "<question>" |
One-shot question about your home — the same engine as the panel’s Ask card |
brain undo [n] |
List the files Claude edited, in plain English, and revert one |
brain own [-r] <path…> |
Make a file Claude cannot write writable again — usually one Home Assistant saved as root. -r does a whole folder. Raises no approval card and needs no sudo |
brain why [ask] |
What brAIn is curious about — why somebody here does something by hand — and what it has worked out. ask asks the next question now, which spends one Claude run |
brain doctor |
Run this first when anything misbehaves — drives the whole stack end-to-end (MCP, auth, listeners, worker pool, memory) and prints PASS/FAIL with a fix hint per part. Free: it never calls Claude. --json gives the same verdict as one object |
brain doctor --deep |
Every face of brAIn, one real round trip each — a plain Claude run, the analyst’s tools, a chat turn, an automation task, Assist, memory, findings and one real fix. Spends about five Claude turns; only ever runs when you ask |
brain doctor --rehearse |
Plant a few defects named brain_test_*, run the checks and the analyst against them, score both, then remove everything. Asks first, and says exactly what it would create. --yes skips the question |
brain doctor --sweep |
Take out anything named brain_test_* a rehearsal left behind. Creates nothing and spends nothing |
brain eval outcomes |
How the Resident’s judgement has held up: what it decided and what you did next, per producer and per entity, and how its stated confidence held. Free. --nightly runs the nightly grading pass now |
brain eval first_look |
Replay captured first looks against today’s prompt and report how often they agree with what you did. Spends real Claude runs, capped (--days, --max-tokens, --max-batches); changes nothing |
brain check |
Run the house checks now, through the panel’s API — list for the catalog and when each last ran. No Claude run, no tokens |
brain weekly [send] |
The week’s numbers and the last report sent; send writes and sends this week’s now |
brain report |
Write one redacted text file to /share/brain/reports/ for a bug report — also listed under ⚙ → Problems (--no-names to hash entity ids) |
brain login [--status|--share] |
Sign in to Claude, and share that login with the other BRUH add-ons. The same command as ha login — the credential is brAIn’s, and this is where people look for it |
brain help |
The full list |
brain memory add "We call the office lamp the beacon"brain memory hypotheses # pending guesses awaiting a yes/nobrain memory confirm "the garage fridge runs 24/7"brain findings done 2 "replaced the battery myself"brain learn energybrain undo --all-today # revert everything Claude changed todaybrain own /config/scenes.yaml # hand a root-saved file back to Claudebrain doctor # free, and the one to run firstbrain doctor --deep # every face, one real round trip eachbrain doctor --rehearse # plant defects here, score, clean upbrain eval outcomes # what the Resident decided, and what you did nextbrain findings goes through the panel’s own API, never the store files — so a CLI ending
writes the same memory line, settled key and undo token the tab’s buttons write. brain doctor’s coverage roughly doubled across 1.25.0 and 1.27.0: it now also proves the panel
and chat API are answering, the terminal’s password gate is actually on, the Claude CLI
itself runs, the three background daemons are alive, the run-sources ledger is
claude-owned, no crashed consolidation pass is still holding its lock, disk space, and how
stale the usage reading is — and it reads /api/health’s daemon roll-call and compares it
against its own view. Since 1.47 it also warns if a rehearsal left anything named
brain_test_* behind, and names the command that removes it.
The three doctors cost three different amounts, and only the first is free:
| What it answers | What it spends | |
|---|---|---|
brain doctor |
Is the plumbing connected? | nothing |
brain doctor --deep |
Does each face work end to end, right now? | about five Claude turns |
brain doctor --rehearse |
Do the checks and the analyst find a defect planted in this house? | one analyst run |
Neither costed one ever runs on a timer, and both are also buttons in ⚙ Settings → Diagnostics. The full walk-through: Deep Check & Rehearsal.
ha — Home Assistant operations
| Command | What it does |
|---|---|
ha log [core|supervisor|host|addon <name>|errors|all] |
Tail HA logs. -f to follow, -n N for line count |
ha reload <target> |
Reload HA config: automations, scripts, scenes, groups, every helper domain (input_booleans, input_numbers, input_selects, input_texts, input_datetimes, timers, counters), core, all — or check to validate without reloading. Singular forms work too |
ha check [path] |
Validate YAML before reloading (alias: ha yaml) |
ha context |
Regenerate /config/CLAUDE.md, the context file Claude reads each session (failed every time until 1.26.0 — the dispatcher ignored the script’s shebang) |
ha entity <action> <id> |
Get/set entity states: get, set, list, search |
ha service call <domain>.<service> |
Call any HA service from the shell |
ha addon <action> <slug> |
Manage add-ons: list, info, restart, stop, start, logs, options |
ha notify "msg" |
Send a persistent or mobile push notification |
ha share <action> |
Cross-add-on file sync via /share: push, pull, ls |
ha login [--status] |
Sign in to Claude from the shell, and share that login with the other BRUH add-ons — the same command as brain login. --status reports every store |
ha help |
The full list |
If ha is already taken
If some other ha command is ever present on PATH inside the container, brAIn installs its own as hass instead rather than shadowing it. The startup log says so when this happens.
Also on PATH
| Command | What it does |
|---|---|
persist-install apk|pip <pkgs> |
Install packages that survive add-on restarts (list, remove too) |
Files Claude cannot write: brain own
Claude Code runs as its own non-root user, and Home Assistant saves automations.yaml,
scripts.yaml and scenes.yaml as root, which can leave them read-only for Claude. Other
add-ons do the same with their own config. Since 2.11 brAIn hands those files back by
itself — at startup, right before Claude edits a file it cannot write or runs a shell command
that names one, and about once a minute for the top-level YAML the editors rewrite and each
add-on’s folder under /addon_configs. Claude is told never to ask you for sudo or
chown.
brain own is the same hand-over on demand, for anything the hooks can’t see — typically a
command writing to a path held in a variable:
brain own /config/scenes.yaml /config/scripts.yamlbrain own -r /config/packages # a whole folderIt works under /config, and under /addon_configs, /share, /media and /addons while
the add-on’s access option for each is on. It makes the file writable for Claude as well as
handing it over, so a file somebody made read-only works too. It never touches anything
outside those folders, .storage, .cloud, brAIn’s own credentials, secrets.yaml, the
recorder database or a file with other hard links; a symbolic link is answered for the file
it points at, which has to pass the same checks. It raises no approval card. If it says the
panel is not answering, the add-on isn’t running — brain doctor checks that. More in
Permissions & Safety.
Undo
Before Claude writes to any file under /config, the previous version is snapshotted —
notebook edits included, since 1.26.0. Only /config is journalled, and secrets.yaml is
never snapshotted. Snapshots are kept for edit_journal_days (default 14).
Since 1.44.0 the journal also covers the writes that happen without a Claude run at all:
accepting a proposal appends an automation
to automations.yaml, and it is snapshotted first, in the same line shape, so brain undo
puts it back exactly as it puts back an edit.
1.46.0 added two more shapes of that write and both are journalled the same way — four
scenes appended to scenes.yaml, and a single entry changed or cut out of
automations.yaml in place, which is what a
condition proposal and a
one-off’s Remove do. The snapshot is the whole file either way, so
brain undo restores the bytes you had rather than reversing an edit after the fact.
brain undo # list what Claude edited, newest first, in plain Englishbrain undo 3 # put edit #3 back, byte for bytebrain undo --all-today # revert everything Claude changed today 1 14:22 automations.yaml modified (added brightness to the hallway action) 2 14:19 scripts.yaml modified 3 09:41 packages/energy.yaml createdThe hook that takes the snapshot can never block an edit: if it fails for any reason it exits quietly and Claude carries on. A journal that stops you working is worse than no journal.
What it covers is edits made with Claude’s file tools. A change made by a shell command — a redirect, a script — reaches no journal, which is one reason the terminal and the chat ask before acting by default. The service calls a Fix it made are put back with Put them back on its card instead; see Permissions & Safety.
This is not a backup system. brAIn doesn’t version your configuration — Home Assistant’s own backups do that job, whole-system and restorable. The edit journal only covers files brAIn itself touched. See Reference.
In the terminal, they’re a palette
You don’t have to remember any of this. In the Terminal tab, typing
brain or ha opens a palette of every subcommand your install actually has — read from
what the dispatchers print, so it can’t go stale — and / lists Claude Code’s own commands,
including anything you’ve dropped in /config/.claude/commands.
Two of those are worth knowing: /learn [topic] starts a study session you can watch and
correct mid-flight, and /memory shows what it knows right now.
Everything is brAIn-usable
The generated context lists both dispatchers, so “reload automations”, “check the logs for zigbee errors”, or “what did you learn last week?” resolve to the right command without you naming it.