Repository navigation
Bound the prompt panel's bar by wrapped rows #453
Description
Parent
Spec: bound the prompt panel's bar by wrapped rows, not characters
What to build
ctui draws the person's own prompts as a panel with a thin ┃ bar down its left edge, built as one ┃ per character of the prompt plus three. A 20,000-character paste therefore builds a 20,000-row text element for a panel a few dozen rows tall, rebuilt on every transcript draw.
After this ticket the panel looks exactly as it does today — the bar still reaches the bottom of every prompt, long or short, and the row still clips — but the bar is only as long as the prompt can possibly be once wrapped.
The bound is the wrapped row count per line against a quarter of the inner width, which is the pessimistic cells-per-row figure once wide characters and long unbreakable words are in play, clamped so it can never exceed today's character count:
cells = max(1, floor(inner / 4))
rows = sum over the prompt's lines of max(1, ceil(line length / cells)) + 3
length = min(rows, character count + 3) // never longer than today
The inner width is derived, not measured: the transcript's column count less the panel's five cells of chrome less the gap a docked Sidebar takes, floored at one. The rewrite takes the viewport's column count as a new optional input, passed from the render event for the person's own prompts; given none, the bar keeps today's character-count length.
Note the naive ceil(length / inner) is a lower bound and would stop the bar partway down the panel. Ships on bugfix/plugin-authoring-review.
Acceptance criteria
- A long single-line prompt with a viewport draws a bar far shorter than its character count, and long enough to reach the bottom of the panel at that width.
- A prompt of many short lines counts each line's own wrap.
- The bar is never longer than today's character count plus three, at any width.
- With no viewport, the bar is today's character-count length, unchanged.
- The docked gap is accounted for in the inner width, and no new dock argument is introduced: the gap the rewrite already receives is the Sidebar's.
- The panel's look is untouched: margin, padding, overflow, background, the bar's colour, the removal of paste tags and edge newlines, and which prompt origins ctui rewrites at all.
- Held by unit tests at the existing mount seam for transcript rewrites, one mount with a viewport and one without.
-
node scripts/check.tsexits 0.
Activity
a1exk-dev commentedon Oct 24, 2026
Two formulas, both sound — pick one in the ticket rather than at the keyboard. This ticket writes the bound as
cells = max(1, floor(inner / 4))thenrows = Σ max(1, ceil(line length / cells)) + 3. #443's decision wrote it asΣ 4 × ceil(line length / inner) + 1, then clamped.Both are valid upper bounds on the rows greedy word wrap can take, and this ticket's is the tighter of the two (
ceil(4L/inner) ≤ 4·ceil(L/inner)), so it is the better one to build. Flagged only so the difference from the decision ticket is deliberate and nobody has to work out which to trust mid-change. The clamp to today's character count, and the no-viewport fallback, are identical in both.fix: bound the prompt panel's bar by wrapped rows, not characters
refactor: name the bar's wrap factor and rename the monthly default m…
a1exk-dev commentedon Oct 24, 2026
Shipped in #470.