Hardening release for the whole distribution chain — the npm package, the three bootstrap wrappers, and the curl-pipe installer. Driven by a full three-way adversarial review of the repo (22 findings, all addressed here or explicitly deferred). No changes to the extraction engine or benchmarks.
Fixed
- Windows npm install — 0.5.0 shipped Windows binaries, but the package's
osfield still blockednpm install -gon Windows withEBADPLATFORM.win32is now allowed. - Installer
$0hijack — undercurl ... | sh, the installer preferred a local./bin/<command>over the official download, so running it inside an untrusted directory could install that directory's scripts. The local-copy path now requires$0to be a realinstall.shon disk. The installer also stages all three commands and only then swaps them in, so a failed download can no longer leave a mixed-version install. - Bricked-install path — a truncated download could previously pass validation, get recorded as the current release, and never be re-fetched. Installs now propagate every error, validate the archive strictly (exactly one regular file, no symlinks or extras), and smoke-test the new binary before committing it.
Added
- Download integrity — when the CDN provides a
<target>.tar.gz.sha256sidecar, the wrappers verify it before installing; a mismatch aborts. SetNUTRIENT_REQUIRE_CHECKSUM=1to make verification mandatory. Downgrades (CDN rollback) now print a warning. - Concurrency safety — an install lock (with stale-lock recovery) serializes updates across all three commands; the live install directory is replaced via an atomic move-aside swap and is never deleted first; state writes and verb links are atomic and race-free (also fixes a Git Bash inefficiency that re-copied the binary on every invocation).
- Network limits — connect/transfer timeouts, bounded retries, and HTTPS-only redirects on every wrapper and installer download, so a stalled CDN can no longer hang an invocation indefinitely.
CI
- shellcheck on all four shell scripts, a macOS matrix leg, installer coverage for all three commands, least-privilege workflow permissions, and a release-tag guard that fails closed on registry errors and verifies the tag's
package.jsonversion.
Install / upgrade
npm install -g @pspdfkit/pdf-to-markdownExisting installs pick up CDN binary updates automatically; wrapper-script changes arrive via npm update -g (or re-running install.sh).
Full changelog: https://github.com/PSPDFKit/pdf-to-markdown/blob/main/CHANGELOG.md