codex-project-mover is a Mac-first CLI for moving a Codex Desktop project folder and updating local Codex metadata so existing conversations continue to point at the new path.
brew install sunshineo/tap/codex-project-mover
codex-project-mover --versionThe Homebrew formula currently supports Apple Silicon macOS. The tap publishes one Sonoma Apple Silicon bottle, which Homebrew can use on newer Apple Silicon macOS releases without source-building Rust.
With Rust 1.85 or newer installed:
cargo install --locked --git https://github.com/sunshineo/codex-project-mover --tag v1.1.0
codex-project-mover --versionFrom a local checkout:
git clone https://github.com/sunshineo/codex-project-mover.git
cd codex-project-mover
git checkout v1.1.0
cargo build --release --locked
./target/release/codex-project-mover --help
./target/release/codex-project-mover --versionThe first prebuilt release target is Apple Silicon macOS.
curl -LO https://github.com/sunshineo/codex-project-mover/releases/download/v1.1.0/codex-project-mover-aarch64-apple-darwin
curl -LO https://github.com/sunshineo/codex-project-mover/releases/download/v1.1.0/codex-project-mover-aarch64-apple-darwin.sha256
shasum -a 256 -c codex-project-mover-aarch64-apple-darwin.sha256
chmod +x codex-project-mover-aarch64-apple-darwin
xattr -d com.apple.quarantine ./codex-project-mover-aarch64-apple-darwin 2>/dev/null || true
./codex-project-mover-aarch64-apple-darwin --versionThis v1 binary is unsigned and unnotarized. If macOS blocks it after download, the xattr command above removes the quarantine attribute:
xattr -d com.apple.quarantine ./codex-project-mover-aarch64-apple-darwinTo install the binary somewhere on your PATH:
mkdir -p "$HOME/.local/bin"
mv codex-project-mover-aarch64-apple-darwin "$HOME/.local/bin/codex-project-mover"Make sure $HOME/.local/bin is in your shell PATH before running codex-project-mover.
codex-project-mover plan --old /old/project --new /new/project
codex-project-mover apply --old /old/project --new /new/project
codex-project-mover apply --old /old/project --new /new/project --auto-rollback
codex-project-mover apply --old /old/project --new /new/project --relink-only --auto-rollback
codex-project-mover verify --old /old/project --new /new/project
codex-project-mover rollback --backup ~/.codex/codex-project-mover-backups/<id>/manifest.json
codex-project-mover rollback --backup ~/.codex/codex-project-mover-backups/<id>
codex-project-mover --json plan --old /old/project --new /new/projectClose Codex before running commands. By default, apply, verify, and rollback exit if they see a Codex process that can plausibly read or write the same local CODEX_HOME state that this tool edits: the main Codex Desktop process, codex app-server, or a standalone codex CLI/codex exec process. They do not stop or kill those processes. plan is a read-only dry run, so it never exits on this check — it reports any detected processes at the end of its output (noting whether apply would refuse) and continues, so the dry run previews every issue a real run would hit.
The guard is intentionally focused. codex exec can persist rollout files and initialize state databases in-process, so a separate codex app-server process is not the only risky shape. Electron helpers, crashpad handlers, extension hosts, and node_modules dependency paths are ignored to avoid false positives from tools that merely contain codex in a path or command line.
If you know the detected process is unrelated to the project being moved, pass --allow-running-codex to proceed. This is an explicit user override; the tool still backs up metadata and verifies the move, but concurrent Codex writes can race with it.
Because Codex should normally be fully closed during the move, you usually can't drive this tool from inside Codex itself. Run it from a plain terminal, or have a different AI coding assistant (such as Claude Code) run it for you. Use --allow-running-codex only when you have checked the reported processes and accept the risk.
Normal apply backs up Codex metadata, copies the old folder to the new path, verifies the copy, updates supported metadata, verifies the old path is gone and new references are present, and moves the old folder to macOS Trash. Copy verification skips non-copyable runtime filesystem entries such as sockets, FIFOs, and device files. With --auto-rollback, apply restores metadata from the just-created backup if post-update metadata verification fails.
When the project folder is a Git worktree root, apply automatically repairs Git worktree metadata. Main worktrees are copied and then repaired with git worktree repair before Codex metadata changes. Linked worktrees are moved with git worktree move instead of a generic filesystem copy. Codex paths should always point at the checkout root, not at .git/worktrees/... internals.
For Git worktrees, plan also reports whether Git fsmonitor daemons are running for worktrees that would move. During normal apply, the tool stops only those source worktree daemons with git fsmonitor--daemon stop before moving or copying. It does not restart them; if core.fsmonitor=true remains configured, Git starts them again on the next relevant Git command.
Relink-only mode is for folders already moved by the user. It requires the old path to be missing and the new path to exist.
Relink-only also attempts Git worktree repair from the new path when the project has already been moved manually. If Git repair fails, the tool stops before updating Codex metadata and prints the Git command context.
Verify checks that supported old-path references are gone and supported new-path references are present.
Rollback restores Codex metadata from a backup manifest. --backup accepts either the backup directory printed by apply or the manifest.json file inside it. If the tool created the new project folder during normal apply, rollback moves that new folder to Trash. It does not restore the old folder from Trash.
Pass global --json before the subcommand to emit structured output:
codex-project-mover --json plan --old /old/project --new /new/project
codex-project-mover --json apply --old /old/project --new /new/project --auto-rollback
codex-project-mover --json verify --old /old/project --new /new/project
codex-project-mover --json rollback --backup ~/.codex/codex-project-mover-backups/<id>/manifest.jsonSuccessful JSON responses include status: "ok" and command-specific fields such as reference counts, backup paths, Git worktree details, process-guard findings, and rollback status. Runtime failures print a JSON object to stderr with status: "error", exit_code, error_kind, and message; verification failures may also include a rollback object.
Exit codes:
0: success2: invalid arguments from CLI parsing3: Codex process guard4: path validation5: backup failure6: copy, move, trash, or Git worktree operation failure7: metadata update failure8: verification failure9: rollback failure
This repository includes a Claude Code plugin at
claude-code/plugins/codex-project-mover. It provides the
/codex-project-mover:move-codex-project skill, which guides Claude Code
through plan, apply, verify, and rollback using --json.
The skill expects the codex-project-mover binary to be available on PATH:
codex-project-mover --versionTo install the plugin through Claude Code's normal /plugin flow, first add
this repository as a marketplace:
/plugin marketplace add sunshineo/codex-project-mover
/plugin install codex-project-mover@codex-project-mover
Then run the skill:
/codex-project-mover:move-codex-project
For direct local development from a checkout:
claude --plugin-dir ./claude-code/plugins/codex-project-moverUse Claude Code rather than Codex for this workflow because Codex should be closed before mutation.
cargo build --release --locked
./target/release/codex-project-mover --help
./target/release/codex-project-mover --versionIntel macOS can be added with a second release artifact after the v1 workflow is stable.
Licensed under the Apache License, Version 2.0.