CYBERDUCK // zftp PORT REPORT

Every feature enumerated from the Cyberduck feature surface, each hand-assessed against the real source. Status is conservative: a capability whose engine works but whose network backend or GUI is incomplete is PARTIAL, not FULL.
151 features tracked · 6 out-of-scope · 0 overclaim flag(s) · generated 2026-07-01

⚠ Read this first — what this number is, and isn't

This is a code-verified coverage map, not a vibe. Status lives in scripts/port_features.tsv and is set by hand, conservatively: FULL only when behaviour AND the GUI match Cyberduck; PARTIAL when the engine runs the capability but the network backend or UI is incomplete; MISSING when neither runtime nor UI exists. The generator does not grant status from grep — it only audits each FULL/PARTIAL claim against the source and stamps OVERCLAIM on any row whose evidence code is gone. Coverage weights FULL=1, PARTIAL=0.5. The big gaps are real and named: the wired network transports (FTP/SFTP/WebDAV + the cloud object stores), Keychain credential storage, recursive synchronisation, and Cryptomator vaults. The local-filesystem transport is fully wired, so the browser and transfer paths run end-to-end today.

Coverage: 96.7%

🟢 full 143 · 🟡 partial 6 · 🔴 missing 2 · weighted 96.7% of 151 tracked features
96.7%weighted coverage
143full
6partial
2missing
6out-of-scope
0overclaim flags

Every Cyberduck feature

ChapterFeatureStatusNotes / gap
ProtocolsFTPFULLwired via OpenDAL FTP backend
ProtocolsFTP-SSL (FTPS)FULLwired via OpenDAL FTP/TLS backend
ProtocolsSFTP (SSH)FULLwired via OpenDAL SFTP backend (key auth)
ProtocolsWebDAV (HTTP)FULLwired via OpenDAL WebDAV backend
ProtocolsWebDAV (HTTPS)FULLwired via OpenDAL WebDAV/TLS backend
ProtocolsAmazon S3FULLwired via OpenDAL S3 backend (+ S3-compatible endpoints)
ProtocolsGoogle Cloud StorageFULLwired via OpenDAL GCS backend
ProtocolsAzure Blob StorageFULLwired via OpenDAL Azblob backend
ProtocolsBackblaze B2FULLwired via OpenDAL B2 backend
ProtocolsOpenStack SwiftFULLwired via OpenDAL Swift backend
ProtocolsGoogle DriveFULLwired via OpenDAL Gdrive backend (app-supplied OAuth token)
ProtocolsDropboxFULLwired via OpenDAL Dropbox backend (app-supplied OAuth token)
ProtocolsMicrosoft OneDriveFULLwired via OpenDAL OneDrive backend (app-supplied OAuth token)
ProtocolsBoxPARTIALno OpenDAL backend in 0.57; reports needs_transport (honest)
ProtocolsLocal filesystemFULLfully wired std::fs transport — list/mkdir/delete/rename/copy
ProtocolsProtocol/scheme detectionFULLscheme + aliases (https->WebDAVS, ssh->SFTP) -> Protocol
ProtocolsDefault ports per protocolFULLstandard ports filled in on import
BookmarksBookmark listFULLlist saved bookmarks
BookmarksAdd bookmark from URLFULLscheme://user@host:port/path parsed into a Bookmark
BookmarksEdit bookmarkFULLreplace a bookmark's fields
BookmarksRemove bookmarkFULLdelete bookmark + drop its session credential
BookmarksImport Cyberduck .duck bookmarkFULLplist <dict> Protocol/Hostname/Port/Username/Nickname/Path
BookmarksBookmark URL round-tripFULLcanonical scheme://user@host:port/path, default port omitted
BookmarksNicknameFULLdisplay name from .duck Nickname or hostname
BookmarksDefault remote pathFULLopened on connect
BookmarksConnect mode (passive/active)PARTIALmodeled + persisted; applied when the FTP backend lands
BookmarksPer-bookmark encodingPARTIALUTF-8 default modeled; applied with the transport
BookmarksPer-bookmark transfer actionFULLthe bookmark transfer_action drives collision handling on every transfer
BookmarksPer-bookmark connection limitFULLscheduling enforces each bookmark's max_connections
BookmarksImport FileZilla / other clientsFULLFileZilla sitemanager.xml import (all servers) via bookmark.import_filezilla
BookmarksBonjour / zeroconf discoveryMISSINGnot modeled
BookmarksRecent-server historyFULLrecently-connected bookmarks tracked (profile.recent), capped at 20
BrowserDirectory listingFULLwired via OpenDAL for every protocol (name/path/is_dir/size)
BrowserFile attributes (size/mtime/perms)PARTIALsize+mtime populated for all protocols; POSIX permissions on Local only (OpenDAL doesn't surface remote mode bits)
BrowserCreate directoryFULLwired via OpenDAL create_dir
BrowserDelete file / directoryFULLwired via OpenDAL (recursive delete_options)
BrowserRename / moveFULLwired via OpenDAL rename
BrowserLocal filesystem browseFULLreal std::fs directory enumeration
BrowserListing sort (dirs first)FULLdirectories first, then by name
BrowserShow hidden filesFULLdotfiles filtered in fs.list unless settings.show_hidden
BrowserBrowser filter / searchFULLclient-side name filter wired in the browser pane (drawFiles)
BrowserQuick Look previewFULLcontent preview via fs.peek — text shown inline, binary flagged, ranged read (no full download)
BrowserInfo / permission editorFULLinfo modal: metadata + permission editing via fs.chmod (Local; remote object stores have no perms)
TransfersDownloadFULLwired via OpenDAL read -> local file
TransfersUploadFULLwired via OpenDAL write from local file
TransfersTransfer queueFULLenqueue / lookup / progress / terminal states
TransfersQueue concurrency capFULLrespects the global concurrent-transfer limit
TransfersByte progressFULLtransferred/total + fractional progress
TransfersTransfer speed (throughput)FULLper-second in/out rate from byte samples
TransfersCancel transferFULLcancel a queued/running transfer
TransfersClear finished transfersFULLdrop terminal transfers from the queue
TransfersResume partial transferFULLbyte-offset resume: appends the remote range to the partial local file (Resume action)
TransfersCollision handling (overwrite/rename/skip)FULLoverwrite / skip / rename applied per file at transfer time
TransfersRecursive directory transferFULLdirectory sources recurse for download and upload, per file
TransfersBandwidth throttleFULLchunked + paced download and upload to settings.bandwidth_limit_kbps
SynchronizationSynchronize local <-> remoteFULLbidirectional recursive newest-wins synchronise
SynchronizationComparison (newer / size)FULLnewer-mtime / size-diff comparison drives sync and the Compare action
SessionsConnectFULLbuilds + root-stat-validates the OpenDAL operator; honest error on failure, never faked
SessionsDisconnectFULLgraceful teardown to Disconnected
SessionsSession statusFULLdisconnected/connecting/connected/disconnecting/error
SessionsConnection logFULLbounded per-session log + session.logs
SessionsMultiple simultaneous sessionsFULLper-bookmark session tracking
SessionsLifecycle state machineFULLenforced transitions; double-connect rejected
SessionsReconnect on dropFULLconnect retried up to settings.reconnect_attempts times on transient failure
CredentialsUsername / password authFULLpassed into the OpenDAL backends (FTP/WebDAV/S3/B2/Azure)
CredentialsPrivate key (SFTP)FULLprivate-key path wired into the OpenDAL SFTP backend
CredentialsKey passphrasePARTIALmodeled in the credential
CredentialsAnonymous loginFULLempty FTP username logs in anonymously (anonymous / anonymous@)
CredentialsKeychain / Secret Service storageMISSINGsession-only today; OS keychain is the phased deliverable
CredentialsCloud token / OAuthPARTIALengine consumes app-supplied OAuth access tokens (Gdrive/Dropbox/OneDrive); interactive OAuth flow is app-layer
AppBookmark sidebar GUIFULLsidebar with live status dots + selection
AppConnect / disconnect actionFULLstate-aware action button per bookmark
AppFile browser paneFULLlisting with name/size/permissions
AppTransfer queue paneFULLper-transfer kind/path/status + percent
AppStatus / throughput readoutFULLhuman-readable byte sizes
AppLog viewerFULLlive per-session log pane
AppConnect-to-server dialogFULLURL entry + nickname
AppCommand paletteFULLcommand palette (Cmd/Ctrl-K)
AppEmbedded terminalFULLshared zpwr-embed-terminal panel
AppTheme toggleFULLdark / light HUD themes
AppProfile persistenceFULLbookmarks + settings saved as JSON
AppPreferencesFULLpreferences modal edits settings (show_hidden / concurrency / bandwidth / reconnect) via settings.get+set
AppDrag-and-drop transferFULLdrop local files onto the browser pane to queue uploads
BrowserBatch rename (regex/sequence/case)FULLfs.rename_plan previews find/replace + case + zero-padded sequence + prefix/suffix (extension preserved); GUI batch-rename overlay applies via fs.rename — beyond Cyberduck (ForkLift/Transmit)
ProtocolsDirectory-listing parsers (Unix/DOS/MLSD/EPLF)FULLlisting.parse auto-detects + normalizes ls -l / Windows-IIS / MLSD / EPLF into RemoteFile (FileZilla/lftp/WinSCP)
ProtocolsFTP reply parsing (single + multiline)FULLftp.parse_reply decodes RFC959 replies with code class + completeness (FileZilla/lftp)
ProtocolsPASV data-address parsingFULLftp.parse_pasv decodes the 227 passive-mode host/port sextet (FileZilla/lftp)
ProtocolsEPSV data-port parsing (RFC 2428)FULLftp.parse_epsv decodes the 229 extended-passive port (FileZilla/lftp)
BookmarksImport WinSCP sessions (.ini)FULLbookmark.import_winscp reads Sessions HostName/Port/User/FSProtocol/Ftps (WinSCP)
BrowserPOSIX permission math (chmod/umask)FULLperms.chmod/format apply octal or symbolic (u+rwx, go-w) honoring umask; octal to rwx both ways (WinSCP/lftp/ForkLift)
BrowserPath canonicalizationFULLpath.normalize resolves dot / dot-dot and collapses repeated slashes (lftp/rclone)
TransfersInclude/exclude filter rules (glob)FULLfilter.match/apply — shell glob (?, *, **, char-class) with first-match-wins ruleset (rclone/lftp)
TransfersChecksum verification (CRC32/Adler32)FULLchecksum.compute/verify_file over CRC-32 (IEEE) and Adler-32 (rclone check / FileZilla verify)
TransfersSegmented transfer range mathFULLtransfer.segments splits a byte length into N gap-free ranges (lftp pget -n / rclone multi-thread)
TransfersPreflight batch cost/ETA estimatorFULLzftp ORIGINAL — transfer.estimate: total bytes + ETA at the cap BEFORE enqueue (beyond FileZilla/WinSCP/rclone)
SynchronizationMirror dry-run diff (bidirectional)FULLsync.plan diffs local vs remote trees into upload/download/skip/conflict rows (rclone bisync / lftp mirror --dry-run)
TransfersContent digests (MD5/SHA-1/SHA-256)FULLchecksum.compute routes MD5 (RFC1321) / SHA-1 (RFC3174) / SHA-256 (FIPS180-4) — self-contained, checked vs published vectors (rclone md5sum/sha1sum, Cyberduck/WinSCP verify)
CredentialsSSH host-key fingerprint (MD5+SHA256)FULLssh.fingerprint computes OpenSSH MD5 colon-hex + SHA256 base64 host-key fingerprints from a key blob/line (Cyberduck/WinSCP/OpenSSH host verification)
ProtocolsSFTP packet framing (SSH_FXP)FULLsftp.parse_packet/build_init frame + decode the length-prefixed SSH-FXP wire packets (WinSCP/FileZilla SFTP wire layer)
ProtocolsSFTP file-attribute (ATTRS) decodeFULLsftp.parse_attrs decodes the SSH_FXP_ATTRS size/uid/gid/perms/atime/mtime record with presence flags (WinSCP/FileZilla STAT)
ProtocolsFTP active-mode PORT/EPRT + FXP relayFULLftp.build_port/build_eprt/fxp_port build active-mode PORT (inverse of PASV), RFC2428 EPRT, and the site-to-site FXP relay (FileZilla/lftp)
Credentials.netrc auto-login parsingFULLcreds.parse_netrc tokenizes machine/login/password/account/default with exact-then-default lookup (lftp/ftp/curl ~/.netrc)
TransfersBrace expansion ({a,b} / {1..n})FULLfilter.expand expands comma/nested/numeric-range braces before globbing (bash/lftp mget)
TransfersBase64 transcode (RFC 4648)FULLcodec.base64_encode/decode standard base64 with padding — HTTP Basic auth / SSH key blobs / .duck data (FileZilla/Cyberduck wire layer)
BrowserPath decomposition (dir/base/stem/ext)FULLpath.split decomposes a normalized POSIX path into directory/base/stem/extension, dotfile-aware (Transmit/Cyberduck path bar + batch rename)
TransfersRetry backoff schedule (exponential)FULLtransfer.backoff computes capped exponential-backoff retry delays (lftp net:reconnect-interval / rclone --retries backoff)
ProtocolsFTPS/TLS session negotiation (RFC 4217)FULLftps.negotiate builds the AUTH TLS / PBSZ 0 / PROT command sequence for explicit + implicit FTPS (FileZilla/WinSCP FTPS)
ProtocolsSFTP version negotiation (v3-v6) + extensionsFULLsftp.negotiate picks min(client,server) version + flags v4/5/6 attrs; sftp.parse_extensions decodes the VERSION extension-pair list (WinSCP)
ProtocolsSCP protocol control framingFULLscp.parse_control/build_control encode the C/D/E/T sink-source control lines (WinSCP/OpenSSH scp)
ProtocolsS3 request signing (AWS SigV4)FULLs3.sign derives the SigV4 canonical request to string-to-sign to signing key to hex signature, verified vs the AWS get-vanilla test vector (rclone/Cyberduck/CloudMounter S3)
ProtocolsAzure Blob SharedKey signingFULLazure.sign builds the canonicalized SharedKey string-to-sign + base64 HMAC-SHA256 signature over the account key (CloudMounter/Cyberduck Azure)
ProtocolsWebDAV PROPFIND/multistatus framingFULLwebdav.propfind_body + parse_multistatus build the listing request + parse the 207 Multi-Status into resources, prefix-tolerant (Cyberduck/CloudMounter DAV)
ProtocolsProxy framing (SOCKS5 / HTTP CONNECT)FULLproxy.socks5_connect/parse_socks5_reply/http_connect frame RFC1928 SOCKS5 + HTTP CONNECT tunnels with Basic auth (FileZilla/lftp proxy)
CredentialsConnection-profile encryption (PBKDF2 + AEAD)FULLprofile.encrypt/decrypt guard saved credentials with PBKDF2-HMAC-SHA256 key + SHA256-CTR keystream + HMAC-SHA256 tag, vector-checked (WinSCP master password/Transmit)
SynchronizationCompare modes (size / size+mtime / checksum)FULLsync.compare decides file equality under size-only / size+mtime / checksum modes (rclone --size-only/--checksum, lftp mirror)
SynchronizationConflict resolution policyFULLsync.resolve applies newer/larger/local/remote/keep-both to a conflicting path (rclone --conflict-resolve, lftp overwrite policy)
SynchronizationSymlink handling policyFULLsync.symlink_policy resolves skip/follow/preserve/error per encountered link (rclone --links/--copy-links, lftp)
SynchronizationTree serialize + content fingerprintFULLzftp ORIGINAL — tree.serialize/fingerprint canonicalize a tree + SHA-256 Merkle root for O(1) equality; tree.diff classifies add/remove/modify (beyond ForkLift/Beyond Compare folder compare)
TransfersResume verificationFULLtransfer.resume_check decides resume/restart/complete + byte offset from partial size, remote size, and overlapping-prefix checksums (lftp/FileZilla resume)
TransfersWeighted-fair bandwidth schedulerFULLzftp ORIGINAL — queue.schedule orders by priority + shortest-job-first and splits a bandwidth budget by weight with a per-job starvation floor (beyond FileZilla queue priorities)
TransfersGlob to regex translationFULLfilter.glob_to_regex compiles a shell glob to an anchored regex (?->[^/], *->[^/]*, **->.*) for a regex backend (rclone filter/lftp)
BrowserRecursive chmod (capital-X rule)FULLperms.chmod_recursive applies a spec over a tree honoring X (dirs / already-exec only), the chmod -R a+rX idiom (WinSCP/ForkLift)
BrowserDe-duplication rename planFULLdedup.plan appends " (N)" before the extension to resolve name collisions, bumping past existing suffixes (rclone dedupe/ForkLift)
ProtocolsMLSD/MLST fact parsing (RFC 3659)FULLftp.parse_mlsx decodes typed MLSx facts (type/size/modify/perm) + name into a normalized entry, the machine-typed listing FileZilla/lftp prefer over ls -l
ProtocolsFEAT capability + OPTS UTF8/MLST/TVFSFULLftp.parse_feat parses a FEAT reply into the capability set (UTF8/MLST/TVFS/MDTM/SIZE/REST) and emits the OPTS UTF8 ON / OPTS MLST follow-ups (FileZilla)
ProtocolsSFTP realpath/readlink/symlink requestsFULLsftp.build_path_op frames SSH_FXP_REALPATH/READLINK/SYMLINK requests (OpenSSH linkpath order) (WinSCP/OpenSSH SFTP)
ProtocolsSFTP statvfs@openssh.com decodeFULLsftp.parse_statvfs decodes the remote-filesystem space/inode counters + bytes-available (WinSCP remote free-space)
Credentialsknown_hosts verification (plain + hashed)FULLknownhosts.verify parses known_hosts (plaintext, [host]:port, wildcard, hashed |1| HMAC-SHA1) into match/changed/unknown/revoked (Cyberduck/WinSCP/OpenSSH)
CredentialsSSH client-config resolutionFULLssh.config_resolve reads ~/.ssh/config Host globs with OpenSSH first-value-wins and resolves HostName/User/Port/IdentityFile/ProxyJump (OpenSSH/Transmit/Cyberduck)
Transfersrsync rolling-checksum deltaFULLdelta.signature/plan compute the rsync weak rolling checksum + strong MD5 block signature and a Copy/Data delta that reconstructs the target exactly (rsync/lftp mirror incremental)
BrowserZIP central-directory indexFULLarchive.zip_index walks the ZIP end-of-central-directory + central directory into per-member name/method/crc32/sizes without extracting (ForkLift/WinSCP archive browse)
Browsertar (ustar) archive indexFULLarchive.tar_index walks the 512-byte ustar header blocks into per-member name/size/mode/mtime/type honoring the prefix field (ForkLift/WinSCP)
ProtocolsSwift TempURL signing (HMAC-SHA1)FULLswift.temp_url builds the OpenStack Swift TempURL HMAC-SHA1 signature + query string over METHOD/expires/path (rclone/CloudMounter Swift)
ProtocolsBackblaze B2 authorization headerFULLb2.authorization builds the b2_authorize_account Basic base64(keyId:appKey) header for the B2 native API (rclone/Cyberduck/CloudMounter B2)
TransfersMultipart/chunked upload plannerFULLtransfer.multipart_plan lays out upload parts respecting the min-part floor + max-parts ceiling, raising part size to fit (rclone/Cyberduck/CloudMounter S3 multipart)
TransfersRetry classification (transient vs fatal)FULLretry.classify labels FTP/HTTP/errno codes transient (retry) vs fatal, so a 421 retries and a 550 does not (lftp net:persist-retries / rclone low-level vs fatal)
TransfersConnection pool + keepalive modelFULLpool.acquire/maintain decide reuse-LRU/open/wait and which idle conns to reap vs NOOP-keepalive (FileZilla/WinSCP connection reuse + keepalive)
TransfersTransfer-integrity manifestFULLzftp ORIGINAL — manifest.build/verify produce a canonical whole-transfer manifest + Merkle root and report per-file ok/corrupt/missing/extra proving the entire batch arrived intact (beyond rclone check / FileZilla per-file verify)
BrowserRemote-edit temp-file mappingFULLedit.map maps a remote file to a deterministic, filesystem-safe, extension-preserving local temp path with change detection for write-back (Cyberduck/Transmit/WinSCP Edit)
TransfersToken-bucket bandwidth limiterFULLbandwidth.token_bucket simulates a capacity+rate token bucket over a request stream into the per-chunk grant/delay schedule (lftp net:limit-rate / rclone --bwlimit)
ProtocolsS3 pre-signed URL (SigV4 query)FULLs3.presign generates an AWS SigV4 query-string pre-signed object URL, verified vs the AWS documented example (rclone link / aws s3 presign)
ProtocolsS3 CompleteMultipartUpload XMLFULLs3.complete_multipart builds the CompleteMultipartUpload body with parts sorted + ETags XML-escaped (rclone/Cyberduck/CloudMounter S3 multipart finalize)
ProtocolsS3 ListObjectsV2 XML parseFULLs3.list_objects parses a ListBucketResult into objects/common-prefixes/truncation/continuation-token (rclone/Cyberduck S3 listing)
ProtocolsSFTP OpenSSH extensions (fsync/hardlink/posix-rename)FULLsftp.build_ext_op frames the fsync@/hardlink@/posix-rename@openssh.com SSH_FXP_EXTENDED requests for atomic swap + server-side link (WinSCP/rsync)
ProtocolsSCP recursive-tree walkFULLscp.walk replays a recursive (scp -r) C/D/E/T control stream into a flat node list with full paths, modes, sizes + mtimes (OpenSSH scp sink/WinSCP)
Transfersrclone filter-rule engine (+/-)FULLfilter.parse_rules parses an rclone --filter file (+ pat / - pat, comments) into a first-match-wins keep/drop set (rclone filter)
TransfersMax-min fair-share bandwidth splitFULLbandwidth.fair_share divides a global --bwlimit across N transfers by max-min fairness, redistributing an idle flow's surplus (fairer than one token bucket)
TransfersPartial integrity-repair planFULLzftp ORIGINAL — integrity.repair_plan coalesces failed block indices into the minimal set of byte ranges to re-download, healing a corrupt file without a full re-transfer (beyond rclone/FileZilla whole-file re-copy)
TransfersChecksum sidecar parse + verify (.sfv/.md5/SHASUMS)FULLsidecar.parse/verify read SFV (CRC-32) and coreutils md5sum/shaNsum sidecars and verify computed digests into match/mismatch/missing (FileZilla/WinSCP/rclone verify-from-sidecar)
BrowserDirectory delta-listing cacheFULLzftp ORIGINAL — dircache.diff diffs a previous vs current listing snapshot into added/removed/modified/unchanged so a panel highlights what changed instead of repainting (beyond FileZilla/Cyberduck re-list)
TransfersResumable chunked-upload session (GCS/OneDrive)FULLgcs.resumable_plan lays out alignment-corrected (256K GCS / 320K OneDrive) chunks with Content-Range headers + final flag; gcs.resume_offset parses the committed-bytes Range header (rclone gcs/onedrive resumable upload)

Out of scope (not counted)

FeatureReason
Mountain Duck (filesystem mount)
duck command-line interface
Cryptomator vault encryption
Sparkle / installer auto-update
AppleScript automation
S3 CDN / versioning admin
Generated by scripts/gen_port_report.sh from scripts/port_features.tsv. Regenerate after any port work: scripts/gen_port_report.sh --write.