MCPcopy Index your code
hub / github.com/claude-code-best/claude-code / holdKey

Function holdKey

src/utils/computerUse/executor.ts:543–575  ·  view source on GitHub ↗
(keyNames: string[], durationMs: number)

Source from the content-addressed store, hash-verified

541 },
542
543 async holdKey(keyNames: string[], durationMs: number): Promise<void> {
544 const input = requireComputerUseInput()
545 // Press/release each wrapped in drainRunLoop; the sleep sits outside so
546 // durationMs isn't bounded by drainRunLoop's 30s timeout. `pressed`
547 // tracks which presses landed so a mid-press throw still releases
548 // everything that was actually pressed.
549 //
550 // `orphaned` guards against a timeout-orphan race: if the press-phase
551 // drainRunLoop times out while the esc-hotkey pump-retain keeps the
552 // pump running, the orphaned lambda would continue pushing to `pressed`
553 // after finally's releasePressed snapshotted the length — leaving keys
554 // stuck. The flag stops the lambda at the next iteration.
555 const pressed: string[] = []
556 let orphaned = false
557 try {
558 await drainRunLoop(async () => {
559 for (const k of keyNames) {
560 if (orphaned) return
561 // Bare Escape: notify the CGEventTap so it doesn't fire the
562 // abort callback for a model-synthesized press. Same as key().
563 if (isBareEscape([k])) {
564 notifyExpectedEscape()
565 }
566 await input.key(k, 'press')
567 pressed.push(k)
568 }
569 })
570 await sleep(durationMs)
571 } finally {
572 orphaned = true
573 await drainRunLoop(() => releasePressed(input, pressed))
574 }
575 },
576
577 async type(text: string, opts: { viaClipboard: boolean }): Promise<void> {
578 const input = requireComputerUseInput()

Callers

nothing calls this directly

Calls 8

requireComputerUseInputFunction · 0.85
drainRunLoopFunction · 0.85
isBareEscapeFunction · 0.85
notifyExpectedEscapeFunction · 0.85
releasePressedFunction · 0.85
keyMethod · 0.65
sleepFunction · 0.50
pushMethod · 0.45

Tested by

no test coverage detected