veeso/termscp
π₯ A feature rich terminal UI file transfer and explorer with support for SCP/SFTP/FTP/S3/SMB
Healthy across all four use cases
weakest axisPermissive license, no critical CVEs, actively maintained β safe to depend on.
Has a license, tests, and CI β clean foundation to fork and modify.
Documented and popular β useful reference codebase to read through.
No critical CVEs, sane security posture β runnable as-is.
- βLast commit 3w ago
- β2 active contributors
- βMIT licensed
Show all 7 evidence items βShow less
- βCI configured
- βTests present
- β Small team β 2 contributors active in recent commits
- β Single-maintainer risk β top contributor 99% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README β live-updates from the latest cached analysis.
[](https://repopilot.app/r/veeso/termscp)Paste at the top of your README.md β renders inline like a shields.io badge.
βΈPreview social card (1200Γ630)
This card auto-renders when someone shares https://repopilot.app/r/veeso/termscp on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: veeso/termscp
Generated by RepoPilot Β· 2026-05-09 Β· Source
π€Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale β STOP and ask the user to regenerate it before proceeding. - Treat the AI Β· unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/veeso/termscp shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything β but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
π―Verdict
GO β Healthy across all four use cases
- Last commit 3w ago
- 2 active contributors
- MIT licensed
- CI configured
- Tests present
- β Small team β 2 contributors active in recent commits
- β Single-maintainer risk β top contributor 99% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
β Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live veeso/termscp
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale β regenerate it at
repopilot.app/r/veeso/termscp.
What it runs against: a local clone of veeso/termscp β the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in veeso/termscp | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit β€ 49 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of veeso/termscp. If you don't
# have one yet, run these first:
#
# git clone https://github.com/veeso/termscp.git
# cd termscp
#
# Then paste this script. Every check is read-only β no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of veeso/termscp and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "veeso/termscp(\\.git)?\\b" \\
&& ok "origin remote is veeso/termscp" \\
|| miss "origin remote is not veeso/termscp (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift β was MIT at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "src/main.rs" \\
&& ok "src/main.rs" \\
|| miss "missing critical file: src/main.rs"
test -f "Cargo.toml" \\
&& ok "Cargo.toml" \\
|| miss "missing critical file: Cargo.toml"
test -f "build.rs" \\
&& ok "build.rs" \\
|| miss "missing critical file: build.rs"
test -f "src/ui/mod.rs" \\
&& ok "src/ui/mod.rs" \\
|| miss "missing critical file: src/ui/mod.rs"
test -f "src/fs/mod.rs" \\
&& ok "src/fs/mod.rs" \\
|| miss "missing critical file: src/fs/mod.rs"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 49 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~19d)"
else
miss "last commit was $days_since_last days ago β artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) β safe to trust"
else
echo "artifact has $fail stale claim(s) β regenerate at https://repopilot.app/r/veeso/termscp"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
β‘TL;DR
termscp is a Rust-based terminal UI file transfer and explorer supporting SCP/SFTP/FTP/S3/SMB/WebDAV/Kube protocols. It provides a feature-rich TUI (terminal user interface) for browsing, uploading, and downloading files across multiple remote storage backends without leaving the terminal. Monolithic Rust binary (src/ contains all logic). Architecture centers on remotefs trait abstraction for pluggable backends (ssh, s3, webdav, kube, smb), with TUI layer using crossterm/tui-rs, configuration stored in ~/.config/termscp/, and keyring integration for credential storage.
π₯Who it's for
DevOps engineers, system administrators, and developers who need a lightweight, keyboard-driven alternative to GUI SFTP clients or cloud explorers; users working over SSH sessions where graphical tools are unavailable or impractical.
π±Maturity & risk
Production-ready and actively maintained. Version 1.0.0 released April 2026, with comprehensive CI/CD across Linux/macOS/Windows in .github/workflows/, consistent commit history visible in repo activity, and multi-language documentation. Single maintainer (@veeso) with regular updates.
Single-maintainer project carrying sustainability risk. Large dependency surface (remotefs-*, keyring, notify-rust, etc.) with potential security surface area; vendored features available for some SMB/TLS deps. Minimal risk for active development, but upstream library changes (especially remotefs ecosystem) could require adaptation.
Active areas of work
Version 1.0.0 is current stable release. CI workflows (linux.yml, macos.yml, windows.yml) actively validate builds; build-artifacts.yml and install.yml suggest active release/packaging pipeline. Codeberg mirror sync workflow indicates distributed presence.
πGet running
git clone https://github.com/veeso/termscp.git
cd termscp
cargo build --release
cargo run --release
Minimum Rust 1.89.0 required (per rust-version in Cargo.toml).
Daily commands:
cargo run --release
No separate dev server; single binary. Can also install via package managers or cargo install termscp.
πΊοΈMap of the codebase
src/main.rsβ Entry point for the terminal UI application; establishes the main event loop and component initialization.Cargo.tomlβ Defines all dependencies (tui-realm, ssh2, rusoto for S3, SMB support) and build metadata; critical for understanding feature compilation.build.rsβ Build-time script that handles platform-specific compilation and version embedding; essential for cross-platform builds.src/ui/mod.rsβ Core UI module orchestrating the terminal interface abstraction across all file transfer protocols.src/fs/mod.rsβ Filesystem abstraction layer supporting multiple backends (SCP, SFTP, FTP, S3, SMB); critical for protocol-agnostic file operations.docs/developer.mdβ Developers' guide explaining architecture, contribution workflow, and internal design decisions.CONTRIBUTING.mdβ Contribution guidelines including code style, testing expectations, and PR review process.
π οΈHow to make changes
Add Support for a New File Transfer Protocol
- Create a new protocol module under src/fs/ (e.g., src/fs/myprotocol/mod.rs) implementing the RemoteFs trait (
src/fs/mod.rs) - Implement the trait methods for connection, file listing, upload, download, and delete operations (
src/fs/myprotocol/mod.rs) - Register the new protocol in the protocol factory/dispatcher in src/app or src/fs/mod.rs (
src/fs/mod.rs) - Add protocol-specific UI authentication view in src/ui/views/ for credential input (
src/ui/views/mod.rs) - Update Cargo.toml with new protocol dependencies and add conditional feature flag (
Cargo.toml)
Add a New UI View or Dialog
- Create a new view file in src/ui/views/myview.rs with a struct implementing the View trait from tui-realm (
src/ui/views/myview.rs) - Register the view in src/ui/mod.rs or the view index/dispatcher (
src/ui/mod.rs) - Add event handlers and input processing for view-specific interactions (
src/ui/views/myview.rs) - Integrate view mounting/unmounting into the application state machine in src/app/ (
src/app/state.rs)
Add a New Configuration Option
- Define the new configuration field in the config data structure (src/system/config/mod.rs) (
src/system/config/mod.rs) - Add serialization/deserialization logic for the config file (typically TOML or JSON) (
src/system/config/mod.rs) - Create or update the config editing UI view in src/ui/views/config.rs (
src/ui/views/config.rs) - Apply the configuration throughout the application where needed (typically in authentication or UI modules) (
src/app/state.rs)
Extend File Operations (e.g., add search/filter)
- Extend the RemoteFs trait in src/fs/mod.rs with a new method signature (
src/fs/mod.rs) - Implement the method in all protocol-specific modules (src/fs/ssh/mod.rs, src/fs/ftp/mod.rs, etc.) (
src/fs/ssh/mod.rs) - Add corresponding UI controls or views in src/ui/views/ to expose the operation to users (
src/ui/views/explorer.rs) - Wire event handling and state updates in src/app/state.rs to trigger the operation (
src/app/state.rs)
π§Why these technologies
- Rust β Provides memory safety, native compilation to small binaries, and strong concurrency primitives; ideal for a cross-platform TUI tool with multiple protocol backends.
- tui-realm β Declarative TUI framework enabling rapid development of interactive terminal interfaces with reusable components and event-driven architecture.
- ssh2 / sftp β Battle-tested SSH protocol libraries enabling SCP and SFTP file transfers with secure authentication.
- rusoto (AWS SDK) β S3-compatible object storage support; allows termscp to act as a cloud file manager for AWS, MinIO, and similar services.
- smbclient-ng / SMB libraries β Windows share and SMB protocol support; enables file operations on corporate network shares and legacy systems.
βοΈTrade-offs already made
-
Protocol-agnostic RemoteFS trait abstraction vs. protocol-specific optimizations
- Why: Unified interface simplifies UI logic and state management across 6+ protocols, enabling code reuse and consistent user experience.
- Consequence: Cannot expose protocol-specific optimizations or features; users see a lowest-common-denominator feature set across all backends.
-
Synchronous filesystem operations in blocking I/O model vs. async/await throughout
- Why: Simpler reasoning about state; easier error handling; TUI event loop already serializes interactions.
- Consequence: Network latency blocks UI updates; requires careful threading or event scheduling to prevent UI freezes during slow transfers.
-
Single-pane file explorer UI vs. dual-pane (Norton Commander style)
- Why: Simpler implementation and codebase; fits smaller terminal windows.
- Consequence: File operations between two remotes require manual switching; less efficient for copy/move workflows.
-
In-memory credential caching with on-disk encrypted storage vs. system keyring integration
- Why: Cross-platform compatibility; works on headless/server systems without native keyring support.
- Consequence: Credentials at rest depend on application-level encryption quality; users must trust termscp's crypto.
π«Non-goals (don't propose these)
- Does not provide GUI (graphical interface); terminal-only by design.
- Does not support real-time file synchronization or continuous directory watching; one-shot operations only.
- Does not implement its own SSH protocol; relies on system libssh2 and openssh libraries.
- Does not provide advanced terminal emulation features (e.g., full xterm compatibility, mouse tracking in all terminals).
- Does not support interactive text editor with rich syntax highlighting; delegates to external editor.
- Does not cache file listings; each directory view issues a fresh remote query.
- Does not provide built-in VPN or proxy configuration; relies on system network setup.
πͺ€Traps & gotchas
Keyring platform dependencies: keyring feature requires native system libraries (Apple Keychain, Windows DPAPI, Linux Secret Service); builds may fail without libdbus-1-dev on Linux or appropriate Windows SDK. SMB vendored feature: smb-vendored pulls in vendored dependencies; impacts binary size and compilation time. Async runtime assumption: tokio likely required implicitly through remotefs-ssh; blocking code in TUI layer must use appropriate async patterns. Config file location: hardcoded to ~/.config/termscp/ (check build.rs or config module); cross-platform path handling is non-negotiable.
ποΈArchitecture
π‘Concepts to learn
- Plugin/Trait-Based Architecture (remotefs abstraction) β termscp's core strength is swapping backends (SSH, S3, SMB, WebDAV) without rewriting TUI logic; understanding trait-based polymorphism in Rust is essential to extending it.
- Async/Await & Tokio Runtime β All file I/O and network operations (SSH, S3, HTTP) must be non-blocking to keep TUI responsive; mastering async Rust patterns is mandatory for modifications.
- Terminal User Interface (TUI) Rendering with Crossterm β termscp's entire user-facing layer depends on low-level terminal control (cursor positioning, color, input handling); required for UI feature work.
- System Keyring Integration (Native Credentials) β termscp stores SSH/FTP credentials in OS-native keyrings (Windows DPAPI, Apple Keychain, Linux Secret Service); security-critical path with platform-specific fragility.
- Encryption at Rest (AES-GCM with CBC mode) β Configuration and cached credentials likely encrypted using aes/aes-gcm/cbc; understanding authenticated encryption prevents data loss or security regressions.
- File Metadata & Directory Traversal Abstraction β remotefs trait abstracts filesystem operations across vastly different backends (local SFTP vs. S3 objects vs. Kube volumes); understanding stat(), readdir(), and permission models is core.
- Cross-Platform Build & CI/CD Pipelines β termscp ships as precompiled binaries for Linux/macOS/Windows via GitHub Actions; understanding Cargo features (keyring, smb-vendored) and platform-conditional compilation is essential for release work.
πRelated repos
mrusme/nkβ Terminal-based file manager with multi-protocol support; direct competitor solving the same TUI file-browsing problem.ducaale/xhβ Rust CLI for HTTPβsimilar ecosystem tooling philosophy of replacing GUI tools with lightweight terminal alternatives.gitpod-io/workspace-fullβ Cloud workspace leveraging terminal-based tools; representative user context where termscp shines (headless/SSH-only environments).ChrisTollman/cockroachβ Another Rust-based TUI for infrastructure/file operations; shares architectural patterns (async Rust, terminal rendering, multi-backend support).bytecodealliance/wasmtimeβ Not directly related, but remotefs ecosystem targets WebDAV and cloudβunderstanding WASM/container runtimes (Kube backend) contextualizes deployment scenarios.
πͺPR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add integration tests for S3/WebDAV/Kube remote filesystem backends
The repo has comprehensive CI workflows for Linux/macOS/Windows but lacks specific integration tests for the remotefs-aws-s3, remotefs-webdav, and remotefs-kube backends. These are optional/feature-gated protocols that deserve dedicated test coverage to prevent regressions. This would involve creating test fixtures and mock servers.
- [ ] Create tests/integration_s3.rs with mock S3 connection tests using localstack or moto
- [ ] Create tests/integration_webdav.rs with mock WebDAV server tests
- [ ] Create tests/integration_kube.rs with mock Kubernetes API tests
- [ ] Update .github/workflows/linux.yml to run integration tests with --features isolated-tests
- [ ] Document test setup in CONTRIBUTING.md for running locally
Add GitHub Actions workflow for security audit and dependency scanning
While the repo has build workflows for multiple platforms (.github/workflows/linux.yml, macos.yml, windows.yml), there's no dedicated security scanning workflow. Given the project handles sensitive operations (file transfers, credentials via keyring), adding cargo-audit and dependency vulnerability checks would be valuable. A SECURITY.md exists but lacks automation.
- [ ] Create .github/workflows/security-audit.yml that runs cargo audit on every PR and scheduled weekly
- [ ] Add cargo-deny configuration file (deny.toml) to check for security advisories
- [ ] Update SECURITY.md with instructions on how to report vulnerabilities and reference the automated scanning
- [ ] Add security check step to the build-artifacts.yml workflow to block releases with vulnerabilities
Refactor CLI argument parsing from argh to structured subcommands module
The Cargo.toml shows argh dependency for CLI parsing, but there's no visible src/cli/ or src/args/ module in the file structure. As the project supports multiple protocols and features, a dedicated CLI module with subcommands (e.g., 'termscp connect', 'termscp config', 'termscp bookmarks') would improve maintainability and reduce main.rs complexity.
- [ ] Create src/cli/mod.rs and src/cli/parser.rs to extract argh-based argument parsing logic
- [ ] Create src/cli/commands/ subdirectory with separate modules for each command (connect.rs, config.rs, bookmarks.rs)
- [ ] Refactor src/main.rs to use the new CLI module instead of inline parsing
- [ ] Add unit tests in src/cli/tests.rs covering argument validation for all subcommands
- [ ] Update CONTRIBUTING.md with architecture notes on the CLI structure
πΏGood first issues
- idea: Add unit tests for config serialization/deserialization in src/config/. Currently visible CI runs tests, but config module likely lacks coverage given no test/ directory listed.
- idea: Document the plugin architecture for remotefs backends in CONTRIBUTING.md with a step-by-step example for adding a new protocol (e.g., SFTP-specific optimizations or a new remote backend).
- idea: Extend CI/CD to run
cargo clippy --all-targetsin workflows (linux.yml, macos.yml, windows.yml already exist) to enforce code quality gates early; currently not visible.
πRecent commits
Click to expand
Recent commits
0ad18eaβ chore: update release date (veeso)2ed71c7β chore: 1.0.0 changelog (veeso)4910298β ci: add linux and windows aarch64 build targets (veeso)bc59df4β fix: filter self-references and dot entries from remote directory listings (veeso)080c013β build: upgrade remotefs-ssh to 0.8.3 (veeso)6252df2β build: migrate to tui-realm 4.0 (veeso)9160c52β build: remotefs-ssh 0.8.2 (veeso)38f1fccβ build: remotefs-ssh 0.8.1 (veeso)6ceaf04β fix: render progress bar immediately after mounting (veeso)534c164β fix: use time-based redraw interval instead of progress-delta threshold (veeso)
πSecurity observations
The termscp codebase demonstrates generally good security practices with use of modern cryptographic libraries and optional security features. However, several concerns exist: incomplete dependency documentation in Cargo.toml, lack of comprehensive security policy details, use of cryptographically weak algorithms (MD-5), and an extensive attack surface from multiple protocol backends. The project would benefit from enhanced security documentation, dependency audit procedures, and clearer guidance on secure configuration. No obvious hardcoded credentials, SQL injection, or XSS vulnerabilities were detected in the available file structure.
- Medium Β· Incomplete Cargo.toml Dependencies β
Cargo.toml - self_update dependency definition. The Cargo.toml file appears to have truncated dependency entries, particularly in the self_update dependency. The archive-zip and archive-tar features are listed but the entry is cut off, making it impossible to verify complete dependency specifications and potential security issues. Fix: Review and complete the full Cargo.toml file to ensure all dependencies are properly specified. Verify that all transitive dependencies have been audited using 'cargo audit'. - Medium Β· Optional SMB Feature Without Security Documentation β
Cargo.toml - features section, remotefs-smb dependency. The SMB feature is optional with a vendored variant (smb-vendored), but there's no documented security considerations for compiling with vendored dependencies. Vendored builds may hide upstream security updates. Fix: Document security implications of using vendored dependencies. Consider implementing dependency update monitoring. Clearly communicate to users that vendored builds may lag behind upstream security patches. - Medium Β· Cryptographic Dependencies Without Version Pinning Strategy β
Cargo.toml - dependencies: aes, aes-gcm, md-5, cbc. The codebase uses cryptographic libraries (aes, aes-gcm, md-5, cbc) with relatively broad version ranges. MD-5 is cryptographically broken and should only be used for non-security purposes. No documented rationale for MD-5 usage is visible. Fix: Audit usage of MD-5 and replace with SHA-256 or stronger algorithms if used for security purposes. Pin cryptographic dependency versions to specific releases. Document the rationale for each cryptographic algorithm's usage. - Low Β· Incomplete Security Policy β
SECURITY.md. The SECURITY.md file states 'only latest version has security updates' but doesn't specify a Long-Term Support (LTS) strategy, security update timeline, or vulnerability disclosure timeline. Fix: Expand security policy to include: vulnerability response timeline, supported version matrix, LTS policy (if applicable), and responsible disclosure guidelines with expected response times. - Low Β· Multiple Remote Backend Support Increases Attack Surface β
Cargo.toml - remotefs-* dependencies, overall architecture. The application supports multiple remote protocols (SCP, SFTP, FTP, S3, SMB, Kube, WebDAV). Each protocol handler represents a potential attack surface. No visible security boundary documentation between protocol implementations. Fix: Maintain a security matrix documenting attack surface per protocol. Implement strict input validation at protocol boundaries. Consider regular security audits of protocol handlers. Document known limitations and security considerations for each protocol. - Low Β· Keyring Feature Dependency Security β
Cargo.toml - keyring dependency, features default = ["keyring", "smb"]. The keyring feature is enabled by default and depends on native system keyring implementations (apple-native, windows-native, sync-secret-service). These have varying security properties and maintenance levels. Fix: Document security properties of each keyring backend. Consider making keyring optional rather than default. Implement fallback mechanisms with clear security warnings. Audit keyring dependency updates regularly.
LLM-derived; treat as a starting point, not a security audit.
πWhere to read next
- Open issues β current backlog
- Recent PRs β what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals β see the live page for receipts. Re-run on a new commit to refresh.