Add standalone native binaries for Windows/macOS/Linux - #54
Open
sugatoray wants to merge 7 commits into
Open
Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Adds src/packages/binaries/ (@pptxdiff/binaries): builds a standalone pptxdiff executable per OS via Node's Single Executable Applications feature, so a user can download one artifact and run it without installing Node.js. Deliberately standalone binaries, not signed OS installers — asked directly, matching a prior explicit decision to avoid Electron/Tauri-style installer/signing overhead. - bin/cli.js: startServer() gains a backward-compatible optional `root` param so the packaged binary can serve assets from next to itself instead of the npm package's own directory. - sea-entry.cjs + build.mjs: bundle via esbuild, generate the SEA blob, inject via postject, copy static app assets alongside the binary, zip as the downloadable artifact. - .github/workflows/binaries.yml: 3-OS CI matrix (SEA has no cross-compile mode, so each OS's binary is built on that OS). - make pkg.binaries.build / npm run build:binary for local builds. Verified end-to-end on Linux: built, ran the actual packaged binary, confirmed it serves index.html/support.js/vendor/* correctly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BxwMTp6RQJ6j6K5K8Jjdpm
build.mjs gains an entrypoint guard (matching capture_screenshots.mjs's
existing pattern) exporting PLATFORM_MAP/ASSET_ENTRIES/resolveTarget/
buildBinary for testability.
- test_build_config.mjs (fast, pure, `npm test`): 17 assertions,
including a static regression guard on bin/cli.js's
startServer(root = ROOT) signature. Demonstrated genuine RED->GREEN
by temporarily reverting that signature and confirming the test
catches it.
- test_build_e2e.mjs (slow, real, `npm run test:e2e`): builds and
runs the actual packaged binary, verifying real HTTP responses and
path-traversal rejection. 11/11 against a real build in this
sandbox.
- Fixed a real bug found while writing the e2e test: the "clean the
output dir" step was a blind rm -rf that would have deleted each
OS folder's tracked README.md/CHANGELOG.md on every build. Replaced
with a targeted cleanup that only removes generated entries;
verified by running the real build twice and confirming the docs
survive both times.
- Added CHANGELOG.md to each pptxdiff-{win,mac,linux} folder and
filled in the root CHANGELOG.md's previously-empty [Unreleased]
section.
- .github/workflows/binaries.yml now runs both test suites before
building each OS's release artifact.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BxwMTp6RQJ6j6K5K8Jjdpm
Direct follow-up to "why aren't you using yao-pkg/pkg?" — investigated hands-on and confirmed two real advantages over Node's SEA feature: - Genuine cross-compilation: built real Windows (PE32+) and macOS (Mach-O) binaries from this Linux sandbox, something SEA cannot do at all (it can only build for its own currently-running platform). - Built-in asset embedding needing zero bin/cli.js changes: pkg's snapshot filesystem preserves the real project's relative directory layout, so pointing pkg directly at the unmodified bin/cli.js with src/pptxdiff/** as assets makes the existing ROOT computation just resolve correctly. Reverted the SEA-era startServer(root) parameter entirely — bin/cli.js is now byte-identical to before this feature. Found and fixed a real, silently-failing gotcha mid-switch: pkg's "assets" glob paths resolve relative to wherever the config file itself lives, not cwd or the entry file's directory. Confirmed via a controlled A/B test; fixed by writing the temp pkg config directly at the repo root (removed in a finally block). New WISDOM.md trap entry with the full reproduction. macOS is deliberately NOT cross-compiled even though pkg technically can: codesign only exists on macOS, and an unsigned binary may not launch at all on Apple Silicon. .github/workflows/binaries.yml now runs 2 jobs instead of 3: linux+win build together on ubuntu-latest (genuine cross-compile), mac stays on its own macos-latest runner. Both test files rewritten and re-verified with genuine RED->GREEN on the config-colocation guard. Output is now a true single file per OS (no more assets/ folder, no more zip wrapper). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BxwMTp6RQJ6j6K5K8Jjdpm
Direct follow-up to "does the mac binary work for Apple Silicon MacBooks?" - the honest answer was yes, but only via Rosetta 2 translation, since only the Intel (x64) target existed. TARGET_MAP gains an outDirKey field, separate from the map's own key, so `mac` and the new `mac-arm64` (node22-macos-arm64) share one output folder (pptxdiff-mac/) while keeping distinct binary names. buildOne() now computes outDir from target.outDirKey rather than the osKey argument. .github/workflows/binaries.yml's build-mac job now builds both mac targets; test_build_e2e.mjs picks mac vs mac-arm64 based on the host's actual os.arch(), so GitHub's Apple Silicon macos-latest runners genuinely exercise the native build. Verified for real in this sandbox: built the arm64 target directly, confirmed via `file` a genuine Mach-O 64-bit arm64 executable, confirmed it lands in the shared folder without disturbing the tracked README.md/CHANGELOG.md there. pkg's own error output independently confirmed the Apple Silicon signing requirement this project's reasoning already relied on. Windows and Linux stay x64-only - not asked about, and arm64 desktop usage is a smaller fraction of their likely audience than Apple Silicon is of the Mac audience. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BxwMTp6RQJ6j6K5K8Jjdpm
Direct follow-up to "can we support arm64 for windows and linux as well?" - immediately after the mac-only arm64 addition. Unlike macOS, neither Windows nor Linux needs a signing step, so both new targets (node22-win-arm64, node22-linux-arm64) fold into the existing cross-compiled build-linux-win CI job rather than needing a new one. Found and fixed a real build failure while verifying pkg actually supports these targets: cross-arch builds need to execute a matching-arch helper binary to generate V8 bytecode, which fails with a genuine exec-format error on a host with no QEMU/binfmt emulation for that arch (confirmed absent in this sandbox, not assumed). pkg's own warning named the fix: --fallback-to-source, now applied unconditionally in buildOne() (a no-op for same-arch builds). Verified via the real production build path: real ELF aarch64 and PE32+ Aarch64 executables, binary size consistent with real assets being embedded, landing correctly in each OS's existing shared output folder without disturbing the tracked docs there. Neither binary was run (no arm64 execution emulation in this sandbox) - CI is what actually executes them for the first time. Genuine RED->GREEN demonstrated on the new --fallback-to-source regression guard, which protects against a class of failure that would silently break every arm64 target while leaving x64 green. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BxwMTp6RQJ6j6K5K8Jjdpm
The public MkDocs docs-site had never been touched across any of the @pptxdiff/binaries commits, even though docs/.scrolls was kept current throughout - confirmed via git log rather than assumed. - getting-started.md: new "Option D - standalone binary" install option, with a matching doc_coverage id (native-binaries, partial). - cli.md: cross-link to Option D. index.md: updated install card. - limitations.md: new row for the binaries' own limitations, and reworded the existing "browser tab, not native window" row so it doesn't read like the binaries are an exception to it. - New changelog subpage changelogs/pptxdiff-binaries.md, transcluding all three per-OS CHANGELOG.md files (this package has no single package-level one) - added to nav and the changelog index. - coverage_registry.yml: two new ids, native-binaries and native-binaries-limitations; sync_doc_coverage.py --write/--check re-run (36 complete, 4 partial, 0 missing). Found and fixed a real mkdocs build --strict failure: the three per-OS CHANGELOG.md files' relative link back to the root CHANGELOG.md was correct on GitHub but broke once transcluded into the new subpage at a different path. Fixed at the source with an absolute GitHub URL, matching every other changelog subpage's existing pattern. Verified for real: mkdocs build --strict clean, and directly grepped the built HTML to confirm the new anchor matches exactly between the defining page and both pages that link to it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BxwMTp6RQJ6j6K5K8Jjdpm
Rebasing the binaries branch onto master (which landed Homebrew and Chocolatey packaging work in the interim) required renumbering the binaries SPEC.md section from the collided §32 to §36, since master's Homebrew formula legitimately owns §32. A few self-references to the binaries feature's own section number, written before the rebase, still said §32 in HANDOFF.md, PLAN.md, and the per-OS CHANGELOG.md files - fixed to §36 (verified every remaining §32 reference in the repo is the real, correct Homebrew one). Also regenerates documentation-coverage.md via sync_doc_coverage.py --write, since the getting-started.md "Option D" naming collision (both this branch and master's Homebrew work independently claimed it) was resolved by renaming this branch's option to "Option E". Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BxwMTp6RQJ6j6K5K8Jjdpm
sugatoray
force-pushed
the
claude/pptxdiff-installers-m3mym2
branch
from
August 9, 2026 03:17
66072eb to
50fe345
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds src/packages/binaries/ (@pptxdiff/binaries): builds a standalone
pptxdiff executable per OS via Node's Single Executable Applications
feature, so a user can download one artifact and run it without
installing Node.js. Deliberately standalone binaries, not signed OS
installers — asked directly, matching a prior explicit decision to
avoid Electron/Tauri-style installer/signing overhead.
rootparam so the packaged binary can serve assets from next toitself instead of the npm package's own directory.
blob, inject via postject, copy static app assets alongside the
binary, zip as the downloadable artifact.
cross-compile mode, so each OS's binary is built on that OS).
Verified end-to-end on Linux: built, ran the actual packaged binary,
confirmed it serves index.html/support.js/vendor/* correctly.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01BxwMTp6RQJ6j6K5K8Jjdpm