sea: mount bundled assets as a virtual file system - #65675
Open
mcollina wants to merge 1 commit into
Open
Conversation
Collaborator
|
Review requested:
|
mcollina
force-pushed
the
vfs-sea-integration
branch
3 times, most recently
from
August 31, 2026 09:14
148a0d7 to
4991e64
Compare
mcollina
requested review from
Qard and
joyeecheung
and removed request for
Qard
August 31, 2026 10:46
pipobscure
added a commit
to pipobscure/bundles
that referenced
this pull request
Sep 1, 2026
The tool was one directory of JavaScript that doubled as a library by accident. This makes the library the point: `src/` is TypeScript compiled to ESM in `dist/`, every capability has a declared entry point, and the CLI is a thin wrapper over the same functions an embedder gets. Four things are now separately importable, which is the shape the rest of the design needs: . create / sign / verify / inspect / run, from code (api.ts) ./record the -r preload that writes down what a run reads ./register the -r preload that mounts only what is signed ./sea build and boot a self-validating executable plus ./provider, ./recorder, ./cli, ./manifest, ./archive, ./files, ./skill, ./sigstore and ./oidc for the layers underneath. The package root deliberately does not re-export the two providers: importing either needs node:vfs, and creating or verifying an archive does not, so a plain `import '@pipobscure/bundle'` must not drag `--experimental-vfs` in. There is a test that holds that line. The sources are erasable-syntax-only, so `node src/main.ts` runs them directly under node's type stripping. That is what lets the tests import the sources rather than the build, and a preload be `-r ./src/register.ts`. @types/node carries neither the node:zlib ZIP API nor node:vfs's provider registry, so `src/types/` declares them; the shapes were checked against the running runtime rather than transcribed from documentation. sea.js is replaced by src/sea.ts. The old bootstrap was a copy of manifest.js inlined into a CommonJS file, which had drifted: its signature marker regex was still the two-field form, so it read every sigstore-signed container as unsigned. The replacement mounts this package out of the SEA blob with node:vfs and requires the real library from there — the userland form of nodejs/node#65675, with the difference that the mount running the application is the signed archive appended to the file. Nothing is duplicated, and the verifier a container runs is the one the test suite tests. `bundle sea` builds one. Three bugs the type checker and the new tests turned up, all real: * --identity and BUNDLE_IDENTITY were only consulted on the sigstore path, so an archive signed against an ordinary CA — which carries no identity claim at all — satisfied a policy demanding one. A machine configured to run only releases from a workflow would have mounted anything key-signed. It now reports valid-untrusted. * Arguments beginning with `--` never reached a mounted application; node claimed them as its own flags. mountArgv() now ends with `--`. * Verifying from a Buffer crashed, and sigstore signing was written against @sigstore/bundle v2 while v3 is installed. Both fixed, and the Buffer path now has a test. 131 tests over the format, both providers, the API, the CLI, the SEA and the published package's own shape, replacing three JavaScript suites.
mcollina
marked this pull request as ready for review
September 1, 2026 15:04
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #65675 +/- ##
==========================================
+ Coverage 90.05% 90.06% +0.01%
==========================================
Files 754 756 +2
Lines 256308 257020 +712
Branches 48464 48579 +115
==========================================
+ Hits 230817 231494 +677
- Misses 16593 16634 +41
+ Partials 8898 8892 -6
🚀 New features to boost your workflow:
|
jasnell
reviewed
Sep 1, 2026
Support "useVfs": true in the SEA configuration: mount the bundled assets as a read-only VFS and run the CommonJS or ESM main script from inside the mount. Signed-off-by: Matteo Collina <hello@matteocollina.com>
mcollina
force-pushed
the
vfs-sea-integration
branch
from
September 2, 2026 06:52
de3de10 to
70c5a3f
Compare
ShogunPanda
approved these changes
Sep 2, 2026
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.
This adds the SEA integration for the virtual file system landed in #63653: setting
"useVfs": truein the SEA configuration mounts the bundled assets as a read-only VFS and runs the injected main script from inside the mount.Since a VFS never shadows the real file system and its mount point is reserved and chosen at runtime, there is no fixed
/seapath. Instead, the main script is placed at the root of the mount and executed from there, so:__filenameand__dirnamepoint inside the virtual file system;__dirname-relative paths with regularnode:fsAPIs;require()calls andnode_moduleslookups resolve against the bundled assets, confined to the mount by the module loader integration.Implementation notes:
SEAProvideris read-only and lazy: asset content stays in the executable's SEA blob and is copied into JS memory only when a file is opened, with sizes cached forstat.VirtualFileSystemexperimental warning; the SEA warning already covers it."mainFormat": "module") are supported: the ESM main is loaded from inside the mount through the ESM loader, soimport.meta.url/filename/dirnamereflect the mount and static imports, dynamicimport(), and bare specifier lookups resolve against the bundled assets."useVfs"is rejected together with"useSnapshot"and"useCodeCache".This PR was prepared with the help of AI. I've reviewed all changes myself.