Electron Extensions API
使用 session.fromPartition("persist:webtabs").extensions.loadExtension()。复用当前登录态、Cookies、下载和 Web Use 的 exact WebTab。
用户可以在 OpenProgram 内置浏览器中打开 Edge Add-ons 或 Chrome Web Store,在扩展详情页点击 OpenProgram 提供的安装操作,确认权限后自动下载、校验、解包并启用。OpenProgram 只承诺 Electron 已实现的 API 子集,不宣称商店中的任意扩展都能正常工作。
persist:webtabs当前所有原生网页 tab 都由 main process 创建 WebContentsView,并共享 persist:webtabs。扩展必须在这个 session 上加载,且要在首个网页加载之前恢复。
使用 session.fromPartition("persist:webtabs").extensions.loadExtension()。复用当前登录态、Cookies、下载和 Web Use 的 exact WebTab。
扩展运行在外部浏览器时,不属于 OpenProgram 内置 tab,也不共享现有 WebContentsView 生命周期。它仍可作为单独的 external-browser computer use 能力存在。
保留为独立能力商店下载只作为安装来源;OpenProgram 不复制 Chrome 的完整 extension API、账号同步、企业策略、商店支付或发布能力。
不采用能力由 Electron 官方支持范围决定。安装前只做 manifest-level preflight,不扫描扩展 JavaScript;未列出的 manifest key 或运行时 chrome.* API 只能标记为未验证,不能写成已兼容。
| 能力 | 第一版 | 行为 | 原因 |
|---|---|---|---|
| Edge Add-ons 详情页安装 | 首选入口 | 识别正式详情页和扩展 ID,显示 OpenProgram 安装操作;确认权限后从 Microsoft 官方更新服务下载并安装。 | 作为默认商店入口,避免把 Chrome Web Store 的可达性作为安装前提。 |
| Chrome Web Store 详情页安装 | 可选入口 | 商店可访问时使用同一流程;无法访问时提示改用 Edge Add-ons 或本地目录,不代理商店网页。 | Google 官方更新服务提供商店扩展包,但网页可达性不由 OpenProgram 保证。 |
| 加载 unpacked extension 文件夹 | 支持 | main process 选择目录、复制到 App 管理目录、校验后加载。 | Electron 的正式入口。 |
| Chrome / Edge 已安装扩展代码 | 第二阶段 | 从用户选择的 browser profile 发现版本目录,复制代码后按同一流程安装。 | 两者采用 Chromium extension 格式;仍需处理 identity 与兼容性。 |
content_scripts、chrome.scripting、storage.local、runtime、webRequest | Electron 子集 | 按 Electron 实际 API 提供;tabs 只承诺官方列出的部分字段与方法。 | Electron 官方支持清单。 |
| Manifest V3 background service worker / declarativeNetRequest | 不兼容 | manifest preflight 标记为不可用并保持禁用;不能把仅能加载 manifest 的结果报告为扩展可工作。 | Electron 官方支持表只列出 Manifest V2 background,未列出 MV3 service worker 或 declarativeNetRequest。 |
| 扩展管理页 | 支持 | 显示图标、名称、版本、来源、权限、兼容状态、启停、重新加载和移除。 | OpenProgram 自己提供管理 UI。 |
| 商店扩展包 | 安装传输格式 | 只从 Microsoft 或 Google 的固定官方更新服务下载;先验证来源、包签名、扩展 ID 和归档边界,再解包到 App 管理目录。Electron 只接收解包后的目录。 | Electron 不能直接加载 packed .crx,所以下载、验证和解包属于 OpenProgram 安装器职责。 |
用户选择任意 .crx 文件 | 不支持 | 本地安装只接受已解压目录,不接受来源和签名关系无法确认的单独文件。 | 避免把商店受控下载扩大为任意软件包安装入口。 |
| Chrome 工具栏 action、动态 badge、完整 popup 行为 | 暂不承诺 | 管理页显示静态扩展图标;不新增常驻 toolbar action。 | Electron 官方支持表未承诺 chrome.action 或 browserAction。 |
| 后台自动更新、同步、企业策略、native messaging | 不支持 | 第一版在管理页显示“检查更新”,仍需用户确认新增权限;storage.sync、storage.managed 与 native host 不可用。 | 商店安装不等于允许后台静默替换代码或扩大权限。 |
https://clients2.google.com/service/update2/crx,扩展 ID 来自商店详情页。https://edge.microsoft.com/extensionwebstorebase/v1/crx。不修改现有 tab 外形、地址栏高度和书签栏。Browser ⋯ 增加 Extensions,打开单例 b:extensions 管理页。普通用户的主入口是 Browse Edge Add-ons;本地目录安装放在页面次要操作中。
用户从 Extensions 管理页打开 Edge Add-ons;Chrome Web Store 可访问时也可直接输入其网址。商店详情页被识别后,浏览器显示“Install in OpenProgram”。
用户点击 OpenProgram 安装操作。网页只能提交当前详情页身份,不能指定下载地址、磁盘路径或自动批准权限。识别失败时,用户可把当前详情页链接粘贴到管理页。
main process 根据商店和扩展 ID 请求固定的官方更新服务,验证包签名、扩展 ID、文件数量、总大小与解包路径,再写入 App 管理目录。临时文件在成功、失败或取消后都清理。
显示扩展名称、来源、host permissions、content scripts、file access 和 Electron 未支持的 manifest 能力。用户确认后才启用;明确不兼容的扩展保持禁用。
扩展加载到 persist:webtabs,对新建网页和现有网页的下一次导航生效。安装完成后 UI 明确提示重新加载已打开的网页,不自动刷新或丢弃网页中的未提交状态。App 重启时恢复已启用扩展;单个扩展失败不阻止浏览器启动。
registry 保存用户意图;Electron session 保存本次进程中的实际加载状态。二者不能混为一个状态。
id、name、version、manifestHash、managedPath。renderer 不接收原始来源路径。
edge-addons、chrome-web-store、folder 或 browser-profile。商店项只保存扩展 ID 和详情页;不保存任意下载 URL。
enabled、allowFileAccess=false、已批准的 manifest hash。manifest 改变后必须重新确认。
loaded、loadErrorCode、manifestCompatibility。进程启动后根据 Electron 实际结果刷新。
浏览器扩展可以读取或修改网页内容,因此安装、启用和权限扩张都必须是明确的用户操作。网页、Agent 和普通 renderer 不能静默完成这些操作。
商店安装只接受 Edge Add-ons 与 Chrome Web Store 的正式详情页,并由 main process 根据扩展 ID 生成固定官方更新请求;网页和 renderer 不能传入下载 URL。目录安装只接受用户通过原生选择器确认的路径。
下载完成后验证 CRX3 签名、由公钥导出的扩展 ID 与详情页 ID 一致,再执行受限解包。拒绝重定向到非官方主机、超量文件、路径穿越、符号链接和无效 manifest。
将 host_permissions、content_scripts.matches、全部网站访问和 file access 转换为用户可读摘要。新权限或 manifest hash 变化会撤销旧批准。
扩展只加载到 persist:webtabs。OpenProgram chat、Settings 和 Extensions manager 运行在默认 session,扩展不能注入这些页面。
allowFileAccess 默认且第一版固定为 false。即使 WebTab 打开 file:// 页面,扩展也不得因此获得本地文件读取权限。
Agent 可以观察扩展对网页 DOM 产生的结果,但不能通过 Web Use 自动安装、移除、启用扩展或批准新增权限。
先 unload,再删除 registry 项和管理目录。任一步失败都保留可诊断状态;不能出现 UI 显示已删除但启动时仍恢复的情况。
从 Chrome/Edge 导入只复制扩展代码。不会复制扩展的 storage.local、storage.sync、IndexedDB、Cookies、登录态、授权决定、企业策略或 native messaging 配置。
每个任务都从公共入口建立一个失败检查,完成后单独审查。商店安装属于第一阶段;Chrome/Edge profile 导入仍在其后。
使用本地签名 CRX3 fixture 验证验签、ID 绑定、受限解包与 unpacked 加载;使用两个扩展夹具分别验证 Electron 已支持能力和明确不兼容能力。测试不请求真实商店,也不读取真实用户扩展。
node desktop/scripts/check-browser-extensions.js新增 desktop/browser-extension-manager.js,由 desktop/main.js 在首个 WebTab 导航前恢复 enabled 项。安装使用临时目录、完整校验和原子 rename;失败不阻止 App 启动。
desktop/browser-extension-manager.js、desktop/main.js、desktop/package.jsonpersist:webtabs,重启恢复,disable/remove 不会再次恢复。preload 只暴露 list、openStore、installFromCurrentStorePage、installFromStoreUrl、chooseAndInstall、enable、reload、remove。Browser ⋯ 增加 Extensions;BuiltinPage 增加单例 extensions,管理页复用现有 built-in page 密度与按钮,不改 tab/toolbar/bookmarks CSS。
desktop/preload.js、web/lib/desktop-bridge.ts、web/lib/state/center-tab-ids.ts、browser-controls.tsx、builtin-tab-pane.tsx 及现有 tab label/icon 分支。详情页识别器只接受两个商店的已知 URL 格式,提取扩展 ID 后交给 main process;main process 使用固定官方更新服务下载,执行签名与 ID 校验、受限解包、manifest preflight 和权限确认。安装取消或失败不能改变已有版本。
复用 browser-profile-import.js 的 browser/profile 发现和真实路径约束,新增扩展候选列表与复制入口。只读取用户选择的 profile;同一扩展只选择最高有效版本。
第一版只在管理页由用户触发检查更新;不增加 update daemon。常驻 toolbar action、动态 badge、popup、账号同步、企业策略和 native messaging 继续保持未支持。
第一阶段的商店安装、本地目录安装、管理与启动恢复已经实现。安装版验收确认 Extensions 页面、Desktop API 和打包依赖可用;真实商店包的下载、签名、身份与本地化名称在隔离目录中验证,不向默认用户配置写入测试扩展。
| 可观察结果 | 状态 | 证据要求 |
|---|---|---|
所有原生 WebTab 共享 persistent persist:webtabs session。 | 已实现 | desktop/main.js 的 WebContentsView 创建路径。 |
| 用户从 Edge Add-ons 详情页点击安装,确认权限后完成下载、校验、解包与启用;新建 WebTab 和现有 WebTab 的下一次导航执行 content script,已打开页面提示重新加载。 | 已实现 | 签名 CRX3 fixture、真实 Edge 商店包隔离验证、Desktop check 与安装版 Extensions 页面验收。 |
| Chrome Web Store 可访问时提供同一安装流程;不可访问时明确提示 Edge Add-ons 与本地目录入口。 | 已实现 | 真实 Chrome 商店包隔离验证;管理页同时提供 Edge Add-ons、本地目录和商店链接入口。 |
| 网页或 renderer 提供任意下载 URL、错误商店 ID、无效签名或危险归档时安装被拒绝且无残留。 | 已实现 | check-browser-extensions.js 覆盖来源、ID、签名、归档边界、超时、取消和回滚。 |
| 用户仍可从本地解压目录安装兼容 fixture。 | 已实现 | 原生目录选择器、manifest preflight 与 Desktop API 检查。 |
| App 重启后 enabled 扩展在首个网页导航前恢复;单个失败不阻止窗口启动。 | 已实现 | manager 冷启动恢复与失败隔离检查;安装版 App 已完成启动验收。 |
| disable、reload、remove 的 UI 与 Electron 实际状态一致,remove 后磁盘和 registry 都没有残留。 | 已实现 | manager 生命周期、失败回滚、替换清理与重启恢复检查。 |
扩展不能注入 OpenProgram chat/Settings,也不能访问 file://。 | 已实现 | 扩展只加载到 persist:webtabs,并以 allowFileAccess: false 加载。 |
| 从 Chrome/Edge profile 导入只复制代码,不复制扩展数据、登录态或权限。 | 第二阶段 | 临时 profile fixture + 源目录只读与目标清理检查。 |
用户不能选择任意 .crx 文件;商店 CRX 只作为受控下载的内部传输格式。 | 已实现 | 文件选择器只接受目录;商店 ID、页面 URL、下载端点和重定向目标均由 main process 校验。 |
node desktop/scripts/check-browser-extensions.js;npm --prefix desktop run check;npm --prefix web run check:built-in-browser;npm --prefix web run test:unit;Web TypeScript;python -m tools.docs_site.checklinks;最后仅使用 /Applications/OpenProgram.app、默认 18100 worker 和 ~/.openprogram 验收。
本页是内置浏览器扩展的规范性设计与第一阶段实现记录。安装版验收没有向默认用户配置安装测试扩展;content script 与生命周期行为由隔离 manager fixture 验证。Chrome/Edge profile 导入、后台自动更新和完整浏览器 action UI 仍属于后续阶段。