# The interface: what we need, how it is grouped, and how it is drawn Written 2026-11-10. This replaces the earlier layout note: it is now the one document that says what the interface contains. Layout comes after this, and is chosen from it. Plain English throughout. No invented shorthand. If a word here is not obvious, it is defined in "Words we use". --- ## Words we use - **Workspace** — one page in TUIOS. The person switches between workspaces. - **Panel** — one pane inside a workspace. Each panel is a program, or one area of one program, that holds one kind of content. - **View** — a way of looking at a panel, for example "the task tree" or "the diff". A panel can hold several views and show one at a time. - **Focus** — which panel receives the keys. Exactly one panel has focus at a time, and the person can always see which one. - **Fact** — a piece of truth with exactly one owner. Tasks, blockers, comments, runs, costs and worktrees belong to Paperclip. A workspace holds at most **four** panels. More than four cannot be read at a glance on one screen, so a fifth thing to look at becomes a view inside a panel, or a new workspace. --- ## How things are grouped The grouping is by what the person is doing, not by which system the data came from. There are four things a person does with this factory: 1. **Decide and direct.** What is the state of the work, what is blocked, what is waiting on me, what do I do next. 2. **Watch.** What is an agent doing right now, what has it changed, what has it cost. 3. **Talk.** Answer an agent, correct it mid-task, unblock a task with words. 4. **Author and govern.** Write a new task or plan, set the verify command, watch the budget, repair the layout when TUIOS loses it. That gives six workspaces. They are deliberately fewer than the number of things we could show, because a person who cannot find the screen they need has gained nothing from more screens. | Workspace | The question it answers | Panels (maximum four) | |---|---|---| | **Board** | what is the state of the work, and what needs me | Task tree · Task summary · Needs you | | **Work** | what is happening now, and what changed | Run log · Diff · Worktree facts | | **Conversation** | what has been said, and what do I say back | Thread · Composer · Task header | | **Author** | what am I asking for, and how will it be judged | Task form · Guidance · Preview | | **Project** | which folder, which machine, what limits, what cost | Project facts · Costs · Settings | | **Repair** | is the layout sound, and what went wrong | Layout map · Health · Log | The **shell** workspace stays as it is: one pane with a prompt in the project folder, for the moments when the person needs a shell and should not have to leave. --- ## The user interface items These are the pieces the panels are made from. Each one says what it is for, which Charmbracelet component implements it, and what it must show in its empty, loading and failed states. The list is deliberately finite: if an item is not here, a panel does not invent it. ### Navigation and framing **1. Workspace strip.** A one-line strip at the top of every panel showing which workspace this is and how many there are, with the current one marked. Implemented in Lipgloss; TUIOS switches workspaces, so this is a position indicator, not a control. Empty state: never empty. Failed state: never applicable. **2. Panel frame.** A border with a title and a focus marker. Rounded border when the panel has focus, plain border when it does not, plus the word `focus` in the title so the difference does not depend on colour. Implemented with Lipgloss borders. Every panel has one, and the frame is what the "too small" message replaces. **3. Footer key hints.** The keys that work right now, in this panel, in this state. Uses the `help` component with `key.Binding`, so a key that does not apply is not shown. Never shows a key that would do nothing. **4. Notice line.** One line for the result of an action, such as "sent", "created AUD-166", or the exact error text. Disappears when the next action starts. Uses Lipgloss only; the text is always the server's own words, never a paraphrase. **5. Stale marker.** The time of the last successful read, shown in the panel title. The purpose is honesty: a panel that has not read recently says so instead of looking current. ### Lists and rows **6. Task row.** One line per task: selection cursor, identifier, status, assignee, title, and a blocker badge when something blocks it. The `list` component with a custom delegate, so filtering and scrolling come for free. **7. Group header.** A heading with a count, such as "Blocked (2)". Not selectable. Implemented in the list delegate. **8. Status pill.** The task's state as a short word with a distinct style per state, and a different shape as well as colour so it survives a monochrome terminal and colour blindness. **9. Assignee chip.** The agent's name, or a dash. Uses the agent name from Paperclip, never an identifier fragment. **10. Blocker badge.** `waits on AUD-163` on the row, read per task from the blocker diagnosis. When the blocker is finished the badge says `ready`, because a task that is ready but still marked blocked is the most confusing state we have. **11. Needs-you card.** One card per decision waiting on a person: a refused merge, a task waiting for an answer, a task whose blocker finished while it was still marked blocked. Each card says what happened, what is expected, and the one key that acts on it. Implemented as `list` items with a different delegate. **12. Table.** For figures that must be compared: per-task cost, per-run duration, per-file change counts. Uses the `table` component with fixed column widths taken from the panel width, never from a constant. ### Reading long content **13. Thread message.** Author, time, and the body with paragraph breaks and code blocks preserved. Bodies are wrapped to the panel, never truncated with an ellipsis in the middle of a sentence. Scrolls inside a `viewport`. **14. Composer.** A multi-line text area for the reply, growing with the text up to a third of the panel, then scrolling. Uses `textarea`. Enter sends and needs to be stated in the footer, because a text area normally treats Enter as a new line. **15. Diff view.** File headers, hunks, and line numbers, with additions and deletions distinguished by a leading character as well as colour. Scrolls inside a `viewport`. Very large diffs are capped with an explicit line saying how many lines were left out, and a key that shows everything. **16. Run timeline.** One row per run: state, what woke it, start and end, duration, cost, and a link to the agent's final message. Uses `table` or a list delegate. **17. Worktree facts.** The folder, the branch, the base it was cut from, and the delivery state. Small, monospaced, never wrapped. ### Input and forms **18. Form field.** A label, an optional "(required)", a hint line under it, and the value. Single-line fields use `textinput`; the description uses `textarea`. Tab moves forward, Shift-Tab moves back, Enter on the last field submits. **19. Validation message.** Directly under the field that is wrong, in the field's own words, and the submit key stays available so the person can correct and try again. **20. Result receipt.** After a write: the identifier that was created or the state that was set, with the server's response behind it. A failure shows the server's message verbatim, because paraphrasing an error we do not understand is how an afternoon is lost. **21. Confirmation prompt.** For anything destructive: the exact thing being removed, and the word that must be typed to continue. Uses `textinput` with no suggestions. ### Status and feedback **22. Spinner with a verb.** While a read or a write is in flight: what is happening, not just that something is. Uses `spinner`. **23. Progress bar.** Only for things with a known count, such as "3 of 7 tasks read". Uses `progress`. Never used as decoration, and never used to fake a duration. **24. Health row.** One line per check in the Repair workspace: name, pass, fail or not run, and the reason. Three states, never two, because "not run" is not "pass". **25. Empty state.** Every panel says why it is empty: "no tasks in this project", "this task has never run", "no worktree, so nothing to compare". An empty panel with no words is a bug. **26. Error state.** The failed thing, the exact message, and the one action that is still possible, such as retry or open the Repair workspace. ### Icons **27. Glyphs.** A small set used consistently: running, waiting, blocked, done, failed, unread. Taken from the glyph set TUIOS reports, with an ASCII fallback, and never the only carrier of meaning. Checked with `tuios list-glyphs` before use, not assumed. --- ## What each panel shows, and where the facts come from | Panel | Shows | Reads from | |---|---|---| | Task tree | groups, rows, badges | company issue list, then the blocker diagnosis per task | | Task summary | status, assignee, priority, blockers, verify command, cost, last run | single task read, blocker diagnosis, cost summary | | Needs you | decisions and waits | task states, merge refusals, pending answers already on the task | | Run log | run timeline and activity | runs, activity | | Diff | changed files and the change | `git` in the task's own worktree | | Worktree facts | folder, branch, base, delivery state | the task's current execution workspace | | Thread | messages | comments | | Composer | the text being written, the status to send | the person, then a comment or a status change | | Task header | identifier, title, status, assignee | single task read | | Task form | the fields being written | the person, then a created task | | Guidance | what a good task needs, and the project's verify command | the project's `.harness` file | | Preview | the description as the agent will receive it | the form, not the server | | Project facts | folder, machine, session, project identifier | the project's `.harness` file | | Costs | spend by task and by agent | cost summary per task, agent budget | | Settings | verify command, budget, watched task | the `.harness` file, then Paperclip for what it owns | | Layout map | workspaces and panels as they actually exist | TUIOS | | Health | checks and their outcome | the checks themselves | | Log | what the repair did | the repair's own output | Two rules follow and are not negotiable: - **A panel never invents a fact.** If Paperclip does not have it, the panel says it does not have it. - **A panel shows when it last read.** So a wrong panel is visibly stale rather than quietly wrong. --- ## How it is drawn **One theme, semantic roles.** Colours are named by role (text, muted, accent, success, warning, error, and a surface colour), and panels ask for the role, never for a hex value. A dark and a light variant exist from the start. **Focus is unmistakable.** The focused panel gets a rounded border, a bright border colour, and the word `focus` in its title. Two of those three do not depend on colour. **Density.** One cell of horizontal padding inside a frame, one blank line between sections, no blank line between rows. Rows are single lines except thread messages, which are the only content that gets paragraph space. **Alignment.** Identifiers, statuses, assignee names and numbers are aligned into columns whose widths are computed from the content in view, capped at a share of the panel width. Never a hardcoded column width. **Truncation.** A truncated title ends in an ellipsis and the full text is available with a key that opens a detail view. Nothing important is truncated silently. **No decoration that carries no meaning.** No gradients, no box-drawing around every row, no colour that does not correspond to a state. **Motion.** Only two things animate: the spinner while something is in flight, and the selection cursor as it moves. Nothing else moves on its own. **The Charmbracelet pieces we use:** `list` for rows and decisions, `table` for figures, `viewport` for anything scrollable, `textarea` for the composer, `textinput` for fields with one line, `help` and `key` for the footer, `spinner` and `progress` for feedback. Tabs are not a component in this collection, so a view switcher inside a panel is built from Lipgloss and the `help` component, and is styled like the rest of the interface. --- ## Keys TUIOS keeps `h`, `j`, `k`, `l`, `z` and `n` in window management mode, so no panel may use them. A bare Esc must stay free, because it closes a box. | Where | Key | Does | |---|---|---| | Any panel | Tab, Shift-Tab | move focus to the next or previous panel | | Any panel | ? | show the keys for this panel | | Any panel | r | read again from Paperclip | | Any panel | q | leave this panel's program, returning the pane to its shell | | Any panel | Esc | close the open overlay or leave the composer, never quit | | Task tree | Up, Down | move the selection | | Task tree | Enter | open this task in the Conversation and Work workspaces | | Task tree | a | assign to the configured agent | | Task tree | Space | expand or collapse a group | | Thread | Up, Down, Page Up, Page Down | scroll | | Composer | Enter | send | | Composer | Shift-Enter | new line | | Composer | s | choose the status to send with the reply | | Diff | Up, Down, Page Up, Page Down | scroll | | Diff | f | show the whole file, not the capped view | | Forms | Tab, Shift-Tab | next or previous field | | Forms | Enter | next field, and submit on the last one | | Destructive | typed word | confirm | No key means two things in two panels. Where a panel needs a key that is taken, it uses a different one rather than overloading. --- ## Size, and what happens when there is not enough Every panel declares a smallest useful size. When a panel is smaller than that, it draws its own short message with the size it has and the size it needs, and nothing else. The program never draws a broken layout and never invents a scrollbar to hide the problem. | Panel | Smallest useful size | |---|---| | Task tree | 30 columns by 10 rows | | Task summary | 30 by 8 | | Needs you | 30 by 6 | | Run log | 40 by 10 | | Diff | 40 by 12 | | Worktree facts | 30 by 6 | | Thread | 40 by 12 | | Composer | 40 by 4 | | Task form | 50 by 14 | | Guidance | 30 by 6 | | Preview | 40 by 10 | | Project facts, Costs, Settings | 40 by 8 | | Layout map, Health, Log | 40 by 8 | The workspace itself needs 80 columns by 24 rows. Below that, the whole workspace shows one message naming the size it has and the size it needs. --- ## Layout, once the panels are settled The panels above do not fit in one workspace, and should not. Layout is chosen by the width of the terminal, so the person gets as much as their screen can carry and never a layout pretending to have room it does not. - **150 columns and wider:** Board shows tree and summary side by side with Needs you under the tree. Work shows run log and diff side by side. Conversation shows thread above composer with the task header above both. - **110 to 149 columns:** two panels per workspace at most; the third becomes a view switched with a tab inside the panel that shares its kind of content. - **80 to 109 columns:** one panel per workspace at full width, in the order Board, Work, Conversation, Author. - **Below 80 by 24:** one message, nothing else. The exact three candidate arrangements are drawn in the earlier note and are still valid for the wide case; what changes here is that the panels themselves are now defined, so the layout is a matter of which panels share a workspace rather than what a panel contains. --- ## What is not in this version, deliberately - No chat with an agent as a separate thing: the Conversation workspace is the chat. - No plan editor: a plan is a task's description, and the Author workspace writes it. - No second task board: TUIOS has one, Paperclip has one, and this interface is the one that knows about blockers and worktrees. - No settings for colours: one theme, two variants, no per-panel colour choices. - No dashboards of figures with nothing to act on: every number sits next to the thing it describes. --- ## Decisions needed before building 1. **Does the tree drive the other workspaces?** Proposal: pressing Enter writes the chosen task's identifier into the project's `.harness/harness.toml` as `watching`, and asks TUIOS to show the Conversation workspace. The other panels watch that file and reload when it changes. One fact, one owner, no message bus, and it survives a restart. 2. **Six workspaces, or fewer?** The proposal is six. Fewer means more switching inside a panel, which costs a key and hides state. 3. **Which glyph set?** Depends on the font in the terminal; must be checked with `tuios list-glyphs` on the machine the person actually uses. 4. **Is the diff a panel or a view inside the Work workspace?** A panel never squeezes the run log; a view keeps the workspace count down.