Interface spec: workspaces grouped by question, tabs and tool panels, plain-language task selection

This commit is contained in:
Sam
2026-11-10 13:25:55 +11:00
parent b44bf73713
commit 5b829000ae
7 changed files with 545 additions and 33 deletions

View File

@@ -20,8 +20,17 @@ defined in "Words we use".
- **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.
A workspace holds as many panels as the work in it needs. **Four side by side is a good
default**, because more than four at once stops being readable — but it is not a rule.
When a workspace needs a fifth thing, there are three honest choices, and all of them are
allowed:
- **a tab** inside an existing panel, for another view of the same kind of content;
- **a tool panel** that opens beside the others and closes again when it is done;
- **zoom**, which is TUIOS's own key, for the moment a panel needs the whole screen.
The only rule is that everything in a workspace belongs to the same question. If a panel
does not help with that question, it belongs in another workspace.
---
@@ -41,7 +50,7 @@ That gives six workspaces. They are deliberately fewer than the number of things
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) |
| Workspace | The question it answers | Panels (a good default set, not a limit) |
|---|---|---|
| **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 |
@@ -53,6 +62,28 @@ screens.
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.
Inside a workspace, panels are either **side by side** or **stacked as tabs**, and the
person switches between tabs without leaving the workspace. A tab is not a second-class
panel: it has the same frame, the same footer and the same focus marker as any other.
## Tools that open as panels
Several things the person needs already exist as good terminal programs, and wrapping them
would be worse than opening them. Each opens in the current workspace, next to what is
already there, and closes when it is done. This is the "many panels can simply be terminal
tools" idea from the product statement, done deliberately rather than by accident.
| Tool | What it is for | Opens with |
|---|---|---|
| **Lazygit** | branches, commits, staging, history, in the project folder | `t` then choosing it |
| **Hunk** | reading a pull request or a branch change as a review | `t` then choosing it |
| **shell** | any command the panel does not cover | `t` then choosing it |
| **git log and diff** | the task's branch without leaving the interface | `t` then choosing it |
| **ocr** | the review of the current change, as it runs | `t` then choosing it |
Both Lazygit and Hunk are already installed on this machine, and Hunk is a flake input of
the system configuration. Neither is ours to rebuild.
---
## The user interface items
@@ -169,11 +200,33 @@ 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.
### Working with several panels
**28. Tab strip.** For a panel holding more than one view: a single line of named tabs
with the current one marked, switched with `[` and `]` while the panel has focus.
Implemented in Lipgloss and styled like the panel frame. A tab name is a word, never a
number, so it survives being read aloud.
**29. Tool panel.** A panel that runs an existing terminal program — Lazygit, Hunk, a
shell, a git command, or the running review. It opens on demand in the current workspace,
takes focus when it opens, and gives focus back when it closes. It runs the real program,
so it is not styled by us and does not pretend to be.
**30. Panel closer.** Every tool panel says how to close it in its own footer (`q` or
`esc`), and closing it returns the workspace to exactly the arrangement it had before,
with focus where it was.
### 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.
unread. Never the only carrier of meaning.
Measured on this machine, and this matters: TUIOS offers four glyph sets — `ascii`,
`default`, `heavy` and `unicode` — and `default` is active. Starship is **not installed
here**, and no Nerd Font is present (`fc-list` finds none), so an icon set that expects a
patched font would draw empty boxes. Until a Nerd Font is installed deliberately, the
interface uses TUIOS's `default` set, which is ordinary Unicode: `╭ ╮ ✕ ▎ ● › …`, with
`ascii` as the fallback.
---
@@ -251,6 +304,8 @@ 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 | [ and ] | previous or next tab, in a panel that has tabs |
| Any panel | t | open a tool panel here: shell, Lazygit, Hunk, git, review |
| 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 |
@@ -270,7 +325,9 @@ them. A bare Esc must stay free, because it closes a box.
| 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.
different one rather than overloading. **Zoom is not ours**: `z` belongs to TUIOS, and the
interface relies on it rather than reimplementing it. The same is true of switching
workspaces: TUIOS does that, and the interface only shows where you are.
---
@@ -299,28 +356,53 @@ program never draws a broken layout and never invents a scrollbar to hide the pr
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.
Tabs change the arithmetic in a useful way: two panels tabbed into one cost the space of
one panel, so a narrow workspace keeps its content by tabbing rather than by shrinking.
That is why tabs are part of the design and not a workaround.
---
## Layout, once the panels are settled
## How the panels sit together
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.
Layout follows 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.
- **150 columns and wider:** Board shows the task tree and task summary side by side, with
Needs you tabbed under the tree. Work shows the run log beside the diff. Conversation
shows the thread above the composer, with the task header above both.
- **110 to 149 columns:** at most two panels side by side; the third becomes a tab in the
panel that holds the same kind of content.
- **80 to 109 columns:** one panel at full width, with the others tabbed beside it, in the
order the work happens: 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.
Two arrangements we already know we want, because they are the moments the person is
actually in:
---
- **Reading a claim and its code.** Task tree on the left, thread on the upper right, diff
on the lower right. The only arrangement where a claim and the change that backs it are
on screen together.
- **Deciding.** Needs you on the left with the task it concerns beside it, so the decision
card and the evidence are never on different workspaces.
## What happens when you pick a task
Plainly: **choosing a task changes what the other panels show.** Pick a task in the task
tree, and the summary, the thread, the run log, the diff and the worktree facts all switch
to that task. Nothing else has to be typed, and no screen has to be told twice.
The rest is implementation, and it is written down only so the behaviour can be trusted:
- the chosen task is remembered in the project's own `.harness/harness.toml`, as one line
naming its identifier;
- the other panels re-read when that line changes, within about a second;
- the choice survives a restart or a lost pane, because it is on disk and not in memory;
- if the chosen task is ever deleted, the panels fall back to the most active task in the
project rather than showing an error.
That is the whole mechanism. It is one line in one file, it is not a second copy of
anything Paperclip owns, and it can be inspected with a text editor when something looks
wrong.
## What is not in this version, deliberately
@@ -331,18 +413,27 @@ layout is a matter of which panels share a workspace rather than what a panel co
- 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.
- No replacement for Lazygit or Hunk: they open as tool panels.
---
## Decided, and what is still open
## Decisions needed before building
Decided by the person, 2026-11-10:
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.
1. **Switching inside a workspace is wanted.** Tabs and zoom are part of the design, and a
workspace may hold more than four panels when the work in it needs them.
2. **Grouping matters more than panel count.** A workspace earns its place by answering one
question well.
3. **Picking a task updates the other panels.** That is the behaviour described above.
4. **Lazygit and Hunk belong inside the interface**, as tool panels, not as things the
person leaves for a shell.
Still open:
1. **Glyphs.** Measured: TUIOS has `ascii`, `default`, `heavy` and `unicode`; `default` is
active. Starship is not installed here and no Nerd Font is present. So the interface
uses the `default` set with an `ascii` fallback unless a Nerd Font is installed on
purpose. If Starship's look is wanted, that is a system change first, then a glyph set.
2. **Which panel wins when the terminal is narrow.** Proposal: the one that answers the
workspace's question, with the rest tabbed rather than hidden.
3. **The order of tabs** in each workspace. Proposal: the order in which the work happens —
what it is, what it says, what it changed.