Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions specs/011-tui/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ related:
- "[[007-channels/spec]]"
- "[[026-tui-subagent-management/spec]]"
- "[[030-tui-slash-autocomplete/spec]]"
- "[[084-tui-mention-picker/spec]]"
- "[[068-session-persistence/spec]]"
---

Expand Down Expand Up @@ -63,15 +64,27 @@ TuiApp
| SubAgents | `a` | Interactive subagent sidebar with j/k navigation and transcript viewer |
| Fleet | `f` | Read-only table of all agent sessions (active/completed/unknown); auto-refreshed by `AgentEvent::FleetSnapshot` (#3884) |
| Task Registry | `/tasks` | Live table of all supervised tasks (see below) |
| Status Bar | always | Current operation spinner + short status text |
| Input Separator | (above input) | Input prompt, busy spinner + verb (when busy), interrupt hint (#6649) |
| Status Bar | always | Stable session parameters, streaming tok/s + TTFT, transient critical hints |

Tab cycling order includes SubAgents. See `026-tui-subagent-management/spec.md` for full SubAgents panel spec.

## Spinner Rule (NON-NEGOTIABLE)

**Every background or implicit operation must show a visible spinner with a short status message.**

Examples:
The spinner and verb are rendered in the **input separator row** (above the input composer), appended after the row's existing idle elements:
```
you ▸ {mode hint} {~N tokens} [queue badges] ▸▸▹ {verb} · {interrupt-hint}
```

Where:
- `you ▸` — prompt glyph; mode hint, `~N tokens` context estimate, and queue badges are the row's existing elements, unchanged
- `▸▸▹` — animated breeze spinner (constant 3-cell width; rendered as a static `·` when motion is off)
- `{verb}` — humanized present-continuous status (e.g., `searching · memory`), truncated before the hint under width pressure
- `{interrupt-hint}` — interrupt instruction; its key/text is owned by #6646 (`esc to interrupt` today, `ctrl+c` once #6646 lands)

Examples of `{verb}`:
- `Searching memory…`
- `Executing tool: shell`
- `Connecting to MCP server…`
Expand All @@ -80,6 +93,8 @@ Examples:

Status messages: short, present continuous tense, no punctuation except `…`.

**When idle** (no background operation), the separator row renders exactly as before this change: prompt glyph, mode hint, `~N tokens` estimate, and queue badges — no spinner, no verb, no interrupt hint. The bottom status bar no longer renders the busy spinner/verb segment in any state (#6649).

## TuiChannel Invariants

- `TuiChannel` owns stdin/stdout — **mutually exclusive with ACP stdio transport**
Expand Down
2 changes: 1 addition & 1 deletion specs/030-tui-slash-autocomplete/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ THEN the dropdown is dismissed automatically
| NFR-001 | Performance | Filter and re-render must complete within a single 16 ms frame; no async work is performed — all filtering is synchronous over the static registries |
| NFR-002 | Correctness | Must not interfere with existing key bindings: Esc (→ Normal mode), Enter (→ submit), Up/Down (→ history navigation) are re-routed only while the dropdown is active |
| NFR-003 | Correctness | Must not conflict with the existing Command Palette (`:` in Normal mode) — the two flows are mutually exclusive by construction (`command_palette` vs `slash_autocomplete` state fields) |
| NFR-004 | Correctness | Must not conflict with the `@` file picker (`KeyCode::Char('@')` path in `handle_insert_key`) |
| NFR-004 | Correctness | Must not conflict with the inline mention picker (`[[084-tui-mention-picker/spec]]`); both surfaces are non-modal overlays with distinct trigger rules (slash-autocomplete triggers on `/` at start of empty input; mention picker triggers on `@` at word-start) |
| NFR-005 | Accessibility | The popup must be dismissible without accepting any suggestion at any point |
| NFR-006 | Architecture | The autocomplete state must live in `App` as a dedicated field, not inside `CommandPaletteState` |
| NFR-007 | Architecture | No new crate dependencies are permitted; ratatui `List` + `Clear` widgets (already used) are sufficient |
Expand Down
Loading
Loading