Repository navigation
feat(vfs-bundle): suggestedEntries; github-bundle defaults to them and to the default branch's head - #199
Merged
Conversation
exo-nikita
force-pushed
the
claude/affectionate-ritchie-1j9umy
branch
from
October 2, 2026 02:00
c95d9d1 to
ae35586
Compare
exo-nikita
force-pushed
the
claude/affectionate-ritchie-1j9umy
branch
2 times, most recently
from
October 2, 2026 03:21
78e7d43 to
3c3a274
Compare
…d to the default branch's head
`@exodus/stasis/vfs-bundle` exports suggestedEntries: the JS entry points a package.json names,
as paths from its directory, resolved the way the JS build resolves them under the same
`conditions`, `mainFields`, `metro`, `platforms`, `jsx` and `typescript`, which are checked the way
the build checks them. In order:
- The package's own entry, resolved as `./` resolves there. That is `main` as Node takes it, or,
with `mainFields` or `metro`, the build's field resolver (Metro's main fields, platform
suffixes and browser maps) once per platform.
- Each `exports` subpath, except patterns and folder mappings, resolved through the package's
name for require() and for import, with the conditions the build adds (the React Native ones
under `metro`, plus browser on web).
- Each `bin`.
Under `typescript`, an entry point that resolution misses (one named by its compiled output) is
mapped to its TS source the way tsc maps it, as the build's fallback does. For `exports`, the
fallback's mapping is now typescriptExportsTarget in resolve-typescript.js.
Only files inside that directory count, and only when the package.json names them from within
it. A main field or `bin` pointing above the directory is left out, so a directory downloaded on
its own gives the same answer as the whole repo. With no package.json the result is empty.
suggestedEntries takes either a project held in a Vfs (`{ vfs, cwd }`) or a GitHub repo at a
commit (`{ github, sha, directory, client }`). For a repo, the directory is downloaded on its own
when it is a plain directory in git with no symlink out of it; otherwise the whole repo is.
buildGitHubBundle and `stasis github-bundle` now take `sha` and `entries` as optional:
- Without `sha`, they build the head of the default branch, as GitHub names it (getRepoHead).
That commit becomes the bundle's `repo.commit`, and the CLI summary prints it.
- Without `entries`, a JS bundle (pnpm, yarn1) takes the entries suggestedEntries suggests for the
tree already fetched, under the build's own options (`--typescript` included). If there are none, the build is refused
before anything is installed. The options are still checked before anything is fetched,
against a JS entry, since every suggested entry is one.
- A Solidity bundle (soldeer) still needs its entries.
The legacy-field build's per-platform resolver setup becomes fieldResolverFor in cmd/bundle.js,
which the build and the default entries both use; the build itself is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KPSLumcb6Rdo4xXL5s5CpE
exo-nikita
force-pushed
the
claude/affectionate-ritchie-1j9umy
branch
from
October 2, 2026 05:45
3c3a274 to
c30593f
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.
suggestedEntries@exodus/stasis/vfs-bundleexportssuggestedEntries. It returns the JS entry points apackage.jsonnames, as paths from its directory. They are resolved the way the JS build resolves them under the sameconditions,mainFields,metro,platforms,jsxandtypescript, which are checked the way the build checks them. In order:./resolves there. That ismainas Node takes it, or, withmainFieldsormetro, the build's field resolver once per platform (Metro's main fields, platform suffixes and browser maps). For example,main: "index"givesindex.ios.js/index.android.js.exportssubpath, resolved through the package's name for bothrequire()andimport, with the conditions the build adds: the React Native ones undermetro, plusbrowseron web. Patterns (./x/*) and folder mappings (./x/) are skipped.bin.Under
typescript, an entry point that resolution misses is mapped to its TS source the way tsc maps it, as the build's fallback does. Such an entry is one named by its compiled output; for example,main: "lib/index.js"giveslib/index.ts. A compiled.jsthat exists in the tree still wins over its source.Only files inside that directory count, and only when the
package.jsonnames them from inside it. A main field orbinthat points above the directory is left out, so a directory downloaded on its own gives the same answer as the whole repo. Without apackage.jsonthe result is empty.For a repo,
shadefaults to the head of the default branch. The directory is downloaded on its own when it is a plain directory in git with no symlink out of it; otherwise the whole repo is downloaded. Either way the bytes come from GitHub or from the cache, asbuildGitHubBundlefetches them.buildGitHubBundle/stasis github-bundlesha/--shaandentriesare now optional:sha: builds the head commit of the default branch, as GitHub reports it (getRepoHead). That commit becomes the bundle'srepo.commit, and the CLI summary prints it.entries, for JS bundles (pnpm,yarn1): uses the entriessuggestedEntriesreturns for the tree already fetched, under the build's own--conditions,--mainFields,--metro --platformsand--typescript. If there are none, the build is refused before anything is installed. The options are still checked before anything is fetched, against a JS entry, since every suggested entry is one.soldeer): these still need their entries listed, and fail with an error before anything is fetched.Shared code
Two pieces are pulled out so the default entries use exactly what the build uses. Both are pure extractions:
stasis bundleandbuildVfsBundlebehave the same.fieldResolverFor(cmd/bundle.js): the build's per-platform field-resolver setup.typescriptExportsTarget(resolve-typescript.js): the fallback's mapping ofexportstargets. The fallback finds a package only undernode_modules, so it can't map a package's ownexports; this helper takes the package's directory instead.The new module is
stasis/src/vfs-bundle/entries.js, which is added to the package'sfiles. The README row and the CLI usage text are updated.Tests
tests/vfs-bundle-github.test.jscovers the following. The fake client gainsgetRepoHead, and itsgetRepoTreeIdnow refuses a path that is not a directory, as upstream does.Repo vs. Vfs:
suggestedEntriesgives the same answer for both, with and withoutconditions, at the default branch's head, and empty with nopackage.json.Metro, platforms and
mainFields: checked on a React Native package whose own entry andexportsdiffer by field, platform and condition:browser;metroon ios and android;metroon web;mainFields;Each case is checked three ways: over a repo, over a Vfs, and as
buildGitHubBundle's default.typescript:mainandexports(including animport-only.mts) named by compiled outputs, with only the TS sources present;main, completed (a.d.tsis never picked);.jswinning over its source;metro.Option refusals: the build's own messages, e.g.
--metrowithout--platforms, or--conditionscombined with--metro.Directory handling:
A main field or
binwritten../x.jsis not suggested; this is also checked through the Metro main fields.Argument checks for
suggestedEntries, before anything is fetched.buildGitHubBundle:CLI: runs with neither
--shanor entries.No disk reads: that test also builds from default entries, and from default entries under
--metro.node --run lintis clean andnode --run testpasses: 2144 passed, 3 skipped.🤖 Generated with Claude Code
https://claude.ai/code/session_01KPSLumcb6Rdo4xXL5s5CpE