From c2a1e6d76d19d9e10096f0c01607ad7dd3f50442 Mon Sep 17 00:00:00 2001 From: kami Date: Mon, 22 Jun 2026 16:32:07 +0000 Subject: [PATCH] docs: archive v2/cursor TUI work in RETRO + add QA-tui-v2 live-QA plan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per the repo's own hygiene + QA rules: record the operator-requested v2 work in RETRO.md (2026-06-22 TUI wave table: d247b19 migration, 85af2c6 cursor/title) and draft docs/qa/QA-tui-v2.md — the kitty-box checklist for the behavioral claims go test can't prove (Shift+Enter newline, the real blinking cursor + its normal-mode/modal gating, window title, and a render-regression sweep across the new v2 layer). Indexed in docs/qa/README.md as the cheapest gate (no model/network/GPU). Co-Authored-By: Claude Opus 4.8 --- RETRO.md | 5 +++++ docs/qa/QA-tui-v2.md | 52 ++++++++++++++++++++++++++++++++++++++++++++ docs/qa/README.md | 2 ++ 3 files changed, 59 insertions(+) create mode 100644 docs/qa/QA-tui-v2.md diff --git a/RETRO.md b/RETRO.md index 8ddb0d3d..61182c7d 100644 --- a/RETRO.md +++ b/RETRO.md @@ -37,8 +37,13 @@ test` green and rendered via `cmd/preview` before commit: | `f14a83c` | Drop the inline tool-*start* rows (they doubled up with the result rows). | | `531910d` | Transcript free-scroll (`PgUp/PgDn`, `^u/^d`, `esc` snaps to tail-follow; clamped via `outputViewport()`/`buildTranscriptRows`, 2 tests) + help overlay (`?`) + event-inspector `/` filter. | | `db27b34` | Page-scroll the `^x` diff/preview/command fullscreen viewer (`↑↓` line, `PgUp/PgDn` page, `^u/^d` half, `g/G` ends; `scrollDiff()` clamp, 2 tests) + advertise it in the modal hint and the `?` help overlay. Closes the §E approval-ergonomics re-audit. | +| `d247b19` | **Bubble Tea v1 → v2** (`charm.land/{bubbletea,lipgloss}/v2`, Go 1.25). A key-handling shim (`key.go`: v2 `KeyPressMsg` → v1-shaped `keyMsg` at the single `Update` boundary) keeps ~190 match sites untouched. Other v2 breaks handled: `lipgloss.Color` is now a func returning `color.Color` (retyped fields/params); `View()` returns `tea.View` (`render()` builds the string, `View()` carries `AltScreen` — alt-screen is a per-frame field now, not a program option); `WithWhitespaceStyle` replaced `WithWhitespace{Background,Foreground}`; preview dropped `SetColorProfile` (v2 = truecolor by default). Enables literal **Shift+Enter** newline via v2 kitty disambiguation (`Ctrl+J`/`Alt+Enter` kept as non-kitty fallback). Live-QA: `docs/qa/QA-tui-v2.md`. | +| `85af2c6` | **Real terminal cursor in composer + window title.** `View.Cursor` replaces the frame-animated `▏`: a width-1 marker rune (U+E123) is located in the fully-composited frame → blinking `CursorBar` at `(X,Y)`; static `render()` resolves it back to `▏` so screenshots/goldens are unchanged. Nil in normal mode (hidden, vim-correct), suppressed when a modal is open (which keeps `editMode==Insert`). `animating()` no longer ticks in insert mode — the terminal blinks the cursor itself, so an idle insert screen holds still (native text selection survives). `View.WindowTitle` = active session/model. New `cursor_test.go` (3) + updated animating-gate test. | These are mostly deterministic render/UX changes (verifiable by `go test` + `cmd/preview`). +The v2 migration + native cursor are unit-verified the same way, but their *behavioral* wins +(Shift+Enter, the real blinking cursor, no regressions across the new render layer) need a real +kitty terminal — that's the live-QA gate in `docs/qa/QA-tui-v2.md`. **§E approval-ergonomics re-audit — DONE (`db27b34`).** Re-checked the band after it gained the grant scope-picker (`A`) and inline action rows: the spec still holds — single-key `y/n/e` for diff --git a/docs/qa/QA-tui-v2.md b/docs/qa/QA-tui-v2.md new file mode 100644 index 00000000..2db04a36 --- /dev/null +++ b/docs/qa/QA-tui-v2.md @@ -0,0 +1,52 @@ +# QA Plan: TUI Bubble Tea v2 + native cursor — `d247b19` `85af2c6` + +**Status:** DRAFT +**Run date / operator:** +**BACKLOG item:** none — operator-requested TUI work, already archived in `RETRO.md` +(2026-06-22). This plan does not gate a BACKLOG→RETRO move; it gates the *behavioral* +claims that `go test` can't prove (Shift+Enter, the real cursor, no render regressions), +which need a real kitty-protocol terminal. + +--- + +## Preconditions + +- [ ] **terminal:** kitty (or any kitty-keyboard-protocol terminal: ghostty / foot / wezterm / recent iTerm2) — Shift+Enter disambiguation depends on it. +- [ ] **tui build/branch:** `feat/backlog-burndown` at `85af2c6` — `cd apps/tui-go && GOTOOLCHAIN=auto go build -o /tmp/correx-tui .` +- [ ] **server up:** a correx server reachable at `--host/--port` (default `localhost:8080`) with at least one resumable session, so in-session views render. _Rebuild the server only while it's stopped (lazy classloading)._ +- [ ] **config synced:** `~/.config/correx` matches `examples/*` (stale copies cause silent bugs). +- [ ] _(optional)_ `CORREX_TUI_LOG=/tmp/tui.log` to capture the `KEY type=… alt=… ` debug lines as corroborating evidence for the key checks. + +## Acceptance gate (one sentence) + +> The TUI is correct on v2 **iff** Shift+Enter inserts a newline in the composer without +> sending, a real blinking cursor tracks the caret in insert mode (and vanishes in normal +> mode / behind modals), and nothing in the render layer regressed from the v1 build. + +## Checks + +Evidence is the live TUI render (an allowed source) plus, where noted, the `CORREX_TUI_LOG` key lines. + +| # | Action | Expected observable evidence | Result | +|---|--------|------------------------------|--------| +| 1 | Enter a session, press `i`, type a word | A blinking vertical-bar cursor sits at the caret; typing extends it. Log shows `KEY … type=keyRunes`. | | +| 2 | With text in the composer, press **Shift+Enter** | A newline is inserted; the input grows to a second row; nothing is submitted. Log line shows the Enter key with `shift` (no `submit`). | | +| 3 | Press **Enter** (bare) | The message submits (composer clears / turn appears). Confirms bare Enter still sends. | | +| 4 | Press **Ctrl+J**, then **Alt+Enter** (fallback paths) | Each inserts a newline without sending (parity with Shift+Enter). | | +| 5 | From insert mode press `esc` to normal mode | The blinking cursor disappears entirely (no stray bar left on screen). | | +| 6 | In insert mode, open the palette (`/` or `p`) | The modal's own filter caret blinks; **no** second cursor shows behind/around the modal. Close it → composer cursor returns. | | +| 7 | Leave the composer in insert mode and idle ~5s, then drag-select text with the mouse | Selection holds (screen isn't being redrawn out from under it) — confirms insert mode no longer forces the frame loop. | | +| 8 | Observe the terminal tab/title while in a session vs. idle | Title reads `correx — ` in-session; `correx — ` (or `correx`) when idle. | | +| 9 | Visual regression sweep: open `?` help, stats, an `e` event inspector, a `^x` diff, the `t` artifacts viewer; resize the terminal narrow↔wide | Colors/borders/opaque panels look as before; modals scroll (`PgUp/PgDn`, `g/G`); diff viewer pages; no garbled ANSI, no off-by-one panel widths, alt-screen restores the shell cleanly on `q`. | | +| 10 | Walk the approval band (trigger a gate), `↑/↓` the queue, approve/reject/steer | Band behaves exactly as on v1 (single-key low tiers, arm→confirm T3+); steering caret still draws. | | + +## Out of scope (explicitly NOT covered this pass) + +- Mouse-wheel scroll (deliberately not added — would fight native text selection). +- Native cursor for the palette/files/steering/config carets (still frame-drawn `▏`; only the main composer moved to `View.Cursor`). +- Behavior on non-kitty terminals beyond the documented Ctrl+J/Alt+Enter fallback. + +## Disposition + +- **PASS** → set Status: PASSED with the run date; the RETRO 2026-06-22 rows for `d247b19`/`85af2c6` stand as live-verified. +- **FAIL** → file each failure as a numbered finding in `BACKLOG.md` (action + exact repro + the render/log signal that was wrong), fix, then re-run only the failed checks. Set Status: FAILED until green. diff --git a/docs/qa/README.md b/docs/qa/README.md index 31c44bdf..69549325 100644 --- a/docs/qa/README.md +++ b/docs/qa/README.md @@ -18,9 +18,11 @@ to RETRO with the run date + cited evidence; on FAIL → refile each miss as a n | `QA-reviewer-static-first.md` | reviewer static-findings exclusion (PARTIAL — producing stage not built) | `447fc7a` | seed `StaticFindingsRecordedEvent` | | `QA-brief-echo-gate.md` | **ARM-IT** plan: brief echo-back gate (off by default; risky to arm blind) | `1df7af5` | prod-candidate model | | `QA-grants.md` | cross-session grants (PROJECT/GLOBAL) + revoke | `c36d41b` `8df0ec7` | model + a T2+ tool call, 2 sessions, 2 workspaces | +| `QA-tui-v2.md` | Bubble Tea v2 + Shift+Enter + native cursor + window title | `d247b19` `85af2c6` | **kitty-protocol terminal** + a server with a resumable session | ## Order of attack (suggested) +0. **`QA-tui-v2`** — cheapest of all: no model / network / GPU, just a kitty terminal + a server with a session to enter. Pure render/keyboard verification. 1. **`QA-llama-health-probe`** + **`QA-idea-promotion`** — cheapest, least model-dependent (health is liveness; promotion can be seeded). Quick wins. 2. **`QA-grants`** — no network/embedder; just a model that drives one repeatable T2+ tool call. The headline check (grant in session A → auto-clear in session B) is a strong, cheap signal. 3. **`QA-research-egress`** — once SearXNG is up.