PRA-only-demo/docs/rpa-core-migration-guide.md
yu 5ef797dcc0 feat: 添加算术验证码与字符验证码处理能力
新增算术验证码解析、字符清洗能力及测试文件,注册OCR_CalculationCode和OCR_CommonEnglishNumbersCode两个新能力,补充验证码处理逻辑
2026-11-05 16:48:20 +08:00

14 KiB
Raw Blame History

rpa-core 迁入 Agent-Employee 指南

本文是 @rpa/core 包从 demo(本仓库)迁入 D:\code\Agent-Employee 的完整操作指南。 抽离改造已于 2026-11-05 完成(阶段 0→5,分支 refactor/rpa-core 已合入 main, commit 4139400..a8084dc),本指南对应任务清单中的「阶段 6 — 迁入 Agent-Employee」。 配套文档:docs/rpa-core-refactor-tasks.md(任务与风险清单)、docs/dev-conventions.md(开发规范)、packages/rpa-core/README.md(包边界与契约)。


1. 迁入对象的当前形态

项 现状
包位置 packages/rpa-core/(npm workspace 成员,@rpa/core,private)
依赖约束 零 Electron、零宿主引用(npm run check:deps 护栏强制)
导出入口 .(engine/driver/browser/types)+ ./capabilities(副作用注册全量能力)
运行时依赖 exceljs / pdf-lib / nodemailer / imapflow / mailparser / mssql / mysql2 / pg / basic-ftp / adm-zip / pngjs / sm-crypto / ws / @gutenye/ocr-node
宿主耦合点 全部经 HostBridge / SubflowSource / BrowserLike 三个接口注入,无反向依赖
验证基线 包内注册 719 个能力 id;demo 全量快照 909 id(含宿主浏览器能力);npm run rpa-cli 零 Electron 跑通 5 个代表能力
测试 包内独立 vitest(串行模式,防桌面自动化竞态);部分冒烟测试需真实 Windows 桌面

2. 迁入前置项(在 demo 侧已延后,迁入时必须补做)

  • 5.2 Bun 冒烟(决策点 10 延期项,迁入第一件事) 在 Agent-Employee 环境用 bun test 跑包内纯逻辑测试,逐项验证:
    • exceljs / pdf-lib / adm-zip / mailparser 等依赖在 Bun 下读写正常;
    • driver/windows/powershell.ts 的 execFile("powershell.exe") + -EncodedCommand 在 Bun 子进程下编码行为一致(GB18030 回退、CLIXML 解析);
    • Bun 的 fetch 与 Node 行为差异对 Http 能力无影响。
    • @gutenye/ocr-node / onnxruntime 原生依赖不在本次范围,单独立项验证(见 §6 留守清单)。
  • catalog platformTag 数据重生成 scripts/build-catalog.mjs 的 platformTag: "win32" 填充逻辑已就绪(desktop/app/office/vision 组), 因外部源数据(Agent-Employee 仓库)此前不在本机未生效。迁入后跑一次 npm run catalog 并核对。
  • 注册入口切换评估 双入口现状:旧 import "@rpa/core/capabilities"(副作用注册)+ 新 await registerAll(engine, groups?)(显式注册,可按域子集)。 Agent-Employee 建议直接用 registerAll;确认稳定后可在包内废弃副作用入口(单独决策,不阻塞迁移)。

3. 迁入步骤(阶段 6.1 → 6.4)

6.1 ADR 评审材料

按 Agent-Employee 流程提交架构决策记录,三份材料可直接取自:

  1. 包边界:packages/rpa-core/README.md「包边界」表(engine / driver / capabilities / browser 四模块职责)。
  2. HostBridge 契约:README「HostBridge 契约」章节 + 包内 src/engine/host-bridge.ts(接口定义即契约,共 4 个方法 + SubflowSource 2 个方法,见 §4.1)。
  3. driver 生命周期:RpaEngine.driver 默认 new WindowsDriver(),createEngine({ driver }) 可注入自定义实现;驱动只承载原始注入原语,拟真/换算/组合策略在能力层。element 域实现由 capabilities/desktop-uia.ts 经 setElementDriverImplementation 反向注册(避免 driver→capabilities 依赖)。

6.2 包迁入 packages/

  1. 保留 git 历史:用 git subtree 或先在 demo 仓库完成搬迁 commit 再整体 fetch,禁止复制目录后重开历史(总原则 1:单一源,杜绝代码漂移 R3)。
  2. bun workspace 接入:
    • Agent-Employee 根 package.json 的 workspaces 加 packages/*;
    • 包 package.json 的 exports 指向 ./src/index.ts 源码直出(现状),若 Agent-Employee 构建链需要产物,再补 build 脚本与 exports 产物路径——此调整属于宿主侧决策,包源码不动;
    • 根 tsconfig paths 增加 "@rpa/core": ["packages/rpa-core/src/index.ts"] 与 "@rpa/core/capabilities"(参考 demo 根 tsconfig.json 现有写法);electron.vite/构建器的对应 alias 同步。
  3. demo 侧解除引用:迁入后 demo 改为只读引用该仓库(git dependency / npm pin),或明确解除引用并确认 demo 归档范围。两边同时活跃开发即违反单一源原则。
  4. 快照基线随包走:resources/capability-snapshot.json 的生成逻辑在 demo 侧 scripts/capability-snapshot.test.ts;迁入后在 Agent-Employee 重建等价快照测试,作为能力集回归基准。

6.3 宿主适配层(product-shell 侧工作)

包要求的全部宿主注入点如下,迁入 = 逐项提供实现:

① HostBridge(必做,4 个方法)——demo 参考实现在 src/main/index.ts L28-50:

import { setHostBridge, type HostDialogWindow } from "@rpa/core";

setHostBridge({
  // human-dialog 能力创建人机交互表单窗口;BrowserWindow 适配为 4 方法最小面
  createFormWindow({ title }) {
    const win = new BrowserWindow({ width: 480, useContentSize: true, alwaysOnTop: true,
      webPreferences: { contextIsolation: true, sandbox: true } });
    const dialogWindow: HostDialogWindow = {
      isDestroyed: () => win.isDestroyed(),
      destroy: () => win.destroy(),
      loadURL: (url) => win.loadURL(url),
      on: (event, listener) => win.on(event, listener),
      executeJavaScript: (script) => win.webContents.executeJavaScript(script, true)
    };
    return dialogWindow;
  },
  // window-extended 鼠标/拖拽坐标换算;未注入时包内回退恒等(测试模式)
  dipToScreenPoint: (p) => screen.dipToScreenPoint(p),
  screenToDipPoint: (p) => screen.screenToDipPoint(p),
  // ai-service 配置读取;未注入返回空配置,requireAiConfig 抛 ai_not_configured
  loadAiConfig: () => ({ baseUrl, apiKey, model, visionModel })  // 来自宿主 settings
});

未注入时的降级行为(包内已定义,宿主测试环境可依赖):DPI 换算恒等、AI 空配置、human-dialog 抛 host_unavailable。

② SubflowSource(必做,2 个方法):setSubflowSource({ listFlows, getFlow }),子流程仓库在宿主侧(demo 对应 flows.ts)。getFlow 返回包内 FlowDefinition(注意:是包内领域类型,非宿主画布模型,需要做映射)。

③ BrowserLike(内置浏览器路径):包内 BrowserLike 接口(src/engine/types.ts)是浏览器能力的抽象面。Agent-Employee 若沿用 Electron product-shell,可直接移植 demo 的 src/main/browser/session.ts + capabilities/browser*.ts;若不是 Electron,需按 BrowserLike 契约重新实现(这是迁入工作量的最大变数,先评审 Agent-Employee 的浏览器方案再估工作量)。

④ ExternalTransport / EmbeddedTransport:外部浏览器 CDP 走包内 ExternalTransport(零改动);内置浏览器 CDP 的 EmbeddedTransport(webContents.debugger 适配)留在宿主,随 ③ 一起移植。

⑤ AI 编排能力:src/main/capabilities/ai-caps.ts 消费包内 chatCompletion/requireAiConfig,配置经 loadAiConfig 注入。宿主提供等价 settings 即可,README 标注「可随后续阶段评估迁入包」。

6.4 权限与治理对接(R10)

  • 危险能力清单(候选,迁入时与 Agent-Employee 权限模型逐一对齐):System_ExecuteCommand、App_Kill、键鼠注入家族(Mouse_/Keyboard_)、Clipboard_*、文件删除/移动家族。
  • 对接方式:在宿主的 RunContext 组装层做能力级 allowlist 拦截(能力 handler 内部无权限概念,这是刻意的——权限属宿主治理职责);registerAll(engine, groups?) 的按域注册可作为粗粒度开关。
  • 能力目录(catalog.json)与 Agent-Employee 插件体系对齐:platformTag 字段已就绪,能力 meta(getCapabilityMeta(id),含参数 schema 与 errorCodes)可供其面板/Agent 消费。

4. 不迁入部分(宿主职责,迁入时明确归属)

demo 侧模块 迁入时的处理
src/renderer/ 不迁(Agent-Employee 用 SolidJS)
src/main/overlay.ts / desktop-pick.ts / vision-lab.ts / fixture/ Electron 窗口强耦合,按 Agent-Employee 等价功能重写或放弃
src/main/local-vision/ onnxruntime-node 原生依赖,Bun 兼容性单独立项,不阻塞迁移
src/main/flows.ts / run/ / settings.ts 应用级编排与持久化,宿主职责(包通过 SubflowSource/HostBridge 取用)
src/main/browser/session.ts + transport.ts + browser* 能力 随宿主浏览器方案决策(§6.3 ③④)

5. 迁入验收标准

  1. bun test(包内纯逻辑测试)全绿 —— 补做 5.2 的结论。
  2. bun run 等价于 npm run rpa-cli 的 CLI host 跑通 5 个代表能力(桌面 / Excel / HTTP / 文件 / 屏幕),证明零宿主可运行。
  3. 能力快照零 diff(719 包内 id 对齐;宿主侧重建快照后 909 对齐)。
  4. check:deps 通过(保持零 Electron 零宿主引用)。
  5. HostBridge 注入后,human-dialog / window-extended DPI / ai-service 三条注入路径有真实交互验证(弹窗、高分屏拖拽、AI 调用各至少 1 例)。
  6. demo 侧(若保留):test + typecheck + catalog 快照三项全绿不回归。

6. 关键决策记录(迁入时不再重新讨论)

# 决策
1 物理搬迁 git mv,非引用保留
2 保留全局注册表 + 副作用注册;createEngine() 工厂收拢进程级状态
3 集中突击式迁移,不长期双轨
4 HostBridge 最小面:createFormWindow / dipToScreenPoint / screenToDipPoint / loadAiConfig
5 浏览器 CDP:外部路径入包,Embedded 留宿主
6 五域 AutomationDriver 接口 + WindowsDriver 机械包一层(行为不变)
7 catalog 只填 platformTag 数据,渲染层置灰延后
8 CapabilityMeta 可选 + 新能力强制
9 注册双入口过渡(副作用 + registerAll)
10 5.2 Bun 冒烟延期到迁入时执行(本文 §2 第一项)

风险 R1-R10 → 任务映射见 docs/rpa-core-refactor-tasks.md 末尾表格;迁移后的新规范增量见 docs/dev-conventions.md(结构化 meta 强制、错误码登记、powershell 助手唯一出口)。


7. 三端支持(Windows / macOS / Linux)

目标:项目最终要在三个桌面平台运行。架构钩子已预埋,工作分「迁入前小改」(demo 侧,避免跨仓库返工)与「迁入后实现」(Agent-Employee 侧,按域补 driver)两批。

7.1 已就位的三端基础(无需改动)

  • 五域 AutomationDriver 接口:能力层只面向 driver.mouse/keyboard/window/screen/element,Windows 实现整体可替换;
  • createEngine({ driver }) 注入 + registerAll(engine, groups?) 按域注册(可只注册当前平台支持的能力组);
  • meta.platforms 字段(src/engine/registry.ts 已定义,字面量待扩展);
  • HostBridge 的 DPI 接口走 Electron,mac Retina / Linux 由 Electron 屏蔽,包内无感知。

7.2 迁入前改(demo 侧,成本低的准备工作)

# 改什么 为什么现在做
1 platforms 类型扩成 "win32" | "darwin" | "linux",能力 meta 填 platforms 数据(catalog 从「只标 win32 组」改为逐能力标注) 纯类型+数据;拖到 Agent-Employee 侧要跨仓库改
2 引擎驱动工厂化:engine.ts 硬编码 new WindowsDriver(),改为按 process.platform 选择,非 win 平台明确抛 platform_unsupported;RUNTIME_ERROR_CODES 同步加该错误码 改动 10 行内
3 注册组与平台边界对齐检查:excel-com / word-extended(COM)/ desktop-uia / desktop 等 Windows 专属能力确保归入可按平台过滤的组 registerAll 的 groups 就是三端注册开关,组错位到时要重构
4 测试 skipIf 守卫补齐:目前仅 4 个测试文件有 process.platform !== "win32" 守卫,键盘/鼠标/窗口冒烟都没有 补齐后纯逻辑测试能在 mac/linux CI 跑
5 dev-conventions 加约束:能力文件禁止散落 process.platform 分支(utility-extended.ts 现有 2 处,收口到明确清单) 防止平台判断扩散,三端化时找不到边界

7.3 迁入后实现(Agent-Employee 侧,独立项目)

  1. LinuxDriver / MacDriver 实现(接口已就位,按域补齐):
    • Linux:鼠标/键盘 xdotool(X11)、ydotool+uinput(Wayland,全局注入受限,是三端中最大技术坑)、element 走 AT-SPI、screen 走 xrandr;
    • macOS:鼠标/键盘 cliclick 或 CGEvent、window 走 AppleScript / System Events、element 走 AX Accessibility API;
    • macOS TCC 权限(辅助功能 / 屏幕录制 / 自动化授权)是 mac 端最大部署摩擦,迁入前先做可行性评估。
  2. Excel/Word COM 替代:mac 走 AppleScript + Office 自动化,linux 走 LibreOffice UNO;或第一版直接标 platforms: ["win32"] 不支持。
  3. external.ts 浏览器路径表平台化:当前硬编码 Windows 可执行路径 + 注册表查询 + powershell 进程枚举,需补 mac(/Applications/Google Chrome.app/... 等)与 linux(which google-chrome)路径表和对应进程发现分支。
  4. 剪贴板/桌面助手替换:powershell → pbpaste/pbcopy(mac)、xclip/wl-copy(linux);人机对话框走 HostBridge 由宿主 GUI 方案实现,包内不感知。
  5. onnxruntime/OCR 三端二进制:原生依赖单独立项验证,不阻塞主线。
  6. CI 三端矩阵;catalog 渲染层按 platforms 置灰(决策点 7 的延后项此时落地)。

7.4 三端化原则

  • 平台差异只存在于 driver 实现与极少数能力文件的明确清单内;能力 handler 层、引擎、注册表、HostBridge 契约保持平台无关。
  • 能力不支持当前平台时的统一行为:注册期按 platforms 过滤(面板不出现),运行期兜底抛 platform_unavailable / platform_unsupported。
  • 新增平台专属脚本助手(如 osascript / xdotool 包装)与 powershell.ts 同级同规:放 driver/<platform>/,经 check:deps 与 review 把关,禁止能力文件自行 spawn。