This one started with Bit, the little polyhedral companion from Tron. During the OpenClaw era of personifying agents, I wanted to build one a shape that hovers, idles, flips between geometries and reacts to what's happening around it.
Claude Code emits lifecycle events through a hook system, I usually have a couple of sessions going at once, and those sessions have states that are important and interesting to watch: thinking, running a tool, blocked on a permission, spawning a subagent, ending. What came out is a live 3D view of every Claude Code session on the machine, and once watching without being able to intervene got annoying a way to drive them too.
The Pipeline
An installer writes hook entries into ~/.claude/settings.json. Each event fires a small shell script that POSTs to the server, Express updates session state and broadcasts over WebSocket, and the client reconciles and animates. Eight lifecycle events map onto distinct visual states:
Geometry, colour and rotation speed carry the state rather than a label doing it, the cyan icosahedron turning slowly is idle, the same shape spinning fast is working, a yellow octahedron is a tool that came back clean, an orange starburst is one that didn't. Subagents orbit their parent session, so a task that fans out reads as a small system instead of a list of rows.
Managed and observed sessions
Observed sessions appear on their own, from hook events fired by Claude Code instances I started in a terminal somewhere. They're visualization-only and get cleaned up shortly after their session ends. Managed sessions are created through ClaudeGrid and backed by tmux, which is what makes everything else possible: send a prompt, capture live pane output, Ctrl+C something that's run away, answer a permission modal, rename, restart one that's gone offline.
The awkward bit is that a session's Claude-side ID isn't known until after it starts, so observed sessions auto-link to managed ones by matching working directory.
Around the edges
Managed sessions persist to ~/.claudegrid/data/sessions.json and survive a server restart. There's a documented REST API covering session CRUD, prompts, cancels, permission responses and pane capture, with a bidirectional WebSocket protocol alongside it. An optional systemd unit ships with install and uninstall scripts and runs the whole thing as a daemon with journalctl-backed logs.
The client is plain ES modules, no framework, just a scene and layout module, a Bit renderer, hover labels, an audio manager and an event log. Three.js with bloom post-processing does the rendering. Audio is procedural via Tone.js and has three modes, because sound on every single event is only fun for a while.

