很多人以为自己切换 model_provider 之后“历史会话丢了”,但更常见的真实情况是:
- 线程数据其实还在
- 只是不同位置的元数据不一致了
- 于是 Codex CLI、Codex App、侧边栏项目列表显示出来的结果不一样
最常见的症状是:
- 切换 provider 后,之前能看到的历史线程突然不见了
codex resume和 Codex App 显示不一致- 线程仍然存在,但左侧项目没了,手动
Add Project之后历史线程又回来
codex-threadkeeper 处理的正是这个问题。它会把这些状态重新对齐:
- rollout 文件:
~/.codex/sessions、~/.codex/archived_sessions - SQLite:
~/.codex/state_5.sqlite - 侧边栏项目状态:
.codex-global-state.json - 受管备份:
~/.codex/backups_state/threadkeeper
一句话说,它不是替代官方 Codex,而是修复 Codex 线程可见性的元数据工具。
这个仓库现在已经不是单纯的 provider sync 小工具,而是独立维护的 codex-threadkeeper。
和早期/原始的实现相比,这一版额外强调了几个实际痛点:
- 不只同步 rollout 和 SQLite,也会补齐缺失的侧边栏项目,解决“线程还在但项目不显示”
- CLI 有明确的阶段进度输出,运行时不会像卡住一样没反应
- summary 会显示备份创建耗时,便于观察性能
- Windows 上对锁目录创建时的瞬时
EPERM做了重试,减少刚执行完立刻重跑时的偶发失败 - 运行时命名空间已经切到
threadkeeper- 备份目录:
backups_state/threadkeeper - 锁目录:
tmp/threadkeeper.lock - GUI 设置:
%AppData%\codex-threadkeeper
- 备份目录:
- 旧的
provider-sync备份不会再被自动扫描,但仍然可以显式传入路径做restore - 继续保留 GUI、CLI、Windows 双击启动器这几种日常入口
你平时其实只会反复用下面几种场景。
| 场景 | 命令 | 什么时候用 |
|---|---|---|
| 先看当前状态 | codex-threadkeeper status |
你还不确定当前 provider、rollout、SQLite 是否一致 |
| 只修复可见性 | codex-threadkeeper sync |
你已经在别处切好了 provider,只想把历史线程重新对齐 |
| 切 provider 并同步 | codex-threadkeeper switch <provider-id> |
你想一步完成改 config.toml 和同步历史 |
| 回滚上一次同步 | codex-threadkeeper restore <backup-dir> |
你同步到了错误 provider,或者想撤销这次改动 |
| 清理旧备份 | codex-threadkeeper prune-backups --keep 5 |
你只想保留最近几份受管备份 |
如果你是普通 Windows 用户,最省事的日常方式是 GUI:
- 打开
CodexThreadkeeper.exe - 点击
Refresh - 选择目标 Provider
- 点击
Execute
如果你更习惯命令行,推荐的日常流程是:
codex-threadkeeper status
codex-threadkeeper sync
codex-threadkeeper status如果你这次不只是修复可见性,而是顺手切 provider:
codex-threadkeeper status
codex-threadkeeper switch openai
codex-threadkeeper status先关闭正在占用 .codex 的进程:
- Codex
- Codex App
app-server- 还在访问当前会话文件的终端窗口
然后执行:
codex-threadkeeper status
codex-threadkeeper sync你通常会在输出里看到这几项:
Updated rollout files- 代表有多少个 rollout 文件被改写到了目标 provider
Added sidebar projects- 代表这次补回了多少个侧边栏项目
Updated SQLite rows- 代表 SQLite 里有多少条线程元数据被更新
如果最后再跑一次:
codex-threadkeeper status看到 rollout 和 SQLite 的 provider 计数都已经一致,基本就说明修复完成了。
npm install -g codex-threadkeeper环境要求:
- Node.js
24+ - 标准
~/.codex目录结构 - 当前主要按 Windows 场景验证
如果你不想装 Node,也不想记命令,直接从 Releases 下载 CodexThreadkeeper.exe 即可。
GUI 适合:
- 普通 Windows 用户
- 想先看状态、再点按钮执行的人
- 希望直接浏览和恢复备份的人
GUI 专用说明见 README_GUI_ZH.md。
codex-threadkeeper status
codex-threadkeeper sync
codex-threadkeeper sync --keep 5
codex-threadkeeper sync --provider openai
codex-threadkeeper switch openai
codex-threadkeeper switch apigather
codex-threadkeeper prune-backups --keep 5
codex-threadkeeper restore C:\Users\you\.codex\backups_state\threadkeeper\20260319T042708906Z
codex-threadkeeper install-windows-launcher显式指定另一个 .codex 目录时:
codex-threadkeeper status --codex-home C:\Users\you\.codex
codex-threadkeeper sync --codex-home C:\Users\you\.codex
codex-threadkeeper switch openai --codex-home C:\Users\you\.codex这不是数据损坏,通常只是 Codex 还开着。
处理方式:
- 关闭 Codex / Codex App /
app-server - 再重跑同一个命令
这通常说明某个活跃会话还占着对应 rollout 文件。
这时的语义是:
- SQLite 大概率已经同步成功
- 大部分 rollout 文件也已经改完
- 只有那几个仍被占用的文件被跳过了
处理方式:
- 先结束那个活跃会话
- 再补跑一次
codex-threadkeeper sync
可以,但不会自动扫描。
你需要显式传入旧目录路径,例如:
codex-threadkeeper restore C:\Users\you\.codex\backups_state\provider-sync\20260319T042708906Z这个工具会修改元数据,但不会替换官方 Codex。
它明确不会做这些事:
- 不处理
auth.json - 不帮你登录第三方 provider
- 不修改消息历史正文
- 不修改标题、时间戳
- 不把旧的非受管备份目录当成自己的备份去清理
运行时默认会使用:
~/.codex/backups_state/threadkeeper/<timestamp>
~/.codex/tmp/threadkeeper.lock
如果你想让 AI 代你执行,机器导向说明见 AGENTS.md。
git clone https://github.com/panjinhe/codex-threadkeeper.git
cd codex-threadkeeper
npm test
dotnet test desktop/CodexThreadkeeper.Core.Tests/CodexThreadkeeper.Core.Tests.csproj
pwsh ./scripts/publish-gui.ps1MIT