MCPcopy
hub / github.com/codeaashu/claude-code / key

Function key

src/utils/computerUse/executor.ts:455–473  ·  view source on GitHub ↗

* xdotool-style sequence e.g. "ctrl+shift+a" → split on '+' and pass to * keys(). keys() dispatches to DispatchQueue.main — drainRunLoop pumps * CFRunLoop so it resolves. Rust's error-path cleanup (enigo_wrap.rs) * releases modifiers on each invocation, so a mid-loop throw leaves

(keySequence: string, repeat?: number)

Source from the content-addressed store, hash-verified

453 * nothing stuck. 8ms between iterations — 125Hz USB polling cadence.
454 */
455 async key(keySequence: string, repeat?: number): Promise<void> {
456 const input = requireComputerUseInput()
457 const parts = keySequence.split('+').filter(p => p.length > 0)
458 // Bare-only: the CGEventTap checks event.flags.isEmpty so ctrl+escape
459 // etc. pass through without aborting.
460 const isEsc = isBareEscape(parts)
461 const n = repeat ?? 1
462 await drainRunLoop(async () => {
463 for (let i = 0; i < n; i++) {
464 if (i > 0) {
465 await sleep(8)
466 }
467 if (isEsc) {
468 notifyExpectedEscape()
469 }
470 await input.keys(parts)
471 }
472 })
473 },
474
475 async holdKey(keyNames: string[], durationMs: number): Promise<void> {
476 const input = requireComputerUseInput()

Callers

nothing calls this directly

Calls 6

requireComputerUseInputFunction · 0.85
isBareEscapeFunction · 0.85
drainRunLoopFunction · 0.85
notifyExpectedEscapeFunction · 0.85
keysMethod · 0.80
sleepFunction · 0.50

Tested by

no test coverage detected