Skip to content

Make the Charm TUI a screen you can sit in - #4

Merged
StephenSHorton merged 10 commits into
mainfrom
cursor/charm-tui-a11b
Oct 4, 2026
Merged

StephenSHorton merged 10 commits into
mainfrom
cursor/charm-tui-a11b

Conversation

@StephenSHorton

@StephenSHorton StephenSHorton commented Oct 3, 2026 •

Copy link
Copy Markdown
Owner

Stacked on #3 (cursor/rock-1-0-a11b).

What was wrong

  • layout() reserved one plan width and View() drew another, and the transcript viewport never wrapped. Any line wider than the transcript column was cut. At 110 columns the column was 110-36-2 = 72 cells, which ends the ready sentence at "not in this sc". At 100 columns the row was 101 cells wide.
  • Four ANSI colors. Glamour used WithAutoStyle, which queries the terminal on stdin while Bubble Tea owns it, and the renderer was rebuilt on every resize.
  • No model name on screen. The meter counted only visible event text, so 72 bytes of a 24000-byte budget never lit one cell. A 32 ms tick ran forever.
  • MouseModeCellMotion was on, but no mouse message ever reached the viewport.
  • The allow dialog was appended below the help line, off screen at normal heights. The default list keymap mapped q to quit, so q in /sessions, /permissions, or the allow dialog quit Rock and left the ask unanswered.
  • clip() sliced bytes.

What changed (all in internal/tui, plus three Deps fields set in cmd/rock)

  • Layout. One geometry, computed in layout() and only read by View(). Plan column plus gap plus transcript fill the row exactly. Transcript text is wrapped on graphemes. Rows go to the header, status, composer, and help first, and the body takes what is left. Plan mode on screens narrower than 64 columns stacks the plan above the transcript.
  • Palette. Ground, panel, copper, hot, text, and mute from site/styles.css, each with a light-terminal pair. Pairs resolve through lipgloss.LightDark when Bubble Tea sends BackgroundColorMsg. Lip Gloss v2 moved AdaptiveColor into compat, which queries the terminal at package init for every rock subcommand. Glamour gets a style built from the same palette.
  • Status line. Mode badge, jev:offline|live, the configured fast model (the strong model while a turn uses it), and the context meter. The meter tracks session.Bytes(), the number the compaction gate reads. It is read on the harness goroutine inside the sink, so there is no race. A critically damped Harmonica spring drives it, and its tick stops when it settles.
  • Mouse. The wheel scrolls the transcript, or the plan when the pointer is over it, or the open list. Click or drag on the transcript scrollbar jumps there. New events no longer pull the view down while you are scrolled up.
  • Panels. /help shows keys plus every slash command. /sessions is newest first and marks the open session. /permissions lists mode, allow, ask, and deny, ending with "Permissions are not a sandbox…". /agents has an empty state. The plan pane says "Plan mode. Shell is blocked…". The allow dialog previews the call (- old / + new for edit_file, $ cmd for shell) and keeps the choices and keys visible at short heights.
  • q closes panels instead of quitting. The placeholder lists all ten slash commands, /default and /quit included. clip() and wrapText() cut on graphemes.
  • Permission semantics are unchanged. The UI only describes the policy.

Tests

internal/tui/model_test.go keeps the four original tests and adds 14 view assertions. They cover the column split and the whole ready sentence at 60, 80, 99, 100, 110, 120, and 140 columns; heights 8–16; the status line; meter easing; each panel opening and closing; q; the plan pane; the allow dialog; wheel and scrollbar; the light palette; Glamour colors; slash commands; and grapheme-safe clipping. One test runs the real harness against an in-process OpenAI-compatible stub and answers the dialog both ways. go test ./... passes, and go test -race ./internal/tui/ passes.

internal/tui/testdata/stubllm and internal/tui/testdata/visual.sh are the tooling for the visual run on a real xterm.

Follow-up cleanup

  • Site headings describe the Go CLI. Title, og:title, hero, sample ask, and 404 no longer joke about the name.
  • Installers and blob links point at main via go install …@main. No GitHub API pin.
  • Docs mark language as Go only (v1-plan.md). Protocol, quarry, and features stay negotiable. Cloud agents can run rock-docs on port 4173; the product binary builds with go build ./cmd/rock.
  • Deleted .github/workflows/pages.yml. Added .github/workflows/ci.yml (go build, go vet, go test -race).
  • rock --help / -h exit 0.
Open in Web Open in Cursor 

cursoragent and others added 10 commits October 3, 2026 17:38
The harness is a Go package behind a Charm TUI, headless print, ACP, and loopback HTTP. Jev gates choose the model, the skill, when to compact, and when a shell call is too dangerous to run. Suzuri launches the binary with OSC 7880.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
The host change allowlists rock and sets ROCK_SESSION_TITLE. The Suzuri tests passed here; this token cannot push that repository.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
The public page is a static site under site/, with its own mineral palette, deployed by Actions when the site or the workflow changes.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
configure-pages can turn GitHub Pages on when the repo has no site yet. The hero copy stays on the session store and the Suzuri pane.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
The host file on that branch matches the tested OSC patch. The page notes that Pages still needs the GitHub Actions source selected once.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
Share one geometry between layout and View so the plan column and the
transcript fill the row exactly, and wrap the transcript instead of
clipping it. The ready sentence is whole at 60, 80, 100, 110, and 140
columns, and the status line, composer, and help survive short heights.

Draw with the site palette (ground, panel, copper, hot, text, mute) as
light/dark pairs resolved from Bubble Tea's background report, and give
Glamour the same palette instead of WithAutoStyle. Put the fast model,
mode, Jev state, and context meter on the status line. The meter tracks
the session size the compaction gate reads and eases on a critically
damped Harmonica spring that stops ticking once it settles.

Forward wheel events to the transcript or the plan under the pointer,
and let a click or drag on the scrollbar move the transcript. Rework
/help, /sessions, /permissions, /agents, /plan, and the allow dialog
into readable panels that keep their safety text. Stop q from quitting
Rock inside lists, list every slash command in the placeholder, and cut
text on graphemes instead of bytes.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
stubllm is a deterministic OpenAI-compatible server: one tool call that
asks by default, then a markdown reply that says whether it ran.
visual.sh runs the rock binary in tmux inside xterm, sends keys through
tmux, resizes, scrolls, and grabs frames with ffmpeg.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
Glamour registers an inline Chroma config once per process under one
shared name and highlights with the 256-color formatter, so code kept
the first theme's colors and lost the palette. Register rock-dark and
rock-light Chroma styles, pick one by name, and highlight in truecolor.
Light one meter cell for any context above zero; the percentage beside
it stays exact.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
The public page was telling a geology story. The headline is the question
people actually ask. macOS, Linux, and Windows each show one command, and
the page picks the matching one. The scripts install the current 1.0 build
with Go.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
Site headings now describe the Go CLI. Installers and blob links point at
main. Docs mark the language as Go only. Pages workflow is gone; CI builds,
vets, and race-tests. rock --help and -h exit 0.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
@StephenSHorton
StephenSHorton changed the base branch from cursor/rock-1-0-a11b to main October 4, 2026 04:42
@StephenSHorton
StephenSHorton marked this pull request as ready for review October 4, 2026 04:42
@StephenSHorton
StephenSHorton merged commit 46737ec into main Oct 4, 2026
1 check passed
This was referenced Oct 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants