Releases: DougJoseph/sftp-watchlist
Release list
v1.18.0 — caseSensitivePatterns
Fork: DougJoseph/vscode-sftp
A personal fork of Natizyskunk's SFTP extension, branched from release 1.16.3 (2023-06-16) and distributed as a .vsix from this repository's Releases — never published to the VS Code marketplace. Extension id DougJoseph.sftp-watchlist.
It differs from upstream in four ways:
- a hook that runs before an upload begins,
- a persistent on-disk transfer log,
caseSensitivePatterns, an opt-in that matches ignore/exclude patterns case-sensitively,- a fix for downloads failing on current VS Code with
isDate is not a function— a defect that affects the stock extension too.
Fork changes
1.18.0 — 2026-08-16 — caseSensitivePatterns
New per-config boolean, default false (upstream behaviour). When true, ignore and remoteExplorer.filesExclude patterns are matched case-sensitively.
Why. The ignore package defaults to ignorecase: true, and src/core/ignore.ts constructed it with no options — so upstream matches case-INSENSITIVELY. A pattern aimed at one capitalization therefore also catches the other, because to the matcher C3/index.php and c3/index.php are the same path — precisely the pair that matters on a case-insensitive local filesystem syncing to a case-sensitive server: a pattern meant to block a remote C3/index.php on DOWNLOAD also blocked the real local c3/index.php on UPLOAD. Silently — an ignored path returns early in createFileHandler, before the spinner and before any connection, so nothing transfers and nothing errors.
Scope — pattern matching only. Ignore is the extension's only pattern matcher and has two consumers, both now honouring the flag: the transfer ignore list (which applies to upload, folder upload, sync in both directions, and download alike) and remoteExplorer.filesExclude. It does NOT change how local and remote filenames are compared to each other during a sync, and it does not affect the local filesystem's own case behaviour. The name says Patterns for exactly that reason — a bare caseSensitive would promise more than it delivers.
Files touched: src/core/ignore.ts (the flag), src/core/fileService.ts (the config field plus the transfer-ignore construction), src/modules/remoteExplorer/treeDataProvider.ts (the Remote Explorer construction), schema/definitions.json.
v1.17.1 — beforeUpload hook, transfer log, ssh2 download fix
Fork: DougJoseph/vscode-sftp
A personal fork of Natizyskunk's SFTP extension, branched from release 1.16.3 (2023-06-16) and distributed as a .vsix from this repository's Releases — never published to the VS Code marketplace. Extension id DougJoseph.sftp-watchlist.
It differs from upstream in three ways:
- a hook that runs before an upload begins,
- a persistent on-disk transfer log,
- a fix for downloads failing on current VS Code with isDate is not a function — a defect that affects the stock extension too.
Fork changes
1.17.1 — 2026-08-16 — ssh2 1.13.0 → 1.17.0, fixing broken downloads
Downloads and remote → local syncs failed on current VS Code with TypeError: isDate is not a function, thrown from ssh2/lib/protocol/SFTP.js attrsToBytes. ssh2 1.13.0 does const { inherits, isDate } = require('util'), and util.isDate — deprecated for years — has been removed from the Node build VS Code now ships. Uploads were unaffected, which is why it went unnoticed: the failing call is on the read path.
This was NOT introduced by the fork. Verified by enabling the stock Natizyskunk.sftp-1.16.3 and reproducing the identical error from its own copy of ssh2 1.13.0, at the same line. Both builds carried the same dependency and the same defect.
ssh2 1.17.0 fixes it upstream — its line 10 reads const { inherits, types: { isDate } } = require('util'). The dependency range moves ^1.13.0 → ^1.17.0; no fork code changes were needed.
Note this raises the packaged size from 582 files / 1.16 MB to 804 files / 1.81 MB, ssh2 1.17.0 having a larger dependency footprint.
1.17.0 — 2026-08-15 — the two features
beforeUpload— a shell command run to completion before any local-to-remote transfer, aborting the transfer on a non-zero exit. Configured persftp.json, withbeforeUploadTimeout(default 120000 ms). The command runs with the config's local root as its working directory and receivesSFTP_LOCAL_BASE,SFTP_REMOTE_PATH,SFTP_HOST,SFTP_PROFILE,SFTP_TARGET_LOCAL,SFTP_TARGET_REMOTEandSFTP_OPERATION, so one script can serve several configs.- Gated by a new
isUploadflag set on exactly four handlers —sync local ➞ remote,upload,upload file,upload folder. Downloads andsync remote ➞ localnever run it. - Fails closed: it runs before the spinner and before any connection is opened, and its rejection propagates, so a failure means nothing was transferred. A hook that failed open would silently reintroduce the drift it exists to prevent.
- Runs once per command, not once per file — a folder upload recurses inside the handler, below this point.
- Gated by a new
- A persistent on-disk transfer log. Upstream logs only to the Output panel, which clears, leaving no record of what went where. Every line the panel receives during an operation is now also written to
<config local root>/sftp-transfer-logs/sftp-transfer-YYYY-MM.log.- Monthly files rather than numbered rotation, so "what happened on 15 August" is a filename.
transferLogKeepMonths(default 24) prunes older ones;transferLog: falsedisables it per config. - Written per project:
createFileHandlerpoints the logger at the log belonging to the config running the operation and releases it in afinally, so an aborted push cannot leave a later operation writing into the wrong project's log. - Lines emitted outside an operation — activation, config loads — belong to no project and stay panel-only.
- The log lines carry a four-digit year, which the panel's own stamp omits.
- Consuming projects must add
/sftp-transfer-logsto theignorelist of everysftp.json, since the folder sits inside a synced tree and would otherwise upload itself.
- Monthly files rather than numbered rotation, so "what happened on 15 August" is a filename.
Files touched: src/logger.ts (a settable sink beside the output channel), src/modules/transferLog.ts (new), src/modules/beforeUpload.ts (new), src/fileHandlers/createFileHandler.ts (both wired at the one point every file operation passes through), src/fileHandlers/transfer/index.ts (isUpload on four handlers), src/core/fileService.ts (four config fields), schema/definitions.json (so sftp.json accepts them without complaint).
2026-08-15
- Branched
watchlistfrom tagv1.16.3. Thedevelopbranch was not used: it does not compile (a missing import insrc/commands/abstract/createCommand.tsand avscode-uriexport mismatch insrc/helper/paths.ts), and it carries unreleased changes that have no place in a build that sits in a deploy path. - Identity changed so the marketplace cannot update over this build and so it is distinguishable in the extensions list:
name→sftp-watchlist,publisher→DougJoseph,displayName→SFTP (watchlist fork), withrepository,bugsandhomepagepointed at this fork. The upstream maintainer's personal email was removed frombugsandauthorso error reports from this build cannot be directed at him. authorretained as Natizyskunk, who wrote nearly all of this code; local additions are recorded undercontributors.- Command ids remain
sftp.*andjsonValidationstill matches.vscode/sftp.json, so existing menus, keybindings and config files work unchanged. LICENSE.txtdeliberately untouched. The MIT terms and the original copyright notice stand.