Skip to content

fix(tui): fire composed macOS Option chords on every slash popup - #1515

Closed
TheGreatAxios wants to merge 15 commits into
mainfrom
cl-8637-audit-and-harden-macos-option-key-shortcuts-when-terminals
Closed

TheGreatAxios wants to merge 15 commits into
mainfrom
cl-8637-audit-and-harden-macos-option-key-shortcuts-when-terminals

Conversation

@TheGreatAxios

@TheGreatAxios TheGreatAxios commented Oct 18, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Composed macOS Option glyphs fire the chord on every slash popup that advertises that letter, including /mcp and the plugin list, not only the model picker.
  • One shared glyph resolver decides whether a glyph is a chord for the open surface. A glyph stays filter text on surfaces that do not advertise that letter.
  • Credential-pane bare s/v claims ignore a hybrid event whose sequence is a composed glyph and whose name is the ASCII letter.

Compaction is no longer in this pull request.

Verification

  • Chord tests on this branch passed before the compaction files were removed.
  • pre-commit tsc --noEmit and bun build pass on the split commit.

Fixes CL-8637

macOS delivers Option+letter either as a modifier bit plus an ASCII name
or as a composed layout glyph with no modifier. This leaf module owns
one allowlist of the macOS US/ABC Option layer and one resolver that
recognises both shapes, scoped to the letters the calling surface
declares. Nothing imports it yet.
OpenListOverlayOpts grows altChords + onAltChord; runOverlayAction becomes the single popup chord read site (silent under a stacked palette), and handleListFilterKey yields any declared glyph ahead of the picker's three legacy clauses. No caller declares chords yet, so behaviour is unchanged; precedence locks cover the stacked palette and the live answer field.
…dicates

The picker builds altChords from the same gating as its handlers and moves the a/d/r bodies to onAltChord; Alt+F keeps a narrowed modifier-only onAction with the never-advertised comment. The composed-glyph predicates, glyph sets and yield clauses in palette.ts are deleted; the general declaration-driven yield covers them. Adds the ƒ and µ negative locks.
Both surfaces declare altChords and move their chord bodies to onAltChord, so a composed macOS Option glyph runs the advertised action instead of leaking into the hidden prompt (the reported defect). Per-glyph tests cover every advertised letter on both surfaces, the canAdd===false refusal, undeclared-letter scoping, and the surviving destructive-action guards.
The five caller-facing booleans leave OpenListOverlayOpts; openListOverlay computes addProvider/setDefault/removeProvider/mcpManage/mcpAdd from kind plus the declared letters, so a surface can no longer advertise a chord it does not handle or forget one it does. OverlayTitlePresentation now Picks from PrimaryOverlayBindings; hint strings and overlay-view frames are byte-identical.
Anti-drift locks (BUILD_PLAN Phase 6): the hint ladders in
overlay-view.ts may only advertise letters their kind can declare and
never Alt+F (src/tui/key-chords-advertised.test.ts, string-level so a
copy change without a declaration fails CI); the rendered /plugins and
/mcp footers stay inside their declared altChords; the resolver matrix
pins ƒ/µ/‰ as never-chords and ◊ as w's listed shifted form; declared
chord glyphs type into the @ popup, the / popup, and the prompt with no
overlay open (I-5/I-6). Docs: docs/TUI.md gains the canonical
"Option-key chords on macOS" section (two shapes, glyph table,
three-clause fallback rule, chord-only Alt+C/V/T/W caveat), with
pointer sentences in PRODUCT/IMPLEMENTATION/MCP/PLUGINS and one
CHANGELOG Unreleased entry.
The macOS U.S./ABC Option layer files the lozenge under Shift+Option+V, not
Shift+Option+W, so listing it as the shifted form of w turned a printable that
belongs to another key into the web-provider chord inside /plugins. An
allowlist is only worth having if every entry is the glyph of its own key:
Shift+Option+W composes the low double quote, and neither it nor the lozenge
is now a chord. The modifier shape still carries Alt+W everywhere.
The canonical macOS section and the release entry both listed the lozenge as a
web-provider chord glyph. It is the shifted form of Option+V, so the resolver
no longer claims it and the copy must not promise it either — the footer is the
output of the declaration, not a second source of truth.
The macOS U.S./ABC Option layer files the double dagger under
Shift+Option+7, not Shift+Option+T, so listing it as the shifted form of t
turned a printable that belongs to another key into the trust chord inside
/plugins: with an untrusted plugin focused, that one keystroke granted
trust and enabled plugin code with no confirmation. An allowlist is only
worth having if every entry is the glyph of its own key, so a permanent
provenance test now checks every row against the layout's own Option
pairs. Shift+Option+T composes the caron; neither it nor the double dagger
is a chord now. The modifier shape still carries Alt+T everywhere, and
docs/TUI.md plus the changelog glyph list follow the shipped table.
@linear-code

linear-code Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

CL-8637

CL-10833

@corbits-triage

corbits-triage Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Triage: Unsure

Not yet confirmed, a maintainer will check:

  • makes one focused change

@TheGreatAxios TheGreatAxios left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Review · Comment

Composed Option glyphs fire only a chord the open surface advertises, and compaction reserves the completion budget. Overflow recovery runs only when the error names a context length, including the vLLM "maximum context length of N" sentence. "exceeds the maximum" or "reduce the length" alone does not fold the transcript.

Findings

No findings.

The changelog entry, the TUI chord section, its doc cross-links, the source-text chord test, and ALT_CHORD_LETTERS are gone. A leftover aside in docs/PRODUCT.md is removed in 3efb311f.

@TheGreatAxios

Copy link
Copy Markdown
Collaborator Author

Superseded by the single-commit chord pull request. Triage would not pass this branch because its history mixed in the compaction work, which landed separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant