Skip to main content

Local-first Codex state sync utility

Project description

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)

  1. Detect if Codex is running

  2. 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 version
  • prefer_local: auto-resolve conflict by taking local version
  • prefer_newer_mtime: auto-resolve conflict by taking side with newer mtime

Sync options

sync.compare controls file comparison strategy:

  • mtime (default): compare by size + mtime
  • mtime_hash_fallback: fast size + mtime path, 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 cloud
  • prefer_cloud: copy cloud version to local
  • manual_abort: mark as conflict and stop in manual_abort conflict mode

sync.session_mode controls scope of sessions sync:

  • all: sync all sessions content (default behavior)
  • last_date_only: sync only the latest date-based folder under sessions
    • supported layouts: sessions/YYYY-MM-DD/... and sessions/YYYY/MM/DD/...
    • if no date-based layout is detected, codexSync logs a warning and syncs all sessions files

Backups

  • backup.compression supports:
    • none (default): backup snapshot is stored as directory tree
    • zip: backup snapshot is stored as a single .zip file
  • restore supports both snapshot formats and auto-selects the latest by mtime if --from is 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, default 10)
  • Retention cleanup (logging.retention_days, default 7)
  • Old log storage mode (logging.archive_mode):
    • zip (default): archive rotated/old logs into .zip
    • text: 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-latest
    • macos-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-sandbox is detected, codexSync reports that Codex is still running and exits with code 3 (no auto-terminate).
  • If codex.exe is running but codex-windows-sandbox is 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.
  • --verbose works for plan, sync --dry-run, sync --apply, restore --dry-run, and restore --apply; it logs tracked processes with PID/name.
  • In verbose mode on Windows, codexSync logs only:
    • whether codex.exe is running,
    • whether codex-windows-sandbox is detected,
    • subprocesses under codex.exe (PID/name/cmd).

Termination-related exit codes for automation:

  • 3 Codex is running / sandbox detected / user rejected termination
  • 5 termination was approved but failed before timeout (fail-safe)

CLI exit codes

  • 0 success
  • 1 runtime error
  • 2 conflict detected (manual resolution required)
  • 3 Codex is running (cold sync precondition failed)
  • 4 invalid config or CLI arguments
  • 5 safe abort (fail-safe)

doctor/preflight return:

  • 0 when all checks passed or warnings only
  • 5 when at least one preflight check failed

Required operation protocol

This tool assumes a strict handoff flow between machines:

  1. Close Codex on machine A.
  2. Wait until cloud sync fully propagates machine A changes.
  3. Run codexSync on machine B.
  4. Start Codex on machine B only after sync completes.
  5. 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.ps1
    • scripts/scheduler/windows/install-task.ps1
    • scripts/scheduler/windows/remove-task.ps1
    • detailed guide: scripts/scheduler/windows/README.MD
  • macOS launchd (LaunchAgent):
    • scripts/scheduler/macos/launchd.config.sh
    • scripts/scheduler/macos/install-launchd.sh
    • scripts/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 to apply only 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:

Contributions are accepted under project contribution terms in:

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

codexsync-0.1.2.tar.gz (56.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

codexsync-0.1.2-py3-none-any.whl (47.5 kB view details)

Uploaded Python 3

File details

Details for the file codexsync-0.1.2.tar.gz.

File metadata

  • Download URL: codexsync-0.1.2.tar.gz
  • Upload date:
  • Size: 56.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.9

File hashes

Hashes for codexsync-0.1.2.tar.gz
Algorithm Hash digest
SHA256 3d368eaf0017e7cd963b7ebd68e656e6efbb19ddbc1fbec749ae1e9df5575d54
MD5 8a549d75c01959f376c1abdd305dfda3
BLAKE2b-256 10afa930742f06fc5d4146dface84e23801648bd34f2170c537c8b4fc952344c

See more details on using hashes here.

File details

Details for the file codexsync-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: codexsync-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 47.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.9

File hashes

Hashes for codexsync-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 fd131286210aa1619b48d9f0b3b5071101008d7c139d267f042a70f920d27ea8
MD5 db359de8909f49af1f021252d8f35d1c
BLAKE2b-256 bd23e5270433202f5fe52880e0bf67f8b737bb7ae10b352c96f72a1003889c85

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page