Files
dotfiles/.config/dot/.claude/tasks/0010-kde-shortcuts-diff-broadscan.md
alexion 3732ccd4d8 chore: Change task numbering to decimal.
Hex doesn't sort nicely in the file system.
2026-07-06 16:50:24 -04:00

6.0 KiB

blocked-by
blocked-by
0005-kde-shortcuts-mechanism
0009-kde-shortcut-completion

What to build

dot kde diff's broad-scan (the pass that reports undeclared drift, not just already-declared entries) currently only walks schema-backed identifiers via iter_schema_identifiers. Shortcuts are treated the same as freeform in cmd_diff -- checked only when already present in the manifest -- per the code comment at the top of that loop. That comment is overstated for shortcuts: unlike freeform, which genuinely has no enumeration source, shortcuts are enumerable via kglobalaccel's allMainComponents/allActionsForComponent, and iter_shortcut_identifiers (added in 0009 for tab-completion) already walks exactly that.

Add a second broad-scan pass in cmd_diff, after the existing schema-backed one, over sorted(set(iter_shortcut_identifiers())): for each identifier, compare shortcutKeys against defaultShortcutKeys (the same live/default read already used for declared shortcuts), and tag declared/undeclared exactly like the schema loop. Remove the shortcuts branch from the manifest-only loop below it (now redundant), leaving that loop for freeform only, since freeform is the only mechanism that still can't be enumerated.

Tolerate two failure modes without aborting the whole command:

  • The enumeration call itself (allMainComponents) failing (no live session, no busctl) -- print one diagnostic to stderr and skip the shortcuts block entirely, same as any other reported problem in diff.
  • An individual action failing to resolve (_resolve_shortcut_action_id raising because its owning app hasn't registered with kglobalaccel this session) -- print that one identifier's error to stderr and continue, matching the schema loop's existing per-identifier tolerance.

Update DIFF_USAGE to reflect that shortcuts now participate in broad-scan alongside schema-backed settings, leaving only freeform as declared-only.

Acceptance criteria

  • dot kde diff reports undeclared shortcut drift (a shortcut changed from its packaged default but never dot kde saved) without requiring it to be in the manifest first
  • Already-declared shortcut drift is still reported, tagged declared, with no duplicate line from the old manifest-only loop
  • A shortcut belonging to an app that hasn't registered with kglobalaccel this session produces one stderr diagnostic for that identifier and does not stop the rest of the scan (schema block, other shortcuts, freeform block) from completing
  • If the allMainComponents enumeration itself fails (no busctl, no live session), diff prints one diagnostic, skips the shortcuts block, and still completes the schema and freeform passes, exiting 0
  • Freeform remains declared-only (unchanged) -- only its loop comment and the removed shortcuts branch change
  • DIFF_USAGE text updated to describe shortcuts as broad-scanned
  • Verified manually against the real session (consistent with the shortcuts mechanism's existing test carve-out, 0005/0009) -- no new automated tests
  • Full existing test suite still passes unchanged

Implementation Notes

  • cmd_diff (commands/kde/kde.py) gained a second broad-scan pass between the existing schema-backed loop and the manifest-only loop: it walks sorted(set(iter_shortcut_identifiers())) (the same enumeration cmd_complete already uses), compares shortcutKeys against defaultShortcutKeys per identifier, and tags declared/undeclared exactly like the schema loop.
  • The manifest-only loop below it lost its shortcuts branch entirely (resolve_mechanism returning "shortcuts" now just falls through if mechanism != "freeform": continue), since the new broad-scan pass already reports every declared shortcut mismatch -- keeping the old branch would have double-printed them.
  • Two failure modes, handled at different granularity: iter_shortcut_identifiers() itself is wrapped in try/except (RuntimeError, OSError) -- a failure there (no live session, missing busctl) prints one diagnostic and skips the whole shortcuts block, letting the schema and freeform passes still run. Inside the per-identifier loop, read_shortcut_value raising RuntimeError (an app that hasn't registered with kglobalaccel this session yet) prints one diagnostic for that identifier and continues, matching the schema loop's existing per-identifier tolerance.
  • Real-world validation on this machine: manually ran the same enumeration in a throwaway script before implementing, confirming 29 of 278 registered shortcuts differed from default (the Meta+1-9 desktop-switch remap, Meta+Shift+1-9 window-to-desktop binds, and Meta+A/Meta+Shift+A activity switching) -- all 29 were dot kde saved into the manifest in the same session as a prerequisite for testing this cleanly. After implementing, dot kde diff reported all 30 shortcuts (29 plus the pre-existing ksmserver.Lock Session) as declared with correct default values, and ~34 unrelated RuntimeErrors for apps not launched this session (Konsole, Spectacle, Dolphin, etc.) printed to stderr without aborting the scan. Removing one entry (kwin.Switch to Desktop 1) from the manifest and re-running confirmed it flips to undeclared with the same live/default values, then restoring the manifest flipped it back to declared -- confirms both tags work and the manifest was left untouched by diff itself (read-only, as documented).
  • Full test suite re-run after the change: 101/101 pass, unchanged from before this task. No automated tests added for the new pass itself, per the shortcuts mechanism's existing carve-out (0005's Implementation Notes: a live kglobalaccel D-Bus session isn't practically substitutable without disproportionate mock infrastructure) -- the existing tests already exercise dot kde diff against the real live session and continued to pass with the new pass active, incidentally covering that it doesn't break anything even though it isn't asserting on the new pass's own output.