/ utils / computerUse / inputLoader.ts
inputLoader.ts
 1  import type {
 2    ComputerUseInput,
 3    ComputerUseInputAPI,
 4  } from '@ant/computer-use-input'
 5  
 6  let cached: ComputerUseInputAPI | undefined
 7  
 8  /**
 9   * Package's js/index.js reads COMPUTER_USE_INPUT_NODE_PATH (baked by
10   * build-with-plugins.ts on darwin targets, unset otherwise — falls through to
11   * the node_modules prebuilds/ path).
12   *
13   * The package exports a discriminated union on `isSupported` — narrowed here
14   * once so callers get the bare `ComputerUseInputAPI` without re-checking.
15   *
16   * key()/keys() dispatch enigo work onto DispatchQueue.main via
17   * dispatch2::run_on_main, then block a tokio worker on a channel. Under
18   * Electron (CFRunLoop drains the main queue) this works; under libuv
19   * (Node/bun) the main queue never drains and the promise hangs. The executor
20   * calls these inside drainRunLoop().
21   */
22  export function requireComputerUseInput(): ComputerUseInputAPI {
23    if (cached) return cached
24    // eslint-disable-next-line @typescript-eslint/no-require-imports
25    const input = require('@ant/computer-use-input') as ComputerUseInput
26    if (!input.isSupported) {
27      throw new Error('@ant/computer-use-input is not supported on this platform')
28    }
29    return (cached = input)
30  }