Interface spec: what each page must show, the source of every fact, and three layouts
This commit is contained in:
@@ -19,6 +19,7 @@ it is a pointer and should be deleted or replaced.
|
|||||||
| `docs/OPEN-ISSUES.md` | this project | what is broken or unfinished in the closed project |
|
| `docs/OPEN-ISSUES.md` | this project | what is broken or unfinished in the closed project |
|
||||||
| `docs/FALLBACK-OMA.md` | this project | what OMA provides, kept in case the pivot is reversed |
|
| `docs/FALLBACK-OMA.md` | this project | what OMA provides, kept in case the pivot is reversed |
|
||||||
| `docs/WHAT-WE-ARE-BUILDING.md` | this project | the person's own statement of the product |
|
| `docs/WHAT-WE-ARE-BUILDING.md` | this project | the person's own statement of the product |
|
||||||
|
| `docs/UI-LAYOUT.md` | this project | what each page must show, where each fact comes from, and the three candidate layouts |
|
||||||
|
|
||||||
## What is not a document of this project
|
## What is not a document of this project
|
||||||
|
|
||||||
|
|||||||
168
docs/UI-LAYOUT.md
Normal file
168
docs/UI-LAYOUT.md
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
# What the interface must show, and three layouts to choose from
|
||||||
|
|
||||||
|
Written 2026-11-10. This is the design document the screens are built against. It says
|
||||||
|
what each page must show, where every fact comes from, what the keys are, and then three
|
||||||
|
layouts at three different shapes. Nothing here is decoration: each line exists because a
|
||||||
|
person needs it to make a decision or to know what is happening.
|
||||||
|
|
||||||
|
## The four questions the interface answers
|
||||||
|
|
||||||
|
1. **What is the state of the work?** todo, in progress, blocked, done — for one project.
|
||||||
|
2. **What is happening right now?** the run, what the agent changed, what it cost.
|
||||||
|
3. **What needs me?** blocked tasks, a merge that was refused, a task waiting for a person.
|
||||||
|
4. **What do I do about it?** reply, unblock, assign, create, merge.
|
||||||
|
|
||||||
|
Anything that does not answer one of those four is not on a screen.
|
||||||
|
|
||||||
|
## Where each fact comes from
|
||||||
|
|
||||||
|
One owner per fact. The middle column is the only place the interface may read it.
|
||||||
|
|
||||||
|
| What is shown | Read from | Never |
|
||||||
|
|---|---|---|
|
||||||
|
| task list, status, title, assignee | `GET /api/companies/{id}/issues` | a local cache or folder name |
|
||||||
|
| blockers ("blocked by AUD-163") | `GET /api/issues/{id}/diagnostics/blockers`, per task | the list endpoint — it carries no blockers |
|
||||||
|
| thread | `GET /api/issues/{id}/comments` | a copy we keep |
|
||||||
|
| run state, start and end | `GET /api/issues/{id}/runs` | a log file we write |
|
||||||
|
| cost | `GET /api/issues/{id}/cost-summary` | our own arithmetic |
|
||||||
|
| what changed | `git` in `currentExecutionWorkspace.cwd` | a diff we store |
|
||||||
|
| which folder, machine, session | `<project>/.harness/harness.toml` | Paperclip (it does not know) |
|
||||||
|
| which task a viewer is on | the same file, `watching` | a hidden second copy |
|
||||||
|
|
||||||
|
The rule that follows: **the interface is allowed to be wrong for one refresh, and is
|
||||||
|
never allowed to be right for the wrong reason.** Every screen shows the time of its last
|
||||||
|
read, so a stale screen says it is stale.
|
||||||
|
|
||||||
|
## Pages and panes
|
||||||
|
|
||||||
|
A **page** is a workspace. A **pane** is one program in it. TUIOS keeps part of the
|
||||||
|
keyboard, so no screen may use `h j k l z n` for its own actions, and a bare Esc must be
|
||||||
|
free to close a box.
|
||||||
|
|
||||||
|
| Page | Pane | Must show | Keys |
|
||||||
|
|---|---|---|---|
|
||||||
|
| shell | shell | a prompt in the project folder | — |
|
||||||
|
| tree | task tree | groups todo / in progress / blocked / done; identifier, status, assignee, title, blocker; a count per group | ↑↓ Tab Shift-Tab move · `a` assign to Builder · `enter` open this task in reply and log · `r` re-read · `q` quit |
|
||||||
|
| reply | conversation | the thread with author and time; a box to type in; the status that will be sent with the reply | `tab` focus the box · `enter` send · `s` cycle status · `esc` leave the box · `r` re-read |
|
||||||
|
| log | run log | run state, start and end, then activity events, newest last | `↑↓` scroll · `g`/`G` top/bottom · `r` re-read · `q` quit |
|
||||||
|
| diff | change | worktree path and branch; commits on the branch; changed files with counts; the diff itself | `↑↓` scroll · `r` re-read |
|
||||||
|
| new | new task form | title, what it must do, must finish first, proves it is done, assign | `tab`/`↑↓` next field · `enter` next, and create on the last · `esc` cancel |
|
||||||
|
|
||||||
|
Two decisions to settle with you, because they change the shape:
|
||||||
|
|
||||||
|
- **Is the diff its own pane or the bottom half of the log?** Its own pane is honest (a
|
||||||
|
long diff never squeezes the log) and costs a workspace. One pane split in two is
|
||||||
|
tighter and hides the diff while the log scrolls.
|
||||||
|
- **Does the tree drive the other panes?** My proposal: pressing `enter` on a task writes
|
||||||
|
`watching = AUD-163` into the project's `harness.toml` and asks TUIOS to show the reply
|
||||||
|
page. The reply, log and diff panes watch that file and reload when it changes. One
|
||||||
|
fact, one owner, no message bus.
|
||||||
|
|
||||||
|
## What must never happen
|
||||||
|
|
||||||
|
- A pane that lies: showing a task as in progress after the run ended.
|
||||||
|
- A key that does nothing visible, or two keys that do the same thing differently.
|
||||||
|
- A layout that breaks below some size instead of saying "too small".
|
||||||
|
- A second copy of anything Paperclip owns, on disk or in memory across refreshes.
|
||||||
|
- An action with no visible result: every write must show what came back, or the error.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# The layouts
|
||||||
|
|
||||||
|
## A — one page each (what exists today, and the safe default)
|
||||||
|
|
||||||
|
Every page is its own workspace, one pane, the whole width. Best at 80 columns and on a
|
||||||
|
phone-sized terminal. Worst for watching two things at once, because switching costs a
|
||||||
|
keystroke and hides the tree.
|
||||||
|
|
||||||
|
```
|
||||||
|
┌ task tree ── workspace 2 of 5 ────────────────────────────────────────────────┐
|
||||||
|
│ spike-2026-11-10 · read 11:42:07 · 6 tasks │
|
||||||
|
│ │
|
||||||
|
│ TODO (2) │
|
||||||
|
│ ▸ AUD-166 todo — Add the weekly cost report │
|
||||||
|
│ AUD-167 todo — Document the merge gate [AUD-166 todo] │
|
||||||
|
│ IN PROGRESS (1) │
|
||||||
|
│ AUD-165 in_progress Builder Review gate probe │
|
||||||
|
│ BLOCKED (1) │
|
||||||
|
│ AUD-162 blocked — Tree render check [AUD-161 todo] │
|
||||||
|
│ DONE (2) │
|
||||||
|
│ AUD-163 done Builder Write NOTES.md │
|
||||||
|
│ │
|
||||||
|
│ ↑↓ move · a assign · enter open · r re-read · q quit │
|
||||||
|
└──────────────────────────────────────────────────────────────────────────────┘
|
||||||
|
1 shell 2 tree* 3 reply 4 log 5 diff 6 new
|
||||||
|
```
|
||||||
|
|
||||||
|
## B — cockpit: tree and conversation side by side
|
||||||
|
|
||||||
|
One workspace holds the work; the tree stays visible while you read and reply. The log
|
||||||
|
and diff live one workspace away, because during a conversation the change matters less
|
||||||
|
than what the agent said.
|
||||||
|
|
||||||
|
```
|
||||||
|
┌ tree 34% ─────────────────┐┌ reply ────────────────────────────────────────────┐
|
||||||
|
│ spike-2026-11-10 ││ AUD-165 in_progress · Builder │
|
||||||
|
│ read 11:42:07 ││ │
|
||||||
|
│ ││ agent 11:38 │
|
||||||
|
│ TODO (2) ││ Workspace Ready — branch AUD-165-… │
|
||||||
|
│ ▸ AUD-166 Add weekly cost ││ │
|
||||||
|
│ AUD-167 Document merge ││ you 11:40 │
|
||||||
|
│ ⤷ waits on AUD-166 ││ Please also guard against HOME being unset. │
|
||||||
|
│ IN PROGRESS (1) ││ │
|
||||||
|
│ AUD-165 Review probe ││ agent 11:41 │
|
||||||
|
│ BLOCKED (1) ││ Done — guard added, tests pass. │
|
||||||
|
│ AUD-162 Tree render ││ │
|
||||||
|
│ ⤷ waits on AUD-161 ││ │
|
||||||
|
│ DONE (2) ││ │
|
||||||
|
│ AUD-163 NOTES.md ││ ┌───────────────────────────────────────────────┐ │
|
||||||
|
│ AUD-164 List lines ││ │ > _ │ │
|
||||||
|
│ ││ └───────────────────────────────────────────────┘ │
|
||||||
|
│ ↑↓ move · a assign ││ status → in_progress · s status · enter send │
|
||||||
|
└───────────────────────────┘└───────────────────────────────────────────────────┘
|
||||||
|
tab focus · esc leave box · r re-read
|
||||||
|
```
|
||||||
|
|
||||||
|
## C — cockpit with the change always visible
|
||||||
|
|
||||||
|
Tree on the left, conversation top right, diff bottom right. The most information at once,
|
||||||
|
and the only layout where a person can see a claim and the code that backs it at the same
|
||||||
|
time. It needs width: below about 120 columns the diff half is unreadable and the layout
|
||||||
|
must fall back to B or A.
|
||||||
|
|
||||||
|
```
|
||||||
|
┌ tree 28% ──────────┐┌ reply 72% ──────────────────────────────────────────────┐
|
||||||
|
│ TODO (2) ││ AUD-165 in_progress · Builder read 11:42:07 │
|
||||||
|
│ ▸ AUD-166 cost ││ agent 11:38 Workspace Ready — branch AUD-165-… │
|
||||||
|
│ AUD-167 docs ││ you 11:40 Please also guard against HOME being unset.│
|
||||||
|
│ ⤷ AUD-166 ││ agent 11:41 Done — guard added, tests pass. │
|
||||||
|
│ IN PROGRESS (1) ││ ┌─────────────────────────────────────────────────────┐ │
|
||||||
|
│ AUD-165 probe ││ │ > _ │ │
|
||||||
|
│ BLOCKED (1) ││ └─────────────────────────────────────────────────────┘ │
|
||||||
|
│ AUD-162 tree │├─ diff ──────────────────────────────────────────────────┤
|
||||||
|
│ ⤷ AUD-161 ││ cleanup.sh · branch AUD-165-… · 1 commit · +4 −0 │
|
||||||
|
│ DONE (2) ││ @@ -1,2 +1,3 @@ │
|
||||||
|
│ AUD-163 NOTES.md ││ -rm -rf "$HOME/tmp" || true │
|
||||||
|
│ ││ +[ -n "$HOME" ] && rm -rf -- "$HOME/tmp" || true │
|
||||||
|
│ ↑↓ · a · enter ││ ↑↓ scroll · r re-read │
|
||||||
|
└────────────────────┘└────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Recommendation
|
||||||
|
|
||||||
|
**C, falling back to B, falling back to A**, chosen by the width the pane actually has, not
|
||||||
|
by a setting. The person gets the most information their terminal can carry, and never a
|
||||||
|
layout that pretends to have room it does not.
|
||||||
|
|
||||||
|
Concretely:
|
||||||
|
|
||||||
|
- 150 columns and wider: C. Tree 28%, right split 55/45 between reply and diff.
|
||||||
|
- 110–149 columns: B, with the diff one workspace away.
|
||||||
|
- 80–109 columns: A, one page each.
|
||||||
|
- Below 80×24: the "too small" screen with the numbers, on every page.
|
||||||
|
|
||||||
|
Two things to settle before building: whether the tree drives the other panes through
|
||||||
|
`harness.toml`, and whether the four screens stay four workspaces or become two.
|
||||||
Reference in New Issue
Block a user