Source profileQuality 94/100Review permissions

terrylica/cc-skills/plugins/macro-keyboard/skills/diagnose-hid-keycodes/SKILL.md

diagnose-hid-keycodes

Find out what an unknown USB/Bluetooth HID button actually emits without assuming the label or documentation. Uses Karabiner's.

Source repository stars
61
Declared platforms
0
Static risk flags
1
Last source update
2026-08-26
Source checked
2026-08-28

Decision brief

What it does: where it fits

Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.

Best for

  • A new HID device arrived and you don't know what its buttons emit
  • A pad has multiple firmware modes and you need to map each mode's keycodes
  • A rule isn't firing and you suspect you guessed the wrong from.keycode

Not for

  • Tasks that require unconfirmed production actions or broad system permissions.
  • Environments where the pinned source and install steps cannot be inspected.

Compatibility matrix

Platform support, with evidence labels

PlatformStatusEvidenceWhat to check
CodexNot declaredNo explicit evidencePortability before use
Claude CodeNot declaredNo explicit evidencePortability before use
CursorNot declaredNo explicit evidencePortability before use
Gemini CLINot declaredNo explicit evidencePortability before use
Open the compatibility checker

Installation

Inspect first. Install second.

The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

Source-detected install commandSource
npx skills add https://github.com/terrylica/cc-skills --skill "plugins/macro-keyboard/skills/diagnose-hid-keycodes"
Safe inspection promptEditorial

Inspect the Agent Skill "diagnose-hid-keycodes" from https://github.com/terrylica/cc-skills/blob/05f53c5b24a445c1895e9b0590212e66cd70f39e/plugins/macro-keyboard/skills/diagnose-hid-keycodes/SKILL.md at commit 05f53c5b24a445c1895e9b0590212e66cd70f39e. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

Workflow

What the source asks the agent to do

  1. 01

    The Three-Tool Workflow

    ignore: true is the key insight: with it enabled, Karabiner doesn't remap anything but still logs the device's events — so you can see the raw keycodes the firmware emits.

    ignore: true is the key insight: with it enabled, Karabiner doesn't remap anything but still logs the device's events — so you can see the raw keycodes the firmware emits.
  2. 02

    Workflow

    Review the “Workflow” section in the pinned source before continuing.

    Review and apply the “Workflow” source section.
  3. 03

    Step 1 — Identify the device's VID/PID

    Review the “Step 1 — Identify the device's VID/PID” section in the pinned source before continuing.

    Review and apply the “Step 1 — Identify the device's VID/PID” source section.
  4. 04

    Step 2 — Add a no-op diagnostic rule (forces Karabiner to grab the device)

    Why not just "ignore": true in devices[]? That tells Karabiner to leave the device entirely alone — EventViewer then won't see its events either. ignore: true is for "hands off this device," not "inspect this device."

    Why not just "ignore": true in devices[]? That tells Karabiner to leave the device entirely alone — EventViewer then won't see its events either. ignore: true is for "hands off this device," not "inspect this device."Correct approach: add an inert complexmodifications rule scoped to the device. Karabiner grabs the device (so EventViewer captures every HID report) but the rule does nothing. Edit /.config/karabiner/karabiner.json → pr…vknone is a Karabiner virtual key that never matches real input, so the manipulator is inert. The deviceif scoping makes Karabiner grab the device for inspection.
  5. 05

    Step 3 — Open EventViewer and press each button

    Press each button slowly. For modifier-combos emitted in one HID report (common on cheap pads), you'll see multiple keydown events in tight sequence:

    Main tab: shows keydown / keyup with decoded keycode names (c, leftcontrol, pageup, etc.)Devices tab: shows which device emitted each event — confirms you're grabbing the right VID/PIDUnknown Events tab: shows events Karabiner couldn't decode — relevant for consumer keys or custom HID descriptors

Permission review

Static risk signals and limitations

Runs scripts

medium · line 94

The documentation asks the agent to run terminal commands or scripts.

python3 -c '

Evidence record

Why each signal appears

EvidenceSourceComputedTestedEditorial
SignalValueEvidence typeMeaning
Quality score94/100ComputedDocumentation, specificity, maintenance, and trust rules
Repository stars61SourceRepository attention, not individual Skill quality
Compatibility0 platformsSourceDeclared in the catalog source record
Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

Pinned source

Provenance and original SKILL.md

Repository
terrylica/cc-skills
Skill path
plugins/macro-keyboard/skills/diagnose-hid-keycodes/SKILL.md
Commit
05f53c5b24a445c1895e9b0590212e66cd70f39e
License
MIT
Collected
2026-08-28
Default branch
main
View the original SKILL.md

Diagnose HID Keycodes

Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.

Given an unknown macro pad, mouse button, foot pedal, or HID gadget, find out exactly what each button emits at the OS level — without guessing from labels, vendor docs, or photos. Cheap HID pads frequently ship with arbitrary or mis-labeled keycodes (the Jieli/Free3-P ships with buttons labeled top/middle/bottom emitting Ctrl+C/Ctrl+V/Ctrl+X — which isn't the cut/copy/paste convention; it's hardware-random).

When to Use This Skill

  • A new HID device arrived and you don't know what its buttons emit
  • A pad has multiple firmware modes and you need to map each mode's keycodes
  • A rule isn't firing and you suspect you guessed the wrong from.key_code
  • You need to document a device for a reproducible setup

The Three-Tool Workflow

ToolPurpose
Karabiner ignore: trueMake Karabiner observe the device without grabbing it
Karabiner-EventViewerDisplay raw HID events as text
Quartz screencapture -lCapture EventViewer's window without stealing focus

ignore: true is the key insight: with it enabled, Karabiner doesn't remap anything but still logs the device's events — so you can see the raw keycodes the firmware emits.

Workflow

Step 1 — Identify the device's VID/PID

# USB
ioreg -p IOUSB -l -w 0 | grep -B 2 -A 6 "<product name or partial>"

# Bluetooth (after pairing)
system_profiler SPBluetoothDataType | grep -A 15 "<pad name>"

Record VID/PID in decimal (Karabiner's JSON format).

Step 2 — Add a no-op diagnostic rule (forces Karabiner to grab the device)

Why not just "ignore": true in devices[]? That tells Karabiner to leave the device entirely alone — EventViewer then won't see its events either. ignore: true is for "hands off this device," not "inspect this device."

Correct approach: add an inert complex_modifications rule scoped to the device. Karabiner grabs the device (so EventViewer captures every HID report) but the rule does nothing. Edit ~/.config/karabiner/karabiner.json → profile 0 → complex_modifications.rules and insert:

{
  "description": "[DIAGNOSTIC] Grab <pad> (no remap)",
  "manipulators": [
    {
      "type": "basic",
      "from": { "key_code": "vk_none" },
      "to": [{ "key_code": "vk_none" }],
      "conditions": [
        {
          "type": "device_if",
          "identifiers": [{ "vendor_id": 19530, "product_id": 16725 }]
        }
      ]
    }
  ]
}

vk_none is a Karabiner virtual key that never matches real input, so the manipulator is inert. The device_if scoping makes Karabiner grab the device for inspection.

Reload Karabiner: Karabiner-Elements menu bar icon → Restart Karabiner-Elements.

Step 3 — Open EventViewer and press each button

open -a "Karabiner-EventViewer"
  • Main tab: shows key_down / key_up with decoded keycode names (c, left_control, page_up, etc.)
  • Devices tab: shows which device emitted each event — confirms you're grabbing the right VID/PID
  • Unknown Events tab: shows events Karabiner couldn't decode — relevant for consumer keys or custom HID descriptors

Press each button slowly. For modifier-combos emitted in one HID report (common on cheap pads), you'll see multiple key_down events in tight sequence:

13:44:02.123  key_down  left_control
13:44:02.123  key_down  c
13:44:02.198  key_up    c
13:44:02.198  key_up    left_control

Same microsecond timestamp for left_control + c = emitted in one HID report → you need simultaneous matcher.

Step 4 — Capture without stealing focus

If you bring EventViewer to the foreground to read it, you lose the ability to press buttons on the test window. Workaround — capture by window ID:

# List windows; find EventViewer's window ID
python3 -c '
from Quartz import CGWindowListCopyWindowInfo, kCGWindowListOptionAll, kCGNullWindowID
for w in CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID):
    if "EventViewer" in w.get("kCGWindowOwnerName", "") or "EventViewer" in w.get("kCGWindowName", ""):
        print(w["kCGWindowNumber"], w.get("kCGWindowName"))
'

# Screenshot that window without focusing it
screencapture -l <WID> -o -x /tmp/eventviewer.png

-l <WID> captures a specific window, -o excludes shadow, -x suppresses the capture sound. The window does not need to be foregrounded.

Step 5 — Repeat for each firmware mode (Bluetooth pads)

Many cheap BT pads have undocumented firmware modes triggered by button combos (hold all 3 keys 5s, hold top 10s, etc.). Each mode can emit completely different keycodes. For each mode you discover:

  1. Switch the pad into that mode
  2. Repeat step 3 — log keycode for each button
  3. Document in a table

Example (Jieli/Free3-P):

ModeTopMiddleBottom
1volume_incrementvolume_decrementspacebar (play/pause)
4page_uppage_downequal_sign

Step 6 — Clean up

Remove the [DIAGNOSTIC] rule from complex_modifications.rules and reload Karabiner. Or convert it into your real remap rule by replacing vk_none with the actual from / to bindings.

Avoid Touch-ID-Triggering Audits

Do NOT query TCC.db or SQLite files under /Library/Application Support/com.apple.TCC/ to "audit permissions" during this workflow — those queries require sudo and trigger the Touch ID prompt on every invocation. Instead:

# Non-sudo audit: is Karabiner actually grabbing the device?
karabiner_cli --list-connected-devices | jq '.[] | select(.product == "<pad-name>")'
# Returns { ..., "is_grabbed": true/false } — same info, no biometric prompt

The working tool IS the audit. This was discovered the hard way; see ../configure-macro-keyboard/references/04-anti-patterns.md → "Sudo-based TCC.db audits trigger Touch ID".

Deep References

Sibling Skills

  • configure-macro-keyboard — once you know what your buttons emit, use this to write the device-scoped Karabiner rule. The vk_none no-op rule from Step 2 here converts directly into the real rule by swapping from / to bindings.
  • emit-fn-key-on-macos — if one of the keycodes you discovered should be remapped to real Fn (for Typeless, dictation, globe key), this sibling skill explains the one correct Karabiner incantation.

Post-Execution Reflection

After this skill completes, reflect before closing the task:

  1. Locate yourself. — Confirm this SKILL.md is the canonical file before any edit.
  2. What failed? — Fix the instruction that caused it.
  3. What worked better than expected? — Promote to recommended practice.
  4. What drifted? — Update vendor IDs, keycodes, or FOSS-tool versions if reality disagrees with the doc.
  5. Log it. — Add an evolution-log entry (or 04-anti-patterns.md row) with trigger, fix, evidence.

Do NOT defer. The next invocation inherits whatever you leave behind.

Frequently asked questions

What to verify before installation and use

What does the diagnose-hid-keycodes source document cover?

Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.

How do I install diagnose-hid-keycodes?

The source record exposes this install command: npx skills add https://github.com/terrylica/cc-skills --skill "plugins/macro-keyboard/skills/diagnose-hid-keycodes". Inspect the command and pinned source before running it.

Which permission-related actions were detected?

Static rules flagged exec-script in the source; the page lists the matching lines and excerpts.

Alternatives

Compare before choosing

Computed 100147

oaustegard/claude-skills

featuring

Generate hierarchical _FEATURES.md files that describe what a codebase DOES from a user/consumer perspective, anchored to source symbols via tree-sitting. Supports large complex codebases through feature-driven decomposition into sub-feature files. Uses a multi-pass synthesis: orientation → detail → overview rewrite. Use when someone says "what does this do", "document features", "feature inventory", "_FEATURES.md", or needs to understand a codebase's purpose before modifying it. Complements tre

Computed 10017

dancingteeth/unified-code-review

unified-code-review

Risk-first code review for PRs and branch audits: blast-radius triage, agent-authored discipline (tests first, intent evidence), call-graph pincer for integration defects between modules, then structural code-judo bar. Use when reviewing PRs, auditing agent-written diffs, catching rubber-stamp green CI, or wiring bugs single-file review misses. Prefer over structure-only thermo-nuclear review alone. Do not use for unrelated coding tasks or as an always-on rule.

Computed 1009

Postpartum-genushyacinthus29/dotnet-skills

dotnet-worker-services

Build long-running .NET background services with `BackgroundService`, Generic Host, graceful shutdown, configuration, logging, and deployment patterns suited to workers and daemons.

Computed 9970

PaulRBerg/agent-skills

skill-writing

Create/scaffold/init a project-local agent skill under `.agents/skills` in an ordinary repository; defer to repository instructions that define a source catalog and lifecycle.