Skip to content
Open Sourceen
AgentDeck

Stream Deck plugin that monitors and controls AI agent instances — Claude Code, Gemini CLI, and Cursor — from physical hardware with real-time status, gesture controls, and token cost tracking.

What is AgentDeck?

AgentDeck is a Stream Deck plugin that brings your AI agent sessions out of the terminal and onto physical hardware. Each key on your Stream Deck maps to a running instance of Claude Code, Gemini CLI, or Cursor Agent, showing real-time status with animated icons, responding to gestures like focus, cancel, and approve, and tracking token usage and cost as you work.

The idea is simple: when you're running multiple AI agents across multiple projects, you lose situational awareness fast. AgentDeck gives you a physical control surface — no more alt-tabbing to check if an agent is waiting for permission or has hit an error.

The Problem It Solves

Headless AI agents are powerful but opaque. They run in terminals, block on permissions, throw errors, and burn tokens — and none of that is visible unless you're actively watching the right window. When you have three or four sessions open across different projects, keeping track of what each agent is doing becomes a context-switching tax.

AgentDeck externalizes that cognitive load onto dedicated hardware. Glance at your Stream Deck, see which agents are running, which are waiting for your approval, and which have finished — without touching your keyboard.

Core Features

Animated Status Icons

Each key renders an animated status icon at 12 FPS, reflecting the current agent state:

StateIconMeaning
IdleGreen checkmarkAgent finished, ready
RunningBlue spinnerProcessing
Tool UseOrange gearExecuting a tool
EditingPurple pencilWriting files
QuestionCyan ?Waiting for input
PermissionRed shieldNeeds approval
ErrorRed !Something went wrong
DisconnectedGray ×No agent connected

Gesture Controls

Three gestures per key, no configuration needed:

  • Single press — focuses the terminal window running that agent
  • Double press — cancels the current operation (sends SIGINT)
  • Hold (500ms) — approves a pending permission request

Multi-Instance Support

Assign different Stream Deck keys to different agent instances. Auto-assignment based on project folder or session ID means the right key lights up for the right project automatically.

Token & Cost Tracking

AgentDeck scans Claude Code session logs in real time, extracts token counts (input, output, cache read, cache write), and calculates running cost using live model pricing for Claude Opus 4, Sonnet 4, and Haiku 4. Switch a key's display mode to see tokens or cost instead of just the status icon.

Display modes per key:
  status   → animated icon
  tokens   → input / output token counts
  cost     → current session cost in USD
  activity → recent activity log

How It Works

Claude Code / Gemini CLI / Cursor
        │
   lifecycle hooks (SessionStart, PreToolUse,
   PermissionRequest, Stop, …)
        │
        ▼
  status-reporter.sh  →  HTTP POST /status
                               │
                         localhost:19847
                               │
                         StatusServer (HTTP + WebSocket)
                               │
                    ┌──────────┴──────────┐
                    │                     │
              InstanceManager       UsageTracker
              (sticky state logic)  (log scanning)
                    │
                    ▼
            Stream Deck Plugin
            (animated icons + gestures)

The plugin runs a lightweight local server on port 19847. Claude Code hooks fire on lifecycle events and send HTTP POSTs to that server. The server broadcasts updates to all connected Stream Deck clients over WebSocket. The plugin renders icons and handles gesture events in the other direction.

Sticky State Logic

permission and question states are "sticky" — they persist even when idle or running updates arrive, preventing icon flicker while the agent is outputting text after a question. States only clear when a progress hook fires (PreToolUse, PostToolUse, Stop, SessionEnd).

Integrations

Claude Code Hooks

AgentDeck works via Claude Code's hooks system. Add the provided hook script to your ~/.claude/settings.json:

{
  "hooks": {
    "SessionStart":       [{ "command": "status-reporter.sh session_start" }],
    "SessionEnd":         [{ "command": "status-reporter.sh session_end" }],
    "PreToolUse":         [{ "command": "status-reporter.sh pre_tool_use" }],
    "PostToolUse":        [{ "command": "status-reporter.sh post_tool_use" }],
    "PermissionRequest":  [{ "command": "status-reporter.sh permission" }],
    "Stop":               [{ "command": "status-reporter.sh stop" }],
    "Notification":       [{ "command": "status-reporter.sh notification" }]
  }
}

Kitty Terminal

AgentDeck has first-class Kitty support via the kitten @ remote control API. It auto-detects sockets (KITTY_LISTEN_ON, /tmp/kitty, /tmp/kitty-*), tests each candidate before using it, and falls back to a direct Kitty launch if remote control isn't available. Requires allow_remote_control yes in kitty.conf.

macOS AppleScript and Windows PowerShell adapters handle terminal focusing for other terminals.

Tech Stack

  • TypeScript 5.7 — strict mode, bundled with Rollup
  • @elgato/streamdeck 1.2 — official Stream Deck SDK
  • ws — WebSocket server for real-time push to the plugin
  • sharp — SVG → PNG icon rendering per frame
  • Node.js 20+, Stream Deck 6.6+

Status

AgentDeck is actively developed. Current support covers Claude Code, Gemini CLI, and Cursor Agent. Planned additions include more terminal adapters (iTerm2, WezTerm, Ghostty, Alacritty), session history export, cost alert thresholds, and OpenAI CLI integration.

Related writeups