Chromium Embedded Framework
OpenHuman 不运行平台内置的 webview。它通过 tauri-runtime 的一个分支运送自己的 Chromium Embedded Framework (CEF) 运行时,而这个单一决定几乎是 OpenHuman 产品中每个"OpenHuman 知道您的工具中发生了什么"功能的承载基础。
为什么用 CEF 而不是 stock webview
Stock Tauri 使用每个平台的原生 webview。macOS 上的 WKWebView、Windows 上的 WebView2、Linux 上的 WebKitGTK。这些对渲染 OpenHuman 应用本身很好。但它们有一个致命的限制:它们都不暴露 Chrome DevTools Protocol (CDP)。
CDP 是承载原语。OpenHuman 中每个"观察 Slack / WhatsApp / Telegram / Discord / Meet 内部发生了什么"功能都通过 CDP 与这些嵌入式应用对话,而不是通过注入的 JavaScript。CDP 提供:
Target.getTargets发现每个页面和服务 workerIndexedDB.requestDatabaseNames/requestDatabase/requestData遍历第三方应用的本地存储DOMSnapshot.captureSnapshot用于只读 DOM 检查,不会触发框架响应性Runtime.evaluate用于临时一次性读取
CEF 今天用于什么
嵌入式第三方 webviews
每个作为托管 web 应用运行的连接提供商都有自己的子 CEF webview:
- WhatsApp Web
- Telegram Web
- Slack
- Discord
- Google Meet
- Gmail
- Zoom
CDP 驱动的扫描器
每个提供商都有一个扫描器模块。每个扫描器持有到 CEF 的长寿命 WebSocket(--remote-debugging-port=19222)并按固定时间表 tick:
| 扫描器 | 频率 | 做什么 |
|---|---|---|
whatsapp_scanner | 2s DOM tick + 30s 全 IDB walk | 读取消息存储,拉取媒体元数据 |
telegram_scanner | 相同 | 加上 QR 登录交接到原生 Telegram Desktop |
slack_scanner | 30s IDB walk | 纯 IDB - 无需 DOM 抓取 |
discord_scanner | 周期性 | 通过 CDP 的频道 + DM 状态 |
meet_scanner | 周期性 | 通话期间实时字幕 + 参与者状态 |
Google Meet 吉祥物相机
Meet agent 不仅参加会议,它还广播自己作为相机。这之所以可行是因为 CEF 允许我们:
- 通过
Page.addScriptToEvaluateOnNewDocument在任何 Meet 代码运行之前注入一个小桥接 - 覆盖
navigator.mediaDevices.getUserMedia以返回来自隐藏 640×480 画布的MediaStream - 在该画布上渲染吉祥物 SVG,通过 CDP 从 Rust 驱动
window.__openhumanSetMood(...)
"无新 JS 注入"规则
规则在 CLAUDE.md 中文档化:迁移的提供商加载零注入 JavaScript。所有抓取都通过扫描器端的 CDP 原生进行。
| 提供商 | 已迁移? |
|---|---|
| ✅ 零 JS | |
| Telegram | ✅ 零 JS |
| Slack | ✅ 零 JS |
| Discord | ✅ 零 JS |
| browserscan | ✅ 零 JS |
| Gmail | 遗留 runtime.js 桥接 |
遗留 LINKEDIN_RECIPE_JS | |
| Google Meet | 相机 + 音频 + 字幕桥接 |
CEF 预热
隐藏的 CEF webview(cef-prewarm)在应用启动时启动浏览器,这样当用户点击时第一个子 webview 会立即生成。
Linux shell 回退
在某些 Linux 桌面上(尤其是 NVIDIA 专有驱动程序设置),Tauri/CEF shell 可能在原生窗口配置期间失败。当核心本身健康时,您可以通过单独运行核心和前端来继续开发:
cargo build --bin openhuman-core
./target/debug/openhuman-core run --port 7788
# 另一终端
cd app
pnpm dev
在常规浏览器中打开 Vite URL,选择 Advanced / remote core 模式,将 RPC URL 设置为 http://127.0.0.1:7788/rpc。