overview
introduction how bise looks and behaves, and why. the laws, the foundations, every component of the terminal UI and the UX patterns behind them, with the reasons we chose them.
bise is a terminal app: one thread where you talk to main, your team lead, while agents work behind it. everything on screen is text in cells, so this system is made of cells too: colors, glyphs, rows, keys and words.
agents: read design.md , the same system in about 3,000 tokens. this site is the layer above the brand book . the book keeps every exact spec with its issue number. here you get the patterns and the reasons, so a new screen feels like the old ones without anyone having to ask. when the two disagree, the book wins and this site gets fixed.
start here
how to read a component page
anatomy : the parts, numbered, with what each one is for.states : the mocks have tabs. rest , ctrl held , narrow , NO_COLOR , ASCII . every mock is drawn in the real palette, on the real cells, and follows the site's light/dark switch.rules : what never changes.do / don't : the mistakes we already made once.
the example
every mock tells the same small story, so you can compare them: you asked for three things (signup is slow on mobile, dark mode, the 404 is sad ). main started three agents: perf , dark-mode and sad-404 . perf is done. dark-mode works in its own worktree. sad-404 has a question for you: the dog: a hat, or a scarf?
start here how to read a component page the example
overview
the five laws every rule on this site comes from one of these five. when two rules fight, the law higher on the list wins.
1. never block
you can always type, send and move. nothing takes the keyboard away from you, nothing opens while you type, nothing waits for a click to let you go on.
main works, you keep typing
├─ you → main · opus 5.5 · high · yolo · ≈∿~· ──────────── 58k · 22% ─┤
│ │ │
│ │ and the footer too▌ │
│ │ │
│ tab queue ⏎ steer ctrl+c interrupt │
╰ ────────────────────────────────────────────────────────────────────── ╯
the composer is never locked during a turn: ⏎ steers the running turn, tab queues for after it.
2. calm by default, loud only for you
at rest the screen says almost nothing. color, motion and position go to what needs you, and nothing else. a done agent is a small pink ✓. an agent stuck on a question shows a pink ? and an item in your inbox.
3. one key for the common case
the answer you give 9 times out of 10 is one key away, from anywhere. ctrl+1 opens the first inbox item, 1 allows the command, and the next item opens by itself.
4. show what happened
every action leaves a trace you can see for a moment, then gets out of the way: a fold line after an answer, ✓ inbox clear on the divider, the row you changed flashing ✓.
5. never lie
no hidden limit, no fake progress, no key that doesn't work, no promise the product can't keep. without ctrl+digits from the terminal, the inbox says click to open. it never shows ctrl+1.
a law is a tie-breaker. "show what happened" never justifies a pop-up that blocks typing: law 1 wins.
1. never block 2. calm by default, loud only for you 3. one key for the common case 4. show what happened 5. never lie
the screen one frame, one thread, one panel. every part of bise's main screen, named, so we all say the same word for the same thing.
rest ctrl held
╭─ bise :* ─────────────────────────────────────────────────────── ┬ ──── ~/acme · # 1 in the inbox ─╮
│ │ │
│ │ signup is slow on mobile. and the 404 is sad ✓✓ │ agents │
│ │ │
│ :* on it: perf, dark-mode and sad-404 started. │ 0 ∿ main :* @ 2 1m 22% │
│ ▸ 9 messages between 3 agents │ 1 ✓ perf │
│ │ 2 ∿ dark-mode 3m 12% ψ │
│ ✉ dark-mode → main │ 3 ? sad-404 18% │
│ which gray for the borders? │ 4 ∿ emoji-csv • 42s 31% │
│ :* i answered dark-mode: the gray in tokens.css. │ 5 ○ release 8% │
│ │ │
│ $ runs the signup benchmark ✓ 4.2s │ inbox │
│ ✓ perf is done · signup 4.1 s → 0.9 s │ 1 ? sad-404 the dog: a h… │
│ │ │
│ ╭─ inbox · 1 waiting for you ─────────────────── ctrl+1 open ─╮ │ │
│ │ 1 ? sad-404 · the dog: a hat, or a scarf? 4m │ │ │
│ ╰ ───────────────────────────────────────────────────────────── ╯ │ │
├─ you → main · opus 5.5 · high · yolo · ≈∿~· ─────────────────── ┴ ──────────────────── 58k · 22% ─┤
│ │ │
│ │ and give the sad dog a hat▌ │
│ │ │
│ @ file $ skills / commands ctrl+1 inbox │
╰ ────────────────────────────────────────────────────────────────────────────────────────────────── ╯
╭─ bise :* ───────────────────────────────── ~/acme · ≈∿~ 3 working · ✓ 1 done · # 1 in the inbox ─╮
│ │ │
│ │ signup is slow on mobile. and the 404 is sad ✓✓ │ agents │
│ │ │
│ :* on it: perf, dark-mode and sad-404 started. │ 0 ∿ main :* @ 2 working │
│ ▸ ctrl+o expand │ 1 ✓ perf done │
│ │ 2 ∿ dark-mode working ψ │
│ ✉ dark-mode → main │ 3 ? sad-404 asks you │
│ which gray for the borders? │ 4 ∿ emoji-csv • working │
│ :* i answered dark-mode: the gray in tokens.css. │ 5 ○ release idle │
│ │ │
│ $ runs the signup benchmark ✓ 4.2s │ inbox │
│ ✓ perf is done · signup 4.1 s → 0.9 s │ 1 ? sad-404 the dog: a h… │
│ │ │
│ ╭─ inbox · 1 waiting for you ─────────────────── ctrl+1 open ─╮ │ │
│ │ 1 ? sad-404 · the dog: a hat, or a scarf? 4m │ │ │
│ ╰ ───────────────────────────────────────────────────────────── ╯ │ │
├─ you → main · opus 5.5 · high · yolo · ≈∿~· working · 1m ────── ┴ ────── 58k / 262k tokens · 22% ─┤
│ │ │
│ │ and give the sad dog a hat▌ │
│ │ │
│ ctrl+c interrupt ctrl+f find ctrl+1 open an inbox item ctrl+s find agent │
╰ ────────────────────────────────────────────────────────────────────────────────────────────────── ╯
100 columns. hold ctrl and every word comes back in its own place; let go and it goes.
anatomy
the frame : a thin rounded border around the whole app. its top border is the header: bise :*, the folder and the inbox count. → frame & header the history : main's thread, append-only, in a reading column. your messages carry a thin pink bar. → your message , three levels the agents panel : one row per agent, its status glyph, its numbers. → agents panel the inbox : what needs you, in its own box above the divider. → inbox the divider : who you talk to, with which model, effort and mode, and whether it works. → divider the composer : your space, raised, never locked. → composer the key bar : the 3-4 keys you can't guess. → key bar anatomy
color color is attention. only what needs you and what failed get a hue. everything else is text, dim or faint.
the palette
role dark light contrast carries never text #ece6da#1b191715:1 what you read: answers, names, your message — dim #a39c90#6b645a6.9:1 the model, the agent's own work, durations something you must act on faint #857d72#7d766c4.6:1 key labels, numbers, separators · a sentence you must read rule #4a4540#cfc8bd1.97:1 lines: the frame, the panel's rule, borders text, ever accent #f4a6b0#b8416b9.7:1 needs you, :*, the agent you talk to, done ✓, read ✓✓, your bar decoration error #ff5a52#b3261e6.1:1 failures only: ✗, failing checks, a wrong key a warning, a default ok #b9d99a#3f7a2a— diff additions only success
surfaces
surface dark light for ground #141211#fdfbf7every cell: bise paints its own background raised #1f1c1a#f4f0e8your space: the composer pane raised 2 #26221f#efeae0an inbox item open in place, one step above chip #231f1d#efe9dfthe envelope chip of a message between agents pill #3a2530#f0d3dca quote or image chip in your text selection #33292c#fdeef2selected text
in context
dark NO_COLOR
? sad-404 needs you
the dog: a hat, or a scarf?
✓ perf is done · signup 4.1 s → 0.9 s
✗ release failed · npm publish: 403 forbidden
∿ dark-mode working · 3m
? sad-404 needs you
the dog: a hat, or a scarf?
✓ perf is done · signup 4.1 s → 0.9 s
✗ release failed · npm publish: 403 forbidden
∿ dark-mode working · 3m
three hues on screen, three meanings: pink needs you or is yours, red failed, the rest is grey. under NO_COLOR, bold takes the accent's job.
rules
pink is never red. "needs you" must not look like an error.never green for done. done is a small pink check. green success reads like a CI dashboard, and it isn't us.one hue per row. if two things on one row want color, one of them is wrong.every readable text is ≥ 4.5:1 on white, our cream, black and a typical dark grey.the rule color is for lines. it was the old faint text color: too dark to read, so text moved to faint.
✓ do
color the one thing on screen that needs the user use dim for the agent's own work, so your words and main's stand out keep the error color for something that really broke ✗ don't
color a default (yolo is dim, not red) use green for success or a passing check use the rule color for text, even a hint the palette surfaces in context rules
typography one font, the user's. one size. importance comes from contrast, weight and room.
one size
a terminal has one font size, so we never pretend otherwise in the product. what's for you reads "bigger" through contrast (text over dim), weight (the speaker in bold) and room (a blank row above and below).
∴ thought for 14s ▸
$ runs the signup benchmark ✓ 4.2s
:* perf is done. signup went from 4.1 s to 0.9 s on a phone.
the hero image was 4.2 MB, it's 310 kB now.
± edit web/src/hero.tsx ✓ +3 −1 ▸
level 2 (main to you) gets text color, a bold speaker and a blank row around it. the agent's own work stays dim.
rules
the user's font in the terminal. JetBrains Mono on the site, the book and every mock.bold is rare : a speaker (:*, @ name to you:), a screen's title, a key you must notice. never a paragraph.lowercase everywhere , except proper nouns (GitHub, Mistral), acronyms (PR, MCP) and keys as printed (ctrl+s). our own name stays bise.no italic, no underline in the product, except a link: the text underlined in the accent.a reading measure : prose wraps at 88 columns at most. code can run to 100.one size rules
space & layout everything sits on whole cells. a few fixed columns, a reading column, one blank row between blocks.
the grid
column / row what starts there column 0 and F−1 the frame column 3 the frame's title, the history's text, the divider's label column 7 the composer's text and the key bar (x0 + 4: the composer is its own pane) panel text from the panel's rule + 2, 28 columns, to F−4 (wider from 165 columns) row 0 the header, in the frame's top border H−2 the key bar, then the frame's bottom
the reading column
prose wraps at 88 columns whatever the width. more width goes to the margin and the panel, never to longer lines. tables and code may run to 100.
widths
terminal layout ≥ 165 the panel grows 1 column for every 5, up to 44 at 240 100–164 the panel at 28 columns, its rule joining the frame 90–99 the panel at 24 columns < 90 no panel: the header keeps short counts < 60 or < 16 rows no frame: a header row, a plain rule for the divider
vertical rhythm
one blank row between history blocks. level 2 gets one above and below. two blank rows in a row is a bug.the history starts on row 2 and ends one blank row above the inbox or the divider. the composer pane at rest: divider, bar row, text, bar row, key bar, frame. nothing under the frame.
✓ do
line a new element up with an existing column right-align numbers in their column (3m, 42s, 12%) keep every column in place even when its cell is blank, so rows line up ✗ don't
start text at a new column of its own use half rows or sub-cell gaps in a mock: the terminal can't let prose grow with the screen the grid the reading column widths vertical rhythm
motion motion means something is alive. the gust while an agent works, the cursor, the :* pop, a flash for 2-3 seconds. nothing bounces, nothing slides.
the gust
an agent at work is a gust blowing by: 5 cells, 110 ms a frame, a 9-frame cycle. head ≈ and ∿ in text, ~ dim, · faint, then 5 empty frames.
divider (5 cells) short (3 cells) panel (1 cell breathes)
├─ you → main · opus 5.5 · high · yolo · ≈∿~· ─────────────────────── ─┤
├─ you → main · opus·hi · yolo · ≈∿~ ───────────────────────────────── ─┤
the gust never disappears while the agent works: it's the last thing kept on a short divider.
timing
motion duration the gust 110 ms a frame, 9 frames a mode switch (shift+tab) the word in accent for 3 s a fold line after an answer 2 s ✓ inbox clear, ✓ copied2 s zen fades in at once; comes back 5 s after your last key
rules
one animation per thing , never two on one row.≤ 10 frames a second , only the cells that change are redrawn.stop when the terminal loses focus, when nothing works, and under a reduce-motion setting: a static ∿ then.no motion to decorate. a pop for :* at launch is the one flourish.the gust timing rules
glyphs one glyph per thing, one thing per glyph. one cell wide, in every common font, with an ASCII form.
the set
glyph means ASCII :*main, your team lead :*│your message (thin bar, accent) `\ ` ┃needs you (heavy bar, accent) `\ ` ∿working: the gust ~?needs you ?✓done (accent); at the end of your message: got it * / v✓✓read by the model vv✗failed (error) x○idle o…waiting on another agent ;·starting, sending .•unread (accent) !ψits own worktree Y↑its pull request (designed) P$a bash call $ƒa TypeScript call f±a file edit %∴thinking :▸ ▾closed / open + -✉︎a message between agents @▣ ❝an image, a quote #
rules
one cell wide in every font we audited. a glyph that turns into a color emoji somewhere is out: ✉ became @ in the panel, ⎇ became ψ.the place tells two marks apart. ✓ leading a row is done; ✓ ✓✓ at the end of your message is got it / read.**every glyph has a row in the /help legend**, and a test fails when one hasn't. a glyph needs no legend after a week. if people ask twice, change it.two meanings for one glyph is a bug. see open questions for the one we still have.the set rules
themes & fallbacks a design isn't done until it works in light and dark, under NO_COLOR, in ASCII and on 16 colors.
the same row, five ways
dark NO_COLOR ASCII
3 ? sad-404 · the dog: a hat, or a scarf? 4m
2 ∿ dark-mode ψ · dims the borders
✓ perf is done
3 ? sad-404 · the dog: a hat, or a scarf? 4m
2 ∿ dark-mode ψ · dims the borders
✓ perf is done
3 ? sad-404 . the dog: a hat, or a scarf? 4m
2 ~ dark-mode Y . dims the borders
* perf is done
the light theme: use the switch at the top right. every mock on this site follows it.
form what changes light the palette's light column, picked from the terminal's background (OSC 11), or forced NO_COLOR no hue, no tint. the accent becomes bold, dim stays dim, chips get [ ] 16 colors no tints: the raised pane and chips go, the bar alone marks your space ASCII (BISE_ASCII=1)every glyph in its ASCII form, boxes in `+ - \ , ...` for a cutreduce motion a static ∿ everywhere
bise paints its own background on every cell, so it reads whatever the terminal's theme. it gives the terminal's color back on exit, on a crash, and when a shell takes the screen.
the same row, five ways the forms
frame & header bise draws itself like an app: a thin rounded frame on the terminal's edge, with the header in its top border.
rest ctrl held no panel (narrow) an agent's view
╭─ bise :* ──────────────────────────────── ~/acme · # 1 in the inbox ─╮
│ │
╭─ bise :* ───── ~/acme · ≈∿~ 3 working · ✓ 1 done · # 1 in the inbox ─╮
│ │
╭─ bise :* ──────────────────────────────────── ∿ 3 · ? 1 · ✓ 1 · # 1 ─╮
│ │
╭─ bise :* · dims the borders to tokens.css ────────────────── ~/acme ─╮
│ │
anatomy
bise bold and :* in accent, from column 3.in an agent's view, its role line : what it's doing now, ≤ 60 characters, written after each of its turns. on the right, dim: the folder and the inbox count. with no panel, the short counts (∿ 3 · ? 1), because the panel is the one that shows agents.
rules
the frame's lines are in the rule color and paint no background. short on room: the folder goes first, then long counts become short. under 60 columns or 16 rows: no frame, a header row instead. anatomy rules
your message what you said, marked by a thin pink bar on every line. its marks at the end say whether it arrived and was read.
sent got it read long
│ signup is slow on mobile. and dark mode. and the 404 is sad ·
│ signup is slow on mobile. and dark mode. and the 404 is sad ✓
│ signup is slow on mobile. and dark mode. and the 404 is sad ✓✓
│ here is the full list of things i noticed on the signup page, in
│ the order i'd fix them:
│ 1. the hero image is 4.2 MB
│ ▸ 12 more lines ✓✓
anatomy
the thin │ bar in accent, on every wrapped line. the heavy ┃ belongs to things that need you. your text, in the text color. the mark: · sending, ✓ the agent got it, ✓✓ (accent) the model read it. past 20 lines: ▸ n more lines, opened by a click, space or ctrl+o.
rules
thin bar = you, heavy bar = needs you. you tell at a glance what you said from what they said. a quote or an image is one chip in your text (❝ 1, ▣ 1), never a separate block above it. anatomy rules
three levels everything in the history sits on one of three levels: it needs you, it's for you, or it's between agents.
┃ ? sad-404 needs you
┃ the dog: a hat, or a scarf?
:* i answered dark-mode: the gray in tokens.css, like everywhere.
✉ dark-mode → main
which gray for the borders?
✉ main → dark-mode
the one in tokens.css.
top to bottom: level 1, level 2, level 3.
level what look 1 · needs you a question, an approval the inbox; the heavy ┃ and a bold accent title, until you answer 2 · for you main talking to you, reports on what you asked text color, the speaker in bold, a blank row above and below 3 · between agents what agents tell each other dim, an envelope chip, folded after a few
rules
levels 2 and 3 differ by brightness and the chip, never by hue. a new kind of event gets a level before it gets a look. if it fits none, it probably shouldn't reach the screen. main answering for you is level 2, and it says why: ▸ why. rules
agent messages when agents talk to each other, it looks like a message: a small tinted chip says who writes to whom, the text goes under it, dim.
one a run folded NO_COLOR
✉ dark-mode → main
which gray for the borders? the mock says #2a2623, tokens.css
says #4a4540. … ▸
✉ perf → main
the hero image is 4.2 MB. ok to convert it to webp?
also: the font loads twice.
✉ main → perf
yes to both.
▸ 9 messages between 3 agents
[✉ dark-mode → main]
which gray for the borders?
rules
the quietest thing on screen: the chip's tint is its only background, no accent inside , main included. the text sits under the chip, never beside it, so every text starts on the same column. at most 2 rows, then … ▸. the same pair stacks with no blank row; a new pair gets one. short on room, the receiver's name is cut before the sender's. never the arrow, never the envelope. rules
tool rows each bash or TypeScript call is one dim row: its glyph, what the model says it's doing, in your language, and its state.
rows one opened ASCII
$ installs the deps ✓ 3.1s
ƒ reads the open issues on GitHub ∿ 12s
$ runs the tests ✗ exit 1 · 0.8s
FAIL signup.spec.ts › keeps the email after a reload…
$ ▸ 6 commands · weighs the hero image ✓ 3.2s
╭─ $ weighs the hero image ✓ 0.1s ──────────────────────────────────── ─╮
│ ls -la public/hero.png │
├ ────────────────────────────────────────────────────────────────────── ┤
│ -rw-r--r-- 1 gab staff 4.2M hero.png │
╰ ────────────────────────────────────────────────────────────────────── ╯
$ installs the deps ok 3.1s
f reads the open issues on GitHub ~ 12s
$ runs the tests x exit 1
> 6 commands · weighs the hero image ok 3.2s
$ bash or ƒ TypeScript, in the lead column (error color when it failed).the model's own description , one short line in your language. running, it's in the text color. the state, right-aligned: ∿ 12s running, ✓ 0.3s done (dim, never green), ✗ exit 1 · 0.8s failed. a failure adds one row: the first error line, cut with ….
4 done calls or more in a run fold into ▸ n commands. failed and running calls keep their rows. a click or space opens one call as a box (15 rows); ctrl+o opens every one. a failure never opens by itself: its first error line is enough to decide. anatomy rules
folds ▸ means there is more here. one line by default, everything one key away. folded is never gone.
closed ctrl held
∴ thought for 14s ▸
± edit web/src/hero.tsx ✓ +3 −1 ▸
▸ 9 messages between 3 agents
│ ▸ 12 more lines ✓✓
∴ thought for 14s ctrl+o expand
± edit web/src/hero.tsx ✓ +3 −1 ctrl+o expand
▸ ctrl+o expand
│ ▸ ctrl+o expand ✓✓
rules
▸ closed, ▾ open. a click or space toggles one, ctrl+o opens or closes all.the fold row says what's inside and how much: ▸ 12 more lines, ▸ 6 commands. search (ctrl+f) finds text in a folded part and opens it. what you must act on is never folded. rules
agents panel one row per agent: its number, its status glyph, its name, and on the right what changes: the turn time, the context, its worktree.
rest ctrl held ⌥ held with a PR
agents
0 ∿ main :* @ 2 1m 22%
1 ✓ perf
2 ∿ dark-mode 3m 12% ψ
3 ? sad-404 18%
4 ∿ emoji-csv • 42s 31%
5 ○ release 8%
agents
0 ∿ main :* @ 2 working
1 ✓ perf done
2 ∿ dark-mode working ψ
3 ? sad-404 asks you
4 ∿ emoji-csv • working
5 ○ release idle
agents · ⌥↑↓ select
⌥0 ∿ main :* @ 2 1m 22%
⌥1 ✓ perf
⌥2 ∿ dark-mode 3m 12% ψ
⌥3 ? sad-404 18%
2 ∿ dark-mode 3m 12% ↑
6 ✓ login-fix 9% ↑
with a PR: ↑ takes ψ's column (a PR implies a branch). red only when its checks fail. designed, not built yet.
anatomy
number , faint: ⌥ + it opens the agent. it never changes while the agent lives.status glyph : the breathing gust, ✓, ?, ✗, ○, ….name , then its marks: main's :* and @ n, the pink • unread.turn time , 3 columns, right-aligned, only while it works.context % , 3 columns, right-aligned.ψ far right when it works in its own worktree.
rules
no state words at rest : the glyph says them. holding ctrl writes them in the time and % columns.every column stays in place even when blank, so the rows line up.a name takes the room its row leaves and is cut with … only there. anatomy rules
divider the rule between the history and your space. it says who you talk to, with which model, effort and mode, and whether it works.
working idle ctrl held mode switched an agent narrow
├─ you → main · opus 5.5 · high · yolo · ≈∿~· ──────────── 58k · 22% ─┤
├─ you → main · opus 5.5 · high · yolo ───────────────────── 18k · 2% ─┤
├─ you → main · opus 5.5 · high · yolo · ≈∿~· working · 1m ─── 58k / 262k tokens · 22% ─┤
├─ you → main · opus 5.5 · high · auto ───────────────────── 18k · 2% ─┤
├─ you → dark-mode · sonnet 5.5 · low · yolo · ψ sb/dark-mode · ≈∿~· ─┤
├─ you → main · opus·hi · yolo · ≈∿~ ───────────────────────────────── ─┤
anatomy
you → dim, the agent's name in accent.model and effort, dim, · faint between them. the approvals mode, dim (accent for 3 s after shift+tab). the gust, only while it works. on the right, the context, short: 58k · 22%.
rules
the divider is also where short notes land: ✓ inbox clear, ✓ copied 9 chars, an open item's you → ? sad-404 · your answer. short on room: the long context falls back to the short one, then the context goes, then the branch name, then opus 5.5 · high becomes opus·hi. the mode goes last. the gust stays. anatomy rules
composer your space: a raised pane with your pink bar. it's never locked, and markdown shows as you type it.
empty typing main works
├─ you → main · opus 5.5 · high · yolo ───────────────────── 18k · 2% ─┤
│ │ │
│ │ what's on your mind? │
│ │ │
│ @ file $ skills / commands │
╰ ────────────────────────────────────────────────────────────────────── ╯
├─ you → main · opus 5.5 · high · yolo ───────────────────── 18k · 2% ─┤
│ │ │
│ │ make the 404 page **funnier**, and give the dog a hat▌ │
│ │ │
│ @ file $ skills / commands │
╰ ────────────────────────────────────────────────────────────────────── ╯
├─ you → main · opus 5.5 · high · yolo · ≈∿~· ──────────── 58k · 22% ─┤
│ │ │
│ │ and the footer too▌ │
│ │ │
│ tab queue ⏎ steer ctrl+c interrupt │
╰ ────────────────────────────────────────────────────────────────────── ╯
rules
raised, edge to edge inside the frame: it's the one place where you type.the bar is faint while empty, accent with text, an image or a recording. never locked : during a turn ⏎ steers it, tab queues for after it.markdown is colored, never hidden : every mark stays, the message sent is the text typed.text starts at column 7, one column right of the history's: the pane is its own space. rules
attachments box what comes with your message, but isn't your text, sits in its own small box above it. so you never think it's part of what you typed.
│ ╭─ attached ──────────────────────────────────────────────────── ─╮ │
│ │ ❝ 1 “la licence du repo,” │ │
│ │ ▣ 2 404.png 1440×900 │ │
│ ╰─ backspace on a chip removes it ────────────────────────────── ─╯ │
│ │ tu recommandes quoi pour ❝ 1 ? et regarde ▣ 2 ▌ │
│ @ file $ skills / commands │
rules
a quote or an image is a chip inline in your text; the box lists what each chip is. the box has its own border and title, so it reads as a tray, not as lines of your message. backspace on a chip removes it from both places. rules
key bar the 3 or 4 keys you can't guess, under the composer. holding ctrl shows every other one.
rest main works an agent's view ctrl held an item open
@ file $ skills / commands ctrl+1 inbox
tab queue ⏎ steer ctrl+c interrupt
esc back to main @ file $ skills / commands
ctrl+c interrupt ctrl+f find ctrl+1 open an inbox item
1-2 answer ←→ choose ↑↓ other items esc back to your message
rules
the key in text color, what it does dim, 3 spaces between pairs. only keys you can't guess. ⏎ send and ? help went: everybody knows them.only keys that work here. ctrl+1 inbox shows only while the inbox has items, and only when the terminal sends ctrl+digits; otherwise /inbox.the bar follows the mode: steering, an agent's view, an open item each have their own. rules
inbox what needs you, in its own box above the divider. it never blocks: you keep typing to main while items wait.
one item four items ctrl held no ctrl+digits
╭─ inbox · 1 waiting for you ──────────────────────────── ctrl+1 open ─╮
│ 1 ? sad-404 · the dog: a hat, or a scarf? 4m │
╰ ────────────────────────────────────────────────────────────────────── ╯
╭─ inbox · 4 waiting for you ────────────────────────── ctrl+1-3 open ─╮
│ 1 ? t3 · $ npm publish --access public 2m │
│ 2 ? api-v2 · $ git push origin main 3m │
│ 3 ? sad-404 · the dog: a hat, or a scarf? 4m │
│ + 1 more · ↑ #409 ready to merge │
╰ ────────────────────────────────────────────────────────────────────── ╯
╭─ inbox · 4 waiting for you ────────────────────────── ctrl+1-3 open ─╮
│ 1 ? t3 · $ npm publish --access public 2m │
│ 2 ? api-v2 · $ git push origin main 3m │
│ 3 ? sad-404 · the dog: a hat, or a scarf? 4m │
│ + 1 more · ↑ #409 ready to merge │
╰ ────────────────────────────────────────────────────────────────────── ╯
╭─ inbox · 1 waiting for you ────────────────────────── click to open ─╮
│ 1 ? sad-404 · the dog: a hat, or a scarf? 4m │
╰ ────────────────────────────────────────────────────────────────────── ╯
what goes in
kind answers an approval 1 allow · 2 always allow … here · 3 noa hard rule (push to main, secrets, a wipe) 1 allow · 3 no: no "always"a sandbox rerun 1 run it again without the sandbox · 2 always here · 3 noa question its choices, or free text ready to merge (designed) 1 merge it · 2 not yet
reports, done notes and FYI stay out: they're main's thread.
rules
its own box , rounded, in the rule color, on the ground. no box when there's nothing.numbered the same everywhere : the row that says 1 here says 1 in the panel, and ctrl+1 opens it.approvals first, then questions, then merges. 3 rows, then + n more. the title's right side only names a key that works: ctrl+1-3 open, click to open, or /inbox opens it. what goes in rules
inbox item an item opens where its row was, with what the agent did last. one key answers it, and the next one opens by itself.
open option chosen right after the last one
╭─ inbox · 2 waiting for you ────────────────────────── ctrl+1-2 open ─╮
│ ┃ │
│ ┃ ? t3 wants to run 1 of 2 · 2m │
│ ┃ $ npm publish --access public │
│ ┃ │
│ ┃ it publishes the package: everyone can install it. │
│ ┃ t3 is shipping 2.5.0 · its last step: ✓ npm run build │
│ ┃ │
│ ┃ 1 allow 2 always allow npm publish * here 3 no │
│ ┃ or type why not, ⏎ says no │
│ ┃ │
│ 2 ? sad-404 · the dog: a hat, or a scarf? 4m │
╰ ────────────────────────────────────────────────────────────────────── ╯
├─ you → ? t3 · your answer ────────────────────────────────────────── ─┤
╭─ inbox · 2 waiting for you ────────────────────────── ctrl+1-2 open ─╮
│ ┃ ? t3 wants to run 1 of 2 · 2m │
│ ┃ $ npm publish --access public │
│ ┃ │
│ ┃ 1 allow 2 always allow npm publish * here 3 no │
│ ┃ or type why not, ⏎ says no │
│ 2 ? sad-404 · the dog: a hat, or a scarf? 4m │
╰ ────────────────────────────────────────────────────────────────────── ╯
╭─ inbox · 1 waiting for you ──────────────────────────── ctrl+1 open ─╮
│ ✓ you allowed t3: npm publish --access public │
│ ┃ ? sad-404 asks 1 of 1 · 4m │
│ ┃ the dog: a hat, or a scarf? │
│ ┃ │
│ ┃ 1 a hat 2 a scarf │
│ ┃ or type your answer, ⏎ sends it │
╰ ────────────────────────────────────────────────────────────────────── ╯
├─ ✓ inbox clear ───────────────────────────────────────────────────── ─┤
│ │ │
│ │ and give the sad dog a hat▌ │
after the last answer, the box goes, your draft comes back and the divider says ✓ inbox clear for 2 s.
keys
key does ctrl+1…9, a clickopen item N, in place 1–9pick that option (empty composer) ← →highlight an option; ⏎ picks it ↑ ↓the previous / next item type, then ⏎ answer in words (for an approval: a no, with your note) ctrl+ofull screen, the other items as tabs escback to your message, the cursor where it was
rules
the open item is raised one step above the composer, with the heavy ┃ on every row. your draft is set aside, never lost : the divider says you → ? t3 · your answer while you answer.after an answer, a fold line for 2 s, then the next item opens by itself : 1, 1, 3, 1 clears four. past half the feed, the item shows its start and … n more lines · ctrl+o full screen. keys rules
pickers every full-screen choice looks the same: a question, a filter, what works first, enter forward, esc back.
/models step 1 step 2
which model does what?
each role picks a provider, then a model. one provider can serve several.
› main Mistral mistral-large-latest · high
agents same as main · Mistral · mistral-large-latest
small jobs auto · Mistral · ministral-8b-latest
voice Mistral voxtral-mini-latest
↑↓ choose · enter change · esc back
agents: which provider?
now: same as main · Mistral · mistral-large-latest
› same as main Mistral · mistral-large-latest
Mistral ✓ ready · main, small jobs use it
Anthropic ✓ ready
OpenAI not set up
more providers…
agents · Anthropic: which model?
type to filter, or a model id that isn't listed.
› son ▌
› claude-sonnet-5-5 recommended
claude-sonnet-4-6
rules
a bold question as the title , one dim line saying what it changes.what works comes first : ready providers before the rest, same as main / auto first, with what they resolve to.the current one says now (dim). one recommended at most, in accent.enter forward, esc back one step, digits pick at once. a step with one choice is skipped.after the last step you land where you started, the row flashing ✓. rules
popups /, @ and $ open a small list right above the composer. tab completes, ⏎ runs, esc closes. typing never stops.
╭─ ──────────────────────────────────────────────────────────────────── ─╮
│ › /models which model does what │
│ /model the model of the agent in view │
│ /theme light · dark · auto │
╰ ────────────────────────────────────────────────────────────────────── ╯
│ │ /mo▌ │
/ commands, @ a file, $ a skill. the list filters as you type.tab completes, ⏎ runs once nothing is left to pick, esc closes and keeps your text.the arguments of a command are listed the same way (/theme → light · dark · auto). rules
find ctrl+f (or cmd+f) finds text in the history, in a small box over its top-right corner, like an editor's find.
╭─ find ───────────────────────── ─╮
│ › hero▌ 2/5 │
╰ ────────────────────────── ╯
the hero image was 4.2 MB, the hero loads twice.
rules
3 rows, its top border on the history's first row, left of the panel's rule. ⏎ next, shift+⏎ previous, esc closes. it searches folded text too, and opens it.it never covers the line it found: the history scrolls. rules
agent palette type part of an agent's name to jump to it. live agents first, archived ones dim.
╭─ find agent ──────────────────────────────────────────────────────── ─╮
│ › dar▌ │
│ │
│ › ∿ dar k-mode · dims the borders to tokens.css │
│ – dar t-sass · archived │
╰ ────────────────────────────────────────────────────────────────────── ╯
rules
ctrl+s everywhere; cmd+k once the terminal has passed a cmd key. /switch works too.↑↓ choose, ⏎ opens the agent's view, esc closes.the part that matches is bold; an archived agent opens read-only. rules
flashes & tips a flash says what just happened, where your eyes already are, for 2-3 seconds. a tip explains something the first time, once.
mode switch copied inbox clear first-time tip
├─ you → main · opus 5.5 · high · auto ───────────────────── 18k · 2% ─┤
auto · safe calls run, risky ones ask you
├─ you → main · opus 5.5 · high · yolo · ✓ copied 9 chars ──────────── ─┤
├─ ✓ inbox clear ───────────────────────────────────────────────────── ─┤
╭─ ──────────────────────────────────── ─╮
│ you're in yolo: everything runs. │
│ ⇧⇥ changes it. │
╰ ───────────────────────────────────── ╯
├─ you → main · opus 5.5 · high · yolo ───────────────────── 18k · 2% ─┤
rules
where your eyes are : the divider, the row you touched, the key bar. never a pop-up in a corner.a sentence of state , not a cheer: ✓ inbox clear, never "all done!".a tip shows once, ever , over the thing it explains, and goes on the next key. rules
patterns
less at rest, more when you hold a key at rest the screen shows what changes and what needs you. holding a modifier brings every word back, in place, and letting go puts it away.
rest ctrl held
2 ∿ dark-mode 3m 12% ψ
3 ? sad-404 18%
2 ∿ dark-mode working ψ
3 ? sad-404 asks you
the modifiers
hold shows ctrlevery ctrl key where it acts (▸ ctrl+o expand, the inbox numbers in accent), the state words, the long forms (58k / 262k tokens), the full header, the full key bar ⌥the panel's numbers as ⌥0 ⌥1, ⌥↑↓ select cmdthe cmd keys, once a cmd key has really reached bise
rules
the held form replaces the rest form in the same cells. nothing moves, nothing pushes.the glyph already says it , so the word waits for ctrl.a key you hold types nothing : it's the cheapest way to see more.
why: "on affiche trop d'informations" (the user). the glyphs said the state, and the words said it again.
the modifiers rules
progressive disclosure one line by default, details one key away. folded is never gone, and what you must act on is never folded.
item by default opened thinking ∴ thought for 14s ▸the full text a bash / TypeScript call one row with the model's description its box: script and output 4+ calls in a run ▸ 6 commands · …the rows a file edit ± edit hero.tsx ✓ +3 −1 ▸the diff agents talking ▸ 9 messages between 3 agentsthe chips your long message 20 rows, ▸ 12 more lines the whole message a report ✓ perf is done ▸ reportthe report
rules
space or a click opens one, ctrl+o opens all, ▾ closes.a failure shows its first error line, a question shows in full: you never open something to know you must act . search finds what's folded and opens it. rules
patterns
never block you can always type, send and move. nothing takes the keyboard away, nothing opens while you type.
where it shows
the composer is never locked. during a turn, ⏎ steers it, tab queues for after it.the inbox never takes the composer. it's a box above it. an item opens only when you ask (ctrl+N, a click), never while your draft has text.an open item sets your draft aside , and esc gives it back, cursor in place.talk to any agent, anytime. ⌥ + its number, then back to main. nobody has to stop.restart whenever. the agents, your thread, your draft and your queue come back.
✓ do
let the user answer later: an item waits in the inbox, the agent waits for it keep the thread in sight while answering: open in place, not on a new screen ✗ don't
open a modal that eats the next keys auto-focus a new item while the user types block sending because an item waits where it shows
one key for the common case the answer you give 9 times out of 10 is one key away, from anywhere. digits pick, the same digit everywhere.
rules
digits pick. in an item, a menu, a picker: 1–9 takes that option at once.one number, one thing, everywhere. the inbox row 1 is 1 in the panel, and ctrl+1 opens it from anywhere.the next one comes to you. after an answer the next item opens by itself: 1, 1, 3, 1 clears four.one key, one meaning. esc is always back one step. ⏎ is always "do it". ctrl+o always opens what's folded.every key that's shown works. we check what the terminal sends; no ctrl+digits → click to open, /inbox.leave the system's keys alone. macOS keeps ctrl+arrows for Spaces, so we don't build on them. when we must take one (cmd+f), the book says how to free it per terminal.every key has a mouse twin , and every click a key.rules
patterns
show it, then fold it every action leaves a trace you can see for a moment, where your eyes already are, then gets out of the way.
what happened where it shows how long you switched mode the mode word in accent on the divider, its words on the key bar 3 s you answered an item a fold line in the box, then the next item 2 s the last item ✓ inbox clear on the divider, your draft back2 s a setting changed the row flashes ✓ 1 flash you copied ✓ copied 9 chars on the divider2 s your message · → ✓ → ✓✓ at its endstays an agent finished its glyph turns ✓, one line in main's thread stays
rules
the same fold line lands in main's thread, so the history keeps the decision. a flash is a state, never a cheer. no exclamation marks. rules
short on room: a written drop order every line that can run out of room has its order written down, and we apply it one step at a time.
80 columns 58 48 32
├─ you → dark-mode · opus 5.5 · high · yolo · ψ sb/dark-mode · ≈∿~· ──── 58k ─┤
├─ you → dark-mode · opus 5.5 · high · yolo · ψ · ≈∿~· ─┤
├─ you → dark-mode · opus·hi · yolo · ψ · ≈∿~ ─┤
├─ you → dark-mode · yolo ∿ ── ─┤
the same divider as the room shrinks. the gust is the last thing to go: never, while it works.
the order
explanation words first (working · , in the inbox), long forms become short (opus 5.5 · high → opus·hi, ∿ 3 working → ∿ 3), whole details go (a branch's name, the model tag), names are cut last , with …, never through a glyph or an arrow,what says "alive" or "needs you" is never dropped: the gust while working, ?.
every new line ships with its drop order, tested at 80 and 150 columns.
the order
errors one line: what happened, then how to fix it, with the command that fixes it. nothing is lost.
✗ turn stopped: no OpenRouter key yet. /provider sets it up.
✗ Mistral says the voice key is wrong. /provider fixes it.
401 · Unauthorized
your recording is kept: ctrl+r retry
? your Mistral account has no credit yet. add some here:
console.mistral.ai/billing
rules
✗ in error color for what broke; ? in accent when it's your call (no credit: you decide).the fix ends the line : a command (/provider sets it up.), a key, a place.the provider's own words go dim under it , never instead of it. nothing is lost : the draft, the clip, the queue are kept, and the line says so.bise says "i": i couldn't reach Mistral, not "an error occurred". rules
zen while you type start typing and everything else fades: the agents, the counts, the chatter. just you and your words. send it and it all comes back.
in and out
in : a key that changes your text (a character, backspace, a paste).holds while you edit or move inside the composer.out : 5 s after your last key, or at once on ⏎, esc, a shortcut, the mouse, focus lost, or anything that needs you.
the look
the chrome goes 45 % of the way to the background: the header, the frame, the panel, the divider's right side, the key bar. the history you read and your text stay as they are. nothing moves, only brightness.
why: "parfois j'ai quand même besoin de lire pour pouvoir écrire. mais j'ai pas besoin de voir tout ce qui se passe ailleurs" (the user).
in and out the look
patterns
your space, their space your space is raised and carries your pink bar. their space is the ground. you never type in theirs, they never draw in yours.
yours (raised) theirs (ground) the composer pane the history an inbox item, open the agents panel the attachments box, above your text the agents' tool rows and chips
rules
everything you type or answer happens on the raised tint, with the │ bar. what isn't your text (attachments, queued messages) sits in its own box, so you never think it's part of it. the raised tint fills edge to edge inside the frame; the frame's lines stay on the ground. rules
defaults that decide bise has opinions, so you don't need settings. every default says what it resolves to, and every pick is remembered.
rules
the first run asks one thing : which model does the work. every other role says same as main or auto.**never a bare auto**: auto · Mistral · mistral-small-latest. name what leaves the machine the first time: auto sends commands to Jev (TypeSafe) to check them.remembered : a pick is saved and survives restarts. never asked twice.one recommended option at most, and only when we'd really pick it.
✓ do
show what a default resolves to, on the same row ask once, at the moment it matters ✗ don't
add a setting to avoid a decision tag something "recommended" because it's ours rules
voice in the UI bise speaks as i, the user is you. human, short, concrete. lowercase.
rules
bise says "i" : i'll work in ~/acme, i couldn't reach Mistral.lowercase everywhere , except proper nouns, acronyms and keys as printed.short sentences. show the moment, not the feeling.no final period on a title or a key label. a full sentence keeps it.nothing LLM-y : no "seamless", no "X, not Y", no "never deleted", no "let's", no exclamation marks.the user's language for what models write to you (a tool row's description, main's answers). the chrome stays English.
✓ do
✓ inbox cleari start an agent when a job needs one.mistral says this key is wrong. copy it again from <link>.✗ don't
All done! 🎉Your agents work seamlessly together.An error occurred while processing your request.rules
vocabulary four nouns to learn: you, main, agents, the inbox. and the same short state words everywhere.
the nouns
say never say you the user, operator main, your team lead orchestrator, hub, coordinator an agent task, sub-agent, worker, hand the inbox cards, notifications a question, an approval a card, a ticket a worktree a sandbox, a clone
the state words
working · idle · done · waiting · asks you · failed · starting · stopped
the same word for the same state in the panel, the header, the help and the site.
units
numbers before units, no fluff: 58k · 22%, 3m, 42s, 4.2 MB, 1 of 2.
the nouns the state words units
message templates the shapes we reuse, so new strings sound like the old ones.
kind template example error ✗ <what happened>. <command> <fixes it>.✗ voice needs a key. /voice setup picks one.your call ? <what>. <where to do it>:? your Mistral account has no credit yet. add some here:flash ✓ <state>✓ inbox clear, ✓ copied 9 charsmode <mode> · <what it means>auto · safe calls run, risky ones ask youtip <the fact>. <key> <does what>.you're in yolo: everything runs. ⇧⇥ changes it.picker title a question which provider?, how hard should it think?picker line what it changes you can change it any time with /model.fold ▸ <n> <things>▸ 12 more lines, ▸ 6 commandsitem head ? <agent> <wants to / asks>? t3 wants to runanswered ✓ you <verb> <agent>: <what>✓ you allowed t3: npm publish --access publichard rule <what it does>. this one always asks.it rewrites main. this one always asks.
process
how we design a change from the user's words to a signed-off capture. nothing is built before he picks.
start from the user's words , quoted in the issue. the design answers them, nothing more.mock it on the real geometry : a local page drawn with the TUI's real columns, colors and rows. a screenshot-level mock, not a sketch.variants only where we hesitate , the pick clearly marked, with one line of why.the user picks. nothing is built before.the builder sends real captures : tmux, 80 and 150 columns, ctrl up and held. the designer signs off, or lists the changes.the book gets the final spec , with the user's words and the issue number. this site follows.
process
checklist twelve questions before a new screen ships.
does it block typing, sending or switching agents? it must not. what is the one key for the common case? which level is it: needs you, for you, between agents? what does it show at rest, and what only with ctrl held? is any color used for something that doesn't need the user? does any glyph mean two things? is it one cell in every font? does every shown key work in this terminal? what's the fallback? what shows right after the user acts, and for how long? what's the drop order at 80 columns? dark, light, NO_COLOR, ASCII: all drawn? every word: lowercase, short, one of the four nouns, no LLM tells? on failure: one line, what happened, the command that fixes it, nothing lost?
process
open questions what we haven't settled yet.
the inbox's mark
the panel shows @ 2 on main's row and the header says # 1 in the inbox. @ is also the file key on the key bar, and # a pull request's number. proposal: bring back ✉︎ (its text form, one cell) for the inbox only, in its own issue.
light theme syntax colors
the dark syntax colors are set; the light ones are still to pick.
pull requests
PR support is designed (the ↑ mark, the ready-to-merge item), not built yet. its pages here say designed until it ships.
the inbox's mark light theme syntax colors pull requests