CLAUDE.md@src/ui · git:20261007.212a13f · 2026-10-07 · sha256 f10cb0295170a806
CLAUDE.md@src/ui git:20261007.212a13fA
Immutable. This exact content never changes and is served at /api/v1/blob/f10cb0295170a806.
# Terminal UI (`src/ui/`) <!-- Loaded when Claude reads files in src/ui/. Checked against the code on 2026-09-23. --> - OpenTUI React (`@opentui/react`, `@opentui/core`), not Ink: lowercase intrinsics (`<box>`, `<text>`, `<scrollbox>`), and the JSX runtime comes from `jsxImportSource`, so no `import React` for JSX. - Colours only through `theme.ts` (the approved web palette with xterm-256 fallbacks); no raw hex in components. No gradients, shadows or glows. Every status is a glyph plus a colour, never colour alone. - The approved website UI (`Shelra/Shelracode-frontend`) is the visual reference, and `docs/ui/DESIGN-SYSTEM.md` records how it translates to terminal cells; keep it in step with `theme.ts` and `acceptance.test.ts`. - The log is the only permanent surface. A plan, a load or a turn summary appears when it exists, and the detail opens on demand (`/plan`, `/diff`, `/checks`, `/context`). Something with nothing to show never draws. - Show only what the runtime knows: read progress, tokens, agents and verification from `Agent` state, never from model text. UI text is English. - Known traps: OpenTUI's `<textarea>` keeps the `onSubmit` it was created with, so use `components/text-area.tsx`. Markdown and code blocks use the local renderers (`markdown.tsx`, `code-highlight.ts`) because OpenTUI's built-in rendering broke list indents, block margins and code colours. - Render tests (`testRender`) run only under `bun test` (see the Bun-only rule in the root CLAUDE.md); pure logic such as `activity.ts` and `observability.ts` stays in Vitest. - Verify the rendered result, not the source: `SHELRA_DEMO_SCENARIO=<name> bun run scripts/ui-demo/main.tsx` mounts the real `App` and `Agent` with real tools on a throw-away fixture; only the model is scripted (scenarios in `scripts/ui-demo/scenarios.ts`; point `HOME`/`USERPROFILE` at a scratch directory). Check 80x24 and 120x40. The owner uses Windows Terminal and Warp. - UI deliverables get three rendered passes, each improving on the last (owner's rule). Load the `terminal-ui` skill for TUI work. - Responsiveness (measured 2026-10-06, `docs/audits/2026-10-ui-responsiveness.md`): every mounted renderable costs layout on every frame, so the log mounts only its last 150 items and reaching the top mounts 100 more (`transcript-window.ts`, `hooks/use-transcript-window.ts`). Nothing on the render path may call into the agent for something that grows with the session (`getContextStats` is cached per message); polled snapshots go through `sameSnapshot` so an unchanged poll does not redraw; streamed text must not re-render its finished blocks (`markdown.tsx` memoizes each block). `scrollToBottom` follows the end only while the reader is there; sending a message uses `jumpToBottom`. Re-measure with `bun run scripts/perf/ui-stress.tsx` (`SHELRA_PERF_WARM=<turns>`).