$ show iterate-ch/cyberduck
Cyberduck is a mature, multi-protocol file transfer client for macOS, Windows, and Linux (CLI). It supports over 30 storage protocols including S3, SFTP, FTP, WebDAV, Azure, Google Drive, Dropbox, Backblaze B2, and many more. The architecture is a Java core library with platform-specific UI bindings: Cocoa for macOS (via Rococoa/JNA), WinForms/WPF for Windows, and a command-line interface (duck). The core defines a clean set of feature interfaces (Read, Write, Find, Delete, etc.) that each protocol module implements, enabling a uniform file operation model. The system also integrates client-side encryption via Cryptomator vaults, which wrap protocol features transparently using decorator patterns. Key external dependencies include Apache HttpClient, JSch (SSH), and various cloud SDKs.
The LLM identified 4 files worth highlighting for reuse:
Provides a base class for converting protocol-specific exceptions (e.g., HTTP 403, AWS errors) into a consistent domain exception hierarchy. Each protocol module extends this with a few lines of mapping logic, making error handling uniform across the entire application. The pattern is clean, reusable, and demonstrates good separation of concerns.
Core interface for write operations. Defines a single method returning an OutputStream, with a TransferStatus parameter for progress tracking. This interface is implemented by every protocol (S3, FTP, etc.) and is the foundation for upload functionality. It is self-contained, well-documented, and exemplifies the kind of minimal, reusable abstraction that makes the codebase extensible.
Encapsulates the complete state of a file transfer: bytes written, checksum, timestamp, encryption parameters, and more. Used as a parameter to all read/write features and updated as the transfer progresses. It is a well-designed value object that enables consistent progress reporting and resumption across protocols.
A decorator that wraps a protocol's Write feature to transparently encrypt data via Cryptomator vaults. It intercepts the write call, creates a vault output stream, and delegates to the underlying write feature. This pattern is replicated for other features (Read, Delete, etc.) and cleanly separates encryption concerns from protocol logic. Highly reusable for any application needing transparent encryption.