Turn a Spotify Car Thing into a command deck for AI-assisted work: Wispr Flow push-to-talk, live Claude / Codex / Cursor usage gauges, Sentry production-error alerts, a configurable macro pad with real app icons, and Spotify/Apple Music controls — all on one 800×480 touchscreen beside your keyboard.
Built on DeskThing, which revives the discontinued Car Thing as a USB companion display. macOS only (the server drives the Mac via JXA/AppleScript-adjacent automation).
- 🎙 Wispr Flow control — press the knob to toggle dictation, hold button
① for push-to-talk. Triggers Wispr via its official
wispr-flow://deep links (no Accessibility permission needed). Music auto-pauses while you dictate and resumes after. A live dictation-target line shows exactly which Mac app your words will land in. - 📊 Claude usage gauges — your subscription's session (5h) and weekly limits as dials, with reset countdowns. Survives Anthropic's aggressive usage-API rate limiting via disk caching, gentle polling, and stale-data warnings instead of blank screens.
- 💳 Credits panel — Codex (OpenAI) 5h/weekly windows and Cursor plan usage alongside Claude, so every AI subscription's burn-down is one glance away. Zero-config: reads the same local sign-ins the vendor tools create.
- 🚨 Sentry error alerts — unresolved production issues on-screen; when a new issue appears the screen edge flashes red, the deck jumps to the Errors tab, and your Mac chimes. Read-only.
- ⌨️ Macro pad — six touch buttons that press keystrokes, type snippets, or open apps/URLs on the Mac. App buttons show the app's real icon (extracted via NSWorkspace). Configured in a JSON file; no rebuild needed.
- 🎵 Now playing — Spotify (or Apple Music) with album art, progress, and transport. Knob rotation = system volume.
- 🤖 Claude Code session monitor — local sessions with working / needs- input / done status; chimes when a session waits on you.
- 🩺 Self-diagnosing — a diagnostics screen (button ⑤) reports every integration's live status, and on-screen banners distinguish "server down" from "connection one-way" from "stale cached client".
| Input | Action |
|---|---|
| Knob press | Wispr Flow toggle (start/stop dictation) |
| Button below knob | Jump to the Macro pad (press again to go back) |
| Button ① | Hold-to-talk (Wispr push-to-talk) |
| Button ② | ⌫ Backspace on the Mac (repeats while held) |
| Button ③ | ⌘[ — app "back" on the Mac |
| Button ④ | ⏎ Return on the Mac |
| Button ⑤ | Diagnostics |
| Knob rotate | macOS system volume |
| Swipe ←/→ / pill | Cycle Usage · Credits · Errors · Macros · Sessions |
- Set up your Car Thing with DeskThing (flash + desktop app).
- Verify and build the app zip (
npm ci && npm test && npm run typecheck && npm run build→dist/claudedeck*.zip) or grab a release zip. - DeskThing → Apps → install from zip → restart the app.
- Automation ("DeskThing wants to control Spotify/Music") — appears on first media poll; click Allow.
- Accessibility (System Settings → Privacy & Security) — needed only for keystroke features (buttons ②③④, keystroke macros). App-open macros and Wispr deep links need nothing.
Claude usage — sign in to Claude Code on the Mac, or run
claude setup-token and save the token:
mkdir -p ~/.claude/claudedeck
echo 'sk-ant-oat01-YOUR-TOKEN' > ~/.claude/claudedeck/token && chmod 600 ~/.claude/claudedeck/tokenCodex credits — install Codex CLI (npm i -g @openai/codex), run
codex, sign in with ChatGPT once. The deck reads ~/.codex/auth.json.
Cursor credits — just have Cursor installed and signed in; the deck reads its local session.
Sentry errors — create a user auth token
with org:read, project:read, event:read, issues:read scopes:
echo 'YOUR_SENTRY_TOKEN' > ~/.claude/claudedeck/sentry-token && chmod 600 ~/.claude/claudedeck/sentry-tokenClaude Code session hooks (precise needs-input detection) — add
Notification/Stop/etc. hooks appending to ~/.claude/claudedeck/events.jsonl;
see server/sessions.ts for the format.
Edit ~/.claude/claudedeck/macros.json (created with defaults on first run;
changes picked up on next press):
{
"buttons": [
{ "label": "Claude", "app": "Claude", "color": "#D97757" },
{ "label": "Screenshot", "combo": "cmd+shift+4", "icon": "screenshot", "color": "#3B82F6" },
{ "label": "Sign-off", "text": "Best,\nYour Name" },
{ "label": "Docs", "open": "https://example.com" }
]
}Per button (up to 6): app (opens app by name, shows its real icon),
combo (cmd/opt/ctrl/shift + a character or named key — return,
escape, tab, arrows, f1–f12), text (types a string), open
(URL/path), color, and icon (screenshot/copy built-in glyphs).
Wispr trigger method (deep link/hotkey) and hotkey combo · usage poll interval · session & error chimes and sound · music-during-dictation (pause/duck/off) · knob direction · Sentry region/org.
- Your tokens never enter this repo or leave your Mac except to their own
vendor APIs (Anthropic, OpenAI, Cursor, Sentry) over HTTPS. They live in
~/.claude/claudedeck/and~/.codex/, read-only. - The Sentry token can only be sent to Sentry's official US or EU API host; arbitrary endpoint overrides are rejected.
- All integrations are read-only — the deck never mutates your Sentry issues, usage, or accounts.
- Trust model: DeskThing's server is reachable on your local network, and ClaudeDeck sends the display usage data, focused-app/window names, Claude session names, media metadata, and Sentry issue summaries. Its macro and keystroke features also mean a client that can reach DeskThing could send keystrokes to your Mac. Run it on networks you trust, or firewall DeskThing's port to localhost/USB.
- Runtime process launches use argument arrays (no shell interpolation); values embedded in JXA scripts are JSON-encoded.
macros.jsonexecutes whatever it's told — treat it like a shell script and don't paste configs from strangers.
Standing on the shoulders of: DeskThing · Wispr Flow's deep-link scheme (via their Raycast extension) · CodexBar's Codex usage recipe · cursor-usage-tracker's Cursor recipe · the Car Thing hacking community.
Built collaboratively with Claude. MIT licensed — see LICENSE.