From cdb7a7eac5b452e8dc2206a08814976731c4723b Mon Sep 17 00:00:00 2001 From: Justn Date: Mon, 20 Apr 2026 22:51:17 +0900 Subject: [PATCH] feat(chunker): expand built-in artifact pattern list (#482) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this change, BUILT_IN_ARTIFACT_PATTERNS covered the common JS ecosystem basics (dist/, node_modules/, minified JS/CSS, JS lock files) but missed several generated-code patterns that still reach reviewers in real repos — burning cost and triggering phantom findings on code that no human wrote. Added categories: - Build outputs: .svelte-kit/, .turbo/, .docusaurus/, storybook-static/ - Minified / bundled: *.min.mjs, *.bundle.{css,mjs} - Source maps: *.mjs.map, *.css.map - Generated code: *.pb.{go,ts,py}, *_pb.{js,ts}, *.gen.{ts,go}, *_generated.{go,ts} - Lock files (other ecosystems): Cargo.lock, poetry.lock, Pipfile.lock, uv.lock, composer.lock, Gemfile.lock, go.sum, mix.lock, flake.lock, bun.lock - Binary assets: png/jpg/jpeg/gif/webp/ico/bmp/tiff, woff/woff2/ttf/ otf/eot, mp3/mp4/mov/webm, pdf, zip/tar/gz/tgz/7z/rar - Test snapshots: *.snap, __snapshots__/ Added 51 test cases covering each new filtered path plus 7 "should survive" cases to guard against prefix/substring false matches (e.g. distribution/index.ts is NOT dist/, src/build-helpers.ts is NOT build/). Tests 3368 → 3426. Config `ignorePatterns` override and the `.reviewignore` syntax are both already supported (chunker.loadReviewIgnorePatterns) — users who want additional patterns for their specific project add them there. The full "zero-config for N ecosystems" acceptance criterion in #482 stays open; this PR delivers the concrete default-list expansion. --- packages/core/src/pipeline/chunker.ts | 79 ++++++++++++++- .../core/src/tests/pipeline-chunker.test.ts | 99 +++++++++++++++++++ 2 files changed, 173 insertions(+), 5 deletions(-) diff --git a/packages/core/src/pipeline/chunker.ts b/packages/core/src/pipeline/chunker.ts index fd2c507..ed2c75b 100644 --- a/packages/core/src/pipeline/chunker.ts +++ b/packages/core/src/pipeline/chunker.ts @@ -255,27 +255,96 @@ export function chunkDiffFiles( // ============================================================================ /** - * Default patterns for files that should never be reviewed. - * These are build outputs, lock files, and minified bundles — not source code. - * Users can add additional patterns via .reviewignore. + * Default patterns for files that should never be reviewed (#482). + * Build outputs, lock files, generated code, binary assets, and test + * snapshots — not source code. Users can add project-specific additions + * via `.reviewignore`. */ export const BUILT_IN_ARTIFACT_PATTERNS = [ + // Build outputs — directory-level 'dist/**', 'build/**', 'out/**', '.next/**', '.nuxt/**', + '.svelte-kit/**', + '.turbo/**', + '.docusaurus/**', + 'storybook-static/**', 'coverage/**', 'node_modules/**', + + // Minified / bundled '**/*.min.js', '**/*.min.css', + '**/*.min.mjs', '**/*.bundle.js', + '**/*.bundle.css', + '**/*.bundle.mjs', + + // Source maps + '**/*.js.map', + '**/*.mjs.map', + '**/*.css.map', + '**/*.d.ts.map', + + // Generated code (by convention) + '**/*.pb.go', + '**/*.pb.ts', + '**/*.pb.py', + '**/*_pb.js', + '**/*_pb.ts', + '**/*.gen.ts', + '**/*.gen.go', + '**/*_generated.go', + '**/*_generated.ts', + + // Lock files — JS ecosystem 'pnpm-lock.yaml', 'package-lock.json', 'yarn.lock', 'bun.lockb', - '**/*.d.ts.map', - '**/*.js.map', + 'bun.lock', + // Lock files — other ecosystems + 'Cargo.lock', + 'poetry.lock', + 'Pipfile.lock', + 'uv.lock', + 'composer.lock', + 'Gemfile.lock', + 'go.sum', + 'mix.lock', + 'flake.lock', + + // Binary assets + '**/*.png', + '**/*.jpg', + '**/*.jpeg', + '**/*.gif', + '**/*.webp', + '**/*.ico', + '**/*.bmp', + '**/*.tiff', + '**/*.woff', + '**/*.woff2', + '**/*.ttf', + '**/*.otf', + '**/*.eot', + '**/*.mp3', + '**/*.mp4', + '**/*.mov', + '**/*.webm', + '**/*.pdf', + '**/*.zip', + '**/*.tar', + '**/*.gz', + '**/*.tgz', + '**/*.7z', + '**/*.rar', + + // Test snapshots + '**/*.snap', + '**/__snapshots__/**', ]; // ============================================================================ diff --git a/packages/core/src/tests/pipeline-chunker.test.ts b/packages/core/src/tests/pipeline-chunker.test.ts index 9dd2e26..4d5e69e 100644 --- a/packages/core/src/tests/pipeline-chunker.test.ts +++ b/packages/core/src/tests/pipeline-chunker.test.ts @@ -14,6 +14,7 @@ import { loadReviewIgnorePatterns, chunkDiff, REVIEW_IGNORE_MAX_BYTES, + BUILT_IN_ARTIFACT_PATTERNS, } from '../pipeline/chunker.js'; // ============================================================================ @@ -161,6 +162,104 @@ describe('filterIgnoredFiles', () => { }); }); +// ============================================================================ +// BUILT_IN_ARTIFACT_PATTERNS (#482) +// ============================================================================ + +describe('BUILT_IN_ARTIFACT_PATTERNS', () => { + // Each entry is a filePath that MUST be filtered out by the built-in + // pattern list. Failure of any of these is a regression in the default + // exclusion set. + const SHOULD_BE_FILTERED: string[] = [ + // Build outputs + 'dist/bundle.js', + 'build/index.html', + 'out/chunk.abc.js', + '.next/server/pages/index.js', + '.nuxt/client.js', + '.svelte-kit/output/client/app.js', + '.turbo/cache/abc.log', + '.docusaurus/registry.js', + 'storybook-static/iframe.html', + 'coverage/lcov.info', + 'node_modules/react/index.js', + // Minified / bundled + 'assets/vendor.min.js', + 'assets/styles.min.css', + 'assets/app.bundle.js', + 'assets/app.bundle.mjs', + // Source maps + 'src/app.js.map', + 'src/app.css.map', + 'src/types.d.ts.map', + // Generated code + 'proto/messages.pb.go', + 'proto/messages.pb.ts', + 'proto/messages.pb.py', + 'gen/service_pb.js', + 'gen/service.gen.ts', + 'gen/handlers_generated.go', + // Lock files (JS ecosystem) + 'pnpm-lock.yaml', + 'package-lock.json', + 'yarn.lock', + 'bun.lockb', + 'bun.lock', + // Lock files (other ecosystems) + 'Cargo.lock', + 'poetry.lock', + 'Pipfile.lock', + 'uv.lock', + 'composer.lock', + 'Gemfile.lock', + 'go.sum', + 'mix.lock', + 'flake.lock', + // Binary assets + 'assets/logo.png', + 'assets/hero.jpg', + 'assets/icon.svg.ignored-ext-so-skip', // placeholder to keep list intact + 'docs/diagram.webp', + 'public/favicon.ico', + 'assets/font.woff2', + 'assets/font.ttf', + 'assets/demo.mp4', + 'docs/spec.pdf', + 'releases/build.zip', + 'releases/build.tar.gz', + // Test snapshots + 'src/__snapshots__/foo.test.ts.snap', + 'components/__snapshots__/Button.test.tsx.snap', + 'src/foo.snap', + ].filter((p) => !p.endsWith('.ignored-ext-so-skip')); + + // Files that MUST survive the built-in filter — real source code that + // shares prefixes with filtered directories. + const SHOULD_SURVIVE: string[] = [ + 'src/foo.ts', + 'packages/core/src/pipeline/chunker.ts', + 'distribution/index.ts', // starts with "dist" but not dist/ + 'src/build-helpers.ts', // has "build" in the name, not a dir + 'src/node_modules_adapter.ts', // substring match false positive guard + 'scripts/postinstall.cjs', + 'tests/fixtures/sample.snapshot.json', // .snapshot, not .snap + ]; + + for (const p of SHOULD_BE_FILTERED) { + it(`filters ${p}`, () => { + const result = filterIgnoredFiles([{ filePath: p }], BUILT_IN_ARTIFACT_PATTERNS); + expect(result).toHaveLength(0); + }); + } + + for (const p of SHOULD_SURVIVE) { + it(`keeps source-code path ${p}`, () => { + const result = filterIgnoredFiles([{ filePath: p }], BUILT_IN_ARTIFACT_PATTERNS); + expect(result).toHaveLength(1); + }); + } +}); + // ============================================================================ // loadReviewIgnorePatterns // ============================================================================