CtrlK
BlogDocsLog inGet started
Tessl Logo

jbaruch/tamboui

Teaches coding agents how to build TUIs with TamboUI correctly: API-level selection, render-thread discipline, display-width safety, CSS-aware element authoring, and JFR conventions.

76

Quality

95%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

Overview
Quality
Evals
Security
Files

char-width-for-display.mdrules/

alwaysApply:
Yes

Use CharWidth for Display Widths

Java's String.length() returns UTF-16 code units, not terminal display columns. A CJK character is one code unit but two columns wide, an emoji is two code units and two columns, and a ZWJ family glyph can be five code units and two columns. Using length() or substring() for terminal layout produces visible breakage: misaligned tables, half-rendered glyphs, off-by-N truncation, garbled scroll regions.

The Required Replacements

  • For width: CharWidth.of(text) — returns the display column count
  • For display-aware truncation: CharWidth.substringByWidth(text, maxWidth) (from start), CharWidth.substringByWidthFromEnd(text, w) (from end)
  • For ellipsized truncation: CharWidth.truncateWithEllipsis(text, w, position)
  • For a single code point: CharWidth.of(int codePoint)

What Counts as a Display-Width Use

  • Computing a column count for layout, alignment, padding, or buffer placement
  • Truncating text that will land in a Buffer cell, in a widget render path, or in a status string sent to the terminal
  • Comparing string sizes against an Rect width, a Constraint, or an inline-display width

What Does NOT Need CharWidth

  • Index arithmetic on input that is guaranteed ASCII (e.g., parsing a config key) — length() is fine there
  • Logging, JSON serialization, file I/O — those are not terminal display surfaces
  • When in doubt about user-provided text, default to CharWidth

Reference Implementation

  • Paragraph.java shows the correct pattern for line-breaking and truncation; copy from it rather than inventing a new approach
  • For new widgets, mirror Paragraph's loop structure: walk grapheme clusters, accumulate width, break on the cell boundary returned by CharWidth

rules

char-width-for-display.md

css-element-style-resolution.md

enable-mouse-capture-when-scrollable.md

exception-hierarchy.md

focusable-needs-id.md

java-8-source-compat.md

jfr-event-conventions.md

persistent-stateful-elements.md

pick-the-api-level.md

pick-the-text-element.md

projector-safe-colors.md

render-thread-discipline.md

resource-lifecycle.md

text-input-submit-pattern.md

CHANGELOG.md

README.md

tile.json