Commands

Commands

homebot --help prints the same list. homebot <command> --help (or homebot help <command>) prints that command’s own page: what it does, its options and examples. Each homebot persona subcommand has a page of its own (homebot persona use --help, homebot help persona use). --help never runs the command, whatever else is on the line. Every command that changes something refreshes the inbox afterwards.

homebot unpack runs every step without asking; homebot unpack --dry-run lists them first.

Use homebot persona to list voices and choose or write one. Personas change eligible terminal messages, while stored text and commands keep their original wording.

Use homebot name [word] to show or set this home’s optional command name, and homebot name --off to remove it. homebot always remains available. See Naming your homebot for PATH, conflicts and removal.

Global options

--plain makes homebot speak in its neutral voice for one run, with no persona; HOMEBOT_PLAIN=1 does it for every run. It goes before the command (homebot --plain save) or among the options of a command that takes options (homebot save --plain). next, keys, triage, inventory, export, actions, action and shell take the words after their name as typed, so there --plain goes before the command’s name. homebot help takes it on either side of the command’s name (homebot help --plain link). homebot --help does not list it.

Attention

Command Does
homebot The inbox: top 5 things that need you. --all for everything.
homebot next Run the fix for the first item.

Moving in

Command Does Flags
homebot unpack [profile] Run a profile’s steps --dry-run, --from N
homebot pack <path> Move from $HOME into the repo, link back --layer common|linux|macos, --private
homebot link Make every link, list what’s in the way. Exits 1 on layout errors. --backup, --dry-run
homebot unlink Remove every link homebot made. Files stay in the repo, so the next homebot link (or the hourly helper) links them again; to keep a file unlinked, take it out of the repo.
homebot cleanup Go through the backups link --backup left: a diff for each (in fzf when it’s installed), then delete, keep, use it, or merge some of its lines into the repo file. See Cleaning up backups. --list

Secrets

Command Does Flags
homebot keys init Create the key pair (asks for a passphrase)
homebot unlock Decrypt private/ --theirs (take the other machine’s version)
homebot lock Encrypt what changed --ours (keep this machine’s version), --wipe (delete plaintext)

Keeping order

Command Does Flags
homebot triage One question per new file in watched folders
homebot inventory Links, secrets, repo, exports, helper at a glance
homebot remote [url] Set up where the repo is backed up. See Backing up.
homebot save Seal, commit, pull --rebase, push -m "msg", --no-push
homebot export [name...] Snapshot installed packages into manifests/
homebot tidy Run the hourly chores now --notify, --quiet
homebot setup Take a machine from nothing to an empty inbox: checks for gitleaks (offers brew install), clones your home repo or starts one in ~/.home (never touching a ~/.home that holds something else), unpacks a clone, installs the commit guard and the background helper, asks for your git name and email when git has none, and offers the zsh startup line, triage, a remote and a commit of what it changed (never your own uncommitted work). Steps already done are skipped, and it ends on the inbox. Without a terminal it asks nothing and creates no repo. The helper gets the XDG_* folders setup ran with; run setup again after changing one. A relative XDG_* is refused. --name chooses the command name (see homebot name). --persona writes persona: after checking the persona as homebot persona use does: it must exist and load, and a refusal leaves the machine untouched. --remove, --name WORD, --persona ID
homebot version Print the version. --check asks GitHub for the latest release, the only release request a command you type makes (the inbox reads what the helper saved), then prints the current and latest versions and how this copy was installed. When a newer release exists it also prints the command that upgrades this install; when this copy is already current it says so and prints no command and nothing about automatic updates. Source and development builds say they don’t update themselves. With update: auto and a newer release it also says what the helper will do here: the install method can’t update itself, cosign is missing or too old, the helper hasn’t seen the release yet, the release is in its 48-hour soak (with the time it ends), the last attempt failed or left the old version in place (the helper tries again no sooner than 24 hours after an attempt), or an automatic update is eligible, on the helper’s next run or, when its next check isn’t due yet, on its first run after the time shown. --check
homebot actions List the actions profiles can use. It takes no arguments; to run one, use homebot action <name>.
homebot action <name> [args] Run one action by hand, e.g. homebot action apt-repos linux/apt-repos
homebot shell zsh Print the shell integration. When a command name is set and ~/.local/bin/<name> links to homebot, it also completes that name, once zsh completion for homebot is loaded before the eval line: by compinit on a Homebrew cask, Debian or RPM install, which ship _homebot (for the cask, Homebrew’s shellenv must run before compinit: see Homebrew), or by sourcing homebot completion zsh on a script or Go install (see Shell integration).
homebot name [word] Show or set the command name for this home; --off returns to homebot. This is separate from the persona. Tab completion for the name works in zsh only (see homebot shell zsh); bash and fish complete homebot but not the name. --off
homebot persona [list] List built-in and local personas and mark the current one. A persona with an error in its chain is marked [unusable]. If homebot.yml cannot be loaded, the list is still printed, nothing is marked current, the config error is reported as persona use reports it, and the exit is 1.
homebot persona show <id> Show the header, colours and four voiced samples.
homebot persona use <id|none> Validate and write persona: in homebot.yml, then refresh the shell nudge, prompt symbol and count. Says so when HOMEBOT_PERSONA overrides the new choice in this shell.
homebot persona new <id> Create a local persona file without overwriting one. --from ID
homebot persona validate [id|file] Check the active choice, an ID or a TOML path, together with the personas it extends; exit 1 on errors, and on a homebot.yml that cannot be loaded. Findings name files under the config directory relative to it.
homebot persona preview <id> Show light and dark samples without changing your repo or sending a notification. --event fills the slots the inbox fills with another message or a count; other slots show a generic sample. --event ID, --all-variants
homebot persona ids List voice IDs, English text and placeholder rules.

Triage keys

homebot triage shows each new thing in ~/.config/* and ~/.* once:

Key Answer
t track everywhere (autolink/common)
o track on this OS only
i ignore forever (written to decisions.yml)
s snooze 7 days (this machine only)
Enter next
q quit

Backing up: homebot remote

Without a remote, nothing leaves the machine, and the inbox says “Not backed up”. homebot remote sets one up:

  • g: create a private GitHub repository with gh; l: the same on GitLab with glab. Only offered when that tool is installed and logged in; when it is installed but not logged in, it says to run gh auth login first. It asks for a name (the repo folder’s, home for ~/.home, by default).
  • u: paste the URL of a repository you already have.
  • Enter: not now.

A new repository’s ssh address is used when ~/.ssh has a key, else its https address (then gh auth setup-git lets git use gh’s login). Then it pushes.

With a remote already set, it checks that git can reach it and pushes what isn’t there yet. When an https remote fails because nobody is logged in and there is an ssh key, it offers the ssh address of the same repository. homebot remote <url> makes that URL the remote. Without a terminal it only explains.

The inbox shows “Not backed up yet” while a remote has never received a push, which is also how a remote git can’t log in to shows up.

Where the repo is found

$HOMEBOT_ROOT → the current directory (walking up to a homebot.yml) → the binary’s location → ~/.home.

Generated command details

The sections below come from the same command tree and help catalog used by the binary. Regenerate them with go run ./tools/gendocs docs.

inbox

Usage: homebot [--all]

Lists what needs you, most urgent first, each with the command that fixes it,
and what the background helper did since you last looked. homebot inbox is
the same command.

Option Meaning
--all show every item, not only the first five

next

Usage: homebot next

Runs the fix for the first inbox item, the command shown next to it. When the
fix is a shell command homebot shouldn't run for you, it prints it instead.

unpack

Usage: homebot unpack [profile]

Runs a profile's steps in order, without asking first: package installs
(brew, apt, flatpak…), links, secrets and run: commands. Each step is
printed as it starts. Without a name it uses this machine's profile from
homebot.yml (profiles.hosts, else profiles.default).

Preview the steps with --dry-run. A step that fails stops the run and prints
the --from that resumes after you fix it. Steps that are already done (a
package that is installed, a link that exists) do nothing the second time.

Option Meaning
--dry-run list the steps without running any
--from N start at step N, skipping the ones before
Example Meaning
homebot unpack --dry-run what this machine's profile would do
homebot unpack server --from 4 resume the server profile at step 4

pack

Usage: homebot pack &lt;path&gt;...

Moves a file or folder from $HOME into the repo and puts a link in its place,
so it is tracked from then on. It goes to autolink/common unless --layer says
otherwise. With --private it is sealed under private/ (encrypted with age)
instead. Commit it with homebot save.

Option Meaning
--layer common|linux|macos the layer to put it in (default: common)
--private a secret: seal it under private/
Example Meaning
homebot pack ~/.config/zed track Zed's settings on every machine
homebot pack --layer linux ~/.config/foo track it on Linux only
homebot pack --private ~/.ssh/id_ed25519 track a key, encrypted

Usage: homebot link

Links everything under autolink/ (and unlocked secrets under private/) into
$HOME. It never overwrites anything: what is in the way is listed as blocked.
A file identical to the repo's copy is replaced by the link, since nothing is
lost.

–backup moves the blockers aside first, renamed <name>.homebot-backup-<time>,
and then links. homebot cleanup goes through those backups later.

Option Meaning
--dry-run show what would change, change nothing
--backup move what is in the way aside, then link

Usage: homebot unlink

Removes every link homebot made. The files stay in the repo, so the links
come back with the next homebot link, and within the hour from the background
helper (homebot tidy). To keep a file unlinked, take it out of the repo.

cleanup

Usage: homebot cleanup

Goes through the backups homebot link --backup left
(<name>.homebot-backup-<time>) one at a time. Each shows how it differs from
what is linked there now (beside the choices, when fzf is installed), and you
pick:

delete remove the backup; what is linked there now stays
keep leave it; homebot asks again next time
use copy the backup over the repo file, then remove it
merge take some of the backup's lines into the repo file

merge opens lazygit when it is installed. The backup's lines are the green
ones: space takes the line under the cursor, shift+arrows select several, d
drops them, q finishes. Without lazygit it is git add -p: y takes a block, n
skips it, s splits it smaller, e edits it. What you took is written to the
repo file, and the same backup comes back with what is left, so you can
delete it.

Option Meaning
--list only list the backups

keys

Usage: homebot keys init

Creates the age key pair that seals private/. It asks for a passphrase, then
writes private/identity.age (the key, encrypted with that passphrase) and
private/recipients.txt (the public key). Run it once ever; other machines get
the key with the repo and run homebot unlock.

unlock

Usage: homebot unlock

Decrypts the secrets in private/ and links them into $HOME. A secret that
changed both here and in the repo is left alone and listed as a conflict.

Option Meaning
--theirs for conflicts, take the repo's version

lock

Usage: homebot lock

Seals the secrets in private/ that changed since they were last sealed. The
background helper does this on its own before each autosave.

Option Meaning
--ours for conflicts, keep this machine's version
--wipe also delete the decrypted copies (keeps any that aren't safely sealed)

triage

Usage: homebot triage

Asks once about each new thing in the watched folders (~/.config/, ~/.) and
each untracked file in the repo. Each answer is saved right away:

t track it everywhere (moves it into autolink/common, links it back)
o track it on this OS only
i ignore it for good (written to decisions.yml)
s snooze it for 7 days (this machine only)
enter next
q stop

inventory

Usage: homebot inventory

One screen: this machine's profile and whether it changed since the last
unpack, links, secrets, things to triage, the repo and its remote, package
exports and the background helper.

remote

Usage: homebot remote [url]

Without a remote, offers to create a private repository with gh (GitHub) or
glab (GitLab), when one is installed and logged in, or takes a URL you paste.
Then it pushes. With a URL, makes that the remote (origin).

With a remote already set, checks that it can be reached. When an https
remote fails for lack of a login and you have an ssh key, it offers the ssh
address of the same repository.

Example Meaning
homebot remote check the remote, or set one up
homebot remote git@github.com:you/home.git use this one

save

Usage: homebot save

Seals changed secrets, commits the changes to tracked files and package
snapshots, then pulls (rebasing local commits) and pushes. New files aren't
committed: triage decides about them first. The background helper does the
same on its own (autosave in homebot.yml).

Option Meaning
-m, --message TEXT the commit message (default: one listing the files)
--no-push commit and pull, but don't push

export

Usage: homebot export [name...]

Writes what is installed (Brewfile, apt and flatpak lists, vendor apt
repositories…) into manifests/, as configured under exports in homebot.yml.
Without names it runs every export for this OS. The background helper runs
them about once a day.

Example Meaning
homebot export apt apt-repos after installing a package from a new apt repository

tidy

Usage: homebot tidy

Runs what the background helper runs on its timer: installs the commit guard
if it's missing, seals secrets, refreshes package exports that are due,
autosaves and syncs (when homebot.yml turns autosave on), fixes links that
are safe to fix, and refreshes the inbox.

Option Meaning
--notify show a desktop notification when something needs you
--quiet print nothing

setup

Usage: homebot setup

Takes you from nothing to an empty inbox, one question at a time. It checks
for git and gitleaks, clones your home repo or starts a new one in ~/.home,
installs the commit guard and the background helper (a systemd user timer on
Linux, a launchd agent on macOS), and offers to load the shell integration,
back the repo up and commit. Steps already done are skipped, so running it
again is safe. Without a terminal it asks nothing, creates no repo, and says
what is left.

Option Meaning
--remove uninstall the background helper
--name WORD choose a command name for your homebot
--persona ID choose the persona for this home repo

actions

Usage: homebot actions

Lists the actions profile steps can use: the built-in ones (link, unlock,
run) and the scripts in homebot/actions/.

action

Usage: homebot action &lt;name&gt; [args...]

Runs one action with the environment a profile step gets. Everything after
the name goes to the action, so homebot action &lt;name&gt; --help reaches the
action; this page is homebot action --help.

Example Meaning
homebot action apt-repos linux/apt-repos add the vendor apt repositories

shell

Usage: homebot shell zsh

Prints the zsh integration: the prompt line that says when something needs
you, refreshed in the background. Load it from .zshrc:

eval "$(homebot shell zsh)"

name

Usage: homebot name [word]

Shows the name in homebot.yml and the name that works here. Give a word
to make it a command on this machine, or use --off to remove a link homebot
made. A name may need a new shell before it works.

Option Meaning
--off remove the name and a link homebot made

persona

Usage: homebot persona [command]

List, inspect, create, and choose the voice homebot speaks in.

Option Meaning
--from ID copy an existing persona's header and lines when creating a new one
--event ID preview one voiced message id
--all-variants show every valid variant in a preview

version

Usage: homebot version

Prints the version of this homebot. homebot --version and homebot -v
print the same.

Option Meaning
--check Check the latest release and show how this install can upgrade