Codex Session Toolkit 是一个 TUI 优先的 Codex 工具箱。它围绕本地 ./codex_bundles/ 工作区,把 Codex Desktop / CLI 会话和自定义 Skills 组织成可浏览、可导出、可导入、可修复、可同步的 Bundle。
这个项目要解决的,是会话管理、Skills 管理、跨设备迁移和 GitHub 同步这些实际需求。它把分散在 ~/.codex/、Desktop 索引、CLI rollout、history、项目路径和 Skills 里的内容,统一整理成一套可落地的工作流:先在本地形成 Bundle,再按需要导入、修复、备份,或同步到一个独立的 GitHub Bundle 仓库。
Codex 的会话数据、Desktop 索引、CLI rollout、history、项目路径、自定义 Skills 和跨设备文件,天然分散在不同位置。这个工具把这些分散内容变成一套围绕实际需求的工作流:
- 会话管理:在 TUI 中浏览、搜索和筛选 Desktop / CLI 会话,查看标题、provider、cwd、rollout 路径、history 和详情,不需要手动翻
~/.codex/。 - Skills 管理:把自定义 Skills 独立打包、导出、导入、恢复和清理,避免和会话数据混在一起。
- 跨设备迁移:把会话导出为 Bundle,按机器、分类、项目和时间归档;目标机器再从 Bundle 导入,而不是直接复制散落的原始状态文件。
- 项目级会话迁移:支持按项目路径筛选,按当前、勾选或全部匹配范围导出,导入时可以把源机器 cwd 映射到当前机器的项目路径。
- GitHub 同步:
./codex_bundles/可以连接到一个独立 GitHub Bundle 仓库,支持状态检查、Pull、Push、远端更新时间检测和冲突保护。 - 导入后修复:导入和修复流程会维护
session_index.jsonl、Desktopthreads表、workspace roots、侧栏顺序、provider 和线程标题,并把目标线程提升到最近线程池前部。 - 清理和回退:可以在 TUI 中预览、勾选并删除归档会话;删除时会保护同 ID 的 active 会话索引和 Desktop 线程记录。导出、导入、修复、清理、GitHub 同步等关键动作支持 Dry-run;导入覆盖前会备份,备份可在 TUI 中恢复。
围绕这些问题,工具当前提供 5 个功能域:
- Session / Browse:查看、搜索、筛选和按项目导出本机会话。
- Bundle / Transfer:浏览、校验、导出和导入会话 Bundle。
- Skills / Transfer:独立导出、导入和管理自定义 Skills。
- Repair / Maintenance:修复 Desktop 可见性、迁移 Provider、管理备份和清理旧副本。
- GitHub / Sync:把
./codex_bundles/作为一个可同步工作区,连接独立 GitHub Bundle 仓库后进行 Pull / Push。
chmod +x ./install.sh ./install.command ./codex-session-toolkit ./codex-session-toolkit.command
./install.sh
./codex-session-toolkitmacOS 可双击:
install.commandcodex-session-toolkit.command
.\install.ps1
.\codex-session-toolkit.cmd也可以双击 install.bat。
安装脚本会在项目根目录创建隔离的 .venv/,不会写入系统 Python 环境。
查看版本:
./codex-session-toolkit --version查看脚本和兼容 CLI 命令:
./codex-session-toolkit --advanced-help无参数启动进入 TUI。这是项目的主入口:
codex-session-toolkit主菜单按功能域组织:
Session / BrowseBundle / TransferSkills / TransferRepair / MaintenanceGitHub / Sync
用于查看、搜索、筛选和导出会话。
- 浏览并导出最近会话
- 搜索 session id、标题、预览、provider、cwd
- 查看会话详情
- 支持当前会话、勾选多条导出;按
a选中全部匹配项后再按e导出 - 按项目路径查看该项目下的会话
- 支持按项目导出当前、勾选多条会话;按
a选中全部匹配项后再按e导出
项目导出路径:
./codex_bundles/<machine>/sessions/project/<project>/<timestamp>/<session_id>/
用于管理会话 Bundle。
- 浏览
./codex_bundles/中的会话 Bundle,并可在浏览页勾选后删除本地 Bundle - 校验 Bundle manifest、session JSONL、history JSONL
- 导出全部 Desktop 会话
- 导出全部 active Desktop 会话
- 导出全部 CLI 会话
- 导入 Bundle 为会话使用单独入口,支持当前、勾选多条导入;按
a选中全部匹配项后再按i导入 - 导入 project 分类时,把源机器 cwd 映射到当前机器项目目录
- 导入时维护
session_index.jsonl、Desktopthreads表、workspace roots 和侧栏状态 - 多选/全部导入会把导入线程写入 Desktop 侧栏顺序和 workspace hint,并提升到 Desktop 最近线程池前部
- 导入到 Desktop 时会提升导入线程的最近排序,但不会自动置顶,避免把多选或全选导入的会话全部变成 pinned
- 选择显示到 Desktop 时,归档来源的 Bundle 会导入为 active 会话,避免只在 TUI 可见而不出现在 Desktop 主线程栏
导入如果会覆盖本地 rollout,会先生成 .bak.<timestamp> 备份。
用于独立迁移自定义 Skills。
- 浏览本机 Skills,默认只显示自定义 Skills
- 在同一个 Skills 列表中导出当前、勾选多条自定义 Skills;按
a选中全部匹配项后再按e导出 - 浏览 standalone Skills Bundle
- 在同一个 Skills Bundle 列表中导入当前、勾选多条 Bundle;按
a选中全部匹配项后再按i导入 - 删除本机自定义 Skills,删除前确认
- 删除 Skills 列表支持
Space多选、a选中全部匹配自定义 Skills、x删除选中/当前
.agents/skills/foo 与 .codex/skills/foo 会按同一个相对 Skill 识别,避免重复导入。
用于 Provider 复制/迁移、Desktop 显示修复和安全清理。
- 复制会话到当前 Provider:保留旧会话,创建一份带
cloned_from关系的新 Provider 副本 - 迁移会话到当前 Provider:直接修正现有会话的 Provider,并修复 Codex Desktop 显示
- 修复 Desktop 有限最近线程池被旧记录占满、侧栏筛选/折叠状态遮挡、空
thread_source和失效threads行 - 删除归档会话
- 删除已复制的旧 Provider 会话
- 管理会话备份
- 清理旧版重复副本
- 可选把未登记 CLI 会话纳入 Desktop
- 支持 Dry-run 预演
Desktop 修复默认只处理 active 会话;需要 archived 会话时,从 Repair / Maintenance 的修复入口中选择对应范围。修复会备份被改动的 Desktop state、SQLite 和索引文件。
删除已复制的旧 Provider 会话会先进入列表页。它只列出能通过新 Provider 副本里的 cloned_from 字段确认迁移关系的旧会话;没有对应新副本的旧会话不会被列出,也不会被删除。
删除归档会话会先进入列表页:
Enter/d预览当前归档会话Space勾选或取消勾选x删除选中项;未勾选时删除当前项a选中全部匹配归档会话;随后按x删除选中项
删除只针对 ~/.codex/archived_sessions/ 下的归档 rollout。若同一个 session id 同时还有 active rollout,工具会保留 session_index.jsonl 中的 active 索引,并把 Desktop threads 记录指回 active 文件,避免误删后左侧线程栏丢失。
用于同步 ./codex_bundles/,不用于同步项目源码。
菜单顺序:
连接独立 GitHub 仓库连接/断开代理查看 GitHub 同步状态从 GitHub 拉取更新推送本机更新到 GitHub
同步内容:
- 会话 Bundle:
sessions/ - standalone Skills Bundle:
skills/
同步方式:
- 连接:连接一个独立 Bundle 仓库,可选择连接后首次推送。
- 代理:配置本机代理接口;状态检查、拉取、推送都会使用它。
- 拉取:从已连接仓库拉取远端 Bundle 更新。
- 推送:提交本机 Bundle 变更,检查远端更新,必要时合并,再推送。
GitHub 同步按“用户先建仓库,再连接”的方式设计。
用户需要先在 GitHub 创建一个独立仓库,例如:
git@github.com:you/codex-bundles.git
然后在 TUI 中进入 GitHub / Sync -> 连接独立 GitHub 仓库 填写仓库地址。工具会拒绝连接到当前项目源码仓库 remote。
同步对象是 ./codex_bundles/ 工作区,范围包含会话 Bundle 和 standalone Skills Bundle。它不会把 ~/.codex/ 原始会话目录直接提交到 GitHub,也不会把 Bundle 混进本项目源码仓库。
工具会在 bundle 仓库自身的 git 命令里归一 credential helper,例如 Windows 记录的 gh.exe auth git-credential 会在 macOS/Linux 上转成可执行的 gh auth git-credential 或当前平台可用的 helper。
查看 GitHub 同步状态 会:
- 先快速读取本地连接状态
- 再用进度 UI 检查远端更新时间
- 显示本地提交时间、远端提交时间、本地领先提交数、远端领先提交数
- 显示本地待同步文件数量
这里的“领先”表示当前目标分支上的提交差异,不是远端分支数量。
普通首页、Bundle 页面、Skills 页面只读本地缓存状态,不会自动联网检查远端。
连接/断开代理 用于 GitHub 同步链路。常见输入:
http://127.0.0.1:7890
socks5://127.0.0.1:7890
127.0.0.1:7890
未写协议时默认按 http:// 处理。配置后,状态检查、拉取和推送都会在执行 git 操作时注入代理环境;断开后停止注入。代理配置只保存在 ./codex_bundles/ 自己的 git 配置里,不会修改本项目源码仓库的 git remote,也不会写全局 git 配置。
从 GitHub 拉取更新 只使用已经连接好的 remote 和分支。TUI 中不会再要求用户重新输入仓库地址或分支。
拉取页只保留一个选择:
- 从当前 remote/branch 拉取
- Dry-run 预览
- 返回
如果远端有新提交,同时本地 ./codex_bundles/ 还有未提交 Bundle 变更,拉取会保护性停止并提示先推送或清理本地变更。
推送本机更新到 GitHub 会显示:
- 推送目标 remote/branch
- 同步范围
- 待同步变更数量
- 会话变更数量
- Skills 变更数量
推送前会检查远端更新。可自动合并时自动合并;发生文件冲突时停止并列出冲突文件。
支持预演的 TUI 动作都遵循同一个交互规则:
- 用户进入选择页。
- 选择 Dry-run。
- 查看预演结果。
- 按 Enter 回到刚才的选择页。
- 用户可以继续选择直接执行或返回。
这个逻辑覆盖 GitHub 拉取、GitHub 推送、GitHub 连接、项目导出、Desktop 修复、Provider 迁移和清理旧副本等流程。
- 进入
Session / Browse。 - 选择
按项目路径查看并导出会话。 - 粘贴项目根目录。
- 查看匹配到的会话。
- 按
e导出当前会话;需要导出全部匹配会话时,先按a选中全部匹配项,再按e导出。 - 第一次可先 Dry-run。
- 把另一台机器的
./codex_bundles/拷贝过来,或从独立 GitHub Bundle 仓库拉取。 - 进入
Bundle / Transfer。 - 选择
导入 Bundle 为会话。 - 用
s/m/l筛选到 project Bundle,按Space勾选,或按a选中全部匹配项后再按i导入。 - 查看工具识别出的当前机器项目路径,必要时修改目标项目路径。
- 选择是否自动创建缺失目录。
- 执行导入。
导入不会强制进入 GitHub 拉取流程。用户手动拷贝 Bundle 后,可以直接导入。
源机器:
- 进入
Skills / Transfer。 - 选择
浏览并导出本机 Skills。 - 按
Space勾选后按e导出,或按a选中全部匹配自定义 Skills 后再按e导出。 - 得到
./codex_bundles/<machine>/skills/<single|selected|all>/<timestamp>/。
目标机器:
- 进入
Skills / Transfer。 - 选择
浏览并导入 Skills Bundle。 - 按
Space勾选后按i导入,或按a选中全部匹配 Skills Bundle 后再按i导入。 - 内容一致的 Skill 会直接复用。
- 内容冲突默认跳过,不覆盖本机版本。
- 进入
Repair / Maintenance。 - 选择
管理会话备份。 - 按
/搜索 session id、provider、cwd 或路径。 - 按
d查看详情。 - 按
r恢复当前备份。 - 按
x删除不再需要的备份。 - 输入
DELETE二次确认。
恢复前如果当前 rollout 仍存在,工具会再生成一份 rollout-xxx.jsonl.bak.restore.<timestamp>。
- 进入
Repair / Maintenance。 - 选择
删除归档会话。 - 按
Enter或d预览当前会话。 - 按
Space勾选多条,或直接停在某条上按x删除当前条。 - 需要清空归档时按
a选中全部匹配项,再按x确认删除选中归档会话。
这个功能用来减轻跨设备同步和搬运负担。它只删除归档 rollout;如果本机还有同 ID 的 active rollout,会保留 active 索引和 Desktop 可见性。
- 进入
Repair / Maintenance。 - 选择
删除已复制的旧 Provider 会话。 - 按
Enter或d预览旧会话和对应的新 Provider 副本。 - 按
Space勾选多条,或直接停在某条上按x删除当前条。 - 需要清空匹配项时按
a选中全部匹配项,再按x确认删除。
这个功能用于“复制会话到当前 Provider”之后,只保留新 Provider 记录。它不会根据 provider 名称粗暴删除旧记录,而是必须找到明确的 cloned_from 关系。
所有新版 Bundle 动作都围绕当前项目目录下的 ./codex_bundles/ 工作区进行。
默认目录:
- Codex 数据目录:
~/.codex/ - Bundle 工作区:
./codex_bundles/
默认结构:
./codex_bundles/<machine>/sessions/single/<timestamp>/<session_id>/
./codex_bundles/<machine>/sessions/desktop/<timestamp>/<session_id>/
./codex_bundles/<machine>/sessions/active/<timestamp>/<session_id>/
./codex_bundles/<machine>/sessions/cli/<timestamp>/<session_id>/
./codex_bundles/<machine>/sessions/project/<project>/<timestamp>/<session_id>/
./codex_bundles/<machine>/skills/single/<timestamp>/
./codex_bundles/<machine>/skills/all/<timestamp>/
<machine> 默认来自当前电脑主机名。需要手动指定时,可在导出前设置:
export CST_MACHINE_LABEL=My-MacBook兼容旧布局:
./codex_sessions/./codex_sessions/bundles/./codex_sessions/desktop_bundles/
新导出默认只写入 ./codex_bundles/。
会话 Bundle 默认包含:
codex/<relative rollout path>.jsonlhistory.jsonlmanifest.envthread_history_1.sqlite,可选,只包含当前 rollout 的投影数据history_lineage.json、父 rollout JSONL 和thread_history/,仅 paginated revert/fork 会话存在,用于恢复继承历史链
会话 Bundle 不再携带或恢复 Skill。这样可以避免当前 Codex 的 Skill root alias、插件和运行时目录被误判为可跨机器复制的本地文件。
standalone Skills Bundle 默认包含:
manifest.envskills_manifest.jsonskills/
project 分类额外记录:
- 导出项目名
- 导出项目原路径
- 每个会话的原始
cwd
Skills 只通过 standalone Skills Bundle 搬运,与会话导入导出解耦。export-skills、import-skill-bundle 和 TUI 的 Skills 区仍支持 best-effort、strict、skip、overwrite 模式。
工具读取 ~/.codex/config.toml 顶层的 sqlite_home,并用它定位 state_*.sqlite 和 thread_history_*.sqlite。如果未配置,则按官方优先级读取 CODEX_SQLITE_HOME,最后回退到 ~/.codex/。相对路径按当前工作目录解析。
导出投影数据时只选择当前 rollout 及其 history_base 祖先对应的 thread_history_projection_state、thread_turns 和 thread_items 行,不会把无关会话的 SQLite 数据带入 Bundle。导入已有数据库时也只替换这些 rollout 的投影行。stable thread id 与物理 rollout id 会分别记录,revert 后仍注册为原 thread。目标机已有内容不同的父 rollout 时保留本地文件,并跳过对应投影,避免 JSONL 与 SQLite 混用不同版本。
工具会尽量保留用户在 Desktop 中看到的真实标题和 provider 语义。
- 导出时优先读取源机器 Desktop
state_*.sqlite中的threads.title - 如果 SQLite 标题缺失,会读取 rollout 中的
thread_name_updated事件作为真实短标题 THREAD_NAME保存左侧线程短标题FIRST_USER_MESSAGE保存第一条用户消息,作为兜底预览- 导入时优先使用
THREAD_NAME - 旧 Bundle 没有标题时,才从现有 Desktop 标题、
thread_name_updated、session_index.jsonl或 rollout 首条用户消息恢复 - 标题比较会折叠换行和多余空白,避免把同一条长提示误判成短标题
AGENTS.md注入上下文、系统技能上下文等元信息不会被当成标题- 账号登录模式下,如果
~/.codex/config.toml没有model_provider,会从 Desktopthreads表和最新 rollout 中推断 - Desktop 修复会保留已有 Desktop 短标题;当旧标题明显是第一条提示或注入上下文时,会用
thread_name_updated恢复真实短标题
如果旧会话既没有 Desktop SQLite 标题、Bundle THREAD_NAME,也没有 thread_name_updated 事件,工具只能退回到第一条有意义的用户消息或工作区/时间兜底名。这是源数据限制,不会伪造不存在的短标题。
Codex Desktop 左侧线程栏不只是读取 rollout 文件。它还依赖 Desktop SQLite 的 threads 表、全局 state 中的 workspace roots、线程到 workspace 的 hint、项目内线程顺序、pin 列表和当前侧栏筛选/折叠状态。历史记录很多时,Desktop 还会优先显示最近线程;旧的归档或失效 threads 行可能占住这个有限列表。
因此,本工具在导入和 repair-desktop 中会同时处理这些状态:
- 写入或修复
threads行,并清理指向缺失/归档 managed rollout 的失效行 - 写入 workspace roots、
thread-workspace-root-hints和sidebar-project-thread-orders - 展开 chats / pinned / threads 分区,清除会挡住目标项目的折叠组,并把 workspace filter 切回全部
- 将导入或修复的线程提升到 Desktop 最近线程池前部
- 导入或修复不会自动写入 pinned 列表,已有置顶会话会保持原样
Provider 识别顺序:
- 命令显式参数
~/.codex/config.toml- 最新 Desktop
threads表 - 最新 rollout 会话文件
主界面和功能页:
| 按键 | 作用 |
|---|---|
↑/↓ 或 j/k |
移动 |
Enter |
进入功能页或执行当前动作 |
←/→ |
切换功能页 |
PgUp/PgDn |
切换功能页 |
h |
打开帮助 |
q |
返回或退出 |
0 |
直接退出 |
二级选择页:
| 按键 | 作用 |
|---|---|
↑/↓ 或 j/k |
选择执行方式、修复范围或同步方式 |
Enter |
确认当前选项 |
q / ← / Esc |
返回上一步 |
浏览器页面:
| 按键 | 作用 |
|---|---|
/ |
搜索会话、Bundle、Skill 或备份 |
Enter |
打开当前条目详情,选择模式下直接确认 |
d |
查看详情 |
e |
在会话/Skills 列表中导出当前或已勾选条目 |
i |
在 Bundle / Skills Bundle 导入页导入当前或已勾选条目 |
x |
在删除类浏览器或 Bundle 浏览页删除当前或已勾选条目 |
p |
在项目会话浏览器中重新输入项目路径 |
Space |
在可批量操作的列表中勾选或取消勾选 |
a |
在支持多选的功能页选中当前筛选结果的全部匹配项 |
s |
按 Bundle 类别筛选 |
m |
按来源机器筛选 Bundle |
l |
切换历史范围:全部历史 / 仅最新 |
g |
在 Skills 列表切换是否显示系统/运行时 Skills |
r |
在备份列表恢复当前备份 |
操作键语义保持统一:a 只表示选中当前筛选结果的全部匹配项,e 只表示导出,i 只表示导入,x 只表示删除。
本项目的主产品界面是 TUI。普通迁移、导入、导出、修复、Skills 管理和 GitHub 同步都应优先从 TUI 完成,不要求用户记忆命令。
CLI 只公开少量稳定入口,用于版本检查、只读检查、Bundle 健康检查和已连接仓库后的同步脚本。旧命令仍保留兼容,但不再作为用户工作流文档化;导出、导入、Skills、修复、拉取和冲突处理都走 TUI。
codex-session-toolkit --advanced-helpcodex-session-toolkit
codex-session-toolkit --version
codex-session-toolkit --advanced-help
codex-session-toolkit list-bundles
codex-session-toolkit validate-bundles
codex-session-toolkit sync-github --dry-run
codex-session-toolkit sync-github- 不修改对话正文内容
- 不会悄悄覆盖原始 session
- 导入覆盖前会自动备份旧 rollout
- 清理旧版重复副本只针对旧版无标记 clone
- 删除已复制的旧 Provider 会话只处理带
cloned_from关系的新旧会话对 - 删除归档会话只处理
~/.codex/archived_sessions/ - 删除归档会话时,如果同 ID active 会话仍存在,会保留 active 索引和 Desktop 线程记录
- 删除 Skill 和删除备份都需要确认
- 导入前会校验 manifest、路径和 JSONL
- GitHub 同步只处理
./codex_bundles/ - 父项目源码仓库通过
.gitignore忽略codex_bundles/ - GitHub 代理只作用于 Bundle 同步链路,不写全局 git 配置
- 建议写入型动作第一次都先 Dry-run
- Python >= 3.8
- 无第三方运行时依赖
- 支持 macOS / Windows / Linux
- GitHub 同步需要本机可用的
git
| 变量 | 作用 |
|---|---|
NO_COLOR=1 |
禁用颜色 |
CST_ASCII_UI=1 |
使用 ASCII UI |
CST_TUI_MAX_WIDTH=120 |
限制 TUI 最大宽度 |
CST_MACHINE_LABEL=My-MacBook |
指定导出时的机器标签 |
| `CST_LAUNCH_MODE=auto | source |
python3 -m ruff check src tests
python3 -m compileall -q src tests
python3 -m unittest discover -s tests -vMIT License. See LICENSE.
