diff --git a/review-enrichment/src/analysis-context.ts b/review-enrichment/src/analysis-context.ts index 752ef5beec..f874c4f95b 100644 --- a/review-enrichment/src/analysis-context.ts +++ b/review-enrichment/src/analysis-context.ts @@ -19,6 +19,7 @@ import { } from "./external-fetch.js"; import { isWorkflowPath } from "./workflow-path.js"; import { isSupportedLockfile } from "./lockfile-path.js"; +import { BINARY_EXT_RE } from "./analyzers/binary-extensions.js"; type ChangedFile = NonNullable[number]; @@ -448,11 +449,10 @@ function categorizeFile(path: string): FileCategory { ) { return { path, extension, category: "docs" }; } - if ( - [".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg", ".pdf", ".zip", ".gz", ".zst"].includes( - extension, - ) - ) { + // Binary assets — delegate to the shared binary-extension inventory (used by asset-weight/provenance) so any + // media/font/archive/model-weight blob categorizes as an asset instead of falling through to `source`. + // `.svg` is text, so it is not in BINARY_EXT_RE, but categorization still treats it as an asset. + if (BINARY_EXT_RE.test(path) || extension === ".svg") { return { path, extension, category: "asset" }; } if (extension) return { path, extension, category: "source" }; diff --git a/review-enrichment/test/analysis-context.test.ts b/review-enrichment/test/analysis-context.test.ts index 29a43aef33..b8553c9910 100644 --- a/review-enrichment/test/analysis-context.test.ts +++ b/review-enrichment/test/analysis-context.test.ts @@ -570,6 +570,39 @@ test("createAnalysisContext classifies long-form doc extensions as docs", () => ); }); +test("createAnalysisContext categorizes shared binary inventory entries as assets", () => { + const context = createAnalysisContext({ + repoFullName: "JSONbored/gittensory", + prNumber: 3359, + files: [ + // A legacy image extension that was already an asset before this change. + { path: "ui/logo.png", patch: null, status: "added" }, + // Binaries beyond the original narrow image/archive list — now recognized via the shared inventory. + { path: "media/demo.mp4", patch: null, status: "added" }, + { path: "fonts/Inter.woff2", patch: null, status: "added" }, + { path: "vendor/lib.wasm", patch: null, status: "added" }, + { path: "models/llama.safetensors", patch: null, status: "added" }, + // .svg is text but still an asset for categorization (kept explicitly). + { path: "icons/logo.svg", patch: "@@ -1,0 +1,1 @@\n+" }, + // A real source file is unaffected. + { path: "src/index.ts", patch: "@@ -1,0 +1,1 @@\n+export {};" }, + ], + }); + + assert.deepEqual( + context.fileCategories.map((file) => [file.path, file.category]), + [ + ["ui/logo.png", "asset"], + ["media/demo.mp4", "asset"], + ["fonts/Inter.woff2", "asset"], + ["vendor/lib.wasm", "asset"], + ["models/llama.safetensors", "asset"], + ["icons/logo.svg", "asset"], + ["src/index.ts", "source"], + ], + ); +}); + test("createAnalysisContext classifies lockfile paths case-insensitively", () => { const context = createAnalysisContext({ repoFullName: "JSONbored/gittensory",