I run several AI agents at once: a handful of Claude Code sessions, plus a small "company" of agents on Paperclip that works on our online store. Giving them work is easy. The hard part is knowing, at a glance, which one is working, which one is done, and which one has been waiting for my answer for twenty minutes.

Logs don't answer that at a glance. So I drew an office.

Cubicle demo

Live demo, no install · GitHub · npx @caglarutkuguler/cubicle

What the office shows

Every agent is a character:

  • Working: sits at its desk and types, with the current task or tool call above its head
  • Needs you: raises a hand, and the monitor turns amber
  • Done: says "✓ done" and walks to the lounge for a coffee
  • Error: slumps at the desk, red screen

The header keeps a count of how many agents need you. That single number turned out to be the most useful thing on the screen.

Three design decisions

1. Zero dependencies

The server is a single Node file of under 200 lines, using only the standard library: it serves one HTML page and proxies a few requests. The page draws everything with fillRect on a 352×208 canvas. There are no image assets, no framework, and no build step.

This wasn't minimalism for its own sake. A tool that sits next to your agents all day should be something you can read in ten minutes and trust.

2. Read-only by design

Cubicle only ever makes GET requests. In Paperclip mode it forwards exactly three endpoints and refuses everything else:

const ALLOWED = [ /^\/api\/health$/, /^\/api\/companies$/, /^\/api\/companies\/[\w-]+\/(agents|issues)$/, ]; 

POST, PATCH and DELETE get a 405, any other path gets a 403. If you point it at an authenticated Paperclip, the API key is added on the server side only: it never reaches the browser, and the browser's own cookies are never forwarded upstream. There is deliberately no --token flag, because flags show up in the process list.

3. "Needs you" from real signals

For Claude Code, Cubicle uses the official hooks. A tiny script rewrites ~/.cubicle/claude-code.json on every event:

Claude Code event In the office
PreToolUse, PostToolUse Types at the desk; bubble shows e.g. Edit checkout.php
PermissionRequest Raises its hand
Stop Goes to the lounge
SessionEnd Leaves the office

The hook always exits 0 and prints nothing, so it can never block a tool call or add tokens to the context. One thing I had to handle: Claude Code also sends a notification after a minute of idling ("waiting for your input"). Treating that as "needs you" made every idle session raise its hand, so those are ignored.

For Paperclip, the interesting signal was hiding in the issue data. When an agent asks the board a question, Paperclip records it in the issue's reviewAttention.paths with the board as the responder. Often the agent is already busy with another issue, so its own status says running. Cubicle keeps it typing, but its bubble flashes the waiting issue's ID every few seconds and the card links straight to it. The first time I turned this on, it found two questions I didn't know were waiting for me.

Try it

# Paperclip (default, expects it on :3100) npx @caglarutkuguler/cubicle # Claude Code npx @caglarutkuguler/cubicle install-hooks npx @caglarutkuguler/cubicle --source claude-code # anything that can write a small JSON file npx @caglarutkuguler/cubicle --source ./agents.json 

Open http://127.0.0.1:3200. Add ?kiosk for a full-screen view on a TV or second monitor.

What's next

A few issues are open and labelled for first-time contributors: a new UI language, per-agent spend for Paperclip, an example adapter for Codex or Gemini CLI, and a replay mode to watch a whole day in 30 seconds. PRs welcome, as long as they keep the two rules: no dependencies, and read-only.

It's MIT licensed: github.com/caglarutkuguler/cubicle