把 Codex Home 从隐藏目录搬出来,用 Git 管理 AI 工作流资产
我最初把 Codex 的重要目录打成 zip,上传到云盘,方便电脑损坏或换设备时恢复。规则和 Skill 改得多了以后,压缩包开始不够用:
- 每次备份都是一个新的压缩包,不容易看差异。
- 只知道「备份了」,但不知道具体变了什么。
- 想回到某个历史版本,需要先下载、解压、人工比较。
- 想在多台设备之间同步,也不够自然。
我需要比较每次改动、找回旧规则,也想在多台设备间同步,于是改用 Git。我把适合同步的文件放进独立仓库,再用链接挂回 Codex 默认读取的位置。
先分清资产和运行态
Codex 的本地状态通常在 ~/.codex 下面。这个目录有点像一个 AI 工具的用户主目录:里面既有真正值得保存的长期资产,也有大量只属于当前机器、当前登录态和当前进程的运行状态。
我现在只把可读、可审查、可迁移的工作流资产放进仓库:
codex-home/
AGENTS.md
global/AGENTS.md
agents_references/
rules/
skills/
tools/
env/global/AGENTS.md 是 Codex 全局运行规则,比如希望 Codex 用什么语气、怎么协作、遇到某类任务先看什么引用。
agents_references/ 放全局规则引用的细节文档。全局入口只保留触发条件和路径,长规则拆到这里,能减少每次会话一上来就读进大量细节。
rules/ 是更细的命令或执行规则,适合长期稳定、跨任务复用的边界。
skills/ 保存可复用流程,比如文档整理、排障和工具操作。下次遇到类似任务时,Codex 可以加载对应 Skill,不必重新整理一遍操作规范。
tools/ 放可复用的小工具、脚本或 MCP server 源码。这里保存源码、README、lockfile 和必要配置,不保存依赖安装目录和运行缓存。
env/ 只适合私有仓库。它可以保存内部工具需要的环境变量文件,但不适合作为公开模板直接分发。如果仓库会公开,应该改成 .env.example 或文档说明,真实 env 留在本机。
这些内容的共同点是:它们能被人读懂,也能通过 Git 看到演进历史。
不该提交的是运行态:
auth.json
config.toml
sessions/
archived_sessions/
browser-profiles/
cache/
plugins/cache/
tmp/
.tmp/
*.sqlite
*.sqlite-shm
*.sqlite-wal
logs/
worktrees/
generated_images/
shell_snapshots/
node_modules/
.venv/
__pycache__/auth.json、browser-profiles/ 可能包含登录态或凭证,不能进 Git。sessions/ 和 archived_sessions/ 体积会越来越大,也可能包含大量上下文和内部信息。*.sqlite、cache/、.tmp/、logs/ 都强依赖当前机器和当前版本,同步到另一台设备上价值不大,风险不少。
我按用途划分:规则、Skill 和工具源码需要同步,登录态、会话数据库和缓存留在各自机器上。

为什么不再把整个 ~/.codex 变成仓库
最直接的想法是:
cd ~/.codex
git init然后配一个白名单 .gitignore,默认忽略所有内容,只放行明确要同步的文件。这个方案能工作,但长期维护会有两个问题。
第一个问题是日常查找。我经常要在编辑器里看 Skill、检查规则是否过期,把它们放进平时使用的代码目录后,这些操作会顺手很多。
第二个问题更实际:Codex 会持续向 ~/.codex 写入登录态、数据库、会话和缓存。即使 .gitignore 很严格,维护规则时仍然要不断分辨哪些目录能动、哪些文件只是程序正在使用的状态。
早期我也试过另一种更粗的做法:把 ~/.codex 整个迁到 ~/code/codex-home,再让 ~/.codex 指向它:

这比直接在隐藏目录里维护舒服,但它仍然把运行态和可迁移资产放在同一个真实目录里。维护一段时间后,更清楚的做法是保留 ~/.codex 作为运行目录,只把需要长期维护的文件和目录软链出去。
现在的结构:运行态留在 ~/.codex
现在推荐的是细粒度软链。
真实仓库放在日常代码目录:
~/code/codex-home/Codex 继续使用默认运行目录:
~/.codex/两边通过少数软链接连起来:

这样,Codex 仍然从熟悉的位置读取规则、Skill 和工具;人维护的是一个普通 Git 仓库。登录态、会话、sqlite、浏览器 profile、插件缓存和临时目录继续留在 ~/.codex,不跟着仓库漂移。
skills/ 有一个小例外,值得单独说一下。Codex 可能会在 ~/.codex/skills/.system/ 下放系统生成的 Skill,这些内容不是我手写的工作流资产,也不应该提交到自己的仓库。
如果只把自己写的 Skill 一个个链接进去,通常碰不到它;如果为了省心,把整个 skills/ 目录链接到仓库里,.system/ 就可能出现在仓库工作区里。这个时候不需要把整个方案推倒,只要在仓库 .gitignore 里忽略:
skills/.system/这里需要隔离的是系统生成内容。它和人工维护内容刚好落在同一个目录层级;把 .system/ 当成运行态处理,仍然可以保留整个 skills/ 目录链接的便利。
AGENTS.md 要拆成两层
把 Codex 资产放进一个仓库后,会遇到一个容易忽略的歧义:仓库根目录也可以有 AGENTS.md,而 Codex 自己的 home 目录也有 AGENTS.md。
如果同一个 AGENTS.md 既写仓库迁移方法,又写跨项目协作规则,链接到 Codex home 后,其他项目也会读到与它们无关的迁移说明。我把这两种用途拆开:
codex-home/
AGENTS.md # 只描述这个仓库怎么维护、怎么迁移
global/AGENTS.md # Codex 全局运行规则然后让 Codex home 里的入口指向全局规则:

这样,根 AGENTS.md 只回答仓库问题:这个仓库保存什么、不保存什么、新机器怎么链接、提交前怎么检查。global/AGENTS.md 只回答 Codex 行为问题:默认语言、协作方式、遇到 Figma 或浏览器任务时读什么 Skill。
global/AGENTS.md 里引用细节文档时,路径也应该写成 Codex home 视角:
${CODEX_HOME:-$HOME/.codex}/agents_references/browser-channel.md不要写成简单的 agents_references/browser-channel.md。全局规则会在很多项目里生效,引用路径必须能从 Codex home 找到,而不是依赖当前工作目录刚好是 codex-home。
当前机器怎么迁移
如果一台机器已经在使用 Codex,迁移时不要一上来就动登录态和 session。更稳的顺序是:
- 在日常代码目录里创建或 clone 私有仓库。
- 把长期资产整理进仓库。
- 备份
~/.codex里同名文件或目录。 - 用软链接把仓库里的资产挂回
~/.codex。 - 启动 Codex,确认规则和 Skill 能正常读取。
- 最后再提交和推送仓库。
准备仓库目录这一步仍然可以手动做:
mkdir -p ~/code/codex-home/global
cd ~/code/codex-home
git init
git branch -M main再把已有资产放进仓库。不同机器的情况不一样,下面只表达路径关系,真正执行前先看清自己本机是否已有对应目录:
cp ~/.codex/AGENTS.md ~/code/codex-home/global/AGENTS.md
cp -R ~/.codex/rules ~/code/codex-home/rules
cp -R ~/.codex/skills ~/code/codex-home/skills如果已经有 agents_references/、tools/ 或私有 env/,也可以按同样方式放进仓库。没有就先不创建空目录。
真正把仓库挂回 Codex home 时,现在更推荐走一个跨平台入口:
node tools/setup-codex-home.mjs --repo "$HOME/code/codex-home" --dry-run
node tools/setup-codex-home.mjs --repo "$HOME/code/codex-home"Windows PowerShell 里仍然是同一个脚本,只是路径写法不同:
node .\tools\setup-codex-home.mjs --repo "$HOME\Desktop\code\codex-home" --dry-run
node .\tools\setup-codex-home.mjs --repo "$HOME\Desktop\code\codex-home"--dry-run 只打印计划,不改文件。确认它会备份哪些旧路径、创建哪些链接以后,再跑真实命令。
这个脚本内部做几件事:
- 已经是正确链接时直接跳过。
- 已有普通文件或错误链接时,先备份成
.local-backup.<timestamp>。 - 缺失的可选目录会跳过,不为了凑结构创建空目录。
AGENTS.md、agents_references、rules、skills、env、tools都按同一份映射关系处理。skills/.system/继续按本机运行态处理,只保留在工作区并被.gitignore忽略。
迁移成功后做几个检查:
test -f ~/.codex/skills/skill-creator/SKILL.md
git -C ~/code/codex-home ls-files | rg '(^|/)(auth|sessions|browser-profiles|cache|tmp|logs|worktrees|generated_images|.*\.sqlite)'第一条用来确认 Skill 可读。第二条用来确认 Git 没有跟踪运行态或敏感文件;正常情况下应该没有输出。链接本身是否正确,脚本最后也会打印 verify 结果。
平台差异收进脚本里
命令入口保持一致,链接类型在脚本内部按平台选择。
macOS 和 Linux 上,文件、目录都可以走普通 symlink。Windows 上要更细一点:目录优先用 junction;文件优先用 symbolic link,如果当前权限不允许创建文件符号链接,再退到同盘 hard link。
原生 Windows 路线现在是可以成立的。Codex 官方文档里,Windows 桌面应用和 CLI 可以在 PowerShell 里配合 Windows sandbox 使用;不需要为了 Codex 本身强行套一层虚拟机。真正要考虑的是链接类型、权限和本机文件系统。
Git Bash 适合日常跑很多类 Unix 命令,但它没有改变底层文件系统。把 macOS 那段 ln -s 原样交给 Git Bash,最后生成什么仍然会受到 Windows 权限、MSYS/Git 配置和目标类型影响。迁移这种长期动作,交给 Node 脚本显式分支更稳。
Windows 上可以这样检查:
Get-Item "$HOME\.codex\AGENTS.md" | Format-List FullName,LinkType,Target
Test-Path "$HOME\.codex\skills\skill-creator\SKILL.md"
git -C $Repo ls-files | rg 'auth|session|sqlite|browser-profiles|cache|tmp|logs|worktrees|generated_images|node_modules|\.venv'如果 AGENTS.md 最后是 hard link,LinkType 不一定像 symbolic link 那样直观;这时重点看两边内容是否同步、Git 是否只跟踪仓库里的那份文件。
那 WSL 合适吗
WSL2 更像一条 Linux 运行路线,适合工具链本来就在 Linux 的工作流。
如果你的项目、本地工具链、包管理器、测试脚本本来就更偏 Linux,或者原生 Windows sandbox 在当前公司设备策略下跑不顺,Codex 的 WSL 文档 也建议选择 WSL2。这个时候就不要把仓库放在 /mnt/c/... 里来回跨文件系统访问,直接放在 WSL 的 home 目录,比如:
mkdir -p ~/code
git clone <private-repo-url> ~/code/codex-homeWSL 里也有自己的 ~/.codex。如果 Windows 原生 Codex 和 WSL 里的 Codex 都要用同一套资产,我会让两边各自 clone 同一个私有仓库,再用 Git 同步,而不是让 Windows 的 ~/.codex 和 WSL 的 ~/.codex 互相指。这样边界更清楚:Windows 运行态留在 Windows,WSL 运行态留在 Linux,真正共享的是 Git 里的工作流资产。
在另一台机器 fork 或 clone
换设备时,只需要 clone 私有仓库并重新建立链接,不用搬旧机器的整个 ~/.codex。
新机器上先让 Codex 自己创建默认目录,或者手动准备空目录:
mkdir -p ~/.codex然后 clone 私有仓库:
git clone <private-repo-url> ~/code/codex-home再运行跨平台脚本:
cd ~/code/codex-home
node tools/setup-codex-home.mjs --repo "$PWD" --dry-run
node tools/setup-codex-home.mjs --repo "$PWD"如果新机器已有自己写过的 Skill 或规则,不要直接删备份目录。先把确实要保留的内容合并进 ~/code/codex-home,再删除 .local-backup.<timestamp>。
链接完成后,再执行登录或打开桌面应用:
codex login登录态和其他运行状态由新机器上的 Codex 初始化。仓库同步的是规则和工具,不会让新机器继承旧机器的登录状态。
为什么主入口改成 Node
Shell 示例很适合解释路径关系,但这套流程要长期在 macOS、Windows 和 WSL 之间复用,主入口就不应该绑定某个 shell。
这个脚本我选了 Node。fsPromises.symlink(target, path, type) 支持 Windows 上的 file、dir、junction 类型;按官方文档,junction 只能指向目录,目标路径会被规范成绝对路径。目录链接的 Windows 分支可以这样写:
import { symlink } from 'node:fs/promises';
const type = process.platform === 'win32' ? 'junction' : undefined;
await symlink(targetDir, linkPath, type);Python 的 pathlib、os.symlink、os.link 能处理路径和部分链接操作;Windows junction 则需要额外调用 Windows 命令、PowerShell 或 Win32 API。Node 提供的 type: "junction" 正好覆盖这一步,脚本可以在同一套文件 API 里完成平台分支。
无论用哪种语言,脚本都应该按「可重复执行」设计:正确链接不动,错误链接先备份,缺失目录跳过或创建明确需要的父目录,任何凭证、session、sqlite、缓存都不搬。
这个选型本身也值得单独写一篇。更完整的判断,我放到了把 Codex Home 迁移做成跨平台 Node 脚本。
迁移后要扫掉旧机器绝对路径
还有一类问题和链接无关,但迁移到多设备后很容易暴露:Skill、规则或工具脚本里写死了旧机器路径。
我会在迁移后扫一遍:
rg -n '/Users/|/home/|C:\\Users\\' AGENTS.md global agents_references rules skills tools env扫出来不代表一定要改。比如某篇文档里为了举例写了 /Users/alice/...,可以保留。但如果是全局规则、Skill 触发说明或工具脚本里的真实工作路径,就应该尽量换成环境变量或相对稳定的入口:
${CODEX_HOME:-$HOME/.codex}
${CODE_DIR:-$HOME/Desktop/code}
${SUGO_WEB_REPO}
${FRONTEND_AI_KNOWLEDGE_REPO}这样仓库迁到 Windows、macOS 或 WSL 时,真正需要改的是本机 env,而不是到处翻 Skill 和脚本。
私有仓库也要检查边界
远端仓库是私有的,不代表可以把所有东西都推上去。私有仓库降低了公开泄露风险,但不能消除误提交凭证、登录态和大体积运行缓存的风险。
我会把仓库分成三类:
- 可以提交:
global/AGENTS.md、agents_references/、rules/、skills/、可复用工具源码、README、lockfile。 - 私有仓库才可以提交:内部工具 env、只给自己使用的私有 Skill、带个人工作流偏好的全局规则。
- 不要提交:
auth.json、config.toml、session、浏览器 profile、sqlite、日志、缓存、插件缓存、依赖安装目录、构建产物。
提交前至少做两件事:
git status --short
git ls-files | rg 'auth|session|sqlite|browser-profiles|cache|tmp|logs|worktrees|generated_images|node_modules|\.venv'第一条看本次提交会包含什么,第二条看 Git 已经跟踪了什么。第二条只要有可疑输出,就先停下来检查。
日常维护
迁移完成后,我直接在 codex-home 里改规则、Skill 和工具,用 Git 看差异、提交和同步。Codex 仍从 ~/.codex 读取链接,登录态和缓存继续由它自己管理。
换机器时复用同一个仓库和链接脚本;遇到规则改坏,也能从提交历史找回旧版本。这个分工比反复打包整个 home 目录更适合日常维护。