Free
$0
forever
- 2 profiles
- One-click switching, shortcuts, CLI
- Folder & branch context
- Identity verdict on every repo
Hats is a menu bar app for developers with more than one GitHub account. Bind a folder to a profile and every repo inside wears the right identity: commit email, SSH key, gh session, signing. Forget anyway, and the guard blocks the push.
Free · macOS 14+ · brew install --cask hats
includeIf sets the email. SSH aliases pick the key. gh auth switch changes the CLI. Each fixes its own layer and leaves the other three ready to betray you. Hats moves all four as one.
user.email Commit identity core.sshCommand Push authentication gh auth GitHub CLI commit.gpgsign Commit signing Bind a folder to a profile once. Every repository inside it, today's and next year's, wears that hat: right email, right key, right gh account, right signature. Clone anywhere under it and you're already the right person.
Prefer to think in organizations? Bind a GitHub org instead, and any of its repos wears the hat wherever you clone it. Underneath it's plain git includeIf: readable, removable, yours.
$ hats rule add --folder ~/clients/acme acme
Coffee, personal hat on. Commits signed with your own name, pushed with your own key. Green light, nothing to think about.
One cd and the folder rule flips all four layers at once: commit email, SSH key, gh session, signing. You typed nothing, you forgot nothing.
Different client, different identity, same zero effort. The right hat is already on when the terminal lands in the folder.
Outside every rule, old reflexes take over, and the commit would leave as personal. The guard refuses it, and prints the way out.
hats use acme: four layers flip, verdict turns green. Push, close the laptop.
cd ~/dev/side-projectcd ~/work/platformcd ~/clients/acme/billinggit clone acme-inc/billing /tmp/hotfixhats use acme $ git commit -m "Hotfix rounding"hats: wrong hat. This repo belongs to 'acme'.✗ commit blocked$ hats use acmeNow wearing 'acme'. gh CLI switched too.
billing % hats statusActive profile: acme <dev@acme.com>Repo: ~/clients/acme/billing (main)Verdict: ✓ identity matches profile 'acme'billing % hats rule add --folder ~/clients/acme acmeRule added: folder '~/clients/acme/' → acmebilling % hats doctor✓ git 2.44 ✓ gh authenticated ✓ guard hooks installedbilling % ▍
Everything the menu bar does, the hats CLI does too:
switch, add rules, check the verdict, run the doctor. Same engine,
same guarantees, so your scripts and CI rituals stay honest.
And when something on the machine fights you, an old URL rewrite, a
repo overriding hooks, a key that never reached GitHub,
hats doctor names it and prints the fix.
The menu bar shows the folder, the branch, and whether the hat matches. You see the mismatch before git does.
A compact widget floats above every app and Space: your accounts, the current repo, one tap to switch.
status, use, rule, check, doctor. The app and the terminal share the same brain, so scripts get the same guarantees.
Finds the traps that break identity setups: sneaky URL rewrites, local hook overrides, keys that never reached GitHub. Each finding ships with its fix.
The guard chains your repo's own hooks right after its check. Husky, commitlint and friends keep working untouched.
Tokens stay in gh, keys in ~/.ssh, passphrases in the macOS Keychain. Hats writes configuration, never credentials.
Download the app or use Homebrew. It lives in your menu bar from the first launch.
brew install --cask hats One profile per account: the onboarding imports your existing identity, connects GitHub in your browser, and handles the SSH keys for you.
Point each folder, or a whole GitHub org, at its profile. From then on the right hat is on before you even open the editor.
~/clients/acme → acme $0
forever
$12.99
one-time license, yours forever
Losing the license never touches your setup: extra profiles and rules are kept, and come back the moment it's active again.
No. The guard's hooks run your repo's own hooks right after their check, so husky and friends keep working exactly as before. If a repo sets its own hooksPath, Hats detects it and tells you the guard is inactive there, instead of failing silently.
Where they already do. GitHub tokens stay in gh's keychain storage, private keys stay in ~/.ssh, passphrases go to the macOS Keychain through ssh-agent. Hats stores configuration, never secrets.
One clearly-marked include block at the end of ~/.gitconfig, pointing at files Hats manages in ~/.config/hats. Your file is backed up before any change, every generated file is validated with git itself, and hats uninstall puts everything back.
Only for the live folder context. It's one line in your shell config, installed and removed from the app with a backup, and it runs in the background without slowing your prompt. Everything else works without it.
Yes: HATS_SKIP=1 git push. The guard is there to catch mistakes, not to argue with you.
Version 1 is GitHub-focused. Profiles already carry a host field, so other hosts are on the table for later. The model was built for it.