diff --git a/review-enrichment/src/analysis-context.ts b/review-enrichment/src/analysis-context.ts index 752ef5beec..091664a4b3 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,11 @@ 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) rather + // than a narrow hand-listed set, so media/fonts/archives/model weights (mp4, woff2, wasm, safetensors, …) + // categorize as assets instead of falling through to `source`. `.svg` is text (not in the binary inventory) + // but is still an asset for categorization, so it is kept explicitly. + 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..dc11a960a9 100644 --- a/review-enrichment/test/analysis-context.test.ts +++ b/review-enrichment/test/analysis-context.test.ts @@ -570,6 +570,36 @@ test("createAnalysisContext classifies long-form doc extensions as docs", () => ); }); +test("createAnalysisContext categorizes the full binary inventory as assets", () => { + const context = createAnalysisContext({ + repoFullName: "JSONbored/gittensory", + prNumber: 3359, + files: [ + // 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]), + [ + ["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",