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.
87
90%
Does it follow best practices?
Impact
84%
1.44xAverage score across 5 eval scenarios
Passed
No known issues
Process steps in order, do not skip ahead. The end state is a ToolkitApp where each pane has a stable id, the app starts with focus on the user's chosen pane (not the first-registered one), Tab cycles between panes, and the focused pane carries a visible border color the audience can spot from across a room. See rules/focusable-needs-id.md for why ids are mandatory, and rules/projector-safe-colors.md for the border color choice.
ListElement, an input textInput(...), sometimes a sidebar list"chat", "trace", "prompt" — short, lowercase, no spacesToolkitApp class, declare one constant per pane: private static final String CHAT_ID = "chat"; (Java) or companion object { const val CHAT_ID = "chat" } (Kotlin).id(CHAT_ID)) and the focus-set site (setFocus(CHAT_ID)) — typos are silent (no compile error, focus just lands on the wrong pane).id(...) and .focusable() on Each Pane.id(CONSTANT).focusable() to its builder chainrules/focusable-needs-id.md — .focusable() without .id(...) is dropped from the chain and the pane silently never receives eventsrender() — see rules/persistent-stateful-elements.mdonStart()onStart() on the ToolkitApp and call runner()?.focusManager()?.setFocus(<PREFERRED_ID>)render() traversal order, not a user-meaningful defaultPROMPT_ID) so the first keystroke goes where the user expectsrender(), look up the current focused id once: val focused = runner()?.focusManager()?.focusedId()focused == ITS_ID — focused → a projector-safe saturated color, unfocused → a dimmer-but-still-visible neutralfun paneBorder(id: String) =
if (runner()?.focusManager()?.focusedId() == id) Color.GREEN else Color.WHITEpanel("CHAT", chatList).rounded().borderColor(paneBorder(CHAT_ID)) — recompute each render so it tracks focus changesrules/projector-safe-colors.md — do not use Color.GRAY for the unfocused border on a demo build, it disappears against light projector backgrounds.focusable() without .id(...) — see rules/focusable-needs-id.mdmouseCapture(true) enabled (see rules/enable-mouse-capture-when-scrollable.md), clicking inside a pane should move focus to it — Toolkit handles this automatically once panes are in the focus chainmouseCapture left at its false default — add the configure() overrideevals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
rules
skills