codexSync
Open-source utility for syncing local Codex state between personal machines using a cloud-synced folder.
[!IMPORTANT] Current real-world validation is Windows-to-Windows only. macOS support exists in code/CI, but end-to-end handoff on real macOS machines is not yet validated.
Why
Developers may want to continue working with Codex on another machine without losing local session state.
What this does
- Syncs local Codex state directory
- Works only after Codex process is closed
- Uses any cloud-synced folder (Dropbox, OneDrive, Syncthing, etc.)
What this does NOT do
- No integration with Codex internals
- No API usage
- No token extraction
- No network interception
- No real-time sync
- No checks for cloud client process/health
- No checks for free space in cloud/network storage
Design principles
- Simple and predictable
- Safe (no corruption)
- Offline-friendly
- Backup-first
- Windows-first
How it works (MVP)
-
Detect if Codex is running
-
If not running:
- Compare local and cloud state
- Sync newer files
- Create backup before overwrite
Conflict policy
conflict.policy supports:
manual_abort: report conflict and stop (default)prefer_cloud: auto-resolve conflict by taking cloud versionprefer_local: auto-resolve conflict by taking local versionprefer_newer_mtime: auto-resolve conflict by taking side with newer mtime
Sync options
sync.compare controls file comparison strategy:
mtime(default): compare bysize + mtimemtime_hash_fallback: fastsize + mtimepath, but when values are equal/close (within tolerance), compare file content hash (SHA-256)
sync.equal_mtime_action controls behavior when file mtimes are equal (within sync.time_tolerance_seconds) but files differ:
skip: do not copy (default)prefer_local: copy local version to cloudprefer_cloud: copy cloud version to localmanual_abort: mark as conflict and stop inmanual_abortconflict mode
sync.session_mode controls scope of sessions sync:
all: sync allsessionscontent (default behavior)last_date_only: sync only the latest date-based folder undersessions- supported layouts:
sessions/YYYY-MM-DD/...andsessions/YYYY/MM/DD/... - if no date-based layout is detected, codexSync logs a warning and syncs all
sessionsfiles
- supported layouts:
Backups
backup.compressionsupports:none(default): backup snapshot is stored as directory treezip: backup snapshot is stored as a single.zipfile
restoresupports both snapshot formats and auto-selects the latest by mtime if--fromis omitted.
Logging
- Levels:
DEBUG|INFO|WARNING|ERROR - Formats (configurable):
text|json|logfmt - Rotation/size/retention/archive rules apply equally to all formats (
text,json,logfmt) - UTF-8 for all log files
- Daily log files with machine id (
<stem>-<machine>-YYYY-MM-DD[.N].log) - Daily/time rotation + size rotation (
logging.max_file_size_mb, default10) - Retention cleanup (
logging.retention_days, default7) - Old log storage mode (
logging.archive_mode):zip(default): archive rotated/old logs into.ziptext: keep rotated logs as plain text files
Platform and CI
- Runtime support is currently Windows-first.
- macOS support is allowed in current project scope (Apple Silicon target).
- Linux runtime support is intentionally out of MVP scope for now.
- CI currently runs on:
windows-latestmacos-latest
CLI commands
Run from project root:
python -m codexsync -c config.toml <command>
Generate config.toml from bundled template:
python -m codexsync init-config
Generate to a custom location:
python -m codexsync init-config --output D:\codexSync\config.toml
Overwrite existing config file:
python -m codexsync init-config --output D:\codexSync\config.toml --force
Validation:
python -m codexsync -c config.toml validate
Preflight diagnostics (same behavior for doctor and preflight):
python -m codexsync -c config.toml doctor
python -m codexsync -c config.toml preflight
Build sync plan (no changes):
python -m codexsync -c config.toml plan
Build plan with process snapshot (--verbose):
python -m codexsync -c config.toml -v plan
Sync simulation (safe test):
python -m codexsync -c config.toml sync --dry-run
Sync simulation with process snapshot (--verbose):
python -m codexsync -c config.toml -v sync --dry-run
Real sync (writes files):
python -m codexsync -c config.toml sync --apply
Typical handoff to another machine:
python -m codexsync -c config.toml sync --apply
Restore from latest backup snapshot to local state:
python -m codexsync -c config.toml restore --apply
Restore from specific backup snapshot:
python -m codexsync -c config.toml restore --from <snapshot_dir_name> --apply
Restore from specific zip snapshot:
python -m codexsync -c config.toml restore --from <snapshot_name.zip> --apply
Restore to cloud target instead of local:
python -m codexsync -c config.toml restore --target cloud --apply
Preview restore without writing:
python -m codexsync -c config.toml restore --dry-run
List CLI help:
python -m codexsync -h
Process termination behavior:
- On Windows, if Codex is still running during
sync/restore, codexSync can terminate Codex processes before continuing. - By default, manual GUI confirmation is enabled (
process_detection.manual_terminate_confirmation = true). - Background process tracking is configured by OS in
process_detection.background_process_names:windows = ["codex-windows-sandbox"]macos = []linux = []
- Confirmation channel is configured by
process_detection.terminate_confirmation_mode = "gui" | "console"(default:gui). - All confirmation prompts are in English in both GUI and console modes.
- If
codex-windows-sandboxis detected, codexSync reports that Codex is still running and exits with code3(no auto-terminate). - If
codex.exeis running butcodex-windows-sandboxis not detected, codexSync asks whether to terminate Codex and continue. - You can force manual confirmation from CLI:
python -m codexsync -c config.toml --manual-terminate-confirmation sync --apply
- You can force auto-terminate without manual confirmation for the current run only:
python -m codexsync -c config.toml --auto-terminate-without-confirmation sync --apply
- On macOS/Linux, previous behavior is kept: running Codex process fails safety precondition.
--verboseworks forplan,sync --dry-run,sync --apply,restore --dry-run, andrestore --apply; it logs tracked processes with PID/name.- In verbose mode on Windows, codexSync logs only:
- whether
codex.exeis running, - whether
codex-windows-sandboxis detected, - subprocesses under
codex.exe(PID/name/cmd).
- whether
Termination-related exit codes for automation:
3Codex is running / sandbox detected / user rejected termination5termination was approved but failed before timeout (fail-safe)
CLI exit codes
0success1runtime error2conflict detected (manual resolution required)3Codex is running (cold sync precondition failed)4invalid config or CLI arguments5safe abort (fail-safe)
doctor/preflight return:
0when all checks passed or warnings only5when at least one preflight check failed
Required operation protocol
This tool assumes a strict handoff flow between machines:
- Close Codex on machine A.
- Wait until cloud sync fully propagates machine A changes.
- Run codexSync on machine B.
- Start Codex on machine B only after sync completes.
- Sign in to Codex again on machine B after file sync.
Important: per OpenAI licensing constraints, authentication tokens are not transferred by codexSync.
The project intentionally does not verify cloud-provider sync status, cloud client process state, or free space on cloud/network storage. These are user responsibilities.
Scheduler setup scripts
This repository includes editable scheduler setup templates:
- Windows Task Scheduler:
scripts/scheduler/windows/task.config.ps1scripts/scheduler/windows/install-task.ps1scripts/scheduler/windows/remove-task.ps1- detailed guide: scripts/scheduler/windows/README.MD
- macOS launchd (LaunchAgent):
scripts/scheduler/macos/launchd.config.shscripts/scheduler/macos/install-launchd.shscripts/scheduler/macos/uninstall-launchd.sh- detailed guide: scripts/scheduler/macos/README.MD
Windows install:
cd scripts/scheduler/windows
# 1) Edit task.config.ps1
.\install-task.ps1
Windows remove:
cd scripts/scheduler/windows
.\remove-task.ps1
macOS install:
cd scripts/scheduler/macos
# 1) Edit launchd.config.sh
chmod +x install-launchd.sh uninstall-launchd.sh run-codexsync.sh
./install-launchd.sh
macOS remove:
cd scripts/scheduler/macos
./uninstall-launchd.sh
Important:
- These scripts only register scheduled jobs, not OS services.
- Keep
MODE="dry-run"while validating behavior; switch toapplyonly when ready. - Cold sync protocol still applies: codexSync must run only when Codex is not running.
Status
MVP (ready for public repository and community testing)
Publishing
See release checklist: docs/PUBLISHING.MD Release notes: CHANGELOG.MD
Licensing
This project uses dual licensing:
- Open-source license:
GPL-3.0-or-later(see LICENSE) - Commercial licensing path: see COMMERCIAL_LICENSE.MD
Contributions are accepted under project contribution terms in:
Release files for codexsync 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| codexsync-0.1.2.tar.gz | 56.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| codexsync-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 104.5 kB
Release files / codexsync-0.1.2.tar.gz
| Download URL | codexsync-0.1.2.tar.gz |
|---|---|
| Size | 56.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3d368eaf0017e7cd963b7ebd68e656e6efbb19ddbc1fbec749ae1e9df5575d54
|
|
BLAKE2b-256 checksum How to use checksums |
10afa930742f06fc5d4146dface84e23801648bd34f2170c537c8b4fc952344c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.9
|
Release files / codexsync-0.1.2-py3-none-any.whl
| Download URL | codexsync-0.1.2-py3-none-any.whl |
|---|---|
| Size | 47.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fd131286210aa1619b48d9f0b3b5071101008d7c139d267f042a70f920d27ea8
|
|
BLAKE2b-256 checksum How to use checksums |
bd23e5270433202f5fe52880e0bf67f8b737bb7ae10b352c96f72a1003889c85
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.9
|