Sherpa
A native macOS SSH terminal app built for developers who manage multiple remote servers. Tabbed SSH sessions, a local terminal, split-pane views, SFTP file browsing, port forwarding, and iCloud sync for hosts and settings.
// Overview
Sherpa is a native macOS SSH client that replaces juggling Terminal tabs and remembering connection strings. It provides a unified interface for managing servers, keys, and file transfers — with everything synced across devices via iCloud.
Designed for developers who SSH into multiple machines daily, Sherpa brings tabbed sessions, split-pane terminals, and integrated SFTP into a single, fast macOS app.
// Architecture
The SSH layer uses libssh for connections, authentication, SFTP, and port forwarding. The terminal emulator is powered by SwiftTerm (VT100/xterm-256color), providing full terminal compatibility. State flows reactively through Combine publishers, keeping the UI in sync with session lifecycle events.
// Key Features
- Tabbed SSH sessions with quick-connect from a saved host list
- Local terminal with the same interface as remote sessions
- Split-pane views — work on multiple sessions side by side
- Integrated SFTP file browser with drag-and-drop transfers
- Port forwarding (local and remote tunnels)
- SSH key management — generate, import, and associate keys with hosts
- iCloud sync for hosts, keys, and settings across all Macs
- Secure credential storage via Keychain and iCloud Keychain
- Server grouping and organization
// Technical Details
libssh: Handles the full SSH protocol stack — password and key-based auth, session multiplexing, SFTP channels, and port forwarding tunnels. Wrapped in a Swift-friendly API layer that manages connection lifecycle and error handling.
SwiftTerm: A full VT100/xterm-256color terminal emulator embedded in SwiftUI. Handles escape sequences, mouse reporting, alternate screen buffer, and 256-color support for tools like vim, htop, and tmux.
Core Data + CloudKit: Host configurations, key metadata, and app settings are persisted with Core Data and automatically synced to iCloud. The sync is conflict-aware and works seamlessly across multiple Macs.
// Challenges & Solutions
Challenge: Integrating libssh (a C library) with Swift's strict concurrency model while maintaining responsive terminal rendering.
Solution: Built a bridging layer that isolates all libssh calls on dedicated serial dispatch queues per connection. Terminal output is buffered and flushed to the SwiftTerm view on the main actor at 60fps cadence, preventing UI jank even during heavy output (e.g., large cat operations).
Challenge: Keeping hosts, keys, and settings in sync across devices without data loss during conflicts.
Solution: Used Core Data's NSPersistentCloudKitContainer with custom merge policies. Host records use a last-writer-wins strategy with timestamps, while SSH keys use a union merge — keys are never silently deleted during sync conflicts.