Skip to content

SDK: the @unbrained/pm-cli/sdk barrel is documented as containing every supported export but omits 45 public exports from sdk/query, sdk/contracts, sdk/runtime and sdk/governance #740

Description

@unbraind

Summary

docs/SDK.md documents the aggregate entrypoint as:

| @unbrained/pm-cli/sdk | Compatibility aggregate containing every supported SDK export |

It does not. 45 public (non-_testOnly) exports reachable from the narrow entrypoints are absent from the barrel.

Measurement

const barrel = await import('@unbrained/pm-cli/sdk');
const b = new Set(Object.keys(barrel));
for (const s of ['authoring','contracts','core','governance','graph','merge','query','runtime','testing']) {
  const m = await import(`@unbrained/pm-cli/sdk/${s}`);
  const missing = Object.keys(m).filter(k => !b.has(k) && !k.startsWith('_testOnly'));
  console.log(s, Object.keys(m).length, missing.length);
}
sdk/authoring   exports=  63  missing_from_barrel=  0
sdk/contracts   exports= 137  missing_from_barrel= 13
sdk/core        exports=  59  missing_from_barrel=  0
sdk/governance  exports=  31  missing_from_barrel=  3
sdk/graph       exports=  71  missing_from_barrel=  0
sdk/merge       exports=  17  missing_from_barrel=  0
sdk/query       exports=  74  missing_from_barrel= 17
sdk/runtime     exports= 197  missing_from_barrel= 12
sdk/testing     exports=  43  missing_from_barrel=  0
---
TOTAL subpath exports: 692   TOTAL public missing from barrel: 45

Five entrypoints are complete; four are not. The omissions are not obviously intentional — they are ordinary public helpers sitting beside siblings that are re-exported.

sdk/query (17)resolveSearchTuning, resolveSearchMaxResults, resolveSearchScoreThreshold, resolveSearchPage, resolveHybridSemanticWeight, resolveContentFieldFilters, resolveMissingMetadataFilters, createSearchCursorFingerprint, classifyImplicitSemanticFallbackReason, collectErrorCauseCodes, applyFilterValueEcho, buildCompactSearchFilterSummary, buildContentFilterEcho, buildGovernanceMissingFilterEcho, buildVerboseSearchFilters, LIST_SORT_FIELDS, LIST_SORT_ORDER_VALUES

sdk/governance (3)scanStorageIntegrity, classifyHistoryAuthorEvent, HISTORY_AUTHOR_ATTRIBUTION_BASELINE

Note the inconsistency inside sdk/query: encodeQueryCursor and paginateQueryRows are in the barrel, but createSearchCursorFingerprint and resolveSearchPage are not — so a consumer building cursor pagination gets half the toolkit from the barrel and has to discover mid-task that the other half needs a different import specifier.

How this surfaced

Real failure, not a hypothetical. Code written against the documented "aggregate contains everything" contract:

import {
  resolveSearchMaxResults,
  resolveSearchScoreThreshold,
  resolveHybridSemanticWeight,
} from "@unbrained/pm-cli/sdk";
src/routes/pm.ts(5,3): error TS2305: Module '"@unbrained/pm-cli/sdk"' has no exported member 'resolveSearchMaxResults'.
src/routes/pm.ts(6,3): error TS2305: Module '"@unbrained/pm-cli/sdk"' has no exported member 'resolveSearchScoreThreshold'.
src/routes/pm.ts(7,3): error TS2305: Module '"@unbrained/pm-cli/sdk"' has no exported member 'resolveHybridSemanticWeight'.

The fix is a one-word specifier change, so the cost is small in isolation — but it is only discoverable by compiling, and the documentation actively points the other way. Anyone reading SDK.md will reasonably assume the barrel is a safe default and that narrow entrypoints are purely an import-cost optimization (which is how the surrounding prose frames them, complete with an import-cost table). That assumption is correct for five of nine entrypoints.

Suggested fix

Either:

  1. Make the barrel complete — re-export the 45 symbols, restoring the documented contract; or
  2. Correct the documentation — if the omissions are deliberate (deprecated, internal-ish, or reserved), say so explicitly and mark which entrypoints are non-aggregated, so "use the barrel and narrow later for import cost" stops being sound-looking advice.

Whichever way it goes, a CI assertion would keep it honest — the project already generates tests/fixtures/sdk/public-surface.json covering every entrypoint, so a test asserting subpathExports ⊆ barrelExports (modulo an explicit, reviewed exclusion list) is cheap and would have caught this at the commit that introduced it.

Environment

  • @unbrained/pm-cli 2026.7.26 (global install, npm)
  • Node 22, Linux

Context

Found while auditing SDK adoption across the 18-package pm-* extension fleet, where fleet-wide usage was 18 of ~490 exports. Related to #738 — both are about the SDK surface being hard to discover accurately from the shipped artifacts; that one is the missing machine-readable map, this one is the documented map being wrong.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions