Skip to content

fix(debug): Alt+Shift+D binding + surface capture feedback in the hint row - #552

Merged
fentas merged 4 commits into
masterfrom
fix-debug-keybinding
Jul 30, 2026
Merged

fix(debug): Alt+Shift+D binding + surface capture feedback in the hint row#552
fentas merged 4 commits into
masterfrom
fix-debug-keybinding

Conversation

@fentas

@fentas fentas commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Two fixes so the debug capture (Alt+Shift+D) actually works + gives clean feedback.

1. The binding never matched (no feedback at all)

The kitty keyboard protocol reports a letter by its unshifted codepoint + a shift-modifier bit. Alt+Shift+D is \x1b[100;4u (d=100), but the binding used \x1b[68;4u (D=68). On kitty-kbd terminals (Ghostty/kitty/foot/WezTerm) it never matched → the debug_capture Action never fired → the bytes were swallowed → nothing happened. Ctrl+Shift+I at defaults.zig:69 already used the correct lowercase (105); the Alt+Shift+* bindings had diverged. Bind the lowercase forms (keep the uppercase as a fallback). Same latent bug fixed for Alt+Shift+W (security_guard warnings).

2. Feedback now shows in the hint row (not inline scrollback)

The capture outcome (report saved → … / recording off … / save failed) is now shown via the status-bar hint row above the footer (TTL-cleared) instead of an inline stdout write that stacked up across presses and collided with the prompt. Falls back to an inline toast only when no status bar is configured. The debug_capture e2e now runs with the status bar on to exercise this path.

zig build test + zig build e2e (debug_capture) green; zig build green.

fentas and others added 2 commits July 2, 2026 17:31
The kitty keyboard protocol reports a letter key by its UNSHIFTED codepoint plus
a shift modifier bit — so Alt+Shift+D is `\x1b[100;4u` (100='d', mod 4=alt+shift),
not `\x1b[68;4u` ('D'=68). The debug_capture binding (and the pre-existing
security_guard_show_warnings / Alt+Shift+W binding, 87='W') used the uppercase
code, so on Ghostty/kitty/foot/WezTerm the CSI-u never matched: the Action never
fired and the meta-bytes were dropped by the CSI-u interceptor — pressing
Alt+Shift+D produced no feedback at all. (Ctrl+Shift+I at defaults.zig:69 already
uses the correct lowercase 105='i'.)

Bind the lowercase forms (`\x1b[100;4u`, `\x1b[119;4u`); keep the uppercase ones
as a fallback for any terminal that reports the shifted code.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The capture outcome ("report saved → …" / "recording off …" / "save failed")
now shows in the status-bar hint row (above the footer, TTL-cleared) instead of
being written inline to stdout — where it stacked up across presses and collided
with the shell prompt. Falls back to an inline toast only when no status bar is
configured. captureDebugReport returns the message; the proxy sets it via
sb.setHint + repaints so it appears immediately. The debug_capture e2e now runs
with the status bar on to exercise this path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@fentas fentas changed the title fix(keymap): Alt+Shift+D and Alt+Shift+W kitty bindings use the unshifted keycode fix(debug): Alt+Shift+D binding + surface capture feedback in the hint row Jul 2, 2026
@fentas
fentas requested a review from Copilot July 30, 2026 19:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes the debug_capture (Alt+Shift+D) workflow so the binding matches on kitty-keyboard terminals and the capture outcome is surfaced cleanly via the status bar hint row instead of stacking inline toasts in scrollback.

Changes:

  • Fix Alt+Shift+W and Alt+Shift+D kitty-kbd CSI-u bindings to use the unshifted keycode (while keeping shifted-code fallbacks).
  • Refactor captureDebugReport to return a short status message and surface it via the status bar hint row (with an inline-toast fallback).
  • Enable the status bar in the debug_capture e2e scenario config to exercise the hint-row feedback path.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
tests/e2e/debug_capture/config.zig Enables status bar in the scenario so the hint-row feedback path is exercised.
src/proxy.zig Returns capture status text and routes it through statusbar hints / fallback toast.
src/defaults.zig Corrects kitty-kbd CSI-u bindings for Alt+Shift+W and Alt+Shift+D using unshifted codepoints.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/proxy.zig Outdated
Comment thread src/proxy.zig Outdated
…ipping

Copilot:
- Respect `statusbar.hint_ttl_ms == 0` (a documented disable switch) instead of
  forcing a 4000ms TTL onto it; fall back to the inline toast so an explicit
  keypress still reports back.
- Drop the stale doc paragraph on captureDebugReport that still described the
  removed inline toast.

Subagent (fix-and-ship):
- The headline fix had ZERO coverage: the e2e typed the legacy `\x1bD`, so
  reverting the CSI-u binding still passed. The scenario now exercises BOTH
  encodings — legacy, then the kitty `\x1b[100;4u` form real terminals send —
  with a short hint TTL (config) so the row clears between them and the second
  assertion can't match the first message. Verified it FAILS with the CSI-u
  binding removed.
- Clip the hint message to the terminal width (UTF-8-safe): the hint row paints
  unclipped, so a long report path wrapped onto the padding row, which the bar
  never erases — leaving a stale fragment after the TTL expired.
- docs/debugging.md: document the hint-row format + the hints-disabled fallback.

Not changed here: the "unshifted keycode" rule would be better encoded as an
`Alt+Shift+<letter>` branch in keymap/parser.zig than as hand-rolled literals
(tracked separately). The uppercase `68;4u` / `87;4u` fallbacks stay — harmless,
and they cover terminals that report the shifted code.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

docs/debugging.md:44

  • The inline-code example for disabling hints is split across two lines, which breaks Markdown inline code formatting. Keep the code span on one line so it renders correctly.
With no status bar configured — or with hints disabled (`statusbar.hint_ttl_ms
= 0`) — the same message is printed inline instead.

docs/debugging.md:40

  • The example output uses ->, but the code path in captureDebugReport returns atty debug: report saved → … (unicode arrow). The docs should match the actual output string so users can reliably grep/recognize it.
atty debug: report saved -> /home/you/.local/share/atty/reports/report-1751000000-123456789.json

Subagent (verdict: ship; it independently mutation-verified the e2e now fails
without the CSI-u binding):
- CLAUDE.md: the Warn-mode note documented `\x1b[87;4u` as THE kitty encoding for
  Alt+Shift+W — the very literal that didn't fire. That's the sentence a future
  agent would copy to reintroduce this bug. Now states the unshifted-keycode rule
  (119='w') with 87 called out as the fallback.
- Bound the hint text by the hint buffer as well as the terminal width: setHint's
  own clamp is byte-wise and could split a codepoint when cols > hint_buf.len.
- docs/debugging.md: show the arrow the code actually emits.

Copilot round 2: no new findings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@fentas

fentas commented Jul 30, 2026

Copy link
Copy Markdown
Owner Author

Review loop complete — 2 rounds (Copilot + subagent in parallel).

Round 1 — 6 findings addressed, 1 deferred:

  • Copilot: hint_ttl_ms == 0 is a documented disable switch but was being overridden with a forced 4000ms TTL → now falls back to the inline toast; stale doc paragraph on captureDebugReport removed.
  • Subagent (fix-and-ship): the headline fix had zero coverage — the e2e typed the legacy \x1bD, so reverting the CSI-u binding still passed. The scenario now exercises both encodings (short hint TTL so the row clears between them); verified it FAILS without \x1b[100;4u. Also: long hint text wrapped onto the status bar's never-erased padding row → now UTF-8-safely clipped to terminal width; docs updated.
  • Deferred: the unshifted-keycode rule belongs in keymap/parser.zig as an Alt+Shift+<letter> branch rather than hand-rolled literals → tracked as keymap: add an Alt+Shift+letter branch to the key parser #554.

Round 2 — 3 findings addressed:

  • Subagent (ship): CLAUDE.md:157 still documented \x1b[87;4u as the kitty encoding for Alt+Shift+W (the non-firing literal) — corrected to the unshifted rule; hint text now bounded by the hint buffer as well as terminal width (setHint's byte-wise clamp could split a codepoint); docs arrow matches emitted output. It also independently mutation-verified the e2e discriminates.
  • Copilot: no new findings.

Subagent verdicts: fix-and-ship → ship. All threads replied + resolved.

@fentas
fentas merged commit 23efc14 into master Jul 30, 2026
6 checks passed
@fentas
fentas deleted the fix-debug-keybinding branch July 30, 2026 20:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants