From a2fa9a6116d09f16b72c44db73c4ffc16c67a88d Mon Sep 17 00:00:00 2001 From: Koji Wakayama Date: Mon, 10 Aug 2026 17:56:02 +0200 Subject: [PATCH] fix(cli): keep build extensions available without extra installs veryfront build activates built-in LLM and eval report extensions even when a project does not configure providers. Those extensions validate their required registries during orchestration, so the build path must prime the same contracts that other bootstraps provide. Constraint: Built-in provider and exporter extensions validate required contract registries during build extension orchestration Constraint: Issue veryfront/veryfront-issue-inbox#456 identifies 0.1.1206 as first bad and 59fe62c4c / PR #3417 as the introducing change Rejected: Require users to install or opt into extra extensions | the failing extensions are already activated by the build path and only need core registries Confidence: high Scope-risk: narrow Related: veryfront/veryfront-issue-inbox#456 Tested: git diff --check Tested: deno test --preload=src/testing/preload.ts --no-check --allow-all cli/shared/build-extensions.test.ts Tested: deno task fmt:check Tested: deno task lint Tested: deno check cli/shared/build-extensions.ts cli/shared/build-extensions.test.ts Tested: Pre-push hook passed formatting, lint, and typecheck before unit tests Tested: Previously verified focused 30-step suite, deno task build:npm, and packed npm consumer build during TDD reproduction Not-tested: Full repository unit suite did not complete; pre-push deno task test:unit failed in cli/commands/styles/command.test.ts with uncaught Unable to get CWD after 3783 passed / 28090 steps --- cli/shared/build-extensions.test.ts | 14 ++++++++++++++ cli/shared/build-extensions.ts | 9 +++++++++ 2 files changed, 23 insertions(+) diff --git a/cli/shared/build-extensions.test.ts b/cli/shared/build-extensions.test.ts index aa03248aa8..b9fb7c2b74 100644 --- a/cli/shared/build-extensions.test.ts +++ b/cli/shared/build-extensions.test.ts @@ -1,6 +1,8 @@ import "#veryfront/schemas/_test-setup.ts"; import { assertEquals, assertExists } from "#veryfront/testing/assert.ts"; import { describe, it } from "#veryfront/testing/bdd.ts"; +import { EvalReportExporterRegistryName } from "veryfront/extensions/eval"; +import { LLMProviderRegistryName } from "veryfront/extensions/llm"; import { setupBuildCliExtensions } from "./build-extensions.ts"; /** Minimal stand-in for the loader; the build path only needs it to resolve. */ @@ -61,6 +63,18 @@ describe("cli/shared/build-extensions", () => { assertEquals(names.has("ext-content-mdx"), true); }); + it("primes the contracts required by built-in providers and exporters", async () => { + let primeContracts: Record = {}; + + await setupBuildCliExtensions("/projects/app", {}, (options) => { + primeContracts = options.primeContracts ?? {}; + return Promise.resolve(loaderStub); + }); + + assertExists(primeContracts[LLMProviderRegistryName]); + assertExists(primeContracts[EvalReportExporterRegistryName]); + }); + it("hands orchestration a logger it can actually log through", async () => { // Not "names the build": cliLogger.component() deliberately returns the // same logger, because CLI output carries no structured component tag. So diff --git a/cli/shared/build-extensions.ts b/cli/shared/build-extensions.ts index 538a7694a5..d199580f46 100644 --- a/cli/shared/build-extensions.ts +++ b/cli/shared/build-extensions.ts @@ -26,6 +26,11 @@ */ import { orchestrateExtensions } from "veryfront/extensions"; +import { + createEvalReportExporterRegistry, + EvalReportExporterRegistryName, +} from "veryfront/extensions/eval"; +import { createLLMProviderRegistry, LLMProviderRegistryName } from "veryfront/extensions/llm"; import { cliLogger } from "#cli/utils"; import { createBuiltinExtensions } from "../../src/extensions/builtin-extensions.ts"; @@ -46,6 +51,10 @@ export async function setupBuildCliExtensions( projectDir, config, logger: cliLogger.component("build-extensions"), + primeContracts: { + [LLMProviderRegistryName]: createLLMProviderRegistry(), + [EvalReportExporterRegistryName]: createEvalReportExporterRegistry(), + }, builtinExtensions: createBuiltinExtensions(), }); }