An operator's control surface for macOS — routing your attention across Claude Code sessions, tabs, windows, panes, apps, documents, and files from a Stream Deck.
Ever lose a beat hunting for the right tab or window? Tactile switches beat hunting-and-clicking. Switchboard is a macOS Stream Deck plugin for fast context-switching: keep an eye on your Claude Code projects from the deck — each key's spark shows working (amber, turning) vs. waiting for your input (white, still), wherever the session runs (tmux, iTerm2, or Terminal.app), and a press raises its window. Jump to Safari tabs (with multi-account Gmail/Calendar presets), switch and cycle app windows, tile and ring windows, drive tmux windows and panes (raising the right iTerm2 window as you go), move between BBEdit documents, and open files by wildcard pattern — all from Stream Deck keys and dials.
I'm an engineer by training, but these days I work from the director's chair, not the IDE — I advise MedTech and SaaS CEOs on aligning technology with strategy. I didn't write Switchboard; I directed an AI agent (Claude) to build it: I specified what I wanted, steered the design, reviewed the work, and insisted on tests at every step. That's how a working, tested tool shipped in an afternoon — and it has kept evolving, session by session, in the open ever since.
That's the point. Switchboard is a Moving Average Labs artifact — a small, concrete proof of how AI changes the way operators build. The lesson isn't the tmux dials; it's the operating model behind them.
Read the full story in the flagship essay → I Directed an AI to Ship Real Software. Advisory work lives at movingavg.com.
Twelve actions, grouped by what they route your attention to.
Claude Code
- Claude Project (key) — a live face for a Claude Code project, wherever it runs (tmux, plain iTerm2, or Terminal.app): the spark shows working (amber, turning) vs waiting for your input (white, still), the bar lights when your keystrokes would land in that session, and pressing raises the hosting window. Hold to capture the frontmost session's project.
Safari
- Safari Tab Jump (key) — jump to an open Safari tab, or open it if it isn't there yet. Built-in presets for multi-account Gmail and Google Calendar, plus custom sites and private-window targets. URL matching supports
*wildcards. Hold the key to capture the current front tab into the button.
Windows & apps
- Open / Switch App (key) — launch or switch to an app, optionally focusing a window whose title matches a pattern. Hold the key to capture the frontmost app into the button.
- Cycle App Windows (dial) — rotate through the windows of the frontmost application; press or tap the touchscreen to flip the dial into cycling the visible apps themselves.
- Scroll Window (dial) — rotate to scroll the frontmost window (one proportional scroll-wheel event via a native helper); press to jump to the top (or, if configured, toggle speed); tap the touchscreen to always toggle fast/slow.
- Arrange Window (dial) — rotate to tile the frontmost window through the active arrangement (halves, thirds, quarters — across columns or rows — or a 2×2/2×3/2×4 grid); counter-clockwise retraces the same arrangement in reverse. Tap the touchscreen to toggle between the button's two configured arrangements (e.g. columns ↔ grid). Press to maximize. Uses a native Accessibility helper that's Dock-aware and multi-monitor correct.
- Window Ring (key) — a curated ring of windows: long-press to add the current window (or remove it, if it's already in the ring), tap to cycle through them. The key shows a live count with a green ring when the current window is a member; optional sound on long-press.
tmux & iTerm2
- Focus tmux Window (key) — raise the iTerm2 window for a tmux window, optionally switching to it. Hold the key to capture the current tmux window into the button. The key face renders live as a mini tmux pane: its status bar lights up in the session's color — with a block cursor — exactly when that window would receive your keystrokes (active in tmux, focused in iTerm2, iTerm2 frontmost). A spark in the corner tracks Claude Code inside the window: amber and slowly turning while it works, still and white when it's finished and waiting for your input.
- Switch tmux Pane (dial) — rotate to move between tmux panes — or, after a press/tap toggles the mode, tmux windows. Only drives the tmux session in the frontmost macOS window — when iTerm2 isn't frontmost the dial does nothing (never a background terminal) — and the mode survives restarts. The touchscreen shows the mode and the pane's running command (or the window name).
- Cycle tmux Window (dial) — rotate to cycle tmux windows; press for the last window. Tap the touchscreen to widen the scope to ALL sessions — rotation then crosses session boundaries and press jumps to the last session. Only drives the tmux client in the frontmost macOS window (does nothing when iTerm2 isn't frontmost). Renders the current session/window live on the touchscreen.
BBEdit
- BBEdit Documents (dial) — move between the open documents in BBEdit's front window, in your chosen order (open order, alphabetical, or by last-modified); push to jump back to the previous document.
Files
- Open File (key) — open the newest, latest-modified, or pattern-matched file in a folder, with your default app / BBEdit / a chosen app, and a live ✓/✗ status badge.
The Focus tmux Window and Claude Project keys render live. Each tmux key is a miniature tmux pane whose status bar lights up in its session's color — with a block cursor — exactly when that window would receive your keystrokes. The spark in the corner tracks Claude Code: amber and turning while it works, still and white when it's finished and waiting for your next prompt. Claude Project keys carry the same face for a whole project, whether the session runs under tmux, plain iTerm2, or Terminal.app. The keys observe and focus — they infer state from the session's own signals and raise its window; they never drive Claude itself.
The dial touchscreens speak the same color language — green drives tmux, blue drives macOS windows and apps, amber drives BBEdit — and the ⇄ mark appears exactly where a tap flips the dial's mode:
- The Cycle tmux Window dial draws dynamic touchscreen graphics — the current session/window renders live on the encoder display.
- Safari Tab Jump matches Safari tabs by
*wildcard, so a tab finds its home even when the URL drifts. - Open File shows a live ✓/✗ status badge right on the key — you can see at a glance whether a matching file exists.
- Safari Tab Jump ships multi-account Gmail and Calendar presets — pick the account number, and the URL and match pattern are built for you.
- Window Ring flashes a green check on add and a red "−" on remove, with an optional sound, so long-press registration is unmistakable.
- A consistent interaction grammar: rotate browses, press escapes to a known place (or toggles the mode where there's no place to escape to), tap flips the dial's mode or scope, and holding a go-to key teaches it whatever you're looking at.
Requires macOS 12+ and the Stream Deck app 6.5+. Pick whichever fits you — in all cases, quit and relaunch Stream Deck afterwards, then add Switchboard's actions to your keys/dials.
Download com.movingavg.switchboard.streamDeckPlugin from the
latest Release and double-click it. Stream Deck
installs the plugin for you. Done.
brew install --cask windaddict/switchboard/switchboard(Requires the published cask; see packaging/homebrew/switchboard.rb.)
For folks who'd rather use Finder than the Terminal:
- Download this repo: green Code button → Download ZIP, then unzip it.
- Open Finder and press ⌘⇧G (Go → Go to Folder). Paste this and press Return:
~/Library/Application Support/com.elgato.StreamDeck/Plugins - From the unzipped repo, drag the
com.movingavg.switchboard.sdPluginfolder into that Plugins window. - Quit and relaunch Stream Deck.
(The plugin is committed pre-built and self-contained, so the dragged folder runs as-is — no build step needed.)
# Symlink the .sdPlugin folder into the Stream Deck plugins dir
ln -s "$(pwd)/com.movingavg.switchboard.sdPlugin" \
~/Library/Application\ Support/com.elgato.StreamDeck/Plugins/
# …or use the Elgato CLI
npx @elgato/cli linkThen restart the Stream Deck app.
Switchboard sends keystrokes and drives other apps, so macOS asks for its grants as you exercise each feature:
- Accessibility — for keystrokes, scrolling, window cycling, and window moving/tiling. System Settings → Privacy & Security → Accessibility → enable Stream Deck.
- Automation — granted per target app (Safari, iTerm2, Terminal, BBEdit) the first time an action drives it. System Settings → Privacy & Security → Automation → enable Stream Deck for the target apps.
If a grant is denied, the key shows an alert and the plugin log spells out the exact re-enable path instead of failing silently.
Personal project, shared as-is — not supported. Built for one Mac and published as a proof artifact (see "The story"), not a product. No issue tracker, no roadmap, no guarantees. Use it, fork it, learn from it.
Licensed under the MIT License — see LICENSE.
Disclaimer of warranty & liability. Switchboard automates your Mac: it sends keystrokes and scroll events and drives other applications (Safari, iTerm2, BBEdit, Finder, and others) via AppleScript and System Events. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. You use it entirely at your own risk; in no event shall the author be liable for any claim, damages, data loss, or other liability arising from the software or its use.
Trademarks & affiliation. Switchboard is an independent, unofficial project. It is not affiliated with, endorsed by, or sponsored by Elgato or Corsair Memory, Inc. Stream Deck is a trademark of Corsair Memory, Inc., used here only to describe compatibility. Safari is a trademark of Apple Inc.; BBEdit of Bare Bones Software, Inc.; iTerm2 and all other product names, logos, and brands are the property of their respective owners.
Elgato Stream Deck SDK v2 · TypeScript / Node · 435 passing tests · streamdeck validate runs in the build · native helpers are universal (Apple Silicon + Intel), Developer ID signed & notarized.
npm install
npm run build # bundles to com.movingavg.switchboard.sdPlugin/bin/plugin.js
npm test # vitest
npm run typecheckThe plugin UUID is
com.movingavg.switchboard, matching the public name Switchboard. It was renamed from a legacy id;scripts/rename.shperforms that migration and rewrites the UUIDs in the Stream Deck profile store so already-configured buttons keep their settings.




