fix[notask]: bump drifted peer ranges + trim redundant SDK peer entries#2089
Merged
Conversation
eb6255c to
b812fbb
Compare
b812fbb to
50afa6c
Compare
50afa6c to
ba9e1ab
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Two related changes to the SDK's `peerDependencies` block, both motivated
by the same TD-HOLEPUNCH-PEER-DEPS follow-up effort: keep the peer block
to what the SDK actually owns, and stop shipping duplicate copies of
stateful Holepunch / bare-* singletons in consumer trees.
Drifted ranges bumped:
- compact-encoding ^2.19.0 -> ^3.0.0 (major dedup: 17+ nested ^3.x copies
across hyperswarm/corestore/hypercore/
hyperdb/hyperblobs/hyperdht/hyperschema/
hyperdispatch/protomux/... collapse to
a single top-level; silences the
`npm ls invalid` warning on every
consumer install)
Redundant peer entries removed:
- bare-dns (transitive via bare-net; SDK doesn't import it; no need
to re-declare a floor on what bare-net already pins)
- bare-http1 (transitive via bare-fetch; same reasoning)
- bare-https (transitive via bare-fetch; removing entirely instead of
bumping ^2.1.3 -> ^3.0.0 — once SDK stops declaring its
own floor, bare-fetch's ^3.0.0 wins and the duplication
resolves)
Moved out of peerDependencies (still listed where SDK source needs them):
- events -> devDependencies (only used by `.d.ts` type stubs;
@types/node already provides the
EventEmitter type; consumers don't
need the npm `events` package at
runtime — Node has it built-in and
Bare maps it to bare-events)
- tar-stream -> dependencies (used in server/utils/archive.ts; no
other consumer in the install tree
so no dedup concern from making it
a hard dep)
llm-splitter KEPT as a required SDK peer. @qvac/rag declares it as an
*optional* peer in its own manifest, which means npm skips installation
unless --include=optional is passed. Removing the SDK-level required peer
broke the LLMChunkAdapter path at runtime (caught by E2E smoke: rag-
embeddings-small-chunks, rag-large-document-32kb, rag-medium-document-10kb
all failed with "Required dependency missing: llm-splitter is required
for LLMChunkAdapter"). The SDK-layer required peer is what guarantees
the package is installed in consumer trees. Revisit if @qvac/rag ever
promotes llm-splitter from optional to required, or bundles it as a hard
dep.
bare-subprocess v6 still deferred for the same reason as before: the only
v6 consumer in the SDK tree today is bare-link@3.2.2 (5-day-old release
at original audit time), and bare-runtime@1.x is still firmly on ^5.0.0.
Revisit when bare-runtime catches up.
This is the first step of the broader peer-deps cleanup effort tracked
in the QVAC SDK & Platforms Asana project. Future steps may consider
moving compact-encoding out of peers entirely and auditing the remaining
optional peers, but those are out of scope here.
No source changes; package.json metadata only.
Validation:
- `bun install` in packages/sdk -> clean.
- `bun run build` -> clean.
- Dedup check via `/tmp/sdk-dedup-check.sh` against packed SDK -> ✅
no Holepunch singletons duplicated.
- E2E smoke catch on initial revision (no llm-splitter) confirmed the
removal was wrong; reverted.
Co-authored-by: Cursor <cursoragent@cursor.com>
ba9e1ab to
4fce30d
Compare
Contributor
QVAC E2E —
|
Contributor
Contributor
Contributor
Contributor
QVAC E2E —
|
opaninakuffo
approved these changes
May 19, 2026
NamelsKing
approved these changes
May 19, 2026
Contributor
Author
|
/review |
Contributor
Tier-based Approval Status |
opaninakuffo
added a commit
that referenced
this pull request
May 20, 2026
* fix: drop SDK peerDependencies; enforce in CI Completes the peer-deps cleanup trajectory started in #2089 by removing the peerDependencies + peerDependenciesMeta blocks from @qvac/sdk entirely and adding a CI gate that asserts the invariant holds on every SDK pod PR. Policy: - dependencies: every package directly imported by SDK source. - devDependencies: build / typecheck / lint-only modules. - No peer declarations -- host owns anything SDK doesn't import. CI gate (.github/workflows/pr-checks-sdk-pod.yml, sdk-only): - Packs the tarball and installs it into a fresh consumer dir. - Fails on any ERESOLVE / `npm warn peer` line on install. - Fails if any of corestore / hyperswarm / hyperdrive / hyperdb / hyperblobs / hyperdht resolves to more than one copy. - Smoke-imports @qvac/sdk and asserts >= 50 named exports. * fix: split SDK conditional modules into optionalDependencies Promote the 7 packages that are runtime-conditional (per-platform or per-feature) from devDependencies into optionalDependencies: - @modelcontextprotocol/sdk (MCP, only if hosting an MCP server) - bare-link (Bare-only linker shim) - compact-encoding (pin to ^3 to dedupe Holepunch v3 tree) - expo-device (Expo runtime only) - expo-file-system (Expo runtime only) - pear-pipe (Pear runtime only) - react-native-bare-kit (RN/Expo runtime only) Why not regular dependencies: - Backend consumers (npm install --omit=optional) get a 182-package tree instead of 790; mobile/Pear consumers get the plug-n-play default with all 7 auto-installed. Why not peerDependencies: - npm 7+ auto-installs peers and emits ERESOLVE on range drift, which is the exact failure mode this PR is fixing for Keet. Validated: - Keet-shape repro (cross-worker-bare-kit@^2 + @qvac/sdk): 0 ERESOLVE. - Default install: 0 peer warnings, 7/7 optionals present. - --omit=optional: 0 peer warnings, lean tree, Holepunch invariant still holds (single copy of corestore / hyperswarm / hyperdrive / hyperdb / hyperblobs / hyperdht / react-native-bare-kit). * test[ci]: add --omit=optional install gate to SDK consumer check The default-install gate validates the plug-n-play path (all optionals present); it does not exercise the lean backend path that consumers get with `npm install --omit=optional`. That path was implicitly trusted when we adopted optionalDependencies in the previous commit. Refactor the inline gate into a check_consumer() helper and call it twice: 1. Default install (plug-n-play): all 7 optionalDeps installed. Catches Keet-style ERESOLVE from optional deps' peer ranges colliding with other deps. Validates mobile/Pear consumer profile. 2. Lean install (--omit=optional): no optionalDeps. Catches (a) backend-required packages accidentally classified as optional, (b) SDK entry-point eagerly importing an optional module. Both scenarios run the same three assertions: - No ERESOLVE / `npm warn peer` lines. - Single copy of corestore / hyperswarm / hyperdrive / hyperdb / hyperblobs / hyperdht. - Smoke import yields >= 50 named exports. Validated locally: lean install yields 385 named exports (well above threshold), Holepunch invariant holds, 0 peer warnings. Adds ~60s of CI per SDK pod PR. * update dev deps * fix: address review — restore expo-build-properties; revert bare-subprocess major bump - Add expo-build-properties to optionalDependencies. withQvacSDK wires it by string into the Expo plugin chain, so dropping it entirely broke plug-n-play for Expo consumers (the consumer-install gate runs in a Node consumer dir, so it didn't catch the missing Expo plugin module). Keeping it optional preserves the previous behavior while letting Node-only backends skip it via --omit=optional. - Revert bare-subprocess to ^5.2.3 (was bumped to ^6.0.0 by bun add). v5→v6 is a major bump for what is only a dev-time shim consumed by scripts/bare-bootstrap.js; staying on the prior major avoids dragging drift into the dev tree and keeps NOTICE accurate. Validated: - bun install + bun run build clean. - Consumer install gate (default + --omit=optional): both green, Holepunch invariant holds, 385 named exports. * chore: drop hyperdb + hyperblobs from SDK dependencies Neither package is imported by SDK source — they were guarantor pins for @qvac/registry-client, which declares both as non-optional peerDependencies. npm 7+ auto-installs non-optional peers, so the consumer install graph is unchanged: hyperdb and hyperblobs still resolve to a single copy in both default and --omit=optional installs, satisfied by registry-client's own peer ranges. Aligns with the "declare what you import, nothing else" policy. Validated: - bun install + bun run build clean. - Default install (790 pkgs): single copy of corestore / hyperswarm / hyperdrive / hyperdb / hyperblobs / hyperdht. - --omit=optional install (182 pkgs): same. - 0 peer warnings in both scenarios; 385 named exports.
Proletter
pushed a commit
that referenced
this pull request
May 24, 2026
…es (#2089) Two related changes to the SDK's `peerDependencies` block, both motivated by the same TD-HOLEPUNCH-PEER-DEPS follow-up effort: keep the peer block to what the SDK actually owns, and stop shipping duplicate copies of stateful Holepunch / bare-* singletons in consumer trees. Drifted ranges bumped: - compact-encoding ^2.19.0 -> ^3.0.0 (major dedup: 17+ nested ^3.x copies across hyperswarm/corestore/hypercore/ hyperdb/hyperblobs/hyperdht/hyperschema/ hyperdispatch/protomux/... collapse to a single top-level; silences the `npm ls invalid` warning on every consumer install) Redundant peer entries removed: - bare-dns (transitive via bare-net; SDK doesn't import it; no need to re-declare a floor on what bare-net already pins) - bare-http1 (transitive via bare-fetch; same reasoning) - bare-https (transitive via bare-fetch; removing entirely instead of bumping ^2.1.3 -> ^3.0.0 — once SDK stops declaring its own floor, bare-fetch's ^3.0.0 wins and the duplication resolves) Moved out of peerDependencies (still listed where SDK source needs them): - events -> devDependencies (only used by `.d.ts` type stubs; @types/node already provides the EventEmitter type; consumers don't need the npm `events` package at runtime — Node has it built-in and Bare maps it to bare-events) - tar-stream -> dependencies (used in server/utils/archive.ts; no other consumer in the install tree so no dedup concern from making it a hard dep) llm-splitter KEPT as a required SDK peer. @qvac/rag declares it as an *optional* peer in its own manifest, which means npm skips installation unless --include=optional is passed. Removing the SDK-level required peer broke the LLMChunkAdapter path at runtime (caught by E2E smoke: rag- embeddings-small-chunks, rag-large-document-32kb, rag-medium-document-10kb all failed with "Required dependency missing: llm-splitter is required for LLMChunkAdapter"). The SDK-layer required peer is what guarantees the package is installed in consumer trees. Revisit if @qvac/rag ever promotes llm-splitter from optional to required, or bundles it as a hard dep. bare-subprocess v6 still deferred for the same reason as before: the only v6 consumer in the SDK tree today is bare-link@3.2.2 (5-day-old release at original audit time), and bare-runtime@1.x is still firmly on ^5.0.0. Revisit when bare-runtime catches up. This is the first step of the broader peer-deps cleanup effort tracked in the QVAC SDK & Platforms Asana project. Future steps may consider moving compact-encoding out of peers entirely and auditing the remaining optional peers, but those are out of scope here. No source changes; package.json metadata only. Validation: - `bun install` in packages/sdk -> clean. - `bun run build` -> clean. - Dedup check via `/tmp/sdk-dedup-check.sh` against packed SDK -> ✅ no Holepunch singletons duplicated. - E2E smoke catch on initial revision (no llm-splitter) confirmed the removal was wrong; reverted. Co-authored-by: Cursor <cursoragent@cursor.com>
Proletter
pushed a commit
that referenced
this pull request
May 24, 2026
* fix: drop SDK peerDependencies; enforce in CI Completes the peer-deps cleanup trajectory started in #2089 by removing the peerDependencies + peerDependenciesMeta blocks from @qvac/sdk entirely and adding a CI gate that asserts the invariant holds on every SDK pod PR. Policy: - dependencies: every package directly imported by SDK source. - devDependencies: build / typecheck / lint-only modules. - No peer declarations -- host owns anything SDK doesn't import. CI gate (.github/workflows/pr-checks-sdk-pod.yml, sdk-only): - Packs the tarball and installs it into a fresh consumer dir. - Fails on any ERESOLVE / `npm warn peer` line on install. - Fails if any of corestore / hyperswarm / hyperdrive / hyperdb / hyperblobs / hyperdht resolves to more than one copy. - Smoke-imports @qvac/sdk and asserts >= 50 named exports. * fix: split SDK conditional modules into optionalDependencies Promote the 7 packages that are runtime-conditional (per-platform or per-feature) from devDependencies into optionalDependencies: - @modelcontextprotocol/sdk (MCP, only if hosting an MCP server) - bare-link (Bare-only linker shim) - compact-encoding (pin to ^3 to dedupe Holepunch v3 tree) - expo-device (Expo runtime only) - expo-file-system (Expo runtime only) - pear-pipe (Pear runtime only) - react-native-bare-kit (RN/Expo runtime only) Why not regular dependencies: - Backend consumers (npm install --omit=optional) get a 182-package tree instead of 790; mobile/Pear consumers get the plug-n-play default with all 7 auto-installed. Why not peerDependencies: - npm 7+ auto-installs peers and emits ERESOLVE on range drift, which is the exact failure mode this PR is fixing for Keet. Validated: - Keet-shape repro (cross-worker-bare-kit@^2 + @qvac/sdk): 0 ERESOLVE. - Default install: 0 peer warnings, 7/7 optionals present. - --omit=optional: 0 peer warnings, lean tree, Holepunch invariant still holds (single copy of corestore / hyperswarm / hyperdrive / hyperdb / hyperblobs / hyperdht / react-native-bare-kit). * test[ci]: add --omit=optional install gate to SDK consumer check The default-install gate validates the plug-n-play path (all optionals present); it does not exercise the lean backend path that consumers get with `npm install --omit=optional`. That path was implicitly trusted when we adopted optionalDependencies in the previous commit. Refactor the inline gate into a check_consumer() helper and call it twice: 1. Default install (plug-n-play): all 7 optionalDeps installed. Catches Keet-style ERESOLVE from optional deps' peer ranges colliding with other deps. Validates mobile/Pear consumer profile. 2. Lean install (--omit=optional): no optionalDeps. Catches (a) backend-required packages accidentally classified as optional, (b) SDK entry-point eagerly importing an optional module. Both scenarios run the same three assertions: - No ERESOLVE / `npm warn peer` lines. - Single copy of corestore / hyperswarm / hyperdrive / hyperdb / hyperblobs / hyperdht. - Smoke import yields >= 50 named exports. Validated locally: lean install yields 385 named exports (well above threshold), Holepunch invariant holds, 0 peer warnings. Adds ~60s of CI per SDK pod PR. * update dev deps * fix: address review — restore expo-build-properties; revert bare-subprocess major bump - Add expo-build-properties to optionalDependencies. withQvacSDK wires it by string into the Expo plugin chain, so dropping it entirely broke plug-n-play for Expo consumers (the consumer-install gate runs in a Node consumer dir, so it didn't catch the missing Expo plugin module). Keeping it optional preserves the previous behavior while letting Node-only backends skip it via --omit=optional. - Revert bare-subprocess to ^5.2.3 (was bumped to ^6.0.0 by bun add). v5→v6 is a major bump for what is only a dev-time shim consumed by scripts/bare-bootstrap.js; staying on the prior major avoids dragging drift into the dev tree and keeps NOTICE accurate. Validated: - bun install + bun run build clean. - Consumer install gate (default + --omit=optional): both green, Holepunch invariant holds, 385 named exports. * chore: drop hyperdb + hyperblobs from SDK dependencies Neither package is imported by SDK source — they were guarantor pins for @qvac/registry-client, which declares both as non-optional peerDependencies. npm 7+ auto-installs non-optional peers, so the consumer install graph is unchanged: hyperdb and hyperblobs still resolve to a single copy in both default and --omit=optional installs, satisfied by registry-client's own peer ranges. Aligns with the "declare what you import, nothing else" policy. Validated: - bun install + bun run build clean. - Default install (790 pkgs): single copy of corestore / hyperswarm / hyperdrive / hyperdb / hyperblobs / hyperdht. - --omit=optional install (182 pkgs): same. - 0 peer warnings in both scenarios; 385 named exports.
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.
What problem does this PR solve?
Two related issues in
@qvac/sdk'speerDependenciesblock, both motivated by the same TD-HOLEPUNCH-PEER-DEPS follow-up effort tracked under the QVAC SDK & Platforms project. This PR is the first step — not the full peer-deps cleanup, just the safe-to-land subset.1. Drifted peer ranges → duplicate copies in consumer
node_modulescompact-encoding^2.19.02.19.2held at top by SDK; 17 nested3.0.xcopies for every^3.0.0consumer across the Holepunch tree (hyperswarm, corestore, hypercore, hyperdb, hyperblobs, hyperdht, hyperschema, hyperdispatch, …)npm ls invalidwarning on every consumer install2. Peer entries declared but not owned by the SDK
bare-dnsbare-net(which SDK does peer-declare); SDK source doesn't import itbare-http1bare-fetch; SDK source doesn't import itbare-httpsbare-fetch; SDK source doesn't import it — removing entirely instead of bumping, because once SDK stops declaring its own floor,bare-fetch's^3.0.0wins naturallyevents.d.tstype stubs —@types/nodealready provides theEventEmittertype for typecheck; consumers never need the npmeventspackage at runtime (Node has it built-in, Bare maps it tobare-events)tar-streamserver/utils/archive.ts); no other consumer in the install tree, so no dedup concern from making it a hard depHow does it solve it?
packages/sdk/package.jsononly — no source changes.Bump (within peerDependencies)
Remove from peerDependencies entirely
Reclassify (move out of peerDependencies)
dependencies: { + "tar-stream": "^3.1.8", } devDependencies: { + "events": "^3.3.0", } peerDependencies: { - "events": "^3.3.0", - "tar-stream": "^3.1.8" }Expected dedup impact
compact-encoding → ^3.0.03.0.xcollapse to a single top-level; silences theinvalid: "^2.19.0" from node_modules/@qvac/sdkwarnings on every consumer'snpm ls.2.19.xcopy still ships underhyperdb@4.22.xandbare-channel@5.2.3(both still on^2.x). Goes away when those upstream packages bump.bare-httpsremoved^2holdout — removing instead of bumping letsbare-fetch's^3.0.0win naturally. Single top-level copy.npm installwarnings for the yarn 1 /legacy-peer-deps=trueaudience on the three entries the SDK never imported anyway.Considered but kept
llm-splitter— initially proposed for removal because@qvac/ragdeclares it as its own peer. Closer inspection (and E2E confirmation) showed@qvac/ragmarks itoptional: trueinpeerDependenciesMeta, which means npm skips installation by default — onlynpm install --include=optionalpulls it in. Removing the SDK-level required peer broke theLLMChunkAdapterpath at runtime (caught by smoke E2E:rag-embeddings-small-chunks,rag-large-document-32kb,rag-medium-document-10kball failed with"Required dependency missing: llm-splitter is required for LLMChunkAdapter"). The SDK-layer required peer is what guarantees the package is in consumer trees. Revisit if@qvac/ragpromotesllm-splitterfrom optional to required, or bundles it as a hard dep.Out of scope (deferred)
bare-subprocess→^6.0.0: onlybare-link@3.2.2in the SDK tree requires v6 (5-day-old release at original audit).bare-runtime@1.x— the runtime SDK code executes in — is still on^5.0.0. Bumping would only flip which version sits at the top (still two copies until upstreambare-runtimemoves). Revisit later.bare-fetch→^3.0.0: floor stale (latest3.0.1, 2 weeks old), no duplication in the tree today. Marginal upside.compact-encodingpeer → dep / drop entirely: defensible to leave as a peer since the rest of the Holepunch stack declares it that way. Out of scope here.bare-fs,bare-path,bare-rpc, etc.) — those are correctly classified as peers per Bare runtime stdlib convention (stateful singletons).Source-impact verification
bare-dns/bare-http1/bare-https: not imported by any SDK source file. Removing from peers is pure metadata.events: only referenced in.d.tstype stubs underpackages/sdk/types/{bare-net,corestore,hyperdrive,hyperswarm,bare-subprocess,pear-pipe}/index.d.ts.@types/node@^24is already indevDependenciesand provides theEventEmittertype. MovingeventstodevDependencieskeeps the SDK build self-contained without forcing it on consumers.tar-stream: imported once atserver/utils/archive.ts(extract sharded model archives). No other consumer in the SDK install tree. Moving todependenciesdoesn't change the install footprint, and matches its single-consumer-in-tree status.compact-encoding: imported once atpackages/sdk/pear/pre.tsascenc.encode(cenc.any, …)/cenc.decode(cenc.any, …). Verified at audit time that v3.0.1 has identicalencode/decode/anyexports and round-trips identically with v2.19.2.How was it tested?
bun installinpackages/sdk— clean.bun run typecheck— clean./tmp/sdk-dedup-check.shagainst a freshly-packed@qvac/sdk@0.11.0in a clean consumer project —✅ PASS, no Holepunch singletons duplicated(single copy ofcorestore,hyperblobs,hyperdb,hyperdht,hyperdrive,hyperswarmeach).llm-splitterremoval (3 RAG tests failed); confirmed restored after revert.🔌 API Changes
None.