| Device | Device ID | Local vault | Personal skill roots | Schedule |
|---|---|---|---|---|
| Windows desktop | win-main |
D:\Sync2Vault |
~/.codex/skills |
every 5 minutes |
| Windows laptop | win-travel |
E:\Sync2Vault |
~/.codex/skills |
every 15 minutes |
| macOS | mac-main |
~/Sync2Vault |
~/.codex/skills, ~/.hermes/skills |
LaunchAgent installed |
Different local paths are expected. In this example, all paths represent the same Syncthing folder ID, sync2-vault.
Use $sync2 for native Codex skill invocation. /sync2 is a conversational alias interpreted by the skill.
| Request | Result |
|---|---|
$sync2 current |
Select the current Codex task, then synchronize it. |
$sync2 |
Synchronize all selected tasks and configured skill roots now. |
$sync2 status |
Show local configuration, selected tasks, sources, conflicts, and scheduler state. |
$sync2 devices |
Show reports received from every bootstrapped device. |
$sync2 skills |
Discover common personal skill roots and synchronize them. |
$sync2 doctor |
Check Node, Codex storage, vault, SQLite index, Syncthing access, and forbidden files. |
$sync2 audit <task> |
Check JSONL syntax, tool-call/output pairs, turn closure, and local index agreement. |
$sync2 repair <task> |
Back up and repair interrupted tool events and stale older turns without inventing output. |
$sync2 auto |
Install or refresh the local automatic task. |
$sync2 project current |
Register the current project as an independent Syncthing folder. |
$sync2 projects |
List project folder IDs and their real local paths. |
From the task to preserve, invoke $sync2 current. Selection propagates to the other devices. Only explicitly selected tasks are synchronized.
To select by title or ID from another task, run:
node <skill-dir>/scripts/sync2.mjs conversation select "<title-or-thread-id>"
node <skill-dir>/scripts/sync2.mjs sync
If a title matches more than one task, use the full thread ID.
Run conversation unselect <id-or-title>, then sync. Existing vault data is retained; unselect is not deletion.
Configured roots synchronize automatically. Add a nonstandard root once:
node <skill-dir>/scripts/sync2.mjs skills add --name <collection> --path "<skill-root>" --exclude .system
node <skill-dir>/scripts/sync2.mjs sync
Use stable collection names across devices. Keep incompatible agent ecosystems in separate collections such as codex and hermes; central storage does not require installing every collection into every agent.
Run this once on the originating device from the actual project root:
$sync2 project current
Accept the resulting Syncthing folder offer on other devices and choose each device's desired local checkout path. Do not independently create a second folder ID for the same project.
Run:
$sync2 doctor
$sync2 status
$sync2 devices
Healthy output has ok: true, no conversation or skill conflicts, rolloutExists: true, indexedInStateDb: true, and a device report for each expected device. Require the same current protocolRevision and scriptSha256 across the fleet, plus lastRunOk: true after automatic scheduling is restored.
For an actively running task, stable: false is expected until its final answer. Require semanticOk: true, zero persistent dangling calls, and zero stale open turns. Sync2 publishes only the independently stable prefix before the active turn; if no healthy prefix exists, it skips the task while continuing skills and projects.
conversationsPushed/Pulled: complete selected-task snapshots published or imported in this run.skillFilesPushed/Pulled: changed files copied after three-way comparison.conversationConflicts: independently continued histories that require an explicit choice.skillConflicts: files changed differently on both sides; originals remain untouched.projectSharesAdded: configured projects newly shared with paired Syncthing devices.warnings: actionable conditions; do not ignore them during deployment.conversationsSkipped: active or semantically incomplete snapshots/heads that were deliberately quarantined.conversationErrors: per-task failures contained without stopping unrelated collections.
A new device commonly reports conversationsPushed: 0 and conversationsPulled: 1 on its first sync. That is normal: it had nothing local to publish. Its next manual or scheduled sync publishes its own device head.
- Windows:
%USERPROFILE%\.codex\skills\sync2\scripts\sync2.mjs - macOS:
~/.codex/skills/sync2/scripts/sync2.mjs - Local configuration:
~/.sync2/config.json - Local three-way state and recovery copies:
~/.sync2/stateand~/.sync2/conflicts
Always pass --config <path> for alternate profiles. Never copy ~/.sync2/config.json between devices because device IDs and local paths must remain unique.
Sync2 includes selected conversation JSONL, portable thread metadata, user-defined skill files, selections, and device reports. It excludes authentication, Codex configuration, full SQLite/WAL databases, logs, caches, generated attachments, system skills, and plugin caches.
Conversation messages that reference local attachments or project files still synchronize as text, but the referenced files do not. Register the containing project separately or transfer those files through an approved storage path.
Before a repair or fleet upgrade:
node <skill-dir>/scripts/sync2.mjs maintenance on --reason "repair"
node <skill-dir>/scripts/sync2.mjs conversation audit <id>
node <skill-dir>/scripts/sync2.mjs conversation repair <id> --title "<known title>"
Disable each device scheduler and pause the Syncthing folder separately; old clients do not understand the maintenance marker. After validation, publish the updated skill with one controlled sync --force, remove maintenance with maintenance off, resume the transport, and reinstall/re-enable schedulers.
Folder-transport deployments do not invoke git-remote-https.exe during routine Sync2 runs. A git-remote-https.exe application error therefore comes from another Git operation or a damaged/misconfigured Git installation, not from conversation or skill reconciliation. Keep folder transport active while repairing Git. Follow the Git helper crash runbook in deployment.md.