Skip to content

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
Terminal window
brain memory add "We call the office lamp the beacon"
brain memory hypotheses # pending guesses awaiting a yes/no
brain memory confirm "the garage fridge runs 24/7"
brain findings done 2 "replaced the battery myself"
brain learn energy
brain undo --all-today # revert everything Claude changed today
brain own /config/scenes.yaml # hand a root-saved file back to Claude
brain doctor # free, and the one to run first
brain doctor --deep # every face, one real round trip each
brain doctor --rehearse # plant defects here, score, clean up
brain eval outcomes # what the Resident decided, and what you did next

brain 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:

Terminal window
brain own /config/scenes.yaml /config/scripts.yaml
brain own -r /config/packages # a whole folder

It 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.

Terminal window
brain undo # list what Claude edited, newest first, in plain English
brain undo 3 # put edit #3 back, byte for byte
brain undo --all-today # revert everything Claude changed today
brain undo
1 14:22 automations.yaml modified (added brightness to the hallway action)
2 14:19 scripts.yaml modified
3 09:41 packages/energy.yaml created

The 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.