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

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.

Global options

Every command takes these.

Global options
OptionDoes
--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
--jsonWrite one JSON document to stdout
--plainUse numbered line prompts, never a full-screen interface
--asciiUse ASCII symbols only
--no-colorTurn colour off (NO_COLOR does too)
--debugAlso log details to stderr, with secrets removed
--cd-file <file>Write the chosen site folder here, for shell integration
--versionPrint the version and exit
-h, --helpPrint 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.

Options of site add
OptionDoes
--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-passwordKeep 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-insecureAllow plain FTP, which sends the password in clear text
--allow-root-deletesAllow deletes when the remote root is "/" or a drive root
--legacy-algorithmsSFTP: allow older algorithms for an old server
--upload-on-saveUpload 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.

Options of site edit
OptionDoes
--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-sensitiveTreat file names as case-sensitive (--no-case-sensitive to turn off)
--cacheCache 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)
--editorEdit 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.

Options of site remove
OptionDoes
-y, --yesDo 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.

Options of server add
OptionDoes
--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-passwordKeep 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-insecureAllow plain FTP, which sends the password in clear text
--allow-root-deletesAllow deletes when the remote root is "/" or a drive root
--legacy-algorithmsSFTP: allow older algorithms for an old server
--upload-on-saveUpload 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
--remoteMake it the site's Remote server, used to synchronize
--testingMake 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.

Options of server edit
OptionDoes
--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-passwordKeep 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-insecureAllow plain FTP, which sends the password in clear text
--allow-root-deletesAllow deletes when the remote root is "/" or a drive root
--legacy-algorithmsSFTP: allow older algorithms for an old server
--upload-on-saveUpload 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-keyRemove the pinned SSH host key, after checking the new one with the host
--forget-certificateRemove the trusted TLS certificate; the next connection verifies it again
--editorEdit 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.

Options of server remove
OptionDoes
-y, --yesDo 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.

Options of server test
OptionDoes
--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.

Options of server set-testing
OptionDoes
--clearLeave 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.

Options of password set
OptionDoes
--kind <kind>password (default) or passphrase, for a private key
--stdinRead 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.

Options of password forget
OptionDoes
--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.

Options of cloak
OptionDoes
--pathTreat every argument as a path inside the local root
--patternTreat every argument as a pattern
--globalWork on the global patterns, which every site uses before its own
--listShow the cloaking settings
--enableTurn cloaking on for the site
--disableTurn cloaking off for the site, keeping its patterns
--use-globalUse the global patterns in the site, as sites do unless told otherwise
--ignore-globalStop 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.

Options of uncloak
OptionDoes
--pathTreat every argument as a path inside the local root
--patternTreat every argument as a pattern
--globalWork 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.

Options of sync
OptionDoes
--putPut newer files to the server
--getGet newer files from the server
--bothGet and put newer files
--deleteDelete files missing on the other side (never-synchronized ones stay unchecked)
-y, --yesRun without asking for confirmation
--preview <mode>Show the preview in the terminal UI (tui), your editor, plain prompts, or print it (none)
--dry-runShow the preview and transfer nothing
--allow-mass-deleteRun 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.

Options of put
OptionDoes
-y, --yesRun 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.

Options of get
OptionDoes
-y, --yesRun 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.

Options of status
OptionDoes
--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.

Options of diff
OptionDoes
--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.

Options of mark-synced
OptionDoes
--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.

Options of state reset
OptionDoes
-y, --yesRun 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:

Values of --preview
ModeShows the preview
tuiFull screen, row by row, with the results after the run. The default in a terminal.
editorAs a text file in your editor; see Editor mode.
plainAs numbered rows and typed commands; see Plain mode.
nonePrinted, 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
Keys on every screen
KeyDoes
Up Down, j kMove
Page Up Page Down, Home EndMove by a page, or to the first or last row
Tab, Shift+TabChange pane or tab, or the preview's filter
SpaceToggle a checkbox, or change a choice; in the preview, check or uncheck every row
EnterActivate the focused item or the screen's primary action
EscGo back, or cancel a question or a running task
/Filter a list as you type
Ctrl+SSave
?Every key of this screen
qQuit, from a top screen or the preview
Ctrl+CCancel the running task, or quit

While a text field has focus, typed characters go into it; Ctrl+U clears it.

Screens and their own keys
ScreenKeys
Sitesn 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 CloakingThe cloaking patterns every site uses before its own, one per line; Ctrl+S saves them, Esc asks before dropping unsaved changes
New siteSite 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 pickerThe 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 homes Synchronize, r check for changes, e site settings; Put and Get newer files from the list
Site SetupCategories 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 editorTab 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
SynchronizeDirection and the delete option; Enter scans and opens the preview
PreviewSpace 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
ProgressEsc cancels cleanly between files
ResultsFailures 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:

Plain preview commands
CommandDoes
3, 1 4, 2-6Check or uncheck rows
p, g, s, m and row numbersSet Put, Get, Skip or Synchronized
x and row numbersDelete, asking where when both copies exist
all, noneCheck or uncheck every row that can run
diff 3Show how the two copies of a row differ
list, helpShow the rows, or the commands, again
goSynchronize the checked rows, after one question
qCancel, transferring nothing

Unattended runs

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.

Installing ssv
ShellAdd
bash, zsheval "$(sync-servers shell-init bash)" in ~/.bashrc, or zsh in ~/.zshrc
fishsync-servers shell-init fish > ~/.config/fish/functions/ssv.fish
PowerShellInvoke-Expression (& sync-servers shell-init pwsh | Out-String) in your profile
cmdsync-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

What the exit code means
CodeMeaning
0Done, or nothing to do
1Error: the command could not run
2Usage error, or no site could be chosen
3Finished, with failed rows or rows still waiting for a decision
4Cancelled
5Stopped 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.