npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@geyj/auto-gui

v0.0.1

Published

Composable desktop automation SDK for Node.js and Electron.

Readme

@geyj/auto-gui

@geyj/auto-gui 是一个面向 Node.js / Electron 的桌面自动化 SDK,目标是用接近 Nut.js 的组合式 API 暴露窗口、鼠标、键盘、剪贴板、屏幕截图、图片查找、颜色查找、OCR 文本查找和 UI 元素查找能力。

当前包是 CommonJS 产物,TypeScript 示例默认按 module: "CommonJS" 编译运行。Node.js 版本要求为 >=22

当前架构

flowchart TB
  app["Node.js / Electron 应用"] --> pkg["@geyj/auto-gui 包入口<br/>根入口 + 子路径入口"]
  pkg --> index["src/index.ts"]

  subgraph ts["TypeScript API 层"]
    types["types.ts<br/>Point / Size / Region / Button / Key"]
    geometry["geometry.ts<br/>centerOf / straightTo / createBezierPath"]
    mouse["mouse.ts"]
    keyboard["keyboard.ts"]
    clipboard["clipboard.ts"]
    screen["screen.ts<br/>截图 / 保存 / 查找底座"]
    windowApi["window.ts"]
    element["element.ts + findElement.ts"]
    text["text.ts + paddle-ocr.ts + findText.ts"]
    image["findImage.ts"]
    color["findColor.ts"]
    utils["utils.ts"]
  end

  mouse --> native["src/native.ts<br/>加载 auto_gui_native.node"]
  keyboard --> native
  clipboard --> native
  screen --> native
  windowApi --> native
  element --> windowApi
  image --> screen
  color --> screen
  text --> screen

  native --> addon["native/src/addon.cc<br/>Node-API / node-addon-api"]
  addon --> platform["native/src/platform_*.cc<br/>Windows / macOS / Linux"]
  text --> models["models/paddleocr<br/>PP-OCRv5 Mobile ONNX"]

安装与构建

源码仓库首次初始化:

npm install
npm run prepare:ocr-models
npm run build:native
npm run build:inspector
npm run build

npm run prepare:ocr-models 会下载 PaddleOCR PP-OCRv5 Mobile ONNX 模型。发布后的 npm 包会把 models/ 一起带上,普通使用者不需要重复执行。

发布到 npm 后,使用者走标准安装流程即可:

npm install @geyj/auto-gui

当前版本还没有预编译 .node 二进制,npm 安装会依赖包内的 binding.gyp 触发本地 node-gyp rebuild。Windows 需要 Visual Studio C++ Build Tools 与 Python;macOS 需要 Xcode Command Line Tools;Linux 需要 X11/XTest 相关开发库。

导入方式

根入口导出全部公开 API:

import {
  Button,
  Key,
  Point,
  Region,
  centerOf,
  clipboard,
  elements,
  findColor,
  findElement,
  findImage,
  findText,
  getActiveWindow,
  keyboard,
  mouse,
  screen,
  sleep
} from "@geyj/auto-gui";

也可以按模块导入,适合大型项目收敛依赖边界:

import { mouse } from "@geyj/auto-gui/mouse";
import { keyboard } from "@geyj/auto-gui/keyboard";
import { clipboard } from "@geyj/auto-gui/clipboard";
import { screen } from "@geyj/auto-gui/screen";
import { getActiveWindow } from "@geyj/auto-gui/window";
import { findText } from "@geyj/auto-gui/findText";
import { findImage } from "@geyj/auto-gui/findImage";
import { findColor } from "@geyj/auto-gui/findColor";
import { findElement } from "@geyj/auto-gui/findElement";
import { sleep } from "@geyj/auto-gui/utils";

快速开始

import { Button, Key, Region, centerOf, findText, keyboard, mouse, screen, singleWord, windowWithTitle } from "@geyj/auto-gui";

const activeWindow = await screen.find(windowWithTitle(/记事本|Notepad/i));
console.log(activeWindow);

const saveButton = await findText(singleWord("保存"), {
  searchRegion: new Region(0, 0, 1200, 800)
});

await mouse.move(centerOf(saveButton));
await mouse.click(Button.LEFT);

await keyboard.type("Hello from auto-gui");
await keyboard.press(Key.LeftControl, Key.S);

当前模块与能力

| 模块 | 入口 | 主要能力 | | --- | --- | --- | | 基础类型 | 根入口 | PointSizeRegionButtonKeyRGBA | | 几何工具 | 根入口 | centerOf()straightTo()createBezierPath() | | 鼠标 | @geyj/auto-gui/mouse | getPosition()setPosition()move()click()doubleClick()rightClick()pressButton()releaseButton()scrollUp()scrollDown()scrollLeft()scrollRight()drag() | | 键盘 | @geyj/auto-gui/keyboard | type()press()pressKey()releaseKey() | | 剪贴板 | @geyj/auto-gui/clipboard | getContent()setContent();文本跨平台,图片写入当前仅 Windows | | 屏幕 | @geyj/auto-gui/screen | width()height()capture()grab()grabRegion()captureRegion()colorAt()highlight()find()findAll()waitFor()read()saveImage() | | 窗口 | @geyj/auto-gui/window | getActiveWindow()getWindows()window.titlewindow.regionmove()resize()focus()minimize()maximize()restore()getElements()find()findAll()waitFor() | | 图片查找 | @geyj/auto-gui/findImage | imageResource()findImage()findAllImages()waitForImage() | | 颜色查找 | @geyj/auto-gui/findColor | pixelWithColor()findColor()findAllColors()waitForColor() | | OCR 文本 | @geyj/auto-gui/findText | singleWord()textLine()findText()findAllTexts()waitForText()readText()providerRegistryPaddleOcrTextFinder | | UI 元素 | @geyj/auto-gui/findElement | elements.*()windowElementDescribedBy()findElement()findAllElements()waitForElement()findMatchingWindowElements() | | 工具函数 | @geyj/auto-gui/utils | sleep(seconds)sleep(minSeconds, maxSeconds)openElementInspector()openColorPicker() |

鼠标

import { Button, mouse, straightTo } from "@geyj/auto-gui";

await mouse.move({ x: 400, y: 300 });
await mouse.move(straightTo({ x: 500, y: 320 }));
await mouse.click(Button.LEFT);
await mouse.doubleClick();
await mouse.rightClick();
await mouse.scrollDown(3);
await mouse.drag([{ x: 100, y: 100 }, { x: 300, y: 240 }]);

mouse.move()mouse.drag() 默认使用平滑贝塞尔轨迹。mouse.config.mouseSpeed = 0 时会直接瞬移到目标点。

键盘

import { Key, keyboard } from "@geyj/auto-gui";

await keyboard.type("第一行");
await keyboard.press(Key.Enter);
await keyboard.type("第二行");
await keyboard.press(Key.LeftControl, Key.A);
await keyboard.press(Key.LeftControl, Key.C);

keyboard.type() 只负责文本输入。Windows 下单个可打印 Unicode 字符直接使用原生键盘事件,整段文本、换行和制表符临时借助剪贴板粘贴;keyboard.press() 用于单键和组合键。

剪贴板

import { clipboard, screen } from "@geyj/auto-gui";

const original = await clipboard.getContent();

await clipboard.setContent("plain text");
await clipboard.setContent({ taskId: 1001, enabled: true });
await clipboard.setContent(await screen.capture());

await clipboard.setContent(original);

clipboard.setContent() 支持任意 JavaScript 值:字符串保持原样,对象和数组序列化为 JSON,其他值转成字符串。传入 Image 或兼容的 RGB/RGBA 原始像素结构时,Windows 会写入系统图片剪贴板。clipboard.getContent() 当前只读取文本。

开发辅助工具

import { openColorPicker, openElementInspector } from "@geyj/auto-gui";

const elementInspector = await openElementInspector({
  delayMs: 1000,
  pollIntervalMs: 120
});

// openColorPicker 当前是同一个桌面捕获器的兼容入口。
const sameInspector = await openColorPicker();

console.log(elementInspector.executablePath, elementInspector.pid, sameInspector.pid);
  • openElementInspector():唤起合并后的 Windows 桌面捕获器 auto-gui-inspector.exe。鼠标移动到目标元素后会出现蓝色选中框,悬停 1 秒后锁定元素详情。
  • openColorPicker():兼容入口,当前同样唤起 auto-gui-inspector.exe。捕获器面板会同时展示当前鼠标坐标和当前位置颜色 rgba(...)

捕获器会展示唯一标识、标题、类名、控件类型、窗口标题、鼠标坐标、颜色 RGBA/HEX、元素坐标等信息,每项都可以单独复制。鼠标移到捕获器窗口上时会暂停捕获,避免准备复制时信息被覆盖。

首次使用或源码开发时先生成 exe:

npm run build:inspector

在测试项目中可以直接运行:

npm --prefix auto-gui-test run test:utils

该命令会保持桌面捕获器运行。使用完关闭捕获器窗口,或在终端按 Ctrl+C 退出。需要让测试自动关闭时,可设置 $env:AUTO_GUI_TOOL_HOLD_SECONDS = "60"

屏幕、图片和颜色

import { FileType, RGBA, Region, findColor, findImage, imageResource, pixelWithColor, saveImage, screen } from "@geyj/auto-gui";

const image = await screen.capture(new Region(0, 0, 400, 300));
await saveImage(image, "artifacts/top-left.png", FileType.PNG);

const template = await imageResource("button.png");
const buttonRegion = await findImage(template, { confidence: 0.99 });

const redPixel = await findColor(pixelWithColor(new RGBA(255, 0, 0, 255)), {
  searchRegion: new Region(0, 0, 800, 600),
  tolerance: 5
});

console.log(buttonRegion, redPixel);

当前图片资源加载和保存只支持 PNG。模板 PNG 需要是 8 位、非交错格式。

窗口和 UI 元素

import { elements, getActiveWindow, getWindows, waitForElement } from "@geyj/auto-gui";

const activeWindow = await getActiveWindow();
console.log(await activeWindow.title, await activeWindow.region);

await activeWindow.focus();
await activeWindow.move({ x: 100, y: 100 });
await activeWindow.resize({ width: 900, height: 700 });

const windows = await getWindows();
console.log(windows.length);

const okButton = await waitForElement(elements.button({ title: "确定" }), 5000, 500, {
  window: activeWindow
});

console.log(okButton);

UI 元素读取当前使用 Windows UI Automation。elements 提供 buttonmenuItemtextFieldcheckBoxdialoglistItemtabcustom 等工厂,并支持 indescendantOfancestorOfafterbeforesiblingOfnthChildnotMatching 等关系查询。

OCR 文字定位

SDK 内置 PaddleOCR PP-OCRv5 Mobile ONNX Provider,并通过 onnxruntime-node 本地推理。第一次调用 OCR 时才会加载 OpenCV、ONNX Runtime 和模型文件。

import { Region, findText, readText, singleWord, textLine, waitForText } from "@geyj/auto-gui";

const saveButton = await findText(singleWord("保存"), {
  searchRegion: new Region(0, 0, 1200, 800),
  confidence: 0.8
});

const exported = await waitForText(textLine(/导出成功/), 5000);
const allText = await readText();

console.log(saveButton, exported, allText);

调用方可以通过 providerRegistry.registerTextFinder(...) 替换默认 OCR Provider。

测试

根目录构建:

npm run prepare:ocr-models
npm run build:native
npm run build

模块化测试项目位于 auto-gui-test/

npm run test:api-capabilities
npm run test:clipboard-image:e2e
npm run test:inspector:e2e
cd auto-gui-test
npm install
npm run test:screen
npm run test:find-image
npm run test:find-color
npm run test:find-element
npm run test:find-text
npm run test:clipboard
npm run test:utils
npm run test:window-list
npm run test:window-active

会操作真实桌面的测试请单独运行:

npm run test:mouse:e2e
npm run test:keyboard:e2e
cd auto-gui-test
npm run test:mouse
npm run test:keyboard
npm run test:window-actions

根目录 npm test 会构建 TypeScript 和桌面捕获器、安装 auto-gui-test,然后运行 API 全景烟雾、Windows 图片剪贴板外部消费者 E2E、捕获器字段级 E2E,以及 auto-gui-test 的完整低影响模块集。真实鼠标、键盘和窗口动作不会混入默认测试,仍需使用上面的显式命令。

npm run test:api-capabilities 会验证根入口和全部子路径导出、基础类型和几何、图片编解码、屏幕/颜色/图片/窗口/UIA 低影响调用、OCR Provider 合约、未实现接口边界以及桌面捕获器启动/关闭。test:clipboard-image:e2e 会用独立 .NET 消费者复核图片尺寸和像素;test:inspector:e2e 会核对捕获器全部字段和“复制全部”行为。

OCR 烟雾测试:

$env:AUTO_GUI_OCR_DEBUG = "1"
npm run test:ocr:smoke -- tmp/ocr-smoke.png

平台支持矩阵

| 能力 | Windows | macOS | Linux | | --- | --- | --- | --- | | 鼠标 | 已实现 | 已实现,需要 Accessibility 权限 | 已实现,依赖 X11 + XTest | | 键盘 | 已实现 | 已实现,需要 Accessibility 权限 | 已实现,依赖 X11 + XTest;文本输入偏 ASCII | | 文本剪贴板 | 已实现 | 已实现 | 已实现,需要 wl-copywl-pastexclipxsel | | 图片剪贴板写入 | 已实现 | 尚未实现 | 尚未实现 | | 屏幕截图、取色、高亮 | 已实现 | 尚未实现 | 尚未实现 | | 窗口控制 | 已实现 | 尚未实现 | 尚未实现 | | UI 元素读取 | 已实现,使用 UI Automation | 尚未实现 | 尚未实现 | | 图片查找 | 已实现,依赖屏幕截图 | 受屏幕实现限制 | 受屏幕实现限制 | | 颜色查找 | 已实现,依赖屏幕截图 | 受屏幕实现限制 | 受屏幕实现限制 | | OCR 文字查找 | 已实现,依赖屏幕截图和内置模型 | 受屏幕实现限制 | 受屏幕实现限制 |

Electron 使用建议

桌面输入和窗口控制属于高权限能力。Electron 项目中建议只在主进程或受信任 preload 中调用 @geyj/auto-gui,再通过 IPC 暴露最小必要接口。不要把系统级鼠标、键盘、截图或剪贴板能力直接开放给远程网页、插件脚本或未验证输入。

已知限制

  • 当前 npm 包没有预编译二进制,安装时会本地编译原生 addon。
  • 当前 exports 只配置了 require 条件,原生 ESM 入口尚未提供。
  • 屏幕录制和流式截图入口已保留,但调用会抛出 UnsupportedScreenOperationError
  • PNG 编解码已实现,JPG 输出类型已保留但尚未实现。
  • Windows 屏幕截图、窗口控制和 UI Automation 读取是同步原生调用,大区域截图或复杂元素树读取可能短暂阻塞 Node.js 事件循环。
  • Windows 下单个可打印 Unicode 字符会直接使用原生键盘事件;整段文本、换行和制表符使用临时剪贴板粘贴。快速逐字符调用和整段输入均已通过真实 Notepad E2E。

完整逐项 API 测试方式见 docs/API_TEST_GUIDE.md

当前能力、平台边界与验证状态见 docs/CAPABILITY_MAP.md,本轮实测结果和问题记录见 docs/API_TEST_REPORT.md

版本更新记录见 CHANGELOG.md