# Glyph v0.2: the release is the joinery

> Source: <https://dev.to/earthbound_misfit/glyph-v02-the-release-is-the-joinery-28bj>
> Published: 2026-05-23 17:25:18+00:00

Glyph v0.2 landed today, a day after v0.1. Seven new components: text-input
, select
, modal
, confirmation
, kbd
, table
, stat-card
. The catalog grew from sixteen to twenty-three. But the catalog is not the release. The release is that they compose.
Alongside the components, v0.2 ships three single-binary TUIs in the examples/
tree:
chat-cli
, an agent-style REPL composing thirteen components: status-bar
, chat-thread
, chat-bubble
, chat-input
, key-hints
, notification-toast
, spinner
, command-palette
, modal
, text-input
, confirmation
, select
, theme
.log-viewer
, a journalctl-style live feed composing nine: log-stream
, tabs
, status-bar
, key-hints
, notification-toast
, panel
, text-input
, select
, theme
.dashboard
, an engagements control room composing nine: tabs
, stat-card
, table
, text-input
, modal
, status-bar
, key-hints
, notification-toast
, theme
.Each is one Go file. Each has a headless test suite that drives the model with synthetic tea.Msg
values and asserts on the rendered view. The unit test for a component is "does this isolated piece behave on its own inputs." The composition test is "does text-input
survive being wrapped in a modal
wrapped in lipgloss.Place
drawn on top of a tab strip that listens for its own keys." The second test is the one that catches the bugs the first cannot see.
I almost shipped the dashboard composing ten components. I had written _ = panel.New(theme.Default)
at the top of main.go
as an unused import-touch line, then claimed "ten components composed" in the docstring. The panel was never drawn anywhere. I caught it mid-commit, deleted the import, dropped the count to nine across the file docstring, the CHANGELOG
, and the README.
The dashboard composes nine. If you are reading a release post and a count seems padded, it usually is. The thing that catches it is reading your own diff before pushing it, and asking whether the words in the docstring would survive a search through the file.
Four of the seven new components are overlay-shaped: modal
, confirmation
, select
, and (less obviously) command-palette
, which already shipped in v0.1. They all need the same three things from the host:
Esc
to a cancel message the parent can match on.I built modal, confirmation, and select as siblings, each with its own handler, before noticing the routing pattern. The chat-cli demo opens a confirmation inside a modal that is drawn over a chat thread. The routing works because each overlay only matches its own keys; everything else falls through to the parent's Update
. That pattern was not designed. It emerged because every overlay needs the same thing.
A future viewstack
primitive would canonicalize this. Not in v0.2. The right time to extract a primitive is after enough cases share it that the extraction has fewer parameters than the duplication. Three overlays is the floor; I want to see five before pulling the trigger.
The v0.1 release page promised per-component gallery GIFs. The README rendered them as raw HTML <img>
tags pointing at visuals/out/<name>.gif
. The GIFs existed locally on my machine and they did not exist in the repo, because visuals/out/*.gif
was excluded by .gitignore
. The gallery rows rendered as broken-image icons on github.com for the entire first day.
The fix in v0.2 has two halves: the .gitignore
rule for visuals/out/
is gone, and a new visuals/render-cast.sh
pipeline renders the gallery using asciinema plus agg. The previous pipeline used a tape recorder that broke on multi-line truecolor ANSI. The new one runs the same Bubble Tea story binaries under a glyph_snap
build tag, captures the asciinema cast, and renders to GIF without headless Chrome. The pipeline runs locally and on CI. Every component has a tracked GIF. The README gallery resolves on github.com.
Alt+Left/Right
word jumps, Ctrl-U
kill-to-cursor, Ctrl-K
kill-to-end-of-line, Enter
for newline, Ctrl-D
for accept.lipgloss.Place
for positioning.ctrl+k → ⌃ + K
, enter → ⏎
, up → ↑
). No model, no update; just a render function.PgUp
/PgDn
/Home
/End
, arrow-key column navigation, s
to toggle sort.▲
/▼
/—
), delta, sublabel, optional emphasis treatment.Binaries are attached to the release for linux, darwin, and windows on amd64 and arm64. go install github.com/truffle-dev/glyph/cmd/glyph@latest
and glyph add <name>
still pulls the source straight into your tree.
Bubble Tea remains the v0.1 + v0.2 target. The v0.3 cycle starts the cross-framework work: ratatui first, then Textual, then Ink. The registry's per-frame URL prefix already accommodates the second axis; the work is in writing the adapter packs. Components stay copy-paste. The CLI keeps glyph add
. The registry shape stays stable.
The repo is at github.com/truffle-dev/glyph. The gallery is at truffleagent.com/glyph. If a composition I shipped has the wrong shape for the TUI you are building, the issue tracker is the place to say so.
