Overlay hints for keystrokes/annotations (cast recording + guided lessons) #22

Closed
opened 2026-06-10 14:53:15 +01:00 by claude-clouddev1 · 1 comment
Collaborator

Motivation

When recording the documentation/website demos as asciinema casts, keystrokes that cause a visible change but produce no glyph of their own — most notably Tab for completion — are invisible to the viewer. The command line simply jumps from show data bo to show data books with no sign that a key was pressed. The same applies to other control keys (Enter, arrows) and to "here's what just happened" step explanations.

asciinema-player has no inline keystroke overlay, and a website-only HTML overlay layered over the player would be fragile — the overlay timings would have to track every recording and break on each re-record. The robust place to solve this is in the app itself: if the app can render an overlay hint, the cast captures it natively and it re-records for free.

Proposal

Add an in-app overlay / annotation layer that can display:

  • keystroke indicators — a transient badge such as ⇥ Tab, ↵ Enter, or ↑/↓ when those keys act; and/or
  • short hint / annotation text — a captioned callout to explain or separate steps.

Driven by a deliberately low-profile / "secret" trigger that a scripted cast (or a future guided lesson) can invoke, without it being a normal user-facing command — e.g. a hidden app command, an env var, or a --flag that opens an "annotation channel" plus a way to push a specific overlay. The exact trigger mechanism is open for design.

Why now / broader value

  • Casts (ADR-website-001 §2): lets demos show otherwise-invisible keys and separate steps for visual learners — the immediate driver (the assistive-editor cast's Tab-completion moment reads as a magic jump today).
  • Guided lessons / tutorial system: there are tentative plans for guided-lesson support (the tutorial/lesson system is acknowledged as in-scope-for-design in CLAUDE.md / requirements.md). An overlay/annotation primitive is exactly what a guided lesson needs to point at things and narrate steps — so building it as a general capability rather than a cast-only hack pays off twice.

Notes / scope

  • This is an app (Rust/ratatui) feature, not a website change. The website casts would simply trigger it during scripted recording.
  • Deserves its own design pass (likely an ADR) covering: the trigger mechanism, the overlay's visual design/placement, the supported annotation kinds (keystroke vs free text), and how it dovetails with the guided-lesson system.
  • Not blocking the website: the assistive-editor cast ships now without it (the Tab moment is noted in the cast caption).
## Motivation When recording the documentation/website demos as asciinema casts, keystrokes that *cause* a visible change but produce no glyph of their own — most notably **Tab** for completion — are invisible to the viewer. The command line simply jumps from `show data bo` to `show data books` with no sign that a key was pressed. The same applies to other control keys (Enter, arrows) and to "here's what just happened" step explanations. asciinema-player has no inline keystroke overlay, and a website-only HTML overlay layered over the player would be fragile — the overlay timings would have to track every recording and break on each re-record. The robust place to solve this is **in the app itself**: if the app can render an overlay hint, the cast captures it natively and it re-records for free. ## Proposal Add an in-app **overlay / annotation layer** that can display: - **keystroke indicators** — a transient badge such as `⇥ Tab`, `↵ Enter`, or `↑/↓` when those keys act; and/or - **short hint / annotation text** — a captioned callout to explain or separate steps. Driven by a deliberately low-profile / "secret" trigger that a scripted cast (or a future guided lesson) can invoke, without it being a normal user-facing command — e.g. a hidden app command, an env var, or a `--flag` that opens an "annotation channel" plus a way to push a specific overlay. The exact trigger mechanism is open for design. ## Why now / broader value - **Casts** (ADR-website-001 §2): lets demos show otherwise-invisible keys and separate steps for visual learners — the immediate driver (the assistive-editor cast's Tab-completion moment reads as a magic jump today). - **Guided lessons / tutorial system**: there are tentative plans for guided-lesson support (the tutorial/lesson system is acknowledged as in-scope-for-design in `CLAUDE.md` / `requirements.md`). An overlay/annotation primitive is exactly what a guided lesson needs to point at things and narrate steps — so building it as a general capability rather than a cast-only hack pays off twice. ## Notes / scope - This is an **app** (Rust/ratatui) feature, not a website change. The website casts would simply trigger it during scripted recording. - Deserves its own design pass (likely an ADR) covering: the trigger mechanism, the overlay's visual design/placement, the supported annotation kinds (keystroke vs free text), and how it dovetails with the guided-lesson system. - Not blocking the website: the assistive-editor cast ships now without it (the Tab moment is noted in the cast caption).
claude-clouddev1 added the enhancement label 2026-06-10 14:53:15 +01:00
Author
Collaborator

Implemented in ADR-0047 (Accepted 2026-06-10, implemented 2026-06-11), phased A→B→C plus a flat-rectangle restyle. Commits f879d542d0f4b2 on main.

Demonstration mode--demo flag / RDBMS_PLAYGROUND_DEMO env, off by default, zero footprint when off:

  • Keystroke badges — automatic, app-detected [TAB]/[ENTER]/[UP]/… over a fixed set of otherwise-invisible keys; re-records for free (the app already sees every key). Auto-expire on a ~1.5 s timer.
  • Step captions — a stealth, control-code-delimited buffer toggled by Ctrl+] (a single ASCII byte autocast can send, unlike arrow keys / Ctrl+!): typed text accumulates invisibly, a second Ctrl+] commits it to a callout (empty commit dismisses). Caption stays until the next keystroke.
  • Both render as flat black-on-yellow rectangles at the output panel's bottom-right (badge stacked above the caption), drawn over modals so they work over the load picker. Caption wraps to ≤3 lines.

The help text advertises only the visible badges; the Ctrl+] caption trigger is kept low-profile per the "secret trigger" framing here. The overlay is a general primitive a future guided-lesson system can reuse.

Tests: 2290 passing / 0 failing / 0 skipped; clippy clean. Two /runda passes (pre-build + whole-implementation, the latter PASS with no blockers).

Follow-up (website branch, out of scope here): wire casts.mjs to emit ^]/text/^] and rely on the automatic badges.

Closing as done.

Implemented in **ADR-0047** (Accepted 2026-06-10, implemented 2026-06-11), phased A→B→C plus a flat-rectangle restyle. Commits `f879d54` → `2d0f4b2` on `main`. **Demonstration mode** — `--demo` flag / `RDBMS_PLAYGROUND_DEMO` env, **off by default, zero footprint when off**: - **Keystroke badges** — automatic, app-detected `[TAB]`/`[ENTER]`/`[UP]`/… over a fixed set of otherwise-invisible keys; re-records for free (the app already sees every key). Auto-expire on a ~1.5 s timer. - **Step captions** — a stealth, control-code-delimited buffer toggled by **`Ctrl+]`** (a single ASCII byte `autocast` can send, unlike arrow keys / `Ctrl+!`): typed text accumulates invisibly, a second `Ctrl+]` commits it to a callout (empty commit dismisses). Caption stays until the next keystroke. - Both render as **flat black-on-yellow rectangles** at the output panel's bottom-right (badge stacked above the caption), drawn over modals so they work over the load picker. Caption wraps to ≤3 lines. The help text advertises only the visible badges; the `Ctrl+]` caption trigger is kept low-profile per the "secret trigger" framing here. The overlay is a general primitive a future guided-lesson system can reuse. Tests: 2290 passing / 0 failing / 0 skipped; clippy clean. Two `/runda` passes (pre-build + whole-implementation, the latter PASS with no blockers). Follow-up (website branch, out of scope here): wire `casts.mjs` to emit `^]`/text/`^]` and rely on the automatic badges. Closing as done.
Sign in to join this conversation.