# ClaudeGrid

Canonical: https://justinp.io/projects/claudegrid

A real-time 3D visualizer and session manager for Claude Code. Lifecycle events stream over WebSocket into a Three.js scene where each session is a Bit; sessions are tmux-backed, so you can drive them from the browser as well as watch them.

Tags: ai, threejs, frontend

Repository: https://github.com/jtp184/claudegrid

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:

![](https://justinp.io/media/1b304018-d1ba-554a-8fa9-4c49c9141f65/image_processing20260821-2343-13aupg3.png)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.

![](https://justinp.io/media/732c2e33-7de5-5fd9-8531-a2d12a8403c3/image_processing20260821-2343-2sxdft.png)

