面向 Codex 的 VS Code / Codex Webview 扩展,用于管理本机 .codex 数据、跨设备迁移记录、多账号槽位切换、账号池登录态切换、用量刷新和按会话 ID 清理对话。
当前主线是纯扩展形态,不包含 Tauri / Electron 独立桌面 App。
Codex 的真实使用数据分散在 .codex 目录、SQLite state、会话文件、历史索引、配置文件和登录态里。手工复制这些文件很容易出现会话丢失、账号串号、状态不同步、SQLite 残留、token 过期、删除不干净等问题。
Codex 迁移助手的核心价值是把这些高风险本地操作做成可视化、可预演、可回滚、可追踪的工具链。
-
跨设备迁移不再靠手工拷目录
- 插件知道哪些文件是会话记录、哪些是状态缓存、哪些是敏感登录态。
- 导出 / 导入支持预演和报告,先看到风险再执行。
- 适合把旧机器的 Codex 工作上下文迁到新机器。
-
多账号使用不再混写同一份
.codex- 账号槽位把每个账号隔离成独立目录。
- 切换通过软链接完成,避免把多个账号的记录、配置和状态混在一起。
- 支持合并和覆盖,能处理“保留记录但换账号”这类真实工作流。
-
账号池只切登录态,不破坏当前工作记录
pool-runner专用槽位承接 token 切换。- 普通账号槽位和当前会话记录不被账号池直接改写。
- 同邮箱的 Free / Team / Plus / Pro token 可以共存,不会互相覆盖。
-
用量刷新更稳定
- 旧版本只拿现有
access_token查用量,过期后只能报错。 - 当前版本接入 Codex OAuth
refresh_token续期逻辑,刷新前会自动换新 token。 - 账号池可以单条刷新、按套餐分类批量刷新,也可以按频率整池串行刷新。
- 旧版本只拿现有
-
危险操作可观察
- 导入、切换、清理都有日志。
- 对话清理支持预览、备份和残留校验。
- 损坏 SQLite、进程占用、登录态失效都会显式提示,不做静默吞错。
一句话:这个扩展不是单纯的 ZIP 备份工具,而是 Codex 本地数据、账号槽位、账号池 token 和会话清理的安全操作台。
- 在不同电脑之间迁移 Codex 会话、历史、配置和本地状态。
- 在同一台设备上维护多个完整 Codex 账号目录。
- 保留现有会话记录,只切换当前使用的账号登录态。
- 批量导入 cli-proxy / Codex token JSON 到账号池。
- 查询账号 5 小时 / 7 天窗口用量,必要时自动续期 token。
- 按会话 ID 批量预览和删除本地对话记录。
- 导出当前
.codex为 ZIP 备份。 - 导入备份 ZIP,支持导入前预演、冲突提示和导入报告。
- 多账号槽位管理:新增、切换、切换并合并、切换并覆盖、删除。
- 切换前检测占用
.codex的外部进程,支持结束进程后继续。 - 切换完成后尝试恢复启动被结束的 Codex 客户端。
- 账号池导入单个 JSON、多个 JSON 或目录中的 JSON。
- 同邮箱 / 同 accountId 的 Free、Team 等不同 token 可同时存在,不会互相覆盖。
- 账号池列表显示
FREE / TEAM / PLUS / PRO标签。 - 账号池表头集成“套餐筛选、视图排序、只看可用账号、按分类批量刷新”,不占用额外工具栏空间。
- 账号池支持单条刷新、表头按分类批量刷新、定时整池顺序刷新。
- 用量刷新前自动使用 Codex OAuth
refresh_token续期 access/id/refresh token。 - 对话清理支持预览、下次重启生效、立即结束相关进程后生效。
- 操作日志带时间前缀,便于排查。
用于跨设备同步记录和上下文。
会处理:
sessions/history.jsonlsession_index.jsonlrules/skills/config.tomlversion.json.codex-global-state.json- 可选
state_*.sqlite* - 可选
auth.json / cap_sid
适合:
- 新电脑恢复旧电脑的 Codex 记录。
- Mac / Windows 之间迁移会话。
- 重要操作前做备份。
用于在本机维护多个完整账号目录。
实现方式:
- 首次初始化会把当前
~/.codex纳入默认槽位。 - 每个账号槽位存放在
~/.codex-profiles/<profileId>。 - 当前活动账号通过
~/.codex -> ~/.codex-profiles/<profileId>软链接切换。
支持操作:
切换:直接切到目标槽位。切换并合并:把当前账号记录合并到目标槽位。切换并覆盖:用当前记录覆盖目标槽位记录,但保留目标登录态。删除:删除非当前激活槽位。
用于保留当前工作记录,只切换认证 token。
实现方式:
- 账号池使用
pool-runner专用槽位承接登录态切换。 - 普通账号槽位不直接被账号池改写。
- 切换账号池条目时只 patch
pool-runner/auth.json的认证字段。
会改写:
last_refreshexpiredtokens.access_tokentokens.account_idtokens.id_tokentokens.refresh_tokentokens.expired
不会改写:
cap_sidsessions/history.jsonlsession_index.jsonlstate_*.sqlite*config.toml
推荐流程:
- 在普通账号槽位里整理好要继续使用的记录。
- 点击“同步当前记录到池槽位”。
- 切换到
pool-runner。 - 在账号池里手动切换 token,或开启自动检测刷新整池用量。
用量查询会读取 Codex auth.json 或账号池 secret 中的 token。
刷新前会尝试按 Codex OAuth refresh_token 流程续期:
- Token URL:
https://auth.openai.com/oauth/token - Grant Type:
refresh_token - Client ID:
app_EMoamEEZ73f0CkXaXp7hrann - Refresh Lead:过期前 5 天开始尝试续期
- 续期成功后写回新的
access_token / id_token / refresh_token / expired / last_refresh
这套逻辑参考并移植自 CLIProxyAPI 的 Codex token refresh 策略。之前 token 容易过期的原因是旧版本只拿现有 access_token 查询用量,不会主动用 refresh_token 换新 token。
失败边界:
refresh_token已失效时,需要重新登录。- 网络失败时会保留原 token,并在日志中展示失败原因。
- 续期失败但旧
access_token仍有效时,会继续尝试查询用量。
如果账号池条目是从 CLIProxy JSON 导入的,扩展会记录这份 JSON 的本地来源路径。后续单条刷新、分类批量刷新、自动检测刷新前,会先读取这份源文件里的最新 token,再执行用量查询和必要的 refresh_token 续期。
这个设计解决的是“CLIProxy 已经在本机持续写回新 token,但扩展账号池里还是旧 token”的问题:
- 扩展不会默认扫描固定目录,也不会自动读取用户未选择过的目录。
- 导入文件 / 导入目录对话框会记住上一次选择的位置,下次打开默认回到该目录。
- 从
.cli-proxy-api或codex-*.json导入的条目会在账号池账号旁显示CLIProxy标签。 - 从普通 JSON 文件导入的条目会显示
FILE标签,并同样支持刷新前同步源文件。 - 重复导入同一批账号时,扩展会按“同邮箱 + 同套餐分类”优先覆盖旧条目;没有邮箱时才回退到“同 accountId + 同套餐分类”。
- 同邮箱的 Free / Team / Plus / Pro 仍会保留为不同条目。
- 多个 Team 邮箱即使共享同一个 accountId,也会按邮箱保留为不同条目。
- 如果旧版本已经导入出重复条目,重新导入同邮箱同套餐的 JSON 时会顺手合并这些历史重复项。
- 源文件缺失或格式不合法时,扩展会回退到账号池本地 secret 缓存继续刷新。
- 没有 CLIProxy 的用户不受影响,扩展仍按本地托管模式用账号池 secret 里的
refresh_token尝试续期。 - 已经失效的
refresh_token无法被扩展或 CLIProxy“救活”,必须重新登录后重新导入。
账号池支持三种刷新方式:
- 单条刷新:只刷新当前行。
- 分类批量刷新:按
全部账号 / Free / Plus / Team / Pro筛选后串行刷新。 - 自动检测:开启后按设置频率串行刷新整个账号池。
- 可选频率:5 分钟、15 分钟、30 分钟、1 小时,也可以禁用。
分类来源:
- 优先使用最近一次用量接口返回的
usage.planType。 - 如果尚未刷新过,则回退到导入 token 时从
id_token解析出的planTypeHint。
额度状态:
free:主要看 7 天窗口。plus / team / pro:同时看 5 小时和 7 天窗口。
当前版本不做无人值守自动换号。账号池切换写入 token 后,仍以手动重启 Codex 或 Reload Window 生效为主。
账号池表头集成了几个只影响展示 / 刷新的控件:
账号表头里的套餐筛选- 可选择全部、Free、Plus、Team、Pro。
账号表头里的视图排序手动顺序套餐分组:Pro > Team > Plus > Free可用优先剩余额度高优先最近刷新优先
状态表头里的只看可用- 开启后只显示当前状态为“可用”的池账号。
5h/7d表头右侧的刷新图标- 点击后展开分类菜单。
- 点击任一分类立即触发批量刷新,不需要二次确认。
- 当前高亮分类也可以重复点击刷新。
这些控件不会改变账号池真实顺序。只有在 全部套餐 + 不开启只看可用 + 手动顺序 的默认视图下,拖拽排序和上移 / 下移才会启用。
账号池列表为了节省宽度,把 5 小时窗口和 7 天窗口合并成一列:
5h/7d
19%/87%
这里的百分比表示对应窗口的已用量 / 剩余额度视图。把鼠标悬浮到 19%/87% 这类百分比上,会显示完整时间提示:
- 最近刷新时间
- 5h 重置时间
- 7d 重置时间
这些时间来自用量接口返回的 fetchedAt 和 resetAt,不是前端自行估算。
对话清理按会话 ID 执行。
流程:
- 输入一个或多个会话 ID。
- 执行预览,确认命中线程、日志、工具记录和文件。
- 选择作用范围:全部账号、当前账号或指定账号。
- 选择生效方式:下次重启生效或立即结束相关进程。
- 执行删除。
SQLite 边界:
- 损坏的
state_*.sqlite会显式报错。 - 对话文件、rollout/global state 等非 SQLite 残留仍会尽量清理。
- 不会静默吞掉数据库损坏问题。
VS Code / Codex Extension Host
├─ src/extension.ts
│ └─ 注册命令、Activity Bar View、Webview Provider
├─ src/ui-host/
│ └─ Webview 消息桥接、任务日志、写锁调度
├─ src/protocol/
│ └─ 前后端消息类型与 Zod 校验
├─ src/engine/
│ ├─ exporter.ts 导出 ZIP
│ ├─ importer.ts 执行导入
│ ├─ scanner.ts 导入预演
│ ├─ profiles.ts 账号槽位与 ~/.codex 软链接
│ ├─ tokenPool.ts 账号池、pool-runner、批量刷新
│ ├─ usage.ts 用量查询与 Codex token 续期
│ ├─ threadCleanup.ts 会话清理
│ ├─ processGuard.ts 占用进程检测、kill、relaunch
│ └─ stateReplace.ts state_*.sqlite 替换
├─ src/util/
│ ├─ sharedData.ts 共享数据路径
│ └─ sharedLock.ts 写操作单写锁
└─ webview/
└─ React UI
默认使用:
~/.codex~/.codex-profiles
账号池元数据和 secret 文件通过 src/util/sharedData.ts 推导,放在 ~/.codex-profiles 体系下。
写操作会经过单写锁:
- 账号槽位切换
- 账号池导入 / 删除 / 排序 / 切换
- 用量刷新后写回 token
- 导入备份
- 对话清理
如果另一端正在写入,会提示稍后重试,避免同时改写 .codex。
auth.json、cap_sid、refresh_token、access_token属于敏感凭据。- 不建议把包含 auth 的备份传给他人或提交到仓库。
- 导出 auth 只适合自己的可信设备之间迁移。
refresh_token失效时只能重新登录,插件不会绕过服务端鉴权。- 账号池 secret 仅保存在本机本地文件中,不上传远端服务。
从 GitHub Release 下载最新 .vsix 后安装:
code --install-extension codex-migration-assistant-<version>.vsix如果使用 Codex / VS Code 兼容环境,也可以在扩展管理页面选择“从 VSIX 安装”。
GitHub Release 地址:
https://github.com/Lutiancheng1/Codex-Migration-Assistant/releases
环境要求:
- Node.js 20+
- npm
- VS Code 或兼容 VS Code Extension Host 的环境
安装依赖:
npm install开发监听:
npm run watch:webview
npm run watch:ext然后按 F5 启动 Extension Host。
npm run typecheck
npm run build
npm run test:unit
npm run package:vsix如果本机默认 Node 低于 20:
npm run package:vsix:node20当前只通过 GitHub Release 分发 VSIX,不发布到 Visual Studio Marketplace。
本地打包:
npm run package:vsix创建 GitHub Release:
git tag v<version>
git push origin v<version>
gh release create v<version> codex-migration-assistant-<version>.vsix --title "v<version>" --notes-file RELEASE_NOTES.md- 当前只维护扩展主线,不维护独立 App。
- 删除账号槽位只能删除非当前激活槽位。
.codex或槽位目录被客户端占用时,需要结束相关进程后继续。- 跨平台迁移后可能需要重启 Codex / Reload Window 才能完全刷新状态。
- 损坏 SQLite 不做静默修复,会显式报告。
- 数据说明:docs/CODEX_DATA_GUIDE.zh-CN.md
- 接力文档:HANDOFF.md
- 项目同步说明:PROJECT_SYNC.md