Skip to content

benkleyner/dev-sync

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dev-sync

CI Release License: MIT

dev-sync keeps local development directories mirrored to remote SFTP destinations. It is built for the common workflow where you edit locally, run a background daemon, and need a remote machine to stay current without manually copying files after every change.

Sync is one-way only: local to remote. Multiple sync pairs run concurrently in a single process.

Features

  • Interactive onboarding (dev-sync init) — prompts for connection details and verifies the remote directory exists before saving
  • Verifies SFTP host keys using ~/.ssh/known_hosts; init can prompt to trust an unknown host
  • Multiple sync pairs run concurrently from one daemon
  • Initial sync on startup, then real-time updates via filesystem events
  • Debounced reconciliation — editor save-storms collapse into one accurate log line per change
  • Finite retry with exponential backoff for transient pair failures
  • Respects .gitignore; skips .git/ directories
  • Structured JSON logging to a file; dev-sync logs for a pretty, recent view
  • Background daemon with proper start/stop/status lifecycle

Install

brew install --cask benkleyner/tap/dev-sync

Release tags publish darwin/linux binaries and update the Homebrew tap via GoReleaser.

Quick start

Configure a local project and remote SFTP directory once:

dev-sync init

Then run the sync daemon in the background:

dev-sync start
dev-sync status
dev-sync logs

Add more sync pairs by running dev-sync init again. Stop the daemon with:

dev-sync stop

Development

Requires Go 1.25 or newer.

go build -o dev-sync .
go test ./...
go vet ./...

Or run without building: go run . <command>.

Commands

Command What it does
init Interactive setup for a new sync pair. Verifies SFTP creds and remote dir.
list Show configured sync pairs.
run Run all pairs in the foreground (logs to terminal, Ctrl-C to stop).
start Launch the daemon in the background.
stop Stop the running daemon.
status Report whether the daemon is running.
logs [n] Print the last n log entries (default 50).
scan <dir> List every file under <dir>, respecting .gitignore. Debug helper.
mirror <src> <user@host:dir> One-off SFTP mirror without using config. Requires DEV_SYNC_PASSWORD env var.
version Print the version.

run and start execute the same syncing logic. run is for interactive development (logs in your terminal); start is for set-and-forget background operation.

Reliability

Each daemon-managed sync pair retries transient connection, initial sync, or watch-loop failures up to 10 times with exponential backoff capped at 60 seconds. Host key verification remains strict: unknown, changed, or revoked host keys fail closed and count against the retry limit.

Host key verification

dev-sync uses the standard OpenSSH ~/.ssh/known_hosts file. During dev-sync init, an unknown SFTP host key is shown with its key type and SHA256 fingerprint, and you can choose whether to add it to known_hosts. Runtime commands (run, start, and mirror) do not prompt; unknown, changed, or revoked host keys fail closed.

Configuration

Config, pidfile, and log file live under your platform's user config directory:

  • macOS: ~/Library/Application Support/dev-sync/
  • Linux: ~/.config/dev-sync/

Contents:

  • config.json — sync pairs and keychain password references (created by init)
  • daemon.pid — written on start, removed on stop
  • daemon.log — JSON-lines log written by the background daemon

The config file is created with 0600 permissions; the directory with 0700.

SFTP passwords are stored in the OS keychain via go-keyring, and legacy plaintext passwords are migrated the next time init, list, run, or start loads the config.

Contributing

Issues and pull requests are welcome. See CONTRIBUTING.md for local setup and contribution guidance. Please report security-sensitive issues through the process in SECURITY.md.

Known limitations

  • One-way sync only. Remote-side changes are not detected and may be overwritten on the next local change.
  • No nested .gitignore support. Only the root .gitignore is consulted.
  • Background daemon control is Unix-only. start/stop/status are disabled on Windows.

About

A small CLI that watches local directories and syncs changes to remote SFTP destinations

Topics

Resources

License

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages