The lash TUI is not a glossy desktop app. It behaves like a workshop console: warm-black surfaces, sodium-orange intent markers, ash-grey structure, and just enough ornament to make progress feel tactile. The goal is disciplined terminal presence, not fake skeuomorphism.
lash should read as an operator tool with style, not a toy terminal skin. The logo, language, and layout all lean on cut metal, scoring marks, and measured contrast.
The interface is terse but not sterile. Sodium is used for decisions, activation, and directional markers. Chalk carries the readable body text. Ash builds the rails, separators, and containers. Everything should feel sturdy enough to hold a long work session without becoming noisy.
The palette is intentionally narrow. Almost every screen is warm black and chalk until sodium appears to signal intent, mode, or the active edge of work.
lash’s design language benefits from type contrast: monospaced command authority for chrome, and a calmer reading voice for explanations and documentation.
The TUI is defined less by cards and more by stacked terminal zones: a compact status strip, uninterrupted history, framed plan/plugin blocks, and an input area with mode context pinned on the lower edge.
lash should never feel flat. The background field is deep and quiet, then layered with scored diagonals, soft noise, and sodium scribe strokes that suggest motion without becoming decorative clutter.
lash does not need a full icon set. A handful of repeated terminal-native marks do the job: the slash, the prompt spear, the diamond task marker, and the boxed plan/task rails.
These rules keep the TUI coherent as new surfaces get added. If a future component breaks one of these, the component should probably change instead of the system.
Sodium is reserved for the active edge — prompts, plan mode, key labels, plan updates, headings that genuinely matter. Info (cool steel blue) is for ambient metadata: scroll position, expansion level, status indicators that inform without demanding attention.
Every line, rail, and box should clarify hierarchy before it tries to look good. Beauty comes from discipline.
Use borders, glyphs, spacing, and dense text rhythm. Avoid pretending the interface is a web dashboard squeezed into a terminal.
Plan mode and update_plan are different concepts. The UI should signal planning-only turns as a badge, checklist tracking as a durable block, and plugin-authored proposals as their own framed history panels.
An active update_plan checklist lives at the logical tail of the transcript — a blank gutter row followed by the item list. No PLAN header, no scribe rule. It is not pinned to the bottom of the frame; scrolling the history scrolls the plan with it, so older turns remain readable without the plan covering any row.
New activities push in above the plan, so at the foot of history the reader sees the plan framed by whatever just happened. The active step uses ▶; done uses ✓; pending uses □. ■ is reserved for the live-assistant-text marker so the two never collide visually. No stacked Current Plan / Proposed Plan panes, no duplicate copies across turns.
The palette and typography should survive hours of reading. No high-saturation backgrounds, no fragile thin text, no ornamental overload.
Status strips stay compressed. Task trays summarize. Plan blocks are framed because they are durable reference artifacts, not transient chatter.
The first line should name the user-meaningful action — command, query, agent task, task transition, patch result. Transport details belong in expansion or failure states, not as default transcript filler.
Patch output is durable evidence, not a transient tool side effect. Successful edits use lichen green lane rails to visually separate them from explorations (amber) and shell commands (dim chalk). Diff surfaces should feel inspectable rather than dumped.
The transcript has a small, fixed alphabet of lead glyphs. Each carries one meaning:
● — user input marker (brand amber)■ — live assistant text only; never reused for plan steps, activity status, or anything else┊ — reasoning gutter (both live-streaming and compact forms)• — completed generic activity (bullet, not middle-dot — · is too light to read as "a thing happened")× — failed activity◆ — ask / subagent▶ / ✓ / □ — plan dock: active, done, pendingAvoid glyph collisions. If two surfaces want the same symbol, one of them is reading the transcript wrong.
Inline keybinding hints (e.g. the compact reasoning tail's "alt+o to expand") render in terminal fonts that may not carry ⌥, ⌃, or ⇧. Use plain ASCII — alt+o, ctrl+o — so the hint is legible everywhere.
When an activity detail line wraps, the continuation row gets two extra columns of indent. The prefix column stays clean and a wrapped line cannot be misread as a new detail item starting fresh.