Command: sync
Relevant source files
The following files were used as context for generating this wiki page:
The sync command is the primary and only entry point for writing or updating the cxs SQLite index. It scans local Codex session logs (JSONL format) according to a provided "selector" and reconciles the index state with the current source file metadata. In the context of the cxs architecture, sync maintains the integrity of the retrieval engine by ensuring that indexed data accurately reflects the underlying filesystem truth.
As a manual-sync tool, cxs does not employ background daemons or real-time watchers. Users or agents are expected to check coverage using the status command and trigger a sync only when the requested coverage is missing or stale.
Sources: README.md:1-20, AGENTS.md:10-25, skill-packages/cxs/references/cli-surface.md:1-10
Core Logic and Architecture
The sync process follows a strict lifecycle to ensure data consistency, particularly when multiple processes might attempt to update the index simultaneously.
1. Synchronization Locking
To prevent database corruption or race conditions, sync uses a file-based locking mechanism. Before any database or filesystem scanning occurs, the command attempts to acquire a lock using withSyncLock. This mechanism waits for existing writers to finish or cleans up stale locks from dead process IDs (PIDs).
Sources: src/indexer.ts:40-45, src/sync-lock.ts
2. Snapshotting and Change Detection
The indexer performs a "Source Snapshot" of the files targeted by the selector. This snapshot generates a fingerprint based on file paths, modification times (mtime), and file sizes. This fingerprint is later used to determine if the index is "fresh" or "stale."
Sources: src/indexer.ts:46-55, src/status.test.ts:50-70
3. Concurrent Processing
cxs utilizes a worker loop pattern with a concurrency limit (defaulting to 16) to parse Codex session files. This prevents EMFILE errors while maximizing I/O throughput. Files are only parsed if their metadata (size or mtime) differs from the existing index records.
Sources: src/indexer.ts:115-140
Sync Process Flow
The following diagram illustrates the high-level logic of the syncSessions function:
Execution Modes
sync operates in two distinct modes regarding error handling and coverage guarantees.
Strict Mode (Default)
In strict mode, the command ensures that the index slice perfectly matches the source snapshot.
- If any file fails to parse, the entire transaction is aborted (by default), and no coverage record is written.
- It reconciles deleted files: if a source JSONL no longer exists, its corresponding rows are removed from the index.
- Successful execution results in a
completecoverage record for the selector.
Best-Effort Mode
Triggered via the --best-effort flag, this mode prioritizes indexing whatever is possible.
- Parsing errors are recorded but do not stop the process for other files.
- Successful sessions are committed to the index.
- Critical Limitation: Best-effort sync does not write a complete coverage record, as the index state is known to be incomplete or inconsistent with the source.
Sources: README.md:110-125, src/indexer.ts:85-110, skill-packages/cxs/references/cli-surface.md:65-75
Selectors
A selector is a mandatory JSON object that defines the scope of the sync operation.
| Selector Kind | Fields | Description |
|---|---|---|
all | root | Indexes all sessions under the root directory. |
cwd | root, cwd | Filters sessions by a specific project directory. |
date_range | root, fromDate, toDate | Filters sessions by a temporal window. |
cwd_date_range | root, cwd, fromDate, toDate | Combines project and date filtering. |
Sources: README.md:95-108, src/types.ts, skill-packages/cxs/references/cli-surface.md:40-50
Command Options
The CLI surface for sync is defined in src/cli.ts.
| Option | Type | Description |
|---|---|---|
--selector | JSON | Required. The structured scope of the sync. |
--db | Path | Custom path to the SQLite index file. |
--best-effort | Boolean | Continue on per-file errors; skips coverage writing. |
--json | Flag | Outputs a machine-readable SyncSummary. |
Sources: src/cli.ts:60-100, skill-packages/cxs/references/cli-surface.md:60-70
Data Structures: SyncSummary
When a sync completes, it returns a SyncSummary object providing a detailed audit of the operation.
{
scanned: number; // Total files found by the selector
added: number; // New sessions indexed
updated: number; // Existing sessions updated (due to changed source)
skipped: number; // Files matching the index (no work needed)
removed: number; // Sessions removed because source was deleted
errors: number; // Count of failed file operations
errorDetails: Array<{ // Detailed per-file diagnostics
filePath: string;
message: string;
}>;
coverage: { // Status of the coverage record
written: boolean;
selector: Selector;
reason?: string; // Reason if written is false (e.g., "best_effort")
};
}
Sources: skill-packages/cxs/references/json-schema.md:65-90, src/types.ts
Implementation Details
Database Reconciliation
During a strict sync transaction, cxs calls deleteSessionsForSelectorExceptFilePaths. This ensures that any session previously indexed under the current selector, but no longer present in the source directory, is purged from the database. This maintains a 1:1 mapping between the index and the source sessions for that specific scope.
Sources: src/indexer.ts:180-200, src/indexer.test.ts:98-120
Legacy Migration
The CLI includes a silent migration step. Before executing any sync command, migrateLegacyCacheDirIfNeeded() is called to move data from the legacy ~/.cache/cxs/ directory to the modern $XDG_STATE_HOME or ~/.local/state/cxs/ location.
Sources: src/cli.ts:12-16, README.md:130-135
Conclusion
The sync command is the engine's consistency guard. By requiring explicit selectors and utilizing fingerprint-based change detection, it avoids the overhead of a continuous daemon while providing high-performance, concurrent indexing of local session logs. Its strict reconciliation logic ensures that "complete" coverage truly represents the state of the local Codex sessions.