Skip to content

ask_user input drops keys when keypresses arrive with 0ms delay (kmonad/QMK home row mods) #1186

@danila-xalgo-io

Description

@danila-xalgo-io

Description

When using kmonad (or similar keyboard remapping tools like QMK) with home row mods, keys are dropped in the ask_user interactive prompt. This happens because these tools can send multiple key events with 0ms delay when "rolling" between keys.

Environment

  • copilot-cli version: 0.0.398
  • OS: macOS (Darwin)
  • Terminal: Tested in Ghostty, WezTerm, with and without tmux
  • Keyboard: kmonad with tap-hold-next-release home row mods

Root Cause Analysis

  1. Node.js receives all keypress events correctly - verified with a raw keypress listener
  2. Standalone Inquirer.js works perfectly - tested with @inquirer/prompts directly
  3. Only copilot-cli's ask_user prompt drops keys

When rolling keys quickly (e.g., typing "aoeu" in Dvorak), kmonad sends adjacent keys with 0-2ms between them:

+  14ms  o
+   1ms  e    <-- 1ms after previous
+  92ms  u
+ 141ms  a
+  29ms  o
+   0ms  e    <-- 0ms (same millisecond!)
+  69ms  u

Reproduction Script

#!/bin/bash
# Save as rapid-key-inject.sh
echo "Waiting 2 seconds - focus the copilot ask_user prompt..."
sleep 2

osascript <<'APPLESCRIPT'
tell application "System Events"
    -- No delay between keystrokes (simulates kmonad rolling)
    keystroke "aoeu aoeu aoeu"
end tell
APPLESCRIPT

echo "Done."

Steps:

  1. Start copilot: copilot
  2. Trigger an ask_user prompt (e.g., ask copilot to do something that requires clarification)
  3. Run ./rapid-key-inject.sh
  4. Quickly focus the copilot ask_user input
  5. Observe: characters are dropped

Expected: "aoeu aoeu aoeu" appears in the input
Actual: Some characters are missing (e.g., "aoe aoe aoe" or worse)

Additional Notes

  • Typing with 1ms delay between keys works fine
  • The prompt "blinks" when this happens, suggesting re-rendering interference
  • Flags like --screen-reader, --stream off do not help
  • This is likely a race condition in the render loop that drops keypresses

Workarounds Attempted (none worked)

  • --screen-reader
  • --stream off
  • NODE_NO_READLINE=1
  • Running through script -q /dev/null copilot
  • Various kmonad tap-hold configurations

Suggested Fix

The ask_user input handler should queue all keypress events and process them sequentially, rather than potentially dropping events during re-renders.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions