docs(glasspane): operator-attention usability roadmap + TUI-enhancements working doc (#188)
Some checks are pending
CI / rust (push) Waiting to run
CI / markdown (push) Waiting to run
CI / port (push) Waiting to run
CI / agent-jail-pkgs (push) Waiting to run

Co-authored-by: Sam & Claude <hello@clawdie.si>
Co-committed-by: Sam & Claude <hello@clawdie.si>
This commit is contained in:
Sam & Claude 2026-06-25 16:59:05 +02:00 committed by clawdie
parent 6078c3f28f
commit c1ae24d5ce
2 changed files with 147 additions and 0 deletions

View file

@ -0,0 +1,92 @@
# Glasspane / colibri-tui — operator usability enhancements (working doc)
Working/design notes for the operator-facing supervision surface. The published
summary lives in [`wiki/glasspane.md`](./wiki/glasspane.md) (*Usability roadmap*);
this doc is the scratch space where we collect references and shape the work
before it lands.
**Premise:** make *"does this agent need me right now?"* the primary,
impossible-to-miss object. We already have the spine — the glasspane state
machine (`Idle → Working → Done / Error / Stalled`), the snapshot API, and the
`colibri-tui` dashboard. The open work is surfacing and *pushing* attention, not
new machinery. Ideas are drawn from agent-cockpit terminal UIs; all wiring is our
own (no external code, no dependency).
## Current colibri-tui keybindings (baseline)
| Key | Action |
| --- | --- |
| `q` / `Esc` | Quit, or close detail pane if open |
| `r` | Refresh snapshot now |
| `s` | Spawn a local `colibri-test-agent` |
| `x` | Kill the selected pane |
| `Enter` | Open/close the detail pane for the selected row |
| `Tab` / `Shift-Tab` | Cycle through distinct sessions |
| `j` / `k` or `↓` / `↑` | Navigate the pane table |
`crates/colibri-glasspane-tui/src/main.rs`
## Reference: agent-cockpit shortcut vocabulary (example, not a spec)
Captured as an example of the *interaction vocabulary* a mature agent cockpit
settles on. Most of it is GUI-only (canvas, embedded browser, diff viewer, split
panes) and irrelevant to a terminal dashboard — kept here only so we can see the
shape. The **transferable** clusters for `colibri-tui` are marked ★.
Legend: ⌘ Cmd · ⌥ Option · ⌃ Control · ⇧ Shift · ↩ Enter.
**Notifications ★ — the "attention" model we care about**
- ⌘I — show notifications
- ⌘⇧U — jump to latest unread
- ⌃⌘U — mark oldest-unread and jump to next
- ⌥⌘U — toggle current item unread
- ⌘⇧H — flash focused panel
**Navigation ★**
- `J`/`K` (+ `⌃N`/`P`, `H`/`L`) — vim-style row/pane movement (we already do `j`/`k`)
- ⌘1…9 / ⌃1…9 — jump directly to workspace / surface N
**Workspaces / surfaces (GUI tab model — mostly N/A to a TUI)**
- ⌘N new workspace · ⌘T new surface · ⌘W close · ⌘⇧R rename · ⌘⇧O reopen previous session
- ⌃⌘] / ⌃⌘[ next/prev workspace · ⌘⇧] / ⌘⇧[ next/prev surface
**Input / focus ★ (relevant once we add "answer a blocked agent")**
- ⌘⇧A — switch focus between terminal and a text-input box
- ⌥⌘⇧A — attach file to the input box
**GUI-only (canvas, browser, diff, find, splits)** — out of scope for the TUI;
listed for completeness only: ⌘D/⌘⇧D splits, ⌃⌘C canvas, ⌘⇧L browser,
⌃⌘⇧D diff viewer, ⌘F find, ⌥⌘= / ⌥⌘- zoom, etc.
## Proposed colibri-tui keymap (draft — to be refined as we build)
Additive to the baseline; nothing here collides with existing keys.
| Key | Proposed action | Roadmap item |
| --- | --- | --- |
| `n` / `N` | Jump to next / previous **attention** pane (Error/Stalled/waiting) | jump-to-next-attention |
| `a` | Toggle the attention filter (show only panes needing the operator) | attention signal |
| `i` | Send input / answer the selected pane (when it is blocked on input) | answer-from-dashboard |
| `t` | Toggle Telegram/desktop notification mute for the session | outbound notifications |
(Mnemonics provisional — `n`ext-attention, `a`ttention-filter, `i`nput, `t`oggle-notify.)
## Open design questions
- **Attention as flag vs. state:** keep the `AgentState` enum small and derive an
attention boolean over it, rather than adding a sixth state. Where does
"waiting for input" come from — inferred from stall + a prompt marker, or an
explicit agent-emitted event?
- **Outbound notify transport:** a `colibri notify` subcommand, or a glasspane
event type a zot/Pi hook fires? Desktop (XFCE) + Telegram (token already
provisioned) are the two sinks.
- **Interactive write path:** "send input to pane N" turns the daemon socket from
read-only supervision into interactive control — needs its own design pass
(auth, which panes accept input, echo/confirmation).
- **Persisted pane history:** how much timeline to keep across daemon restarts so
"what happened while I was away" survives a reboot, without growing unbounded.
## See also
- [`wiki/glasspane.md`](./wiki/glasspane.md) — state machine + published roadmap
- [`wiki/tui.md`](./wiki/tui.md) — the dashboard client and its current keybindings

View file

@ -91,6 +91,61 @@ that's fundamentally about current state, not event delivery.
→ [`crates/colibri-glasspane/src/lib.rs`](../../crates/colibri-glasspane/src/lib.rs)
(`Supervisor`, `snapshot`)
## Usability roadmap (TODO)
Glasspane has the supervision spine — a stable state machine and a snapshot API.
The open work is operator-facing: making *"does this agent need me right now?"*
the primary, impossible-to-miss object. These are captured as direction, not yet
built. The data mostly already exists; the work is surfacing and pushing it.
Ideas drawn from agent-cockpit terminal UIs; wiring is our own. Working notes,
reference shortcut vocabulary, and a draft keymap live in
[`../GLASSPANE-TUI-ENHANCEMENTS.md`](../GLASSPANE-TUI-ENHANCEMENTS.md).
### Attention as a first-class derived signal
Today a pane is `Idle/Working/Done/Error/Stalled`. Promote "needs the operator"
into an explicit **attention flag** derived from the existing states (`Error`,
`Stalled`, and a future "waiting for input") rather than a sixth state. The state
machine stays small; attention is a view over it. The TUI highlights attention
rows; the daemon and notifier read the same flag.
### Push notifications outbound, not just on-screen
The operator supervises headless hosts over Tailscale, not by staring at the
TUI. When a pane raises attention (or hits `Done`), push it **out**: a desktop
notification on the live image (XFCE) and a **Telegram** message (the token is
already provisioned). An explicit `colibri notify`-style path — or a glasspane
event type that a zot/Pi hook fires — lets an agent say "I'm blocked" rather than
relying only on inferred state. Highest real-world impact item.
### Jump-to-next-attention navigation in the TUI
A keybinding in `colibri-tui` that cycles to the next attention pane. Trivial
given the attention flag; large ergonomic win when supervising many agents.
`crates/colibri-glasspane-tui/src/main.rs`
### Richer pane rows (context at a glance)
Glasspane already stashes non-state events in pane metadata. Surface that in the
TUI row: current **repo/branch**, **last line / task summary**, the **jail** the
agent runs in, optionally listening ports. Turns "Working" into "Working on
`fix/x` in jail `cms`, last: running tests".
### Persist pane history across daemon restarts
The supervisor is in-memory (`Arc<RwLock<...>>`); a daemon restart loses the
timeline. Persist pane transitions/history so returning after hours (or a
reboot) preserves "what happened while I was away". Lightweight durability, not a
new subsystem.
### Answer a blocked agent from the dashboard (bigger lift)
The snapshot API is read-heavy by design. A future write path — "send input to
pane N" over the daemon socket — would let the operator **respond** to a blocked
agent from `colibri-tui`, not just observe/spawn/kill. This is direction, not a
quick win; it changes the socket from read-only supervision to interactive
control and needs its own design pass.
## See also
- [agent-harness](./agent-harness.md) — the zot/Colibri split that Glasspane observes