@a11ign/screenreader-worker

中文文档
0.13.13发布于 2026/10/17AGPL-3.0-or-laterTypeScriptES Module构建来源已验证近 30 天下载 8458

Drives a real NVDA screen reader through real navigation on Windows and returns what it announced. The HTTP contract is the API.

原始使用文档
文档目录5 节
  1. The HTTP contract is the API
  2. CAPTURE_PROTOCOL_VERSION is not the package version
  3. guidepup is pinned exactly, and that is deliberate
  4. What the programmatic surface is for
  5. One behaviour worth knowing before you read a transcript

@a11ign/screenreader-worker

Drives a real NVDA screen reader through real navigation on Windows and returns what it announced.

Windows only, with an interactive desktop session. Not a limitation to be worked around: NVDA is a real Windows application, and guidepup needs a logged-on desktop to drive it. A service, an SSH session or utmctl exec all land in session 0, where NVDA reports its own absence as nvda.start failed: NVDA is not supported — which reads like a broken install and is not one.

npm install @a11ign/screenreader-worker
npx a11ign-nvda-worker            # serves on :8765

The HTTP contract is the API

Almost nobody should import this package. A capture needs Windows, NVDA and a desktop, so the normal shape is a small Windows worker serving HTTP to a controller running anywhere:

POST /capture      { url, task?, probeForms?, probeFocus?, probeTables? }  → the capture
GET  /health       readiness, vitals, environment, code hash
GET  /diagnostics  Edge profile sizes, orphan processes, NVDA config + logs   (on demand — it walks disks)

Dispatch on ready, not on ok. ok only ever meant "the HTTP server is answering", and a worker answered it while NVDA could not start — which is how this pool's dominant failure hid for a day. ready is about the environment: Edge is resolvable, ForegroundLockTimeout is 0, the worker is free. ready: false right after a boot is normal and self-correcting.

Watch vitals.recoveries. It counts faults the worker papered over. The worst fault this pool has had produced zero failures — one guest's NVDA went mute on 4 of 4 captures, the retry absorbed every one, and the only symptom was 122.9 s per capture against a healthy peer's 40.6 s.

CAPTURE_PROTOCOL_VERSION is not the package version

It versions the wire contract and the meaning of the evidence, independently of semver, and conflating the two would be expensive in both directions: a package major must not invalidate cached captures, and a protocol bump must not wait for a major.

Bump it when a change alters what the evidence means — a new field a signal reads, a probe that announces differently. It is a cache key, so a bump forces a full recapture. That is the point, and it is why a refactor must not touch it.

guidepup is pinned exactly, and that is deliberate

"@guidepup/guidepup": "0.31.0" — no caret. guidepup parses NVDA's speech before this package ever sees it, so its version is evidence. Upgrading 0.29.2 → 0.31.0 fixed an intermittent OBJECT REPLACEMENT CHARACTER (U+FFFC) appended to form-field announcements: 1 in 15 captures before, 0 in 15 after. A caret range would let npm update silently change what a capture says.

What the programmatic surface is for

import { captureWithNvda, CAPTURE_PROTOCOL_VERSION, codeVersion } from "@a11ign/screenreader-worker";

captureWithNvda(url, options) is the one-shot path, for a controller that already runs on the Windows box. codeVersion() hashes the worker's own files so a deploy can be verified over the channel the worker serves on — which matters because push-then-restart can fail silently in both halves, and a check that goes through the same channel as the action verifies nothing.

Everything else — capture-core internals, the speech-socket shim, browser-session, the diagnostics payload shapes — is not public and will change without a major.

One behaviour worth knowing before you read a transcript

NVDA has two modes, and in focus mode single letters are typed into the page instead of navigating. A control activation is a focus change, which switches focus mode on and it sticks — so a naive sweep after activating a form types its own quick-nav keys into whatever has focus. This ran here for 2,122 captures with every check green, and one site search-as-you-typed them and rendered 1 result for FFffGGggKKkkLLll, which was read as a page defect. The sweep now detects the echo and escalates out of focus mode, and reports focusModeStuck rather than "this page has no links" when it cannot recover — because "nothing was found" and "we could not ask" must never be the same evidence.

版本与发布记录

@a11ign/screenreader-worker 共发布 30 个版本,首次发布于 2026/10/04;过去 12 个月发布了 30 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.13.13latest2026/10/1721 天前
0.13.122026/10/1721 天前
0.13.112026/10/1721 天前
0.13.102026/10/1721 天前
0.13.92026/10/1721 天前
0.13.82026/10/1721 天前

其他发布通道:reserved → 0.0.0-reserved.0。

关于 @a11ign/screenreader-worker 的常见问题

@a11ign/screenreader-worker 是什么?

Drives a real NVDA screen reader through real navigation on Windows and returns what it announced. The HTTP contract is the API.

如何安装 @a11ign/screenreader-worker?

在项目目录运行 npm install @a11ign/screenreader-worker,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 a11ign-nvda-worker,可以用 npx a11ign-nvda-worker 直接运行。

@a11ign/screenreader-worker 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@a11ign/screenreader-worker 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@a11ign/screenreader-worker 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@a11ign/screenreader-worker 可以商用吗?

@a11ign/screenreader-worker 使用 AGPL-3.0-or-later 许可。最严格的 Copyleft:除分发外,通过网络向用户提供基于它的服务也需要开源对应源码。闭源 SaaS 使用前务必评估。以上为概括,不构成法律意见,请以许可原文为准。

@a11ign/screenreader-worker 的下载量有多少?

根据 npm 官方下载统计,@a11ign/screenreader-worker 在 2026/10/05 – 2026/11/03 这 30 天内被下载 8,458 次,日均约 282 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@a11ign/screenreader-worker 还在维护吗?

最新版本 0.13.13 发布于 2026/10/17(21 天前);至今共发布 30 个版本,其中过去 12 个月发布了 30 个;首次发布于 2026/10/04。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。