codex-browser-fix
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCodex Browser Fix
Codex 浏览器修复
Codex only. The desktop app bundles a Chrome plugin that drives any Chromium browser through the ChatGPT extension. Two things break it, and the vendor skill covers neither:
| Symptom | Cause | Fix |
|---|---|---|
| | Preflight installs a launcher that overrides the provider for that one subprocess |
| Extension found yesterday, missing or erroring today | The desktop app updated; | Preflight re-syncs the cache and the trust hashes to the installed app |
| User asked for Brave (or Vivaldi, Opera) and the agent picked Chrome | The vendor skill only names | Select by |
The installed Chrome plugin's own skill ( inside the app bundle) stays the authority for browser APIs. This skill owns local setup, recovery, and browser-family selection.
skills/control-chrome/SKILL.md仅限 Codex。桌面应用随附了一个 Chrome 插件,通过 ChatGPT 扩展驱动任何 Chromium 浏览器。有两种情况会导致它失效,而厂商 skill 均未涵盖:
| 症状 | 原因 | 修复 |
|---|---|---|
扩展被发现后出现 | | 预检会安装一个启动器,仅对该子进程覆盖 provider |
| 昨天还能找到扩展,今天缺失或报错 | 桌面应用已更新; | 预检将缓存和信任哈希重新同步到已安装的应用 |
| 用户要求 Brave(或 Vivaldi、Opera),agent 却选了 Chrome | 厂商 skill 只列出 | 按 |
已安装的 Chrome 插件自带的 skill(应用 bundle 内的 )仍是浏览器 API 的权威来源。本 skill 负责本地设置、恢复和浏览器系列选择。
skills/control-chrome/SKILL.mdWhen to Apply
何时使用
- The user names Brave, Vivaldi, Opera, Edge, Chrome, or "my browser" for a task that needs their tabs or sign-in
- The Chrome plugin errors with
Codex auth token is unavailable - Browser discovery finds no extension connection, or fails right after a ChatGPT or Codex desktop update
- "check the browser setup" / "fix the browser connection"
- 用户提到 Brave、Vivaldi、Opera、Edge、Chrome 或“我的浏览器”,且任务需要其标签页或登录状态
- Chrome 插件报错
Codex auth token is unavailable - 浏览器发现找不到扩展连接,或在 ChatGPT 或 Codex 桌面应用更新后立即失败
- “检查浏览器设置”/“修复浏览器连接”
Workflow
工作流
1. Preflight the plugin
1. 预检插件
Run before importing or selecting a browser. Requires Bun and the ChatGPT or Codex desktop app. is the installed skill folder (Codex default: ).
browser-client.mjs<skill-dir>~/.codex/skills/codex-browser-fixbash
bun "<skill-dir>/scripts/browser-plugin-preflight.mts" # sync + verify
bun "<skill-dir>/scripts/browser-plugin-preflight.mts" --check # read-only verify, exit 1 on driftIt prints the app bundle version, the plugin path to import from, and which caches were synchronized. Re-run it after every desktop app update or restart. A failure names the missing file or stale setting and exits 1; a missing , bundle, or executable is an error, never a pass.
browser-client.mjsconfig.tomlThe codex home is or . A non-standard install passes with the bundled Chrome plugin directory. on a missing exits 1; a missing value exits 2.
$CODEX_HOME~/.codex--plugin-dir <dir>--checkconfig.toml--plugin-dirWhat it changes, and nothing else ( is the codex home):
<home>- : every existing pinned version entry, the current version's entry, and the
<home>/plugins/cache/openai-bundled/chromelink follow the installed app bundle.latest: the current version's companion copy and its<home>/plugins/cache/openai-bundled/browserlink only. Replaced stale copies move tolatest.<home>/plugin-rollbacks/ - , under
<home>/config.toml:[mcp_servers.node_repl.env], the app version, and the trusted code paths. UnderCODEX_CLI_PATH: the[shell_environment_policy.set]hash. Each value must already be assigned there; the edit is parse-verified to change nothing else.browser-client.mjs - : a generated launcher. Only its
<home>/scripts/browser-codexsubcommand getsapp-server; every other subcommand passes through unchanged. The main provider,-c 'model_provider="openai"', and credentials are untouched.CODEX_HOME - Each : its own
<home>/hosts/<host>/companion cache, and, where it has aplugins/cache/openai-bundled/browser, the same config edits plus its ownconfig.toml. The Chrome cache is global only.scripts/browser-codex
在导入 或选择浏览器之前运行。需要 Bun 以及 ChatGPT 或 Codex 桌面应用。 是已安装的 skill 文件夹(Codex 默认:)。
browser-client.mjs<skill-dir>~/.codex/skills/codex-browser-fixbash
bun "<skill-dir>/scripts/browser-plugin-preflight.mts" # sync + verify
bun "<skill-dir>/scripts/browser-plugin-preflight.mts" --check # read-only verify, exit 1 on drift它会打印应用 bundle 版本、供导入 的插件路径,以及已同步的缓存。每次桌面应用更新或重启后都应重新运行。失败时会指出缺失的文件或过期的设置并以退出码 1 结束;缺少 、bundle 或可执行文件属于错误,绝不应视为通过。
browser-client.mjsconfig.tomlcodex 主目录为 或 。非标准安装可通过 传入随附的 Chrome 插件目录。在缺少 时执行 会以退出码 1 结束;缺少 值则以退出码 2 结束。
$CODEX_HOME~/.codex--plugin-dir <dir>config.toml--check--plugin-dir它会修改以下内容,且仅修改这些( 为 codex 主目录):
<home>- :所有已存在的固定版本条目、当前版本条目以及
<home>/plugins/cache/openai-bundled/chrome链接都跟随已安装的应用 bundle。latest:仅当前版本的配套副本及其<home>/plugins/cache/openai-bundled/browser链接。被替换的过期副本会移到latest。<home>/plugin-rollbacks/ - :在
<home>/config.toml下设置[mcp_servers.node_repl.env]、应用版本和受信任的代码路径。在CODEX_CLI_PATH下设置[shell_environment_policy.set]的哈希。每个值都必须已存在于该处;此编辑会经过解析验证,确保不改变其他内容。browser-client.mjs - :一个生成的启动器。只有其
<home>/scripts/browser-codex子命令会获得app-server;其他所有子命令均原样透传。主 provider、-c 'model_provider="openai"'和凭据均不受影响。CODEX_HOME - 每个 :各自的
<home>/hosts/<host>/配套缓存;如果其中有plugins/cache/openai-bundled/browser,则进行相同的配置修改,并生成各自的config.toml。Chrome 缓存仅全局存在。scripts/browser-codex
2. Bootstrap the vendor way
2. 按厂商方式引导
Follow the installed skill through its JavaScript tool: import from the path the preflight printed, call once, and reuse the and browser bindings across turns. Never reset a working session to repeat setup.
control-chromenode_replbrowser-client.mjssetupBrowserRuntime()agent按照已安装的 skill,通过其 JavaScript 工具:从预检打印的路径导入 ,调用一次 ,并在多轮对话中复用 和浏览器绑定。绝不要重置一个可用的会话来重复设置。
control-chromenode_replbrowser-client.mjssetupBrowserRuntime()agent3. Select the browser family
3. 选择浏览器系列
Chrome and Edge have vendor selectors: and . Every other Chromium family is matched from the list:
agent.browsers.get("chrome")agent.browsers.get("edge")js
// Declared once per session; call it again with a profile name after asking.
async function selectExtension(family, profileName) {
const label = (c) => c.profileName ?? c.name; // the name shown when asking
const candidates = (await agent.browsers.list()).filter(
(c) =>
c.type === "extension" &&
c.family === family &&
(profileName === undefined || label(c) === profileName),
);
if (candidates.length === 0) throw new Error(`No connected ${family} extension`);
if (candidates.length > 1) {
const profiles = candidates.map(label).join(", ");
throw new Error(`Several ${family} profiles connected (${profiles}); ask which one`);
}
return agent.browsers.get(candidates[0].id);
}
let browser = await selectExtension("brave", undefined); // or ("brave", "Work") once known
nodeRepl.write(await browser.documentation());- No candidate: report the browser as unavailable in the user's words (the extension is missing or disconnected). Several: ask which profile, then call again with that name and reassign
selectExtension. Never guess.browser - Family names follow the plugin's :
scripts/extension-ids.json,brave,chrome,edge,opera.vivaldi - An explicit browser request is a hard constraint. Never substitute Google Chrome because the plugin is named Chrome, and never fall back to Computer Use or a fresh browser.
- After selection, read the complete output as the vendor skill requires, name the session, then claim the exact tab object from
documentation()that matches the task.browser.user.openTabs() - A stale or closed tab gets a fresh tab from the existing browser binding. Re-select a browser only after an explicit disconnection or a user-requested switch.
Chrome 和 Edge 有厂商选择器: 和 。其他 Chromium 系列则从列表中匹配:
agent.browsers.get("chrome")agent.browsers.get("edge")js
// Declared once per session; call it again with a profile name after asking.
async function selectExtension(family, profileName) {
const label = (c) => c.profileName ?? c.name; // the name shown when asking
const candidates = (await agent.browsers.list()).filter(
(c) =>
c.type === "extension" &&
c.family === family &&
(profileName === undefined || label(c) === profileName),
);
if (candidates.length === 0) throw new Error(`No connected ${family} extension`);
if (candidates.length > 1) {
const profiles = candidates.map(label).join(", ");
throw new Error(`Several ${family} profiles connected (${profiles}); ask which one`);
}
return agent.browsers.get(candidates[0].id);
}
let browser = await selectExtension("brave", undefined); // or ("brave", "Work") once known
nodeRepl.write(await browser.documentation());- 没有候选:用用户的话报告该浏览器不可用(扩展缺失或未连接)。有多个:询问使用哪个配置文件,然后以该名称再次调用 并重新赋值
selectExtension。绝不要猜测。browser - 系列名称遵循插件的 :
scripts/extension-ids.json、brave、chrome、edge、opera。vivaldi - 明确的浏览器请求是硬约束。绝不要因为插件名为 Chrome 就换成 Google Chrome,也绝不要回退到 Computer Use 或全新浏览器。
- 选择后,按厂商 skill 的要求阅读完整的 输出,为会话命名,然后从
documentation()中认领与任务匹配的精确 tab 对象。browser.user.openTabs() - 过期或已关闭的 tab 应从现有浏览器绑定中获取新 tab。仅在明确断开连接或用户要求切换后,才重新选择浏览器。
4. Work and hand off
4. 工作与交接
- Inspect the page before acting; re-check state after each meaningful action. A completed click or upload is not a saved result: verify the fields, media, and saved state on the page before reporting success.
- Read the vendor upload instructions before photo or document uploads.
- Preserve tabs per the vendor's handoff rules. Never clear browser storage; it holds local drafts and signed-in state.
- Connection setup authorizes nothing else. Applications, messages, purchases, and publications still follow the current request and project approval rules.
- 操作前先检查页面;每次有意义的操作后重新检查状态。点击或上传完成并不等于结果已保存:在报告成功前,务必验证页面上的字段、媒体和已保存状态。
- 上传照片或文档前,阅读厂商的上传说明。
- 按厂商的交接规则保留 tab。绝不要清除浏览器存储;其中保存着本地草稿和登录状态。
- 连接设置不授权任何其他操作。应用、消息、购买和发布仍遵循当前的请求和项目审批规则。
Recovery
恢复
- , empty discovery, cache or trust failures: run the preflight, then read recovery.
Codex auth token is unavailable - Discovery or selection fails after a good bootstrap: .
await agent.documentation.get("bootstrap-troubleshooting") - Extension install or communication fails: .
await agent.documentation.get("chrome-troubleshooting") - A running browser helper keeps the environment it started with. A new launcher setting takes effect when that helper next starts; do not kill a working connection to apply it.
Never: switch the main off and back on, copy tokens, patch app binaries, or reinstall components speculatively. Report a real sign-in requirement as the user's action.
model_provider- 出现 、发现结果为空、缓存或信任失败:运行预检,然后阅读 recovery。
Codex auth token is unavailable - 成功引导后发现或选择失败:。
await agent.documentation.get("bootstrap-troubleshooting") - 扩展安装或通信失败:。
await agent.documentation.get("chrome-troubleshooting") - 正在运行的浏览器助手会保持其启动时的环境。新的启动器设置会在该助手下次启动时生效;不要为了应用设置而杀掉一个正常工作的连接。
绝不要:关闭再重新打开主 、复制令牌、修补应用二进制文件,或投机性地重新安装组件。若确实需要用户登录,应将其作为用户操作告知。
model_providerFallback Without the Desktop Plugin
无桌面插件时的回退方案
The preflight runs from any terminal with Bun, independent of an MCP host, and reports which bundle, cache, or setting is missing. Prepare task material locally where useful. Live browser work resumes only in a desktop Codex session with the Chrome plugin and the requested browser connection; never substitute another browser or automation transport.
--check预检的 模式可在任何装有 Bun 的终端中运行,不依赖 MCP 主机,并会报告缺少哪个 bundle、缓存或设置。如有需要,可在本地准备任务材料。实时浏览器工作只会在带有 Chrome 插件和所需浏览器连接的桌面 Codex 会话中恢复;绝不要改用其他浏览器或自动化传输方式。
--checkReferences
参考
- : the auth incident specimen, what the preflight synchronizes, and the extension-versus-tab failure split
references/recovery.md - : the sole setup implementation (sync and
scripts/browser-plugin-preflight.mts)--check - : the launcher generator and the
scripts/browser-auth-launcher.mtsedit, unit-tested in the authoring repositoryconfig.toml
- :认证事件样本、预检同步的内容,以及扩展缺失与 tab 失败的区分
references/recovery.md - :唯一的设置实现(同步与
scripts/browser-plugin-preflight.mts)--check - :启动器生成器与
scripts/browser-auth-launcher.mts编辑,已在编写仓库中进行单元测试config.toml