Sync & Status
The everyday pair: status looks at drift without writing anything, sync applies the safe part of it.
Checking status
lintsync status shows drift from the preset without ever writing anything — the read-only sibling of sync --dry-run.
lintsync status [options]lintsync status
lintsync status --all --tag type:npm-packageUnlike sync, a conflict here is just a state of the project, not a failure of the command: status exits 0 as long as it could actually read the config and find the preset, even if there's a conflict to look at. Only a genuine execution error (bad manifest, unknown preset, unreadable file) is non-zero.
Options
--cwd <path>
Project directory. Default: the current directory.
--tool <name>
Restrict the check to one tool (eslint, prettier, or stylelint).
--all
Run across every project in the registry instead of one --cwd — see Projects & Batch Mode.
--tag <tag>
Combined with --all, restricts the batch to projects carrying this tag. Has no effect without --all.
--registry <path>
Combined with --all, use a project registry file somewhere other than the default — see Projects & Batch Mode.
--json
Machine-readable output.
--quiet
Suppress output on success.
--verbose
Also print the manifest's recorded value for each conflict, not just the local and preset values.
Applying changes
lintsync sync compares the current project against its preset and applies the safe changes.
lintsync sync [options]lintsync sync # preview: shows what would change, writes nothing without --yes
lintsync sync --yes # apply non-conflicting changes
lintsync sync --dry-run # explicit preview, never writes even with --yes
lintsync sync --tool eslint # restrict to one toolExample output — a real run with one conflict, in the default (non-quiet, non-verbose) view:
eslint (eslint.config.mjs) — preset npm-lib@0.1.0
✗ 1 conflict:
rules.no-console (local: "warn", preset: "error")
prettier (.prettierrc.json) — preset npm-lib@0.1.0
✓ up to date
Total: 2 tools, 1 conflict. Exit code: 1When run in a real terminal without --dry-run/--yes/--json, a conflict opens an interactive TUI instead of just reporting it — see Resolving a conflict below. In CI (no TTY) or with --json, a conflict is reported and left completely untouched.
A conflict on one key withholds all pending changes for that tool's file until it's resolved — nothing is written half-way. "Keep local" or a manual value from the TUI is a per-run decision, not a permanent pin: the manifest has no field for "intentionally diverges forever," so the same conflict can resurface on a later sync if the file or the preset changes again.
Options
--tool <name>
Restrict the sync to one tool.
--dry-run
Preview only — never writes, even together with --yes.
-y, --yes
Apply non-conflicting changes. Required to actually write anything; without it (and without --dry-run), sync still only previews.
--all
Run across every project in the registry — see Batch mode below.
--tag <tag>
Combined with --all, restricts the batch to projects carrying this tag.
--registry <path>
Combined with --all, use a project registry file somewhere other than the default.
--cwd <path>
Project directory. Default: the current directory.
--json
Machine-readable output.
--quiet
Suppress output on success.
--verbose
Print every changed key individually (one per line) instead of a single comma-joined summary line, and also print the manifest's recorded value for each conflict.
Batch mode
Pass --all to run sync across every project in the registry (see Projects & Batch Mode) instead of one --cwd:
lintsync sync --all # every registered project
lintsync sync --all --tag type:site # only projects tagged type:site
lintsync sync --all --yesBatch runs are always non-interactive — a conflict is reported per project, never opens the TUI.
Resolving a conflict (the TUI)
In a real terminal, without --dry-run/--yes/--json, a sync conflict opens an interactive resolver instead of failing:
- Left/Right arrow — page between conflicts, without requiring a resolution first.
- Up/Down arrow — move the cursor between the three choices: Accept preset, Keep local, Edit manually.
- Enter — commit the highlighted choice. Choosing Edit manually instead enters a text-input mode, seeded with the file's current value.
- Inside manual-edit mode: typing edits the buffer, Enter commits it (parsed as JSON when it's valid JSON, a plain string otherwise — the same rule
setuses), Escape cancels back to the option list without recording anything, Backspace deletes the last character.
A live preview line always shows what the currently-highlighted (or currently-typed) choice would actually produce. The resolver shows a three-way diff for the page's conflict — the local file's value, the manifest's last-applied value, and what the preset currently wants:
Conflict 1/2: rules.no-console
Local: "warn"
Manifest (was): "off"
Preset (would be): "error"
▸ Accept preset
Keep local
Edit manually
Preview: "error"Resolving every page's conflict applies the whole batch (both your resolutions and any already-planned non-conflicting changes for that tool) in one write — a tool you touched here ends up fully in sync, never half-applied.
Exit codes
| Code | Meaning |
|---|---|
0 | Success — no changes needed, changes applied, or (for status) just observed |
1 | Unresolved conflict (sync only) — also the exit code for an ordinary command-line usage mistake (an unknown flag, a missing required argument) on any command, not just a sync conflict |
2 | Execution error — file/preset not found, unsupported format, parse failure, an edit that can't be made safely |
3 | Batch mode only (--all): projects disagreed on their exit code |
The same table applies to sync, status, init, get, set, unset, and migrate — though in practice get/set/unset/migrate only ever return 0 or 2 (they have no notion of a "conflict" or a batch run).