test(exports): widen both export guards one directory down, and fix what they find - #813
Merged
sroussey merged 2 commits intoAug 16, 2026
Conversation
sroussey
force-pushed
the
claude/wonderful-turing-rjtcnx-ai-types
branch
from
August 16, 2026 16:31
6efb8a2 to
d02a046
Compare
Both guards landed in #717 look only at the layer they were written for, and the same defect class survives one level below. `ExportBarrelParity` keyed on the hard-coded `src/ai/index{,.browser}.ts` pair, so it never saw `src/ai/runtime.browser.ts` — the barrel a browser consumer gets under `@workglow/<vendor>/ai-runtime`. It now walks `providers/<vendor>/src` recursively and pairs every `<stem>.browser.ts` with the `<stem>.ts` beside it (~53 pairs, against 5 before). Three things that widening needs: - Specifier keys strip a trailing `.browser`, or every runtime pair reports as total drift (`* from "./common/Ollama_Client"` against `* from "./common/Ollama_Client.browser"`) and the guard says nothing. That makes a star-export comparison across a `.browser` sibling NOMINAL — and the recursive scan is what closes it, since `Ollama_Client.browser.ts` vs `Ollama_Client.ts` is itself a compared pair now. - A browser file whose entire surface is `* from "./<nodeStem>"` is skipped: it IS the node surface, and it is the shape #717 wants (llamacpp-server, stable-diffusion-server), which the widened scan now reaches. - `INTENTIONAL_NODE_ONLY` is rekeyed from the package dir to the browser FILE path, since a package now contributes several pairs. The vacuous-pass assertion (`pairs` equals the pinned keys) is removed rather than adjusted: 53 pairs against 5 pins makes equality flatly wrong, and any form of it means a correct new provider fails until somebody registers it as needing no exemption. Its two roles are stated separately instead — the scan found the tree, and it recursed into it. `ExportTypesPairing`'s `duplicateBrowserEntryViolations` scan is likewise recursive over `src` rather than a flat `readdirSync`. The relative/bare distinction is unchanged and is still the whole rule; all nine `packages/workglow` bare-specifier shims still classify BARE and stay unreported. Scope stays at `providers/` deliberately: `packages/` pulls in `packages/tasks/src/task/image/imageTextRender.browser.ts`, a genuine implementation split (one factory against the node module's fifteen names) needing a fifteen-name exemption for no benefit. This commit is intentionally red. It reports exactly two real defects, fixed in the commit that follows: providers/ollama/src/ai/runtime.ts exports * from "./common/Ollama_StructuredGeneration", * from "./common/Ollama_TextGeneration" but providers/ollama/src/ai/runtime.browser.ts does not providers/openrouter/src/ai/runtime.browser.ts is identical to providers/openrouter/src/ai/runtime.ts and names only relative specifiers, so both entries resolve the same module graph and the declaration split is nominal Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lgxtp7mQECdh7F2UT9CVwN
…ds found Both are the defect class #717 fixed at the entry layer, surviving one directory down in `src/ai/`. **ollama** — `runtime.ts` exports `Ollama_TextGeneration` and `Ollama_StructuredGeneration`; `runtime.browser.ts` did not. This is a source-compatibility fix, not a cosmetic one: before #717 the browser `types` condition pointed at the NODE declarations, so a browser consumer importing `createOllamaTextGenerationStream` from `@workglow/ollama/ai-runtime` compiled fine and got `undefined` at runtime. With #717's accurate types it becomes a hard TS2305 for anyone with `customConditions: ["browser"]`. Restoring the two `export *` lines is what makes the declaration honest. Neither module has a `.browser` variant, and neither imports a node builtin — both are already compiled into the browser bundle via `Ollama_JobRunFns.browser`. Verified: the rebuilt `ai-runtime.browser.js` gains no code, only the two names in the entry's export list (and a module reordering, since they are now direct entry re-exports). Every other provider's `runtime.browser.ts` was audited against its `runtime.ts` — deepseek, openai, openrouter and xai are in parity modulo the `.browser` specifier suffix. ollama was the only omission. **openrouter** — `runtime.browser.ts` was a byte copy of `runtime.ts` naming only RELATIVE specifiers, so both already resolved the same module graph and the declaration split was nominal: two `.d.ts` files kept equal by hand. It now re-exports its node peer, in the shape #717 established for `providers/llamacpp-server`. Rebuilt `ai-runtime.browser.js` is byte-identical. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lgxtp7mQECdh7F2UT9CVwN
sroussey
force-pushed
the
claude/optimistic-goldberg-d74u5n-export-guard-depth
branch
from
August 16, 2026 16:37
cf54657 to
3e57e17
Compare
sroussey
merged commit Aug 16, 2026
f4ce54b
into
claude/wonderful-turing-rjtcnx-ai-types
10 of 11 checks passed
sroussey
deleted the
claude/optimistic-goldberg-d74u5n-export-guard-depth
branch
August 24, 2026 18:48
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.
Stacked on #717 (base:
claude/wonderful-turing-rjtcnx-ai-types). The manifest work in #717 is not touched here — this is the same defect class surviving one directory below where #717's new guards look.Both guards landed in #717 examine only the layer they were written for:
ExportBarrelParitykeyed on the hard-codedsrc/ai/index{,.browser}.tspair, so it never sawsrc/ai/runtime.browser.ts— the barrel a browser consumer gets under@workglow/<vendor>/ai-runtime.ExportTypesPairing'sduplicateBrowserEntryViolationscollected pairs with a flatreaddirSync(srcDir), so it saw only the entry layer the manifests name.Two commits, deliberately not squashed
The A-then-B ordering is the evidence the widening bites. Commit A widens the guards only and is red, reporting exactly two defects and nothing else:
Commit B fixes those two sources and turns it green.
What the widening needed
The recursive scan takes
ExportBarrelParityfrom 5 pairs to ~53, and three things had to come with it:.browser. Without it every runtime pair reports as total drift (* from "./common/Ollama_Client"against* from "./common/Ollama_Client.browser") and the guard says nothing. The residual is documented in the source: this makes a star-export comparison across a.browsersibling nominal — and the recursive scan is exactly what closes it, sinceOllama_Client.browser.tsvsOllama_Client.tsis itself a compared pair now.* from "./<nodeStem>"IS the node surface, and it is the shape fix(providers): point each export condition's types at its own declaration #717 wants — the widened scan now reachesllamacpp-serverandstable-diffusion-server, which would otherwise report the node file's every other statement as drift.INTENTIONAL_NODE_ONLYis rekeyed from package dir to browser FILE path, since a package now contributes several pairs. Both consumers (drift loop, staleness loop) key onpair.browserPath.The vacuous-pass assertion is removed rather than adjusted.
expect(pairs.map(…).sort()).toEqual([...INTENTIONAL_NODE_ONLY.keys()])is flatly wrong at 53 pairs against 5 pins, and any form of it still means a correct new provider fails until somebody registers it as needing no exemption. Its two real roles are stated separately instead:pairs.length > 40(the scan found the tree) andpairs.some(p => p.browserPath.includes("/src/ai/"))(and it recursed into it). The staleness test is kept, retargeted to the path.Scope stays at
providers/deliberately, and the doc comment says why: extending topackages/pulls inpackages/tasks/src/task/image/imageTextRender.browser.ts, a genuine implementation split whose browser file exports one factory against the node module's fifteen names — a fifteen-name exemption buying nothing.For
ExportTypesPairing, the relative/bare distinction is unchanged and is still the whole rule. Verified under the recursive scan: all ninepackages/workglowbare-specifier shims still classify BARE and stay unreported. The> 9floor is kept (they are still the negative case) and asome(p => p.browserPath.includes("/src/ai/"))assertion is added so a regression to the flat scan fails loudly.The source fixes
ollama is a source-compatibility fix, not a cosmetic one. Before #717 the browser
typescondition pointed at the NODE declarations, so a browser consumer importingcreateOllamaTextGenerationStreamfrom@workglow/ollama/ai-runtimecompiled fine and gotundefinedat runtime. With #717's accurate types it becomes a hard TS2305 for anyone withcustomConditions: ["browser"].Neither module has a
.browservariant and neither imports a node builtin; both are already compiled into the browser bundle viaOllama_JobRunFns.browser. Verified against a rebuild:ai-runtime.browser.jsgains no code — the only content delta is the two names in the entry's export list, plus a module reordering because they are now direct entry re-exports.Every other provider's
runtime.browser.tswas audited against itsruntime.ts: deepseek, openai, openrouter and xai are in parity modulo the.browserspecifier suffix. ollama was the only omission. (Theai-runtime.browser.tsentry layer was audited too;llamacpp-serverandstable-diffusion-serverdiffer only in being the intended sibling re-export.)openrouter was a byte copy naming only relative specifiers, so both halves already resolved the same module graph and the split was nominal. It now re-exports its node peer, reusing the wording #717 established in
providers/llamacpp-server/src/ai-runtime.browser.ts. Rebuiltai-runtime.browser.jsis byte-identical (modulodebugId).Verification
bun scripts/test.ts util vitestafter Abun scripts/test.ts util vitestafter BExportBarrelParity+ExportTypesPairingdirectlyBunExportConditions.test.ts"bun"condition set is untouched (nopackage.jsonis modified by either commit)bun run build:typesbunx turbo run build-js build-types --filter=@workglow/ollama --filter=@workglow/openrouterbun run formatNotes for whoever merges
Rebase resolution rule. This branch was rebased onto
origin/mainbefore the fixes.mainhad addedexport { <vendor>EffortPolicy } from "./common/<Vendor>_EffortPolicy";to both barrels of openai / xai / deepseek / openrouter while #717's own commit addedexport *lines toindex.browser.tsin the same region. deepseek and xai auto-merged; openai and openrouter conflicted and were resolved as the UNION of both sides in BOTH files. Taking one side's EffortPolicy line inindex.tsbut notindex.browser.ts— or dropping a branch-restoredexport *— silently recreates exactly the asymmetryExportBarrelParityexists to catch. The resolution was verified with the guard itself (a dropped line surfaces as a new<vendor>EffortPolicy from "./common/<Vendor>_EffortPolicy"entry in the drift list); no such entry appeared.Diff size. Because this branch is rebased onto
mainand the base branch is not, GitHub computes the diff from an old merge base and shows ~117 commits. The change actually under review is the two commits at the tip;git diff <PR-717-tip-as-rebased>..HEADis 4 files. Rebasing #717 ontomaincollapses this to those two commits.Generated by Claude Code