- Python 94.1%
- TypeScript 5.9%
| .gitignore | ||
| .python-version | ||
| cli.py | ||
| config.py | ||
| deck.py | ||
| demo.jpg | ||
| LICENSE | ||
| main.py | ||
| omp.py | ||
| pyproject.toml | ||
| README.md | ||
| ruff.toml | ||
| session.py | ||
| splash.png | ||
| spookycat.ts | ||
| surface.py | ||
| test_render.py | ||
| test_session.py | ||
| uv.lock | ||
SpookyCat
Custom Elgato Stream Deck Mini controller for surfacing your live oh-my-pi (OMP) coding sessions.
Every running OMP session reports itself and takes a slot on the deck. Slots are paged, sorted so sessions that want your attention bubble to the front, and tapping one brings that session's terminal to the foreground.
- Blue -- session is generating
- Red -- session wants a decision (an
ask/resolveprompt) — these jump to page 1 - Green -- session is idle, waiting for you
How it works
SpookyCat is push-only: a tiny OMP extension loaded into every session reports lifecycle transitions over a Unix socket (/tmp/spookycat.sock). SpookyCat keeps an in-memory registry keyed by working directory (one session per directory) and renders it across the deck.
- A session appears on its first event and disappears on clean shutdown.
- Each report includes the session's
pid; SpookyCat reaps sessions whose process died without a clean exit (reap_interval, default 5s). - SpookyCat does not control or spawn terminals — it only raises the existing window/tab whose title matches the session.
Slots, pages, and icons
- Page 1: slots 1-5 (keys 0-4), next on the bottom-right key.
- Page 2+: prev bottom-left, next bottom-right, 4 slots each.
- asking sessions sort to the front; otherwise most-recently-active first.
Each slot's icon is derived from its working directory:
| Path contains | Icon |
|---|---|
worktree-<greek> (e.g. worktree-alpha) |
the greek letter (α) |
ingesting |
Ω |
a multi-word last segment (uptime-edge) |
acronym (UE) |
| otherwise | first 4 letters (spookycat → spoo) |
Override any icon in the config [icons] table.
Requirements
- macOS
- Elgato Stream Deck Mini (6 keys)
- A terminal (Ghostty by default) running oh-my-pi
- uv for Python project management
hidapi(brew install hidapi)- Accessibility permissions for the terminal/app running SpookyCat (to raise windows)
Setup
# Install dependencies
brew install hidapi
uv sync
# Install the OMP extension (loads in every oh-my-pi session)
uv run python main.py install-extension
# Install CLI helper (adds `spookycat` to ~/.local/bin)
uv run python main.py install-cli
# Install macOS app (for Raycast/Spotlight)
uv run python main.py install-app
Restart any running OMP sessions after installing the extension.
Usage
# Run from terminal
spookycat
# Run with debug logging
spookycat --log-level=debug
Launch from Raycast by searching "SpookyCat". A menu bar icon (👻) appears -- click it to quit.
Button behavior
- Tap a slot to raise that session's terminal.
- Tap the active slot while its terminal is focused to switch back to your previous window (Cmd+`).
- Tap prev/next to page through sessions.
Config
Optional, at ~/.config/lol.pjw.spookycat/spookycat.toml (created on first run):
[settings]
reap_interval = 5
[colors]
working = "#2980b9"
asking = "#c0392b"
idle = "#27ae60"
[icons]
"~/telemetry-anomalies" = "ANO"
Commands
| Command | Description |
|---|---|
install-extension |
Install the OMP extension to ~/.omp/agent/extensions/ |
uninstall-extension |
Remove the OMP extension |
install-app |
Create SpookyCat.app in ~/Applications |
uninstall-app |
Remove SpookyCat.app |
install-cli |
Add spookycat to ~/.local/bin |
uninstall-cli |
Remove CLI helper |
print-sample-config |
Print example config to stdout |
License
MIT, see LICENSE
