Show HN: Brb – A Claude Code plugin for adhdmaxxing Developer usebrb released Brb, a macOS-only Claude Code plugin that uses lifecycle hooks to show a break panel after long Claude turns and alert users with sound, banner, and a 'Back to work' dialog when Claude finishes. The plugin installs via 'claude plugin marketplace add usebrb/brb' and 'claude plugin install brb@brb', stores config in ~/.claude/brb/, and supports commands like 'brb park', 'brb windows', 'brb timer', 'brb matrix', and 'brb log'. When Claude works, brb offers a break. When it finishes, brb calls you back. It hangs off Claude Code's own lifecycle hooks. macOS only it uses osascript for the UI . As a Claude Code plugin — nothing touches your settings.json : claude plugin marketplace add usebrb/brb claude plugin install brb@brb Then /reload-plugins , or start a new session. /plugin toggles it on and off. That is the whole install — the plugin ships the hooks, which is all brb needs. Optionally, add the brb command to your shell for brb park , brb windows , brb timer , brb matrix and brb log : curl -fsSL https://raw.githubusercontent.com/usebrb/brb/main/install-cli.sh | bash That installs a small wrapper which runs whichever plugin version is currently installed, so the command and the hooks never drift apart. A plugin's bin/ joins the Bash tool's PATH rather than your shell's, which is why this step exists. Config, item list and logs live in ~/.claude/brb/ and are shared by both. Installing without the plugin manager ./install.sh writes the hooks straight into ~/.claude/settings.json backing it up first and links the CLI. Use this only if you are not using the plugin — running both registers the hooks twice and everything fires twice. ./uninstall.sh reverses it. macOS only: the panel and alerts are AppleScript. On other platforms the hooks exit immediately and do nothing. Claude Code shares one configuration across its local surfaces, so a user-scope install covers the CLI, the Desktop app, VS Code and JetBrains at once — there is nothing extra to install per surface. The host app is never assumed to be a terminal. brb walks up the process tree to whichever .app owns the session and stores its bundle id, so "Back to work" raises Terminal from a terminal session, the Claude app from a Desktop session, and VS Code from an editor session. The CLI still needs a real shell, which on Desktop means the integrated terminal. Two independent things. The break panel — a native list you pick from. Fires on one condition: a turn passed the break timer default 10s . It shows whether or not you're at the terminal, because offering the break is its whole job. The alerts — sound, banner, and a dialog with a Back to work button. | Situation | Panel | Alert | |---|---|---| | Turn finishes faster than the timer | no | no | | Long turn, panel shown, you ignored it | yes | no | | Long turn, you clicked a note item | yes | no | | Long turn, you clicked a site | yes | done + Back to work | | Claude is blocked on you and you're away | — | "Claude needs you" | | Another Claude session still busy | stays up | your alert still fires | Clicking a site is the whole condition — you're called back whether or not you happen to be looking at the browser when the turn ends. Also requiring you to still be away made it a coin flip: glance at the terminal for two seconds at the wrong moment and the alert was silently dropped. Set REQUIRE AWAY=1 in config.sh for the stricter behaviour. The callback still requires you to have actually left through the panel . Seeing the panel and dismissing it doesn't count, and neither does a note: item — those don't take you anywhere, so there's nothing to call you back from. Anything where Claude is blocked on you is deliberately exempt from that rule — a permission prompt, a question, a link it needs opened. Gating those would mean stalling in silence. They still stay quiet if you're at the terminal, since you can already see them. brb panel the real panel, right now brb alert the real callback, right now brb attention a "Claude needs you" ping brb demo 20 full flow: pick a site, then the callback 20s later brb matrix every decision path, printed, NO UI drawn brb matrix is the fast one — it runs each branch with BRB DRY=1 and prints what each would have done, so you can check the logic without a single popup. brb status config, live sessions, what's armed brb log -f follow the decision log brb timer 45s or set it from the panel's ⏱ row brb items edit the panel list brb off / brb on kill switch brb doctor check the install The terminal that owns a session is found by walking the process tree hook → claude → shell → Terminal.app and stored as a bundle id. That's a fact about who owns the session, not a guess about what happened to be focused when the hook ran — an earlier version used frontmost-app and would mis-record the terminal if you tabbed away at the wrong instant. Bundle ids are compared case-insensitively: System Events and LaunchServices disagree on case for the same app. Edit ~/.claude/brb/items.txt , or pick ➕ Add your own… at the bottom of the panel — it opens CONTRIBUTING.md /usebrb/brb/blob/main/CONTRIBUTING.md , where the format is documented and PRs against the default list are welcome. Item icons are emoji or unicode glyphs. Color emoji render fine, but you can't supply an image file, so real brand marks aren't available — and Unicode has no X/Twitter glyph at all. A per-item logo would need a different UI surface. - ~/.claude/brb/items.txt — your panel list. Created the first time you run brb items or pick Add your own… in the panel. Format is Label|target , where target is a URL, an app:// scheme, or note:some text .Until you make one, the panel reads the list shipped with the plugin, so you keep getting new default items as they are added. Once your copy exists it takes over and updates leave it alone. Never edit the copy inside the plugin directory — that is replaced wholesale on every update. - ~/.claude/brb/config.sh — optional overrides sounds, titles . - ~/.claude/brb/state/ — runtime state and brb.log . AppleScript dialogs take no position and default to the main display — the one with the menu bar — which is the wrong screen whenever you're working elsewhere. brb positions every dialog on the owning terminal's window, so the panel, the callback, and the terminal that "Back to work" raises all land on one screen. Anchoring to the frontmost window instead proved unreliable during screen recordings, where focus jumps between displays. Your browser is left where it lives. MOVE BROWSER=1 in config.sh will drag it onto the terminal's display when you take a break, but on a single display that means it lands directly on top of the terminal, so it's off by default. Notification banners can't be positioned at all — macOS always draws them on the display holding the menu bar. Move the menu bar in System Settings → Displays if they appear on the wrong screen. That reposition needs Accessibility permission. Without it everything still works, the dialogs just land on the main display. Grant it under System Settings → Privacy & Security → Accessibility for your terminal app. Notification banners need permission for "Script Editor" under System Settings → Notifications. A sound plays regardless, so you're never left with no signal. Hooks are registered async: true and never block a turn. Their timeouts are generous only because they cap how long the detached children — the break timer and the callback dialog — are allowed to live.