TUI: the contextual key line is too dense, mode-blind, and mixes three label formats - #114
Merged
Conversation
The contextual key line had grown to fourteen slots on the cockpit and rendered the same idea three ways: `d dispatch · D agent`, `n new · N plan`, and `r/R refine`. Settle on the combined form — one slot per lowercase/uppercase pair of a single action, labelled with the base verb — and give the uppercase glosses somewhere to live, since the line cannot carry them. `?` opens a per-screen key map: a peek-style overlay dismissed by any key, listing every binding that screen has, grouped into actions, navigation, and screen switching. It documents the keys no hint has ever carried (`o`, `g`, `a`, `l`, `J`/`K`, the page keys, `ctrl-r`, `1`-`4`) and the three uppercase variants, each worded to say what the shifted key does differently from its sibling. `?` is bound in the shared navigation block so it also reaches the projects and Config screens, which intercept before the trailing match. With the map in place the line keeps only what changes a task's state or destiny: `x` score, `h` history, `c` docs and `l` log come off it. No key is rebound, and the worst-case cockpit line is now ten slots. `key_hints` is now a filter over `hint_candidates`, which lists every slot a screen can show with a flag for whether the selection earns it — that is what lets the drift test check the whole set, gated slots included, against the screen's key map from a single App.
MJohnson459
force-pushed
the
feat/keymap-overlay
branch
from
August 1, 2026 20:07
eea7717 to
7e489ba
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Settle one label convention for the TUI's contextual key line, and add the
?key map that lets the line get shorter without making keys undiscoverable.
One convention.
d/D,r/Randn/Nare each a lowercase defaultand an uppercase variant of one action, and the line rendered that three
different ways. They now take a single slot keyed on the pair and labelled with
the base verb —
d/D dispatch,r/R refine,n/N new. The projects screen'sa/Aand the Config screen'sa/Astay apart: unrelated actions thathappen to share a letter. No key is rebound.
A
?key map. A newMode::KeyMap, opened by?and dismissed by any key,renders the current screen's complete bindings in a popup — actions in one
column, navigation over screen switching in the other, so the cockpit's map fits
80x24 without clipping. It is bound in
key_normal's shared navigation blockrather than the trailing match, so it also reaches the projects and Config
screens, which intercept before that match. It documents every key that had no
hint at all (
o,g,a,l,J/K, PageUp/PageDown,ctrl-r,j/k,1-4,?) and the three uppercase glosses the line no longer carries; thoseglosses live together in
DISPATCH_KEYS/REFINE_KEYS/NEW_KEYS, worded to oneshape, so the follow-up below can rewrite them in one place.
A shorter line. With the map in place the line keeps only what changes a
task's state or destiny.
x score,h historyandc docscome off it as thetask specified, and so does
l log: paging a log in$PAGERis a browsingconvenience by the same rule, and without dropping it a review row carrying a
session log reached eleven slots. The worst case is now exactly ten, on both the
proposal row and the review row.
Drift guard.
key_hintsis now a filter over a newhint_candidates, whichlists every slot a screen can show together with whether the selection earns it.
That is what makes the guard test total: it checks every candidate — gated slots
included — against that screen's
key_map, splitting combined slots sod/Dischecked as
dandD. A future trim of the line fails the test if it drops akey the map does not carry.
Docs. DESIGN.md §9 gains a paragraph on the convention, on which pairs
combine and which do not, and on the
?overlay as the full map. Theui-redesign §2citation onkey_hints— a document that does not exist inthis repo — now points at §9, and the doc comment that had drifted onto
selection_is_proposedis back onkey_hints. CHANGELOG entries added underAdded and Changed.
Also.
App::selected_session_logwent with thelhint it existed to gate;view_session_lognever used it, and the two tests that called it assert thesame thing a line away.
Verified.
cargo test --workspace(556 tests) andcargo clippy --workspace --all-targets -- -D warningsare clean. New tests: the overlay opens on?from a screen whose own handler intercepts (projects), renders that screen's map
including the keys the line dropped, and closes on a key the screen binds; the
line stays at ten slots or fewer on every row of a queue holding a proposal, a
ready task and a review task; and every hintable key appears in its screen's
map. Beyond the tests I rendered all four screens' overlays through the real
draw path at 80x24 and read them.
Follow-up filed as #333 — decide what lowercase and uppercase actually mean
and audit every uppercase binding against it, carrying the exceptions (
dspawns agents while lowercase;
r's accidental backgrounded session from #325;#315's proposed
n/Nflip; the non-spawning uppercase keys). It may rebindkeys, which this task deliberately did not.
Branch
feat/keymap-overlayis local and unpushed.