Fix: keep Node built-ins out of the @google/adk browser entry graph - #671
Open
AmaadMartin wants to merge 4 commits into
Open
Fix: keep Node built-ins out of the @google/adk browser entry graph#671AmaadMartin wants to merge 4 commits into
AmaadMartin wants to merge 4 commits into
Conversation
added 4 commits
August 5, 2026 01:59
core/src/common.ts is the export surface shared by the Node entry and the browser entry, but the skills toolset, the skills loader and loadWebPage reached node:fs/promises, node:path, node:dns/promises and node:net through it. Re-export them from core/src/index.ts so the Node surface is unchanged.
The bundled build hardcoded dist/<target>/index.js, so it wrote dist/web/index.js while core/package.json#browser names dist/web/index_web.js. esbuild also rejects alias without bundle, so the browser shims never reached the non-bundled build that prepublishOnly runs.
…egex The regex could not see an unprefixed specifier, and core/src/artifacts/ file_artifact_service.ts imports 'fs/promises' that way, so an unprefixed leak into the common.ts graph would have passed. The metafile lists every external import structurally and node:module's isBuiltin accepts both spellings.
7 tasks
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.
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
Link to an existing issue (if applicable):
Or, if no issue exists, describe the change:
Problem:
core/package.json#browsernames./dist/web/index_web.js, but the browser entry graph reachesnode:dns/promises,node:net,node:fs/promisesandnode:path, so a bundler cannot resolve it.core/src/common.tsis the export surface shared by the Node entry and the browser entry, and the filesystem-backed skills toolset, the skills loader andloadWebPagehad leaked into it. The bundled build also wrotedist/web/index.js, a name thebrowserfield never points at. esbuild rejectsaliaswithoutbundle, so thenode:async_hooksshim never reached the non-bundled build thatprepublishOnlyruns.Solution: I moved those exports from
core/src/common.tstocore/src/index.ts, so the Node surface is unchanged and the browser graph loses the built-ins.core/build.jsnow derives the bundled output name from the entry, and the web target always bundles so the shim alias reaches the published artifact. Theesmandcjsoutputs are unchanged in both build modes.Consequences worth knowing:
core/dist/web/goes from 198 emitted.jsfiles toindex_web.jsplus its sourcemap.core/package.json#browseris the only reference tocore/dist/webin the repo.minifyandsourcemapderive frombundle, so the published web artifact is now minified with a sourcemap. That was already the shape of thebuild:bundleweb output.loadWebPage. Neither could ever run in a browser, and the browser entry does not load at all today.integrations/build.js:60has the byte-identical output-name bug, andintegrations/package.json:21names./dist/web/index_web.jstoo, so thatbrowserfield is dead the same way. I left it for a follow-up:integrations/src/index_web.tsexports onlyversion, so it has no built-in leak and no alias table, and fixing it here would widen a leak-focused PR.Two deviations from the task spec, both because the tree moved under it:
node:cryptoin the browser graph and acrypto_shim.tsalias. Neither exists now:core/src/utils/env_aware_utils.tsalready usesglobalThis.crypto, andcore/build.jsaliases onlynode:async_hooks. The test pins the set the alias table actually declares.env_aware_utils.ts. That comment no longer says the stale thing, so I left the file alone.Collision check
I checked the 569 open PRs on the fork. Nothing lands this change. The adjacent ones are complementary and I did not stack on any of them:
createRequirebanner on the Node platform. That banner is the one remaining Node-shaped import in the web bundle and is out of scope here.node:async_hooksalias with a runtime store swap. It touches a different part ofcore/build.js.core/src/common.ts.#555 also adds
tests/integration/build_output/web_output_test.ts, which asserts the emitteddist/webcontents. I did not add a second build-output test at that path; the build script edits are verified by the manual steps below.Testing Plan
Unit Tests:
New file
core/test/index_web_test.ts(4 cases). The first bundlescore/src/index_web.tswith esbuild and no alias, reads the external imports out of the metafile, and asserts the onesisBuiltinaccepts equal the setcore/build.jsaliases. The metafile is what makes the guard complete: an unprefixed specifier such as theimport * as fs from 'fs/promises'incore/src/artifacts/file_artifact_service.ts:8is a real built-in that anode:text scan cannot see. The rest pin the symbol lists on both entry points.Proof the tests can fail. Each mutation below was applied to the fixed tree, run, and reverted.
export {LOAD_WEB_PAGE, loadWebPage} from './tools/load_web_page.js';tocore/src/common.ts:export {SkillToolset} from './tools/skill/skill_toolset.js';tocore/src/common.ts:export {FileArtifactService} from './artifacts/file_artifact_service.js';tocore/src/common.ts, the unprefixed case:loadSkillFromZipBufferfrom the./skills/loader.jsblock incore/src/index.ts:Revert
bundle: truetobundleon the web target incore/build.js:npm run buildemits 198 per-file modules intocore/dist/web/, andcore/dist/web/utils/client_labels.jskeeps its rawnode:async_hooksimport.Revert the outfile derivation to
./dist/${targetDir}/index.js:npm run buildemitscore/dist/web/index.js, whichcore/package.json#browserdoes not name.Coverage: this change adds no executable source line.
core/src/common.tsandcore/src/index.tsare re-export only, andcore/build.jsis outside the coverageincludeglobs invitest.config.ts.Manual End-to-End (E2E) Tests:
core/dist/esm/index.js,core/dist/cjs/index.jsandcore/dist/types/index.d.tsexist in both modes, and the.d.tsstill declares all 14 moved symbols.Repo gates, run from the root on the pushed commit:
npm run build,npm run lint,npm run format:checkandnpm run docs:checkall exit 0.npm run ts:checkreports the same 286 errors in 46 files before and after this change — the two error sets are byte-identical, so the failure is pre-existing and unrelated.Checklist