sftp-sync-tui
v0.1.0
Published
Low-memory terminal dual-pane SFTP file manager and project-level sync CLI
Maintainers
Readme
sftp-sync-tui
A low-memory, terminal dual-pane SFTP file manager and project-level sync CLI. It only holds an SFTP connection while a command is running and leaves no background process behind when it exits.
低内存的终端双栏 SFTP 文件管理器与项目级同步 CLI。它只在命令运行期间建立 SFTP 连接,退出后不保留后台进程。
Why another SFTP tool? Most SFTP clients are either heavyweight GUI apps (FileZilla, WinSCP) or generic CLIs (lftp, rclone).
sftp-sync-tuigives you an interactive dual-pane terminal browser with project-scoped config, Git-change upload, single-prompt conflict resolution, and zero resident processes — all in one small Node.js package with a single dependency (ssh2).为什么再做一个 SFTP 工具? 大多数 SFTP 客户端要么是重量级 GUI(FileZilla、WinSCP),要么是通用 CLI(lftp、rclone)。
sftp-sync-tui提供交互式双栏终端浏览、项目级配置、Git 变更上传、单次确认的冲突处理,以及零驻留进程——全部封装在一个仅依赖ssh2的小型 Node.js 包里。
Features / 功能
- Dual-pane terminal browser — local pane on the left, remote pane on the right; entering a directory on one side syncs the other side to the same relative path. / 双栏终端浏览——左栏本地、右栏远端;进入任一侧目录时,另一侧自动进入相同的相对目录。
- Project-level config — a single
sftp.jsonin the project root; all transfer paths are confined tolocalPath/remotePathroots. / 项目级配置——项目根目录一个sftp.json;所有传输路径限制在localPath/remotePath根目录内。 - Batch transfer —
Spaceto multi-select,Uupload /Ddownload;Arecursive upload all /Zrecursive download all; empty directories are created on the remote side. / 批量传输——Space多选,U上传 /D下载;A递归上传全部 /Z递归下载全部;空目录会在远端创建。 - Git integration —
Glists modified / staged / untracked files; select and upload withEnterorU. Git deletions never delete remote files. / Git 集成——G列出已修改 / 已暂存 / 未跟踪文件;用Enter或U上传勾选项。Git 删除项不会删除远端文件。 - Conflict handling — collects conflicts for the whole batch and asks once; rejecting overwrite skips only the conflicting files. Uploads prefer atomic server-side replacement, with a reversible backup-and-restore fallback when unsupported. / 冲突处理——汇总当前批次的冲突并只询问一次;拒绝覆盖只跳过冲突文件。上传优先使用服务器端原子替换,不支持时使用可回滚的备份替换。
- Resilient transfers — status bar shows current file, index, byte progress and percentage; a single file failure does not abort the rest;
Fretries failures,Lviews the recent transfer log. / 健壮传输——状态栏显示当前文件、序号、字节进度和百分比;单个文件失败不中断其余;F重试失败项,L查看最近传输日志。 - Low memory, no daemon — connection lives only for the command's lifetime. / 低内存、无守护进程——连接只在命令运行期间存在。
- Color-aware — terminal colors with automatic
NO_COLORfallback to plain text. / 颜色感知——终端颜色,自动NO_COLOR回退为纯文本。
Requirements / 环境要求
Node.js 24.7 or higher. / Node.js 24.7 或更高版本。
Install / 安装
From the repository (local development): / 从仓库(本地开发):
npm install
npm linkPublished package (global install): / 发布后全局安装:
npm install --global sftp-sync-tuiConfiguration / 配置
Create sftp.json in the project root: / 在项目根目录创建 sftp.json:
{
"name": "staging",
"host": "sftp.example.com",
"port": 22,
"username": "deploy",
"password": "请填写密码",
"localPath": ".",
"remotePath": "/srv/www/site"
}localPath is relative to the project root (defaults to .); remotePath is the accessible remote root. All transfer paths are confined to these two roots. / localPath 相对项目根目录,默认是 .;remotePath 是允许访问的远端根目录。所有传输路径都会限制在这两个根目录内。
Password and private-key auth are mutually exclusive. Private key path is relative to the project root: / 密码认证和私钥认证二选一。私钥路径相对项目根目录:
{
"host": "sftp.example.com",
"username": "deploy",
"privateKeyPath": ".secrets/id_ed25519",
"passphrase": "私钥口令,可选",
"remotePath": "/srv/www/site"
}Add sftp.json to your project .gitignore — never commit passwords or key passphrases. / 将 sftp.json 加入项目 .gitignore,不要提交密码或私钥口令。
Usage / 使用
Test the connection: / 测试连接:
sftp-sync-tui config testOpen the dual-pane file manager: / 打开双栏文件管理器:
sftp-sync-tui filesLaunched from the project root, the left pane shows local localPath and the right pane shows remote remotePath. / 从项目根目录启动后,左栏显示本地 localPath,右栏显示远端 remotePath。
Keybindings / 快捷键
| Key | Action / 操作 |
| --- | --- |
| Tab | Switch pane / 切换面板 |
| ↑ ↓ or j k | Move / 移动 |
| Enter | Enter directory / 进入目录 |
| Backspace | Go up / 上级目录 |
| Space | Select file/dir (multi-select) / 选择文件或目录(多选) |
| U | Upload local selection / 上传本地选择 |
| D | Download remote selection / 下载远端选择 |
| A | Recursive upload all local content / 递归上传本地全部内容 |
| Z | Recursive download all remote content / 递归下载远端全部内容 |
| G | Open Git changed/staged/untracked list / 打开 Git 已修改/已暂存/未跟踪列表 |
| R | Refresh / 刷新 |
| F | Retry failed transfers / 重试失败项 |
| L | View recent transfer log / 查看最近传输日志 |
| Q | Quit / 退出 |
Inside the Git list: Space to toggle, Enter or U to upload, Esc to return. / Git 列表内:Space 勾选,Enter 或 U 上传,Esc 返回。
Selecting a directory transfers its files recursively; uploading an empty directory creates the matching directory on the remote. On name collisions the program collects the whole batch's conflicts and asks once; rejecting overwrite skips the conflicting files. Uploads prefer atomic server-side replacement; when unsupported, a temporary backup is made and restored automatically if replacement fails. / 选择目录会递归传输其中的文件,上传空目录时会在远端创建对应目录。发现同名目标时,程序会汇总当前批次的冲突并只询问一次;拒绝覆盖将跳过冲突文件。上传优先使用服务器支持的原子替换;不支持时会临时备份旧文件,替换失败将自动恢复备份。
Development / 开发
npm test