Files
claude@clouddev1 18303784a0 docs: session handoff 63 + ADR-0046 marked implemented (#20/#21/#23)
ADR-0046 status -> Accepted + implemented (8 commits 9f5f76b..22bec61);
README index updated; the two draft-divergent decisions recorded inline
(App.relationships not SchemaCache; nav overlay partial-clear + gutter).
Handoff 63 covers the full UI build across Phases A/B/C; issues
#20/#21/#23 closed on Gitea.
2026-06-10 21:30:00 +00:00

8.4 KiB

Session handoff — 2026-06-10 (63)

Sixty-third handover. Continues from handoff-62 (C4 m:n + #19). This was a single-ADR, full-build session: it designed and implemented ADR-0046 end to end — the UI work for the three sidebar/input issues #20 / #21 / #23, all now closed on Gitea.

§1. State at handoff

Branch: main. HEAD 22bec61 (plus an uncommitted docs finalization — ADR status flip + this handoff — see §7). Push is the user's step.

Tests: 2263 passing / 0 failing / 1 ignored (the 1 ignored is the long-standing doc-test). Clippy clean (nursery, all targets). +26 over the handoff-62 baseline of 2237.

This session's commits (8 + the docs finalization):

22bec61 feat(ui): scroll the focused sidebar panel + refine the nav overlay (DC3 + DC2)
c9da6ff feat(ui): Ctrl-O navigation mode — peek + expand the schema sidebar (DC1/DC2/DC4)
94825d0 feat(ui): relationships sidebar panel + schema data (DB2/DB4)
386627a feat(ui): width-derived sidebar visibility — hide at <=90 cols (DB1)
41bae99 feat(ui): two-row input display on tall terminals (DA4)
e0b9470 feat(ui): horizontal-scroll long input so the cursor stays visible (DA3)
9f5f76b fix(ui): geometry-fixed hint-panel height kills the typing jump (DA1/DA2)
93266b9 docs: ADR-0046 UI sidebar nav-mode + responsive input/hint

Issues closed: #20, #21, #23 (all via ADR-0046). #22 (in-app overlay/keystroke-annotation layer for casts/lessons) remains open — its own future ADR; adjacent but out of scope here.

§2. What shipped — ADR-0046 (read it; it's the source of truth)

Three coupled UI issues, treated as one decision because they share the terminal width/height budget. Phased A → B → C.

Phase A — input & hint (#20, #23).

  • DA1/DA2 (#20): the Hint panel height is now a pure function of terminal geometry (hint_rows → later panel_heights), fixed between resizes — it no longer resizes as you type, killing the jump. Compact (<40 rows) = hint 2; comfortable = hint 2, or 3 only when the column is narrow (inner < 54). This reverses issue #12's shrink-to-content sizing (its two tests were replaced by an anti-jump invariant). Long hints ellipsize at the fixed budget.
  • DA3 (#23): long input horizontally scrolls to keep the cursor visible (input_scroll_offset, pure input_scroll_offset() helper), with muted < / > edge markers; resets on submit / history. Preserves ADR-0027's 6-col indicator reserve.
  • DA4 (#23): on a tall terminal (>=40 rows) the input renders across two visual rows (soft-wrap of the single logical line; indicator stays on row 1). Distinct from deferred multi-line I1; expand_runs_to_cells is the substrate I1 should reuse.

Phase B — the sidebar (#21).

  • DB1: the left column is width-optionalsidebar_visible() = width > 90, so it's hidden at <=90 (the 90-col screencasts) and the right column takes the full width. (Resize a terminal below ~90 to see it; in a normal wide terminal it shows, by design.)
  • DB2/DB4: a Relationships panel stacks below Tables — each relationship is name + endpoints broken at the arrow (Customers.id -> / indented Orders.customer_id), ellipsized. The panel floors at 5 rows ("(none)") and grows to a 50%-of-column cap (relationships_panel_height). Overrides S2 (relations were to be nested in the tables list; a sibling panel is the honest shape).

Phase C — navigation mode (#21).

  • DC1/DC4: Ctrl-O enters a navigation mode orthogonal to the input mode, cycling focus Input → Tables → Relationships → Input (Esc exits). It's routed in the main key handler after the modal gate, so it's inert behind a modal; in nav mode every non-nav key is inert (the input is occluded). NavFocus enum on App.
  • DC2: the focused panel is revealed (peek, even when width-hidden) and drawn as a 45-col expanded overlay, clearing the sidebar strip + a one-column gutter and leaving the base output/input/hint visible (unchanged) to the right. (Two variants were eyeballed; this partial-clear-with-gutter was chosen over a full-area clear.)
  • DC3: the focused panel scrolls — Up/Down by a line, PageUp/PageDown by its visible rows; per-panel offsets clamped to content at render time, mirroring the output-panel scroll.

Ctrl-B was rejected for nav mode (it's the tmux prefix → unreachable inside tmux); Ctrl-O is multiplexer-safe.

§3. Two decisions that landed differently from the draft

Both recorded inline in the ADR (and called out in its Status):

  1. Relationship data on App, not SchemaCache (DB2). SchemaCache is walker/completion-facing and needs only relationship names (untouched); the full records are UI-only, so App.relationships mirrors app.tables, and it avoided editing ~23 SchemaCache literals. Delivered via Database::read_all_relationships (new worker request) + AppEvent::RelationshipsRefreshed from the runtime's schema refresh.
  2. Nav overlay = partial clear + 1-col gutter (DC2), not a full-area clear — truer to "underneath keeps its layout."

§4. Process notes

  • The pre-build /runda pass earned its keep again. It caught the Ctrl-B/tmux collision, a SchemaCache retype that would have broken completion, the 2-row-input/indicator placement, the missing nav-mode key disposition + modal gate, and three unreferenced requirements (S1 evolved, S2 overridden, S4 corrected — requirements.md updated).
  • Snapshot discipline: DB1's 90-col threshold collided with the test-suite's 80-col convention — many snapshots/tests were retuned (sidebar-dependent ones now render at 110; input tests at narrower widths so the now-wider input still overflows). One masked-intent integration check (matched "Customers" in output, not the panel) was corrected.
  • Each phase was committed green + clippy-clean, user-confirmed message, no AI attribution, append-only.

§5. Requirements / S-items touched

requirements.md annotated: S1 (three-region layout → left region width-optional), S2 (overridden — relationships get a sibling panel, not nested), S4 (corrected — the "keyboard-toggleable" hint claim was never implemented and is struck; the panel is always-on).

§6. Remaining open landscape (unchanged from handoff-62, minus the closed items)

  1. TT5 CI — test infra solid (2263 green); no pipeline. Gitea Actions / Woodpecker decision + likely a Linux-first scope call.
  2. SD1 seed then H2 hint — the two unblockers for A1 app-commands; both net-new, own ADR. SD1 should seed m:n junctions.
  3. V2/S3 multi-result tabs or V4 journal — larger output-model redesign, design-first, own ADR.
  4. C3a modify relationship — small follow-up (drop+add covers it).
  5. #22 overlay/annotation layer — own ADR; shares the cast + overlay space with DC2 (designed to coexist).
  6. Tutorial/lesson system — acknowledged in scope; needs its own ADR.

ADR-0046 OOS (deferred): true multi-line input (I1); readline shortcuts (I1b); cross-session sidebar persistence; a persistent show/hide toggle (Ctrl-O peek covers it); output as a third nav focus; relationship search/edit from the panel; a hint-area toggle.

§7. How to take over

  1. Read handoffs 61 → 62 → 63, then CLAUDE.md, docs/requirements.md, docs/adr/README.md, and ADR-0046 (fully landed).
  2. Pending: an uncommitted docs finalization (ADR-0046 status → implemented; README index status; this handoff). Commit it as docs: session handoff 63 (the user confirms commit messages).
  3. For UI/layout work: src/ui.rs now has panel_heights, sidebar_visible, relationships_panel_height, the nav overlay, and &mut App sidebar panels (they report scroll viewports). App gained input_scroll_offset, nav_focus, relationships, and the tables_scroll / relationships_scroll (+ last_*_visible) fields.
  4. For relationship/schema-cache work: relationship names are in SchemaCache.relationships (completion); full records are on App.relationships via Database::read_all_relationships + RelationshipsRefreshed.
  5. Eyeball reminder honoured: the user reviewed the nav overlay appearance and chose the partial-clear + 1-col-gutter variant.
  6. Run a cargo sweep at some point — target/ has grown across this build-heavy session.