Skip to content

Mapper: a save that declines says so; captured media keys map to Kanata names - #1326

Merged
malpern merged 1 commit into
masterfrom
fix/mapper-silent-failure
Oct 20, 2026
Merged

malpern merged 1 commit into
masterfrom
fix/mapper-silent-failure

Conversation

@malpern

@malpern malpern commented Oct 20, 2026

Copy link
Copy Markdown
Owner

Found during the phase 6 hardware check on the Air: a ` → Mute rule captured in the overlay Mapper disappeared with nothing on screen and nothing in the log.

Why it was silent

  • The overlay never rendered viewModel.statusMessage (only set it), so every refusal, "nothing to save" and failed save was invisible.
  • autosaveCapturedMapping and save returned early without logging.

What changes

  • The overlay shows the Mapper status under the keycaps (overlay-mapper-status), red for errors.
  • Autosave logs why it skipped; a missing runtime coordinator is logged as an error and shown. save logs each early return and the rule it is about to write.
  • KeyMappingFormatter.keyNameMap maps the media names KeyboardCapture assigns (volumeup, playpause, …) to the Kanata names the session posts (volu, pp, …). Before this a captured volume key reached the generator as volumeup and would have been typed as letters (the generator-unknown-names card covers the general case).

Tests

MapperAutosaveVisibilityTests (no coordinator → visible error; identity and missing-capture declines carry a message), MapperKanataFormatTests.testCapturedMediaKeysBecomeKanataMediaNames; AdmissionEnvironmentTests updated to the mapped name. KEYPATH_TEST_ENFORCE_CLEAN_SUMMARY=1 Scripts/run-tests-safe.sh: 5,784 passed, 0 app warnings/errors, 0 build warnings. check-accessibility.py clean.

🤖 Generated with Claude Code

…ta names

The overlay Mapper saves on capture and has no Save button, yet it never
rendered the view model's status message and the save path's early returns
did not log — so a declined save looked like a mapping that vanished (seen
on the Air, 2026-10-20: a `  → mute rule disappeared with nothing in the log).
The overlay now shows the status under the keycaps; autosave logs why it
skipped and reports a missing runtime coordinator as an error; save logs
each early return and the rule it is about to write.

KeyMappingFormatter also mapped no media names, so a captured volume or
brightness key reached the generator as "volumeup" and would have been typed
as letters. The names KeyboardCapture assigns now map to the Kanata names
the session posts.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-20T14:16:15.611650Z 45ac7ec PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@claude

claude Bot commented Oct 20, 2026

Copy link
Copy Markdown

Review (diff only)

Overall looks good: the autosave paths now surface a status message and log instead of silently returning, and the overlay shows it. A few points worth a look:

  1. Stale status never cleared. The new overlay status Text is driven by viewModel.statusMessage. If nothing resets it on the next capture or on a successful autosave, an old error such as "Nothing to save - input and output are the same" will stay visible after the user fixes the mapping. Please confirm that the clear/reset path covers the overlay, or reset the status at the start of autosaveCapturedMapping/finalizeCapture. A test for this would help.
  2. volumeup → volu mapping and admission naming. The updated AdmissionEnvironmentTests expect the refusal to say "Volume Up" when the key is volu. That display-name lookup isn't in this diff, so I couldn't check it. Please confirm it exists in the base branch. Otherwise those tests fail.
  3. Formatter coverage. eject is added to the map but isn't in testCapturedMediaKeysBecomeKanataMediaNames. Add it, or drop it if the session can't send it. The comment also says fast-forward/rewind/backlight "stay as is". They then reach Kanata as unknown names (e.g. fastforward) and fail at save or config validation. Consider declining them explicitly with a clear message.
  4. Test isolation. testIdentityMappingDeclinesWithAMessage and testMissingCaptureDeclinesWithAMessage construct a real RuntimeCoordinator(). They only hit early-return paths, so they're likely fine, but make sure they never reach saveCustomRule.

No blocking correctness bugs found in the diff itself.

🤖 Generated with Claude Code

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 45ac7ecb15

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +22 to +24
// Media keys as `KeyboardCapture.mediaKeyCodeToString` names them, to
// the Kanata names the session can post (phase 6). Fast-forward,
// rewind and keyboard backlight have no Kanata name and stay as is.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle the media names emitted by real F7/F9 presses

On Apple keyboards, F7/F9 media-mode presses arrive as rewind and fastforward (KeyboardCapture.mediaKeyCodeToString handles codes 20/19), not previous and next. Leaving those names unchanged means an output captured from these common keys reaches ConfigurationService.convertToKanataSequence, which treats the unknown multi-character token as a text macro, so the saved mapping types “rewind” or “fastforward” instead of controlling playback. Translate them to prev/next, or reject them explicitly rather than allowing a wrong rule to save.

Useful? React with 👍 / 👎.

@malpern
malpern merged commit 68ab83a into master Oct 20, 2026
3 checks passed
@malpern
malpern deleted the fix/mapper-silent-failure branch October 20, 2026 14:16
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.

1 participant