I make a small Mac app that shows Claude Code sessions in the notch as a pixel crew, one little face per agent. I wanted the same faces in the terminal too, in Claude Code's status line and in the rows it shows for sub-agents. This is how it works now, and what didn't work on the way.
Claude Code wrote most of the code for this. Claude also wrote this post, since English isn't my first language, and I read it in Thai before posting. The numbers and file names come from the repo.
Claude Code runs any command you give it as a status line. It sends JSON on stdin (model, context use, plan limits, session id, transcript path) and shows whatever the command prints. There is also subagentStatusLine for the rows under ● main.
A tiny one looks like this:
#!/usr/bin/env python3
import json, sys
data = json.load(sys.stdin)
face = chr(0x3F000) # one wide character from the font, more on that below
print(f"{face} {data['model']['display_name']}")
In AgentValley it's a subcommand of the app itself, wired in ~/.claude/settings.json:
"statusLine": {
"type": "command",
"command": "'/Applications/AgentValley.app/Contents/MacOS/AgentValley' crew status",
"padding": 1,
"refreshInterval": 30
},
"subagentStatusLine": {
"type": "command",
"command": "'/Applications/AgentValley.app/Contents/MacOS/AgentValley' crew agents"
}
Two things matter here. It runs on every new message, so keep it fast. Ours reads only the last 1 MB of the transcript and aims for under 50 ms. And always exit 0, because a status line that fails just shows nothing and you don't find out why.
A status line is text. Claude Code strips kitty image codes out of it, so real images are out.
Half-block characters came first (▀ ▄ in truecolor, two pixels per text row). That works in every terminal, but a 12x12 face is 6 lines tall, way too big for a status line.
So each face became one character in a font. The terminal draws a character, and the font has the colour picture inside it.
The first pick was the Private Use Area, since that is what it's for. It broke in the Chrome-based terminals, Cursor and Paradev (formerly Superset). They never look in another font for a private use character, so you get a box unless your main terminal font has it.
Unassigned code points behave differently there. Those terminals do fall back to any installed font that has the glyph. So the faces live at the unassigned end of Plane 3, U+3F000 to U+3F7FF. Characters there count as East Asian Wide, so every terminal and Claude Code agree one of them takes two cells. That part matters. If Claude Code measures the line one way and the terminal draws it another, everything after the face shifts over.
If Unicode ever assigns that range, the faces have to move.
Before that, each face was split into two normal-width characters. Ghostty fits every colour glyph to 95% of its cell and centres it, so the two halves always had a thin gap between them. One wide character fixed it.
Terminals don't agree on colour font formats either. Chrome-based ones draw COLR and never SVG. Ghostty draws colour only from SVG or sbix. So every face is in the font twice, as COLR v0 + CPAL and as OpenType-SVG, plus plain outlines as a fallback.
The font is built with fontTools in Python. The pixels come from the same 12x12 grids the Mac app draws, dumped to JSON by a Swift test, so the terminal and the notch can't drift apart. A test fails if the committed font is older than the faces. Each pixel is a square in a 1200-unit em, and runs of the same colour in a row are merged into one rectangle to keep the file small. Right now it's about 2.2 MB with 1,490 characters (faces holding different things, plus name tags).
Ghostty won't use a colour font as fallback for these characters on its own. You map the range in its config and restart it:
font-codepoint-map = U+3F000-U+3F7FF=AgentValley Crew
It's tested in Terminal, iTerm2, Ghostty 1.3.1, Paradev and Cursor. Not yet in VS Code, WezTerm, kitty, Warp or Zed. If you try one of those I'd like to hear what you see.
The font (OFL) and the code (MIT) are in AgentValley, a free Mac app: https://github.com/morsechimwai/agent-valley