Command line
The program is sync-servers. With no command in a terminal it opens the full-screen interface; every task is also a command, for scripts and for anyone who prefers typing.
- Commands
- Preview modes
- The terminal interface
- Editor mode
- Plain mode
- Unattended runs
- Shell integration
- Exit codes
- JSON output
Commands
This reference is generated from the same definitions as sync-servers --help; sync-servers <command> --help prints the part for one command. A command acts on the site of the current folder unless it is given --site; see Which site a command means.
sites: List the sitessite add: Add a site and its first server; in a terminal, connect first and pick the root from the serversite edit: Change a site, with options or as JSON in your editorsite show: Show a site and its serverssite remove: Remove a site, its saved passwords and its sync recordssite path: Print a site's local root (with shell integration, change to it)server list: List a site's serversserver add: Add a server to a site; in a terminal, connect first and pick the root from the serverserver edit: Change a server: asks again in a terminal, or takes options, or JSON in your editorserver remove: Remove a server, its saved passwords and its sync recordsserver test: Connect, sign in, check the remote root and show what the server offers; in a terminal, fix what it findsserver set-remote: Make a server the one synchronization usesserver set-testing: Make a server the Testing server, or clear the rolepassword set: Save a password or key passphrase in the OS credential storepassword forget: Remove a saved password or key passphrasecloak: Cloak files and folders so no operation touches them, in one site or every site, or list what is cloakeduncloak: Remove cloaked paths or patterns, from one site or from the global patternssync: Synchronize a site with its Remote server: preview, then transferput: Put files or folders now, with a preview only when a decision is neededget: Get files or folders now, with a preview only when a decision is neededstatus: Show what changed on each side since the last sync; transfers nothingdiff: Show how the local and remote copies of a file differmark-synced: Record files as in sync without transferring themstate reset: Forget the sync records of a site and server; the next sync starts from scratchconfig path: Show the folders sync-servers reads and writesconfig edit: Edit the whole sites.json in your editor, also when it is not validdoctor: Check Node.js, the folders, the credential store, the terminal and every siteshell-init: Print the "ssv" shell function that changes to a chosen site's folder (bash, zsh, fish, pwsh, cmd)help: Show help for a command
Global options
Every command takes these.
| Option | Does |
|---|---|
--site <name> | The site to work on, by name or id |
--server <name> | The server to work on, by name or id |
--config-dir <folder> | Use this settings folder |
--state-dir <folder> | Use this state folder |
--json | Write one JSON document to stdout |
--plain | Use numbered line prompts, never a full-screen interface |
--ascii | Use ASCII symbols only |
--no-color | Turn colour off (NO_COLOR does too) |
--debug | Also log details to stderr, with secrets removed |
--cd-file <file> | Write the chosen site folder here, for shell integration |
--version | Print the version and exit |
-h, --help | Print help and exit |
sync-servers sites
List the sites.
sync-servers sites
sync-servers sites --json
sync-servers site add
Add a site and its first server; in a terminal, connect first and pick the root from the server.
| Option | Does |
|---|---|
--name <name> | The site name, unique ignoring case |
--local-root <folder> | The local site folder, which must exist |
--server-name <name> | The name of the first server (default: its host) |
--protocol <protocol> | sftp (default), ftps, ftps-implicit, ftp or local |
--host <host> | The host name or IP address; host:port and sftp://, ftps:// and ftpes:// addresses work too |
--port <port> | The port, when not the protocol default |
--user <name> | The user name |
--auth <method> | password, key or agent (key and agent are SFTP only) |
--key-path <file> | The private key file for --auth key |
--save-password | Keep the password in the OS credential store (--no-save-password to stop) |
--remote-root <path> | The site root on the server; for local, a folder |
--web-url <url> | The web address of the site on this server |
--timeout <seconds> | Seconds to wait for the server (default 30) |
--ip-family <4|6> | Connect over IPv4 or IPv6 only |
--allow-insecure | Allow plain FTP, which sends the password in clear text |
--allow-root-deletes | Allow deletes when the remote root is "/" or a drive root |
--legacy-algorithms | SFTP: allow older algorithms for an old server |
--upload-on-save | Upload files when they are saved in the VS Code extension |
--ca-file <file> | FTPS: a PEM file of extra certificate authorities |
--tls-servername <host> | FTPS: the name to verify the certificate against |
--tls-min-version <version> | FTPS: TLSv1.2 (default) or TLSv1.3 |
--file-mode <mode> | Permissions for uploaded files, such as 644 |
--dir-mode <mode> | Permissions for created folders, such as 755 |
sync-servers site add
sync-servers site add --name "My Site" --local-root ~/sites/my-site --protocol ftps --host 203.0.113.10 --user demo-user@example.com
sync-servers site add --name "My Site" --local-root ~/sites/my-site --host sftp.example.com --user demo-user --remote-root /var/www/my-site
sync-servers site edit [<site>]
Change a site, with options or as JSON in your editor.
| Option | Does |
|---|---|
--name <name> | Rename the site |
--local-root <folder> | Move the local site folder |
--web-url <url> | The local web address, such as http://localhost:8080/ |
--case-sensitive | Treat file names as case-sensitive (--no-case-sensitive to turn off) |
--cache | Cache local scans between runs (--no-cache to turn off) |
--symlinks <policy> | Symbolic links in the local folder: skip them (skip), follow those inside the site (follow-inside-root), or follow all (follow) |
--editor | Edit the whole site as JSON in your editor |
sync-servers site edit "My Site" --name "Sample App"
sync-servers site edit --local-root ~/sites/my-site
sync-servers site edit --symlinks follow-inside-root
sync-servers site edit --editor
sync-servers site show [<site>]
Show a site and its servers.
sync-servers site show
sync-servers site show "My Site" --json
sync-servers site remove <site>
Remove a site, its saved passwords and its sync records.
| Option | Does |
|---|---|
-y, --yes | Do not ask for confirmation |
sync-servers site remove "My Site"
sync-servers site remove "My Site" --yes
sync-servers site path [<site>]
Print a site's local root (with shell integration, change to it).
sync-servers site path "My Site"
ssv site path "My Site"
sync-servers server list
List a site's servers.
sync-servers server list
sync-servers server list --site "My Site" --json
sync-servers server add
Add a server to a site; in a terminal, connect first and pick the root from the server.
| Option | Does |
|---|---|
--name <name> | The server name, unique within the site (default: the host) |
--protocol <protocol> | sftp (default), ftps, ftps-implicit, ftp or local |
--host <host> | The host name or IP address; host:port and sftp://, ftps:// and ftpes:// addresses work too |
--port <port> | The port, when not the protocol default |
--user <name> | The user name |
--auth <method> | password, key or agent (key and agent are SFTP only) |
--key-path <file> | The private key file for --auth key |
--save-password | Keep the password in the OS credential store (--no-save-password to stop) |
--remote-root <path> | The site root on the server; for local, a folder |
--web-url <url> | The web address of the site on this server |
--timeout <seconds> | Seconds to wait for the server (default 30) |
--ip-family <4|6> | Connect over IPv4 or IPv6 only |
--allow-insecure | Allow plain FTP, which sends the password in clear text |
--allow-root-deletes | Allow deletes when the remote root is "/" or a drive root |
--legacy-algorithms | SFTP: allow older algorithms for an old server |
--upload-on-save | Upload files when they are saved in the VS Code extension |
--ca-file <file> | FTPS: a PEM file of extra certificate authorities |
--tls-servername <host> | FTPS: the name to verify the certificate against |
--tls-min-version <version> | FTPS: TLSv1.2 (default) or TLSv1.3 |
--file-mode <mode> | Permissions for uploaded files, such as 644 |
--dir-mode <mode> | Permissions for created folders, such as 755 |
--remote | Make it the site's Remote server, used to synchronize |
--testing | Make it the site's Testing server |
sync-servers server add
sync-servers server add --name Production --host sftp.example.com --user demo-user --remote-root /var/www/my-site
sync-servers server add --name Staging --host ftpes://ftp.example.org --user demo-user --remote-root /public --testing
sync-servers server edit [<server>]
Change a server: asks again in a terminal, or takes options, or JSON in your editor.
| Option | Does |
|---|---|
--name <name> | The server name, unique within the site (default: the host) |
--protocol <protocol> | sftp (default), ftps, ftps-implicit, ftp or local |
--host <host> | The host name or IP address; host:port and sftp://, ftps:// and ftpes:// addresses work too |
--port <port> | The port, when not the protocol default |
--user <name> | The user name |
--auth <method> | password, key or agent (key and agent are SFTP only) |
--key-path <file> | The private key file for --auth key |
--save-password | Keep the password in the OS credential store (--no-save-password to stop) |
--remote-root <path> | The site root on the server; for local, a folder |
--web-url <url> | The web address of the site on this server |
--timeout <seconds> | Seconds to wait for the server (default 30) |
--ip-family <4|6> | Connect over IPv4 or IPv6 only |
--allow-insecure | Allow plain FTP, which sends the password in clear text |
--allow-root-deletes | Allow deletes when the remote root is "/" or a drive root |
--legacy-algorithms | SFTP: allow older algorithms for an old server |
--upload-on-save | Upload files when they are saved in the VS Code extension |
--ca-file <file> | FTPS: a PEM file of extra certificate authorities |
--tls-servername <host> | FTPS: the name to verify the certificate against |
--tls-min-version <version> | FTPS: TLSv1.2 (default) or TLSv1.3 |
--file-mode <mode> | Permissions for uploaded files, such as 644 |
--dir-mode <mode> | Permissions for created folders, such as 755 |
--forget-host-key | Remove the pinned SSH host key, after checking the new one with the host |
--forget-certificate | Remove the trusted TLS certificate; the next connection verifies it again |
--editor | Edit the whole server as JSON in your editor |
sync-servers server edit Production
sync-servers server edit Production --port 2222
sync-servers server edit Production --forget-host-key
sync-servers server edit Production --forget-certificate
sync-servers server edit --editor
sync-servers server remove <server>
Remove a server, its saved passwords and its sync records.
| Option | Does |
|---|---|
-y, --yes | Do not ask for confirmation |
sync-servers server remove Staging
sync-servers server remove Staging --site "My Site" --yes
sync-servers server test [<server>]
Connect, sign in, check the remote root and show what the server offers; in a terminal, fix what it finds.
| Option | Does |
|---|---|
--host-key <fingerprint> | Accept this SSH host key (SHA256:...) when it is not pinned yet, for scripts |
--trust-certificate <sha256> | Accept this TLS certificate (SHA-256 fingerprint) when it does not verify, for scripts |
sync-servers server test
sync-servers server test Production --site "My Site"
sync-servers server test --host-key SHA256:<fingerprint>
sync-servers server test --trust-certificate 3A:91:5C:<...>:C4
sync-servers server set-remote <server>
Make a server the one synchronization uses.
sync-servers server set-remote Production
sync-servers server set-testing [<server>]
Make a server the Testing server, or clear the role.
| Option | Does |
|---|---|
--clear | Leave the site without a Testing server |
sync-servers server set-testing Staging
sync-servers server set-testing --clear
sync-servers password set [<server>]
Save a password or key passphrase in the OS credential store.
| Option | Does |
|---|---|
--kind <kind> | password (default) or passphrase, for a private key |
--stdin | Read it from standard input instead of asking |
sync-servers password set Production
printf %s "$SECRET" | sync-servers password set Production --stdin
sync-servers password forget [<server>]
Remove a saved password or key passphrase.
| Option | Does |
|---|---|
--kind <kind> | password or passphrase; both when not given |
sync-servers password forget Production
sync-servers cloak [<path or pattern>...]
Cloak files and folders so no operation touches them, in one site or every site, or list what is cloaked.
| Option | Does |
|---|---|
--path | Treat every argument as a path inside the local root |
--pattern | Treat every argument as a pattern |
--global | Work on the global patterns, which every site uses before its own |
--list | Show the cloaking settings |
--enable | Turn cloaking on for the site |
--disable | Turn cloaking off for the site, keeping its patterns |
--use-global | Use the global patterns in the site, as sites do unless told otherwise |
--ignore-global | Stop using the global patterns in the site |
sync-servers cloak .psd "archive*" node_modules/
sync-servers cloak img/raw
sync-servers cloak --global .git/ node_modules/
sync-servers cloak --list
sync-servers uncloak <path or pattern>...
Remove cloaked paths or patterns, from one site or from the global patterns.
| Option | Does |
|---|---|
--path | Treat every argument as a path inside the local root |
--pattern | Treat every argument as a pattern |
--global | Work on the global patterns, which every site uses before its own |
sync-servers uncloak .psd
sync-servers uncloak img/raw
sync-servers uncloak --global node_modules/
sync-servers sync [<path>...]
Synchronize a site with its Remote server: preview, then transfer.
| Option | Does |
|---|---|
--put | Put newer files to the server |
--get | Get newer files from the server |
--both | Get and put newer files |
--delete | Delete files missing on the other side (never-synchronized ones stay unchecked) |
-y, --yes | Run without asking for confirmation |
--preview <mode> | Show the preview in the terminal UI (tui), your editor, plain prompts, or print it (none) |
--dry-run | Show the preview and transfer nothing |
--allow-mass-delete | Run deletes past the mass-delete limit without asking |
--plan-out <file> | Save the plan as JSON |
--plan-in <file> | Run a saved plan, if the site and server have not changed since |
--host-key <fingerprint> | Accept this SSH host key (SHA256:...) when it is not pinned yet |
--trust-certificate <sha256> | Accept this TLS certificate (SHA-256 fingerprint) when it does not verify |
sync-servers sync --put
sync-servers sync --both --delete --dry-run
sync-servers sync --put --preview editor
sync-servers sync --get css img --yes
sync-servers sync --put --plan-out plan.json
sync-servers put <path>...
Put files or folders now, with a preview only when a decision is needed.
| Option | Does |
|---|---|
-y, --yes | Run without asking for confirmation |
--preview <mode> | Show the preview in the terminal UI (tui), your editor, plain prompts, or print it (none) |
--host-key <fingerprint> | Accept this SSH host key (SHA256:...) when it is not pinned yet |
--trust-certificate <sha256> | Accept this TLS certificate (SHA-256 fingerprint) when it does not verify |
sync-servers put css/site.css
sync-servers put img --site "My Site"
sync-servers get <path>...
Get files or folders now, with a preview only when a decision is needed.
| Option | Does |
|---|---|
-y, --yes | Run without asking for confirmation |
--preview <mode> | Show the preview in the terminal UI (tui), your editor, plain prompts, or print it (none) |
--host-key <fingerprint> | Accept this SSH host key (SHA256:...) when it is not pinned yet |
--trust-certificate <sha256> | Accept this TLS certificate (SHA-256 fingerprint) when it does not verify |
sync-servers get css/site.css
sync-servers get img --site "My Site"
sync-servers status [<path>...]
Show what changed on each side since the last sync; transfers nothing.
| Option | Does |
|---|---|
--host-key <fingerprint> | Accept this SSH host key (SHA256:...) when it is not pinned yet |
--trust-certificate <sha256> | Accept this TLS certificate (SHA-256 fingerprint) when it does not verify |
sync-servers status
sync-servers status css --json
sync-servers diff <path>
Show how the local and remote copies of a file differ.
| Option | Does |
|---|---|
--host-key <fingerprint> | Accept this SSH host key (SHA256:...) when it is not pinned yet |
--trust-certificate <sha256> | Accept this TLS certificate (SHA-256 fingerprint) when it does not verify |
sync-servers diff css/site.css
sync-servers mark-synced <path>...
Record files as in sync without transferring them.
| Option | Does |
|---|---|
--host-key <fingerprint> | Accept this SSH host key (SHA256:...) when it is not pinned yet |
--trust-certificate <sha256> | Accept this TLS certificate (SHA-256 fingerprint) when it does not verify |
sync-servers mark-synced css/site.css
sync-servers mark-synced .
sync-servers state reset
Forget the sync records of a site and server; the next sync starts from scratch.
| Option | Does |
|---|---|
-y, --yes | Run without asking for confirmation |
sync-servers state reset
sync-servers state reset --site "My Site" --yes
sync-servers config path
Show the folders sync-servers reads and writes.
sync-servers config path
sync-servers config path --json
sync-servers config edit
Edit the whole sites.json in your editor, also when it is not valid.
sync-servers config edit
sync-servers doctor
Check Node.js, the folders, the credential store, the terminal and every site.
sync-servers doctor
sync-servers doctor --json
sync-servers shell-init <shell>
Print the "ssv" shell function that changes to a chosen site's folder (bash, zsh, fish, pwsh, cmd).
eval "$(sync-servers shell-init bash)"
sync-servers shell-init fish > ~/.config/fish/functions/ssv.fish
Invoke-Expression (& sync-servers shell-init pwsh | Out-String)
sync-servers help [<command>]
Show help for a command.
sync-servers help server add
Preview modes
sync, and put or get when a decision is needed, show a preview before anything moves. --preview chooses how:
| Mode | Shows the preview |
|---|---|
tui | Full screen, row by row, with the results after the run. The default in a terminal. |
editor | As a text file in your editor; see Editor mode. |
plain | As numbered rows and typed commands; see Plain mode. |
none | Printed, followed by one yes or no question in a terminal. The default without a terminal. |
Without --preview, the mode is none when nobody can answer: with --yes, --dry-run, --json, or no terminal. Otherwise it comes from SYNC_SERVERS_UI, else tui, which becomes plain with --plain, with TERM=dumb, or in a terminal that cannot be put in raw mode. --yes together with a preview mode is a usage error.
The terminal interface
Run sync-servers with no command. It opens at the site of the current folder, or at the list of sites. Everything works from the keyboard at 80 by 24, and ? on any screen lists every key of that screen. --ascii uses ASCII symbols only, and --no-color or NO_COLOR turns colour off; every symbol stands beside a word, so nothing is lost.
Every screen has the same frame. Two solid lines frame the content. While rows are hidden above or below what is shown, a dashed line marks that edge; at the first or last row it disappears. Under the bottom line, the menu lists the screen's keys as key = action, with a pipe between them, wrapping onto more rows on a narrow terminal. The last row shows messages, the progress of a running task, or the full text of the focused row.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
______________________________________________________________________________
Space = CHECK/UNCHECK ALL | c = Check/Uncheck | p = Put | g = Get
s = Skip | d = Diff | a = All | q = Quit | Enter = Synchronize
css/site.css
| Key | Does |
|---|---|
| Up Down, j k | Move |
| Page Up Page Down, Home End | Move by a page, or to the first or last row |
| Tab, Shift+Tab | Change pane or tab, or the preview's filter |
| Space | Toggle a checkbox, or change a choice; in the preview, check or uncheck every row |
| Enter | Activate the focused item or the screen's primary action |
| Esc | Go back, or cancel a question or a running task |
| / | Filter a list as you type |
| Ctrl+S | Save |
| ? | Every key of this screen |
| q | Quit, from a top screen or the preview |
| Ctrl+C | Cancel the running task, or quit |
While a text field has focus, typed characters go into it; Ctrl+U clears it.
| Screen | Keys |
|---|---|
| Sites | n new site in one form, Shift+N new site in Site Setup, e edit, Enter open, d remove (the folder and server files are not touched), c the global cloaking patterns |
| Global Cloaking | The cloaking patterns every site uses before its own, one per line; Ctrl+S saves them, Esc asks before dropping unsaved changes |
| New site | Site name, Local folder, Protocol, Host, User, Password and Save password, then Ctrl+S or the Connect button: signs in, asks about a new host key or certificate, opens the folder picker, and saves the site and its server together. A refused sign-in shows under User. Esc asks before dropping what you typed |
| Folder picker | The folders of the server, starting where the account opens, with the folder shown in the title: Enter opens a folder, Backspace goes up, s or Use this folder accepts, Esc cancels |
| Site home | s Synchronize, r check for changes, e site settings; Put and Get newer files from the list |
| Site Setup | Categories on the left: Site, Servers, Local Info, Cloaking, Synchronization, Security. In Servers: a add, Enter edit, c duplicate, Del remove, t test, r make Remote, Shift+T make Testing. In Cloaking: Use global patterns turns the global patterns on or off for the site, which lists them, and Edit global patterns... opens them |
| Server editor | Tab switches Basic and Advanced. Basic: Protocol, Host (host:port fills Port), Port, User, Root directory with Browse..., Test. Test and Browse connect with the values the form shows, without saving them; what they decide, such as a trusted certificate, is saved with the server on Ctrl+S. Advanced holds the Web URL, the host key and the trusted certificate, with Forget buttons |
| Synchronize | Direction and the delete option; Enter scans and opens the preview |
| Preview | Space check or uncheck every row (all unchecked when most are checked, else all checked), c check or uncheck the focused row, p Put, g Get, s Skip, m mark synchronized, x delete, a check all, or uncheck all when all are checked, d difference, Tab filter, Enter synchronize, q quit without transferring anything, as Ctrl+C does |
| Progress | Esc cancels cleanly between files |
| Results | Failures first; Esc done |
The terminal is restored on every way out: a normal exit, Ctrl+C, a signal, or an error.
Editor mode
--preview editor, or SYNC_SERVERS_UI=editor, writes the plan to a private temporary file and opens it in the first of SYNC_SERVERS_EDITOR, VISUAL and EDITOR, else Notepad on Windows or nano, then vi, elsewhere. An editor that returns at once, such as VS Code, needs its wait flag: SYNC_SERVERS_EDITOR="code --wait".
# sync-servers preview: My Site -> Production (SFTP)
# Put newer files to remote
# Files: 37 will be updated, 169 will be skipped, 12 need a decision
#
# Check or uncheck a box, or change the action word, then save and close to
# synchronize. Close without saving, or delete every row, to cancel.
# put get skip synced delete-remote delete-local
#
[x] put 1 img/hero.svg
[ ] resolve 3 css/site.css # Changed locally and on the server.
[ ] put 4 .env # Matches the sensitive pattern ".env".
The number identifies the row; the path is there to read and is checked against the number. A deleted row is skipped. A number the plan does not hold, a changed path, an unknown action, an action the file cannot take, or a resolve row left checked reopens the file with the problems as comments at the top. An edit can only choose among the planned rows; it can never add a path.
Plain mode
--plain, TERM=dumb, or a terminal without raw mode runs every flow as numbered prompts, with no alternate screen and no cursor movement, which screen readers and logging terminals follow. With no command it shows the sites as a numbered list and a menu for the chosen site. The preview prints numbered rows and takes commands:
| Command | Does |
|---|---|
3, 1 4, 2-6 | Check or uncheck rows |
p, g, s, m and row numbers | Set Put, Get, Skip or Synchronized |
x and row numbers | Delete, asking where when both copies exist |
all, none | Check or uncheck every row that can run |
diff 3 | Show how the two copies of a row differ |
list, help | Show the rows, or the commands, again |
go | Synchronize the checked rows, after one question |
q | Cancel, transferring nothing |
Unattended runs
- Without a terminal, nothing ever asks. A secret that cannot be found fails with
E_AUTH; an unknown SSH host key is refused unless--host-keynames it. syncwithout--yesprints the preview and transfers nothing, so a script that forgets the flag does no harm.--yesruns the checked rows. Rows that need a decision are never decided for you: they are reported, and the exit code is 3.- Deletes run only with both
--deleteand--yes, and past the mass-delete limit only with--allow-mass-deleteas well. --plan-out plan.jsonsaves the plan;--plan-in plan.jsonruns it later, after checking that a fresh scan still matches what the plan was built from.
SYNC_SERVERS_PASSWORD="$DEPLOY_PASSWORD" \
sync-servers sync --put --yes --site "My Site" --host-key SHA256:<fingerprint>
Shell integration
A program cannot change its shell's folder. sync-servers shell-init <shell> prints a small ssv function that runs sync-servers with --cd-file and then changes to the folder of the site you chose. It changes folder only to an existing local folder of a configured site.
| Shell | Add |
|---|---|
| bash, zsh | eval "$(sync-servers shell-init bash)" in ~/.bashrc, or zsh in ~/.zshrc |
| fish | sync-servers shell-init fish > ~/.config/fish/functions/ssv.fish |
| PowerShell | Invoke-Expression (& sync-servers shell-init pwsh | Out-String) in your profile |
| cmd | sync-servers shell-init cmd > "%USERPROFILE%\bin\ssv.cmd", with that folder on PATH |
Then ssv opens the sites and lands in the one you open, and ssv site path "My Site" goes straight there.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Done, or nothing to do |
| 1 | Error: the command could not run |
| 2 | Usage error, or no site could be chosen |
| 3 | Finished, with failed rows or rows still waiting for a decision |
| 4 | Cancelled |
| 5 | Stopped by a safety guard: host key mismatch, insecure protocol, empty root or mass delete |
JSON output
--json writes one JSON document to standard output and nothing else; progress and warnings go to standard error. Every document names its kind and version, so a script can tell when the shape changes:
{
"schema": "sync-servers/status@1",
"siteId": "3f2b7c1e-8a4d-4f6b-9c2e-1d5a7b9e0c31",
"local": [{ "path": "css/site.css", "state": "local-changed" }],
...
}
The kinds are sites, site, site-removed, site-path, servers, server, server-removed, server-test, cloaking, cloaking-global, sync, status, diff, mark-synced, config-paths, doctor and error. Paths are site-relative, and secrets never appear.