From c591b7414e0ed22bd53664b5cdbc95a47815d2bf Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 15 Jul 2026 14:24:33 +0100 Subject: [PATCH 01/17] feat: add more patterns to unnecessary files hints --- app/utils/package-content-hints.ts | 4 ++++ test/unit/app/utils/package-content-hints.spec.ts | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/app/utils/package-content-hints.ts b/app/utils/package-content-hints.ts index 8df8287950..0e15a6489b 100644 --- a/app/utils/package-content-hints.ts +++ b/app/utils/package-content-hints.ts @@ -11,8 +11,10 @@ const POSSIBLY_UNNECESSARY_FILES: ReadonlySet = new Set([ '.editorconfig', '.prettierignore', '.eslintignore', + '.jshintignore', '.gitignore', '.gitattributes', + '.travis.yml', 'tsconfig.json', '.node-version', '.nvmrc', @@ -27,6 +29,7 @@ const POSSIBLY_UNNECESSARY_FILES: ReadonlySet = new Set([ '.env.production.local', '.nycrc', 'nyc.json', + 'CHANGELOG.md' ]) const POSSIBLY_UNNECESSARY_DIRECTORIES: ReadonlySet = new Set([ @@ -40,6 +43,7 @@ const POSSIBLY_UNNECESSARY_DIRECTORIES: ReadonlySet = new Set([ '__tests__', 'spec', 'specs', + 'examples', ]) const POSSIBLY_UNNECESSARY_DIRECTORY_PATTERNS: readonly RegExp[] = [/^__.+__$/] diff --git a/test/unit/app/utils/package-content-hints.spec.ts b/test/unit/app/utils/package-content-hints.spec.ts index 770e33d4ea..ef9aaa9811 100644 --- a/test/unit/app/utils/package-content-hints.spec.ts +++ b/test/unit/app/utils/package-content-hints.spec.ts @@ -8,6 +8,7 @@ describe('isPossiblyUnnecessaryContent', () => { expect(isPossiblyUnnecessaryContent('.gitattributes', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('.prettierignore', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('.eslintignore', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('.jshintignore', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('tsconfig.json', 'file')).toBe(true) }) @@ -30,6 +31,14 @@ describe('isPossiblyUnnecessaryContent', () => { expect(isPossiblyUnnecessaryContent('nyc.json', 'file')).toBe(true) }) + it('flags editor and CI files', () => { + expect(isPossiblyUnnecessaryContent('.travis.yml', 'file')).toBe(true) + }) + + it('flags changelog files', () => { + expect(isPossiblyUnnecessaryContent('CHANGELOG.md', 'file')).toBe(true) + }) + it('matches ESLint configuration patterns', () => { for (const extension of ['js', 'cjs', 'mjs', 'ts', 'mts', 'cts']) { expect(isPossiblyUnnecessaryContent(`eslint.config.${extension}`, 'file')).toBe(true) @@ -105,6 +114,10 @@ describe('isPossiblyUnnecessaryContent', () => { expect(isPossiblyUnnecessaryContent('specs', 'directory')).toBe(true) }) + it('flags example directories', () => { + expect(isPossiblyUnnecessaryContent('examples', 'directory')).toBe(true) + }) + it('does not flag ordinary source files or directories', () => { expect(isPossiblyUnnecessaryContent('index.js', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('package.json', 'file')).toBe(false) From 6b2882abdb9a4ac2b78a9deb74074cd57e648512 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Wed, 15 Jul 2026 13:27:37 +0000 Subject: [PATCH 02/17] [autofix.ci] apply automated fixes --- app/utils/package-content-hints.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/utils/package-content-hints.ts b/app/utils/package-content-hints.ts index 0e15a6489b..dae2ee138d 100644 --- a/app/utils/package-content-hints.ts +++ b/app/utils/package-content-hints.ts @@ -29,7 +29,7 @@ const POSSIBLY_UNNECESSARY_FILES: ReadonlySet = new Set([ '.env.production.local', '.nycrc', 'nyc.json', - 'CHANGELOG.md' + 'CHANGELOG.md', ]) const POSSIBLY_UNNECESSARY_DIRECTORIES: ReadonlySet = new Set([ From 7b7cd38b1f9f544a3a7501372ac14c0e4efd7f14 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 15 Jul 2026 14:32:11 +0100 Subject: [PATCH 03/17] feat: more patterns --- app/utils/package-content-hints.ts | 5 ++++- test/unit/app/utils/package-content-hints.spec.ts | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/utils/package-content-hints.ts b/app/utils/package-content-hints.ts index dae2ee138d..4e6b9bed69 100644 --- a/app/utils/package-content-hints.ts +++ b/app/utils/package-content-hints.ts @@ -30,6 +30,9 @@ const POSSIBLY_UNNECESSARY_FILES: ReadonlySet = new Set([ '.nycrc', 'nyc.json', 'CHANGELOG.md', + 'changelog.md', + 'CHANGELOG.markdown', + 'changelog.markdown', ]) const POSSIBLY_UNNECESSARY_DIRECTORIES: ReadonlySet = new Set([ @@ -40,9 +43,9 @@ const POSSIBLY_UNNECESSARY_DIRECTORIES: ReadonlySet = new Set([ '.zed', 'test', 'tests', - '__tests__', 'spec', 'specs', + 'example', 'examples', ]) diff --git a/test/unit/app/utils/package-content-hints.spec.ts b/test/unit/app/utils/package-content-hints.spec.ts index ef9aaa9811..92b7b0cabd 100644 --- a/test/unit/app/utils/package-content-hints.spec.ts +++ b/test/unit/app/utils/package-content-hints.spec.ts @@ -37,6 +37,9 @@ describe('isPossiblyUnnecessaryContent', () => { it('flags changelog files', () => { expect(isPossiblyUnnecessaryContent('CHANGELOG.md', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('changelog.md', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('CHANGELOG.markdown', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('changelog.markdown', 'file')).toBe(true) }) it('matches ESLint configuration patterns', () => { @@ -115,6 +118,7 @@ describe('isPossiblyUnnecessaryContent', () => { }) it('flags example directories', () => { + expect(isPossiblyUnnecessaryContent('example', 'directory')).toBe(true) expect(isPossiblyUnnecessaryContent('examples', 'directory')).toBe(true) }) From 88c71cec3477d1004be43d4a7de5b4bad869c9d7 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 15 Jul 2026 14:36:33 +0100 Subject: [PATCH 04/17] feat: more patterns --- app/utils/package-content-hints.ts | 2 ++ test/unit/app/utils/package-content-hints.spec.ts | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/app/utils/package-content-hints.ts b/app/utils/package-content-hints.ts index 4e6b9bed69..f430ad6adf 100644 --- a/app/utils/package-content-hints.ts +++ b/app/utils/package-content-hints.ts @@ -65,6 +65,8 @@ const POSSIBLY_UNNECESSARY_PATTERNS: readonly RegExp[] = [ /^\.(?!npmrc$)[a-z][a-z0-9_-]*rc$/, /^\.(?!npmrc\.)[a-z][a-z0-9_-]*rc\.(?:json|js|cjs|mjs|yml|yaml|toml)$/, /^\.[a-z][a-z0-9_-]*\.config\.(?:js|cjs|mjs|ts|mts|cts)$/, + // Match files ending in .test.js, .test.ts, .spec.js, .spec.ts, etc. + /(?:test|spec)\.(?:j|t)s$/, ] export function isPossiblyUnnecessaryContent(name: string, type: 'file' | 'directory'): boolean { diff --git a/test/unit/app/utils/package-content-hints.spec.ts b/test/unit/app/utils/package-content-hints.spec.ts index 92b7b0cabd..62ffd818ea 100644 --- a/test/unit/app/utils/package-content-hints.spec.ts +++ b/test/unit/app/utils/package-content-hints.spec.ts @@ -35,6 +35,14 @@ describe('isPossiblyUnnecessaryContent', () => { expect(isPossiblyUnnecessaryContent('.travis.yml', 'file')).toBe(true) }) + it('flags test files', () => { + expect(isPossiblyUnnecessaryContent('test.js', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('index.test.js', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('index.spec.js', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('index.test.ts', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('index.spec.ts', 'file')).toBe(true) + }) + it('flags changelog files', () => { expect(isPossiblyUnnecessaryContent('CHANGELOG.md', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('changelog.md', 'file')).toBe(true) From ce019eedc75d3d90594723f820666899a916285e Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 15 Jul 2026 18:11:56 +0100 Subject: [PATCH 05/17] feat: add more patterns --- app/utils/package-content-hints.ts | 5 +++++ .../app/utils/package-content-hints.spec.ts | 17 +++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/app/utils/package-content-hints.ts b/app/utils/package-content-hints.ts index f430ad6adf..524a6dfb9d 100644 --- a/app/utils/package-content-hints.ts +++ b/app/utils/package-content-hints.ts @@ -12,9 +12,11 @@ const POSSIBLY_UNNECESSARY_FILES: ReadonlySet = new Set([ '.prettierignore', '.eslintignore', '.jshintignore', + '.npmignore', '.gitignore', '.gitattributes', '.travis.yml', + 'Makefile', 'tsconfig.json', '.node-version', '.nvmrc', @@ -33,6 +35,9 @@ const POSSIBLY_UNNECESSARY_FILES: ReadonlySet = new Set([ 'changelog.md', 'CHANGELOG.markdown', 'changelog.markdown', + 'RELEASENOTES.md', + 'CONTRIBUTING.md', + 'AUTHORS', ]) const POSSIBLY_UNNECESSARY_DIRECTORIES: ReadonlySet = new Set([ diff --git a/test/unit/app/utils/package-content-hints.spec.ts b/test/unit/app/utils/package-content-hints.spec.ts index 62ffd818ea..aba749d9ed 100644 --- a/test/unit/app/utils/package-content-hints.spec.ts +++ b/test/unit/app/utils/package-content-hints.spec.ts @@ -9,6 +9,7 @@ describe('isPossiblyUnnecessaryContent', () => { expect(isPossiblyUnnecessaryContent('.prettierignore', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('.eslintignore', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('.jshintignore', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('.npmignore', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('tsconfig.json', 'file')).toBe(true) }) @@ -33,6 +34,7 @@ describe('isPossiblyUnnecessaryContent', () => { it('flags editor and CI files', () => { expect(isPossiblyUnnecessaryContent('.travis.yml', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('Makefile', 'file')).toBe(true) }) it('flags test files', () => { @@ -43,11 +45,14 @@ describe('isPossiblyUnnecessaryContent', () => { expect(isPossiblyUnnecessaryContent('index.spec.ts', 'file')).toBe(true) }) - it('flags changelog files', () => { + it('flags changelog and non-readme description files', () => { expect(isPossiblyUnnecessaryContent('CHANGELOG.md', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('changelog.md', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('CHANGELOG.markdown', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('changelog.markdown', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('RELEASENOTES.md', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('CONTRIBUTING.md', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('AUTHORS', 'file')).toBe(true) }) it('matches ESLint configuration patterns', () => { @@ -134,13 +139,21 @@ describe('isPossiblyUnnecessaryContent', () => { expect(isPossiblyUnnecessaryContent('index.js', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('package.json', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('README.md', 'file')).toBe(false) - expect(isPossiblyUnnecessaryContent('LICENSE', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('readme.md', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('main.ts', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('src', 'directory')).toBe(false) expect(isPossiblyUnnecessaryContent('lib', 'directory')).toBe(false) expect(isPossiblyUnnecessaryContent('dist', 'directory')).toBe(false) }) + it('does not flag legal related files', () => { + expect(isPossiblyUnnecessaryContent('license', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('LICENSE', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('LICENSE-MIT.txt', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('NOTICE', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('UNLICENSE', 'file')).toBe(false) + }) + it('does not confuse a directory name passed as a file with the directory match', () => { expect(isPossiblyUnnecessaryContent('.vscode', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('test', 'file')).toBe(false) From 8a68ab170153bbd05adabebb74e9de0cc618032b Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 15 Jul 2026 18:17:56 +0100 Subject: [PATCH 06/17] chore: simplify patterns --- app/utils/package-content-hints.ts | 8 ++---- .../app/utils/package-content-hints.spec.ts | 25 +++++++++++++------ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/app/utils/package-content-hints.ts b/app/utils/package-content-hints.ts index 524a6dfb9d..479a264b98 100644 --- a/app/utils/package-content-hints.ts +++ b/app/utils/package-content-hints.ts @@ -31,12 +31,6 @@ const POSSIBLY_UNNECESSARY_FILES: ReadonlySet = new Set([ '.env.production.local', '.nycrc', 'nyc.json', - 'CHANGELOG.md', - 'changelog.md', - 'CHANGELOG.markdown', - 'changelog.markdown', - 'RELEASENOTES.md', - 'CONTRIBUTING.md', 'AUTHORS', ]) @@ -72,6 +66,8 @@ const POSSIBLY_UNNECESSARY_PATTERNS: readonly RegExp[] = [ /^\.[a-z][a-z0-9_-]*\.config\.(?:js|cjs|mjs|ts|mts|cts)$/, // Match files ending in .test.js, .test.ts, .spec.js, .spec.ts, etc. /(?:test|spec)\.(?:j|t)s$/, + // Match CHANGELOG.md, etc + /^(?:changelog|releasenotes|release-notes|history|contributing|contribute)\.(?:md|markdown|txt)$/i, ] export function isPossiblyUnnecessaryContent(name: string, type: 'file' | 'directory'): boolean { diff --git a/test/unit/app/utils/package-content-hints.spec.ts b/test/unit/app/utils/package-content-hints.spec.ts index aba749d9ed..ffa179d83e 100644 --- a/test/unit/app/utils/package-content-hints.spec.ts +++ b/test/unit/app/utils/package-content-hints.spec.ts @@ -45,16 +45,27 @@ describe('isPossiblyUnnecessaryContent', () => { expect(isPossiblyUnnecessaryContent('index.spec.ts', 'file')).toBe(true) }) - it('flags changelog and non-readme description files', () => { - expect(isPossiblyUnnecessaryContent('CHANGELOG.md', 'file')).toBe(true) - expect(isPossiblyUnnecessaryContent('changelog.md', 'file')).toBe(true) - expect(isPossiblyUnnecessaryContent('CHANGELOG.markdown', 'file')).toBe(true) - expect(isPossiblyUnnecessaryContent('changelog.markdown', 'file')).toBe(true) - expect(isPossiblyUnnecessaryContent('RELEASENOTES.md', 'file')).toBe(true) - expect(isPossiblyUnnecessaryContent('CONTRIBUTING.md', 'file')).toBe(true) + it('flags unnecessay metadata and documentation files', () => { expect(isPossiblyUnnecessaryContent('AUTHORS', 'file')).toBe(true) }) + it('flags changelog, release notes, and contributing files', () => { + const files = [ + 'CHANGELOG.md', + 'changelog.md', + 'CHANGELOG.markdown', + 'changelog.markdown', + 'RELEASENOTES.md', + 'release-notest.md', + 'CONTRIBUTING.md', + 'HISTORY.md', + 'history.txt', + ] + for (const name of files) { + expect(isPossiblyUnnecessaryContent(name, 'file')).toBe(true) + } + }) + it('matches ESLint configuration patterns', () => { for (const extension of ['js', 'cjs', 'mjs', 'ts', 'mts', 'cts']) { expect(isPossiblyUnnecessaryContent(`eslint.config.${extension}`, 'file')).toBe(true) From 45927454b0e2797a840ca734640440a1d70f692f Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 15 Jul 2026 18:20:31 +0100 Subject: [PATCH 07/17] fix: do not match latest.js --- app/utils/package-content-hints.ts | 4 +++- test/unit/app/utils/package-content-hints.spec.ts | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/utils/package-content-hints.ts b/app/utils/package-content-hints.ts index 479a264b98..14d600320a 100644 --- a/app/utils/package-content-hints.ts +++ b/app/utils/package-content-hints.ts @@ -32,6 +32,8 @@ const POSSIBLY_UNNECESSARY_FILES: ReadonlySet = new Set([ '.nycrc', 'nyc.json', 'AUTHORS', + 'test.js', + 'test.ts', ]) const POSSIBLY_UNNECESSARY_DIRECTORIES: ReadonlySet = new Set([ @@ -65,7 +67,7 @@ const POSSIBLY_UNNECESSARY_PATTERNS: readonly RegExp[] = [ /^\.(?!npmrc\.)[a-z][a-z0-9_-]*rc\.(?:json|js|cjs|mjs|yml|yaml|toml)$/, /^\.[a-z][a-z0-9_-]*\.config\.(?:js|cjs|mjs|ts|mts|cts)$/, // Match files ending in .test.js, .test.ts, .spec.js, .spec.ts, etc. - /(?:test|spec)\.(?:j|t)s$/, + /\.(?:test|spec)\.(?:j|t)s$/, // Match CHANGELOG.md, etc /^(?:changelog|releasenotes|release-notes|history|contributing|contribute)\.(?:md|markdown|txt)$/i, ] diff --git a/test/unit/app/utils/package-content-hints.spec.ts b/test/unit/app/utils/package-content-hints.spec.ts index ffa179d83e..c6a8a75c21 100644 --- a/test/unit/app/utils/package-content-hints.spec.ts +++ b/test/unit/app/utils/package-content-hints.spec.ts @@ -148,6 +148,7 @@ describe('isPossiblyUnnecessaryContent', () => { it('does not flag ordinary source files or directories', () => { expect(isPossiblyUnnecessaryContent('index.js', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('latest.js', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('package.json', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('README.md', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('readme.md', 'file')).toBe(false) From 91c2896a65f36f4379edf1877390a29bbccd91b4 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 15 Jul 2026 18:24:43 +0100 Subject: [PATCH 08/17] more tests --- test/unit/app/utils/package-content-hints.spec.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/unit/app/utils/package-content-hints.spec.ts b/test/unit/app/utils/package-content-hints.spec.ts index c6a8a75c21..ba8ec7f1dd 100644 --- a/test/unit/app/utils/package-content-hints.spec.ts +++ b/test/unit/app/utils/package-content-hints.spec.ts @@ -52,6 +52,7 @@ describe('isPossiblyUnnecessaryContent', () => { it('flags changelog, release notes, and contributing files', () => { const files = [ 'CHANGELOG.md', + 'Changelog.md', 'changelog.md', 'CHANGELOG.markdown', 'changelog.markdown', @@ -59,6 +60,7 @@ describe('isPossiblyUnnecessaryContent', () => { 'release-notest.md', 'CONTRIBUTING.md', 'HISTORY.md', + 'History.md', 'history.txt', ] for (const name of files) { From dbe6cfae545468b6999efe92fc66fae956f3c639 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 15 Jul 2026 18:28:08 +0100 Subject: [PATCH 09/17] test: check both license spellings --- test/unit/app/utils/package-content-hints.spec.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/unit/app/utils/package-content-hints.spec.ts b/test/unit/app/utils/package-content-hints.spec.ts index ba8ec7f1dd..4641f31303 100644 --- a/test/unit/app/utils/package-content-hints.spec.ts +++ b/test/unit/app/utils/package-content-hints.spec.ts @@ -161,8 +161,10 @@ describe('isPossiblyUnnecessaryContent', () => { }) it('does not flag legal related files', () => { - expect(isPossiblyUnnecessaryContent('license', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('LICENSE', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('LICENCE', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('license', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('licence', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('LICENSE-MIT.txt', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('NOTICE', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('UNLICENSE', 'file')).toBe(false) From dac0e8142a5f802bdc5ed85d188b7f780f00521a Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 15 Jul 2026 18:43:55 +0100 Subject: [PATCH 10/17] feat: add more patterns --- app/utils/package-content-hints.ts | 4 ++++ .../app/utils/package-content-hints.spec.ts | 21 ++++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/app/utils/package-content-hints.ts b/app/utils/package-content-hints.ts index 14d600320a..2ee53509cb 100644 --- a/app/utils/package-content-hints.ts +++ b/app/utils/package-content-hints.ts @@ -16,6 +16,7 @@ const POSSIBLY_UNNECESSARY_FILES: ReadonlySet = new Set([ '.gitignore', '.gitattributes', '.travis.yml', + '.verb.md', 'Makefile', 'tsconfig.json', '.node-version', @@ -31,6 +32,7 @@ const POSSIBLY_UNNECESSARY_FILES: ReadonlySet = new Set([ '.env.production.local', '.nycrc', 'nyc.json', + '.DS_Store', 'AUTHORS', 'test.js', 'test.ts', @@ -48,6 +50,7 @@ const POSSIBLY_UNNECESSARY_DIRECTORIES: ReadonlySet = new Set([ 'specs', 'example', 'examples', + 'benchmark', ]) const POSSIBLY_UNNECESSARY_DIRECTORY_PATTERNS: readonly RegExp[] = [/^__.+__$/] @@ -61,6 +64,7 @@ const POSSIBLY_UNNECESSARY_PATTERNS: readonly RegExp[] = [ /^\.oxlintrc(?:\.(?:json|js|cjs|yml|yaml))?$/, /^oxfmt\.config\.(?:js|cjs|mjs|ts|mts|cts)$/, /^\.oxfmtrc(?:\.(?:json|js|cjs|yml|yaml))?$/, + /^example\.(?:js|cjs|mjs|ts|mts|cts)$/, // Match common dot-prefixed config files without flagging all dotfiles; // files like .npmrc, .npmignore, and .gitkeep can be intentional artifacts. /^\.(?!npmrc$)[a-z][a-z0-9_-]*rc$/, diff --git a/test/unit/app/utils/package-content-hints.spec.ts b/test/unit/app/utils/package-content-hints.spec.ts index 4641f31303..542180e296 100644 --- a/test/unit/app/utils/package-content-hints.spec.ts +++ b/test/unit/app/utils/package-content-hints.spec.ts @@ -34,15 +34,15 @@ describe('isPossiblyUnnecessaryContent', () => { it('flags editor and CI files', () => { expect(isPossiblyUnnecessaryContent('.travis.yml', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('.verb.md', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('Makefile', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('.DS_Store', 'file')).toBe(true) }) - it('flags test files', () => { - expect(isPossiblyUnnecessaryContent('test.js', 'file')).toBe(true) - expect(isPossiblyUnnecessaryContent('index.test.js', 'file')).toBe(true) - expect(isPossiblyUnnecessaryContent('index.spec.js', 'file')).toBe(true) - expect(isPossiblyUnnecessaryContent('index.test.ts', 'file')).toBe(true) - expect(isPossiblyUnnecessaryContent('index.spec.ts', 'file')).toBe(true) + it('flags example and development files', () => { + expect(isPossiblyUnnecessaryContent('bench.js', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('example.js', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('example.mjs', 'file')).toBe(true) }) it('flags unnecessay metadata and documentation files', () => { @@ -57,7 +57,7 @@ describe('isPossiblyUnnecessaryContent', () => { 'CHANGELOG.markdown', 'changelog.markdown', 'RELEASENOTES.md', - 'release-notest.md', + 'release-notes.md', 'CONTRIBUTING.md', 'HISTORY.md', 'History.md', @@ -143,6 +143,10 @@ describe('isPossiblyUnnecessaryContent', () => { expect(isPossiblyUnnecessaryContent('specs', 'directory')).toBe(true) }) + it('flags development directories', () => { + expect(isPossiblyUnnecessaryContent('benchmark', 'directory')).toBe(true) + }) + it('flags example directories', () => { expect(isPossiblyUnnecessaryContent('example', 'directory')).toBe(true) expect(isPossiblyUnnecessaryContent('examples', 'directory')).toBe(true) @@ -165,6 +169,9 @@ describe('isPossiblyUnnecessaryContent', () => { expect(isPossiblyUnnecessaryContent('LICENCE', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('license', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('licence', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('LICENSE.md', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('LICENCE.md', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('LICENSE-MIT', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('LICENSE-MIT.txt', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('NOTICE', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('UNLICENSE', 'file')).toBe(false) From 5898312f8f91d9ce22d70e55fda094604e37d275 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 15 Jul 2026 18:45:33 +0100 Subject: [PATCH 11/17] fix --- app/utils/package-content-hints.ts | 3 ++- test/unit/app/utils/package-content-hints.spec.ts | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/utils/package-content-hints.ts b/app/utils/package-content-hints.ts index 2ee53509cb..357c028be5 100644 --- a/app/utils/package-content-hints.ts +++ b/app/utils/package-content-hints.ts @@ -64,7 +64,6 @@ const POSSIBLY_UNNECESSARY_PATTERNS: readonly RegExp[] = [ /^\.oxlintrc(?:\.(?:json|js|cjs|yml|yaml))?$/, /^oxfmt\.config\.(?:js|cjs|mjs|ts|mts|cts)$/, /^\.oxfmtrc(?:\.(?:json|js|cjs|yml|yaml))?$/, - /^example\.(?:js|cjs|mjs|ts|mts|cts)$/, // Match common dot-prefixed config files without flagging all dotfiles; // files like .npmrc, .npmignore, and .gitkeep can be intentional artifacts. /^\.(?!npmrc$)[a-z][a-z0-9_-]*rc$/, @@ -74,6 +73,8 @@ const POSSIBLY_UNNECESSARY_PATTERNS: readonly RegExp[] = [ /\.(?:test|spec)\.(?:j|t)s$/, // Match CHANGELOG.md, etc /^(?:changelog|releasenotes|release-notes|history|contributing|contribute)\.(?:md|markdown|txt)$/i, + // Match examples.js, stc + /^example(?:s)\.(js|cjs|mjs|ts|mts|cts)$/, ] export function isPossiblyUnnecessaryContent(name: string, type: 'file' | 'directory'): boolean { diff --git a/test/unit/app/utils/package-content-hints.spec.ts b/test/unit/app/utils/package-content-hints.spec.ts index 542180e296..0bf8535419 100644 --- a/test/unit/app/utils/package-content-hints.spec.ts +++ b/test/unit/app/utils/package-content-hints.spec.ts @@ -42,6 +42,7 @@ describe('isPossiblyUnnecessaryContent', () => { it('flags example and development files', () => { expect(isPossiblyUnnecessaryContent('bench.js', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('example.js', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('examples.js', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('example.mjs', 'file')).toBe(true) }) From 3cee99ab15906bceab031ea81a61cec905a5373a Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Wed, 15 Jul 2026 17:46:50 +0000 Subject: [PATCH 12/17] [autofix.ci] apply automated fixes --- app/utils/package-content-hints.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/utils/package-content-hints.ts b/app/utils/package-content-hints.ts index 357c028be5..6aad26fbf7 100644 --- a/app/utils/package-content-hints.ts +++ b/app/utils/package-content-hints.ts @@ -74,7 +74,7 @@ const POSSIBLY_UNNECESSARY_PATTERNS: readonly RegExp[] = [ // Match CHANGELOG.md, etc /^(?:changelog|releasenotes|release-notes|history|contributing|contribute)\.(?:md|markdown|txt)$/i, // Match examples.js, stc - /^example(?:s)\.(js|cjs|mjs|ts|mts|cts)$/, + /^examples\.(js|cjs|mjs|ts|mts|cts)$/, ] export function isPossiblyUnnecessaryContent(name: string, type: 'file' | 'directory'): boolean { From 34d02098e25b764bd732402079221aba3275ba02 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 15 Jul 2026 18:50:17 +0100 Subject: [PATCH 13/17] update test --- app/utils/package-content-hints.ts | 2 +- test/unit/app/utils/package-content-hints.spec.ts | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/utils/package-content-hints.ts b/app/utils/package-content-hints.ts index 6aad26fbf7..81e1df2cae 100644 --- a/app/utils/package-content-hints.ts +++ b/app/utils/package-content-hints.ts @@ -65,7 +65,7 @@ const POSSIBLY_UNNECESSARY_PATTERNS: readonly RegExp[] = [ /^oxfmt\.config\.(?:js|cjs|mjs|ts|mts|cts)$/, /^\.oxfmtrc(?:\.(?:json|js|cjs|yml|yaml))?$/, // Match common dot-prefixed config files without flagging all dotfiles; - // files like .npmrc, .npmignore, and .gitkeep can be intentional artifacts. + // files like .npmrc can be intentional artifacts. /^\.(?!npmrc$)[a-z][a-z0-9_-]*rc$/, /^\.(?!npmrc\.)[a-z][a-z0-9_-]*rc\.(?:json|js|cjs|mjs|yml|yaml|toml)$/, /^\.[a-z][a-z0-9_-]*\.config\.(?:js|cjs|mjs|ts|mts|cts)$/, diff --git a/test/unit/app/utils/package-content-hints.spec.ts b/test/unit/app/utils/package-content-hints.spec.ts index 0bf8535419..a2102ee8f5 100644 --- a/test/unit/app/utils/package-content-hints.spec.ts +++ b/test/unit/app/utils/package-content-hints.spec.ts @@ -50,7 +50,7 @@ describe('isPossiblyUnnecessaryContent', () => { expect(isPossiblyUnnecessaryContent('AUTHORS', 'file')).toBe(true) }) - it('flags changelog, release notes, and contributing files', () => { + describe('changelog, release notes, and contributing files', () => { const files = [ 'CHANGELOG.md', 'Changelog.md', @@ -65,7 +65,9 @@ describe('isPossiblyUnnecessaryContent', () => { 'history.txt', ] for (const name of files) { - expect(isPossiblyUnnecessaryContent(name, 'file')).toBe(true) + it(`flags ${name}`, () => { + expect(isPossiblyUnnecessaryContent(name, 'file')).toBe(true) + }) } }) From 1019a76c76a0088f759615008d7a9f162232fae3 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 15 Jul 2026 18:54:49 +0100 Subject: [PATCH 14/17] fix pattern --- app/utils/package-content-hints.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/utils/package-content-hints.ts b/app/utils/package-content-hints.ts index 81e1df2cae..aabdf5c1f2 100644 --- a/app/utils/package-content-hints.ts +++ b/app/utils/package-content-hints.ts @@ -36,6 +36,7 @@ const POSSIBLY_UNNECESSARY_FILES: ReadonlySet = new Set([ 'AUTHORS', 'test.js', 'test.ts', + 'bench.js', ]) const POSSIBLY_UNNECESSARY_DIRECTORIES: ReadonlySet = new Set([ @@ -73,8 +74,8 @@ const POSSIBLY_UNNECESSARY_PATTERNS: readonly RegExp[] = [ /\.(?:test|spec)\.(?:j|t)s$/, // Match CHANGELOG.md, etc /^(?:changelog|releasenotes|release-notes|history|contributing|contribute)\.(?:md|markdown|txt)$/i, - // Match examples.js, stc - /^examples\.(js|cjs|mjs|ts|mts|cts)$/, + // Match example.mjs, examples.js, stc + /^examples?\.(?:js|cjs|mjs|ts|mts|cts)$/, ] export function isPossiblyUnnecessaryContent(name: string, type: 'file' | 'directory'): boolean { From f7692a522bf9e80d86c259a53f7fb56c79b1b5e0 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 17 Jul 2026 11:25:55 +0100 Subject: [PATCH 15/17] feat: add more patterns --- app/utils/package-content-hints.ts | 2 ++ test/unit/app/utils/package-content-hints.spec.ts | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/app/utils/package-content-hints.ts b/app/utils/package-content-hints.ts index aabdf5c1f2..e59e00d8ae 100644 --- a/app/utils/package-content-hints.ts +++ b/app/utils/package-content-hints.ts @@ -36,6 +36,8 @@ const POSSIBLY_UNNECESSARY_FILES: ReadonlySet = new Set([ 'AUTHORS', 'test.js', 'test.ts', + 'tests.js', + 'tests.ts', 'bench.js', ]) diff --git a/test/unit/app/utils/package-content-hints.spec.ts b/test/unit/app/utils/package-content-hints.spec.ts index a2102ee8f5..1640019952 100644 --- a/test/unit/app/utils/package-content-hints.spec.ts +++ b/test/unit/app/utils/package-content-hints.spec.ts @@ -40,6 +40,13 @@ describe('isPossiblyUnnecessaryContent', () => { }) it('flags example and development files', () => { + expect(isPossiblyUnnecessaryContent('test.js', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('tests.js', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('test.ts', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('index.test.js', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('index.test.ts', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('index.spec.js', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('index.spec.ts', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('bench.js', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('example.js', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('examples.js', 'file')).toBe(true) From d94d268e8f253238f41aea20217c0a4b8bf4da72 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 17 Jul 2026 19:13:29 +0100 Subject: [PATCH 16/17] feat: add more patterns --- app/utils/package-content-hints.ts | 9 +- .../app/utils/package-content-hints.spec.ts | 130 ++++++++++-------- 2 files changed, 83 insertions(+), 56 deletions(-) diff --git a/app/utils/package-content-hints.ts b/app/utils/package-content-hints.ts index e59e00d8ae..a56779ce46 100644 --- a/app/utils/package-content-hints.ts +++ b/app/utils/package-content-hints.ts @@ -39,6 +39,10 @@ const POSSIBLY_UNNECESSARY_FILES: ReadonlySet = new Set([ 'tests.js', 'tests.ts', 'bench.js', + 'yarn.lock', + 'bun.lock', + 'bun.lockb', + 'package-lock.json', ]) const POSSIBLY_UNNECESSARY_DIRECTORIES: ReadonlySet = new Set([ @@ -47,6 +51,8 @@ const POSSIBLY_UNNECESSARY_DIRECTORIES: ReadonlySet = new Set([ '.github', '.idea', '.zed', + '.yarn', + '.husky', 'test', 'tests', 'spec', @@ -67,6 +73,7 @@ const POSSIBLY_UNNECESSARY_PATTERNS: readonly RegExp[] = [ /^\.oxlintrc(?:\.(?:json|js|cjs|yml|yaml))?$/, /^oxfmt\.config\.(?:js|cjs|mjs|ts|mts|cts)$/, /^\.oxfmtrc(?:\.(?:json|js|cjs|yml|yaml))?$/, + /^jest\.config\.(?:js|cjs|mjs|ts|mts|cts)$/, // Match common dot-prefixed config files without flagging all dotfiles; // files like .npmrc can be intentional artifacts. /^\.(?!npmrc$)[a-z][a-z0-9_-]*rc$/, @@ -75,7 +82,7 @@ const POSSIBLY_UNNECESSARY_PATTERNS: readonly RegExp[] = [ // Match files ending in .test.js, .test.ts, .spec.js, .spec.ts, etc. /\.(?:test|spec)\.(?:j|t)s$/, // Match CHANGELOG.md, etc - /^(?:changelog|releasenotes|release-notes|history|contributing|contribute)\.(?:md|markdown|txt)$/i, + /^(?:changelog|releasenotes|release-notes|history|contributing|contribute|news|collaborators)\.(?:md|markdown|txt)$/i, // Match example.mjs, examples.js, stc /^examples?\.(?:js|cjs|mjs|ts|mts|cts)$/, ] diff --git a/test/unit/app/utils/package-content-hints.spec.ts b/test/unit/app/utils/package-content-hints.spec.ts index 1640019952..babf599e20 100644 --- a/test/unit/app/utils/package-content-hints.spec.ts +++ b/test/unit/app/utils/package-content-hints.spec.ts @@ -39,6 +39,13 @@ describe('isPossiblyUnnecessaryContent', () => { expect(isPossiblyUnnecessaryContent('.DS_Store', 'file')).toBe(true) }) + it('flags package manager lockfiles', () => { + expect(isPossiblyUnnecessaryContent('yarn.lock', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('bun.lock', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('bun.lockb', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('package-lock.json', 'file')).toBe(true) + }) + it('flags example and development files', () => { expect(isPossiblyUnnecessaryContent('test.js', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('tests.js', 'file')).toBe(true) @@ -55,6 +62,7 @@ describe('isPossiblyUnnecessaryContent', () => { it('flags unnecessay metadata and documentation files', () => { expect(isPossiblyUnnecessaryContent('AUTHORS', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('collaborators.md', 'file')).toBe(true) }) describe('changelog, release notes, and contributing files', () => { @@ -70,6 +78,7 @@ describe('isPossiblyUnnecessaryContent', () => { 'HISTORY.md', 'History.md', 'history.txt', + 'NEWS.md', ] for (const name of files) { it(`flags ${name}`, () => { @@ -78,61 +87,69 @@ describe('isPossiblyUnnecessaryContent', () => { } }) - it('matches ESLint configuration patterns', () => { - for (const extension of ['js', 'cjs', 'mjs', 'ts', 'mts', 'cts']) { - expect(isPossiblyUnnecessaryContent(`eslint.config.${extension}`, 'file')).toBe(true) - } - expect(isPossiblyUnnecessaryContent('.eslintrc', 'file')).toBe(true) - for (const extension of ['json', 'js', 'cjs', 'yml', 'yaml']) { - expect(isPossiblyUnnecessaryContent(`.eslintrc.${extension}`, 'file')).toBe(true) - } - expect(isPossiblyUnnecessaryContent('eslint.config.json', 'file')).toBe(false) - expect(isPossiblyUnnecessaryContent('.eslintrc.txt', 'file')).toBe(false) - }) - - it('matches Prettier configuration patterns', () => { - expect(isPossiblyUnnecessaryContent('.prettierrc', 'file')).toBe(true) - for (const extension of ['json', 'js', 'cjs', 'yml', 'yaml', 'toml']) { - expect(isPossiblyUnnecessaryContent(`.prettierrc.${extension}`, 'file')).toBe(true) - } - for (const extension of ['js', 'cjs', 'mjs', 'ts', 'mts', 'cts']) { - expect(isPossiblyUnnecessaryContent(`prettier.config.${extension}`, 'file')).toBe(true) - } - expect(isPossiblyUnnecessaryContent('.prettierrc.txt', 'file')).toBe(false) - expect(isPossiblyUnnecessaryContent('prettier.config.json', 'file')).toBe(false) - }) - - it('matches oxlint and oxfmt configuration patterns', () => { - for (const extension of ['js', 'cjs', 'mjs', 'ts', 'mts', 'cts']) { - expect(isPossiblyUnnecessaryContent(`oxlint.config.${extension}`, 'file')).toBe(true) - expect(isPossiblyUnnecessaryContent(`oxfmt.config.${extension}`, 'file')).toBe(true) - } - expect(isPossiblyUnnecessaryContent('.oxlintrc', 'file')).toBe(true) - expect(isPossiblyUnnecessaryContent('.oxfmtrc', 'file')).toBe(true) - for (const extension of ['json', 'js', 'cjs', 'yml', 'yaml']) { - expect(isPossiblyUnnecessaryContent(`.oxlintrc.${extension}`, 'file')).toBe(true) - expect(isPossiblyUnnecessaryContent(`.oxfmtrc.${extension}`, 'file')).toBe(true) - } - expect(isPossiblyUnnecessaryContent('oxlint.config.json', 'file')).toBe(false) - expect(isPossiblyUnnecessaryContent('oxfmt.config.json', 'file')).toBe(false) - expect(isPossiblyUnnecessaryContent('.oxlintrc.txt', 'file')).toBe(false) - expect(isPossiblyUnnecessaryContent('.oxfmtrc.txt', 'file')).toBe(false) - }) - - it('matches common dot-prefixed configuration patterns without over-flagging', () => { - expect(isPossiblyUnnecessaryContent('.babelrc', 'file')).toBe(true) - for (const extension of ['json', 'js', 'cjs', 'mjs', 'yml', 'yaml', 'toml']) { - expect(isPossiblyUnnecessaryContent(`.stylelintrc.${extension}`, 'file')).toBe(true) - } - expect(isPossiblyUnnecessaryContent('.browserslistrc', 'file')).toBe(true) - for (const extension of ['js', 'cjs', 'mjs', 'ts', 'mts', 'cts']) { - expect(isPossiblyUnnecessaryContent(`.tailwind.config.${extension}`, 'file')).toBe(true) - } - // .npmrc is sometimes an intentional shipped artifact; do not flag it. - expect(isPossiblyUnnecessaryContent('.npmrc', 'file')).toBe(false) - expect(isPossiblyUnnecessaryContent('.npmrc.json', 'file')).toBe(false) - expect(isPossiblyUnnecessaryContent('.stylelintrc.ts', 'file')).toBe(false) - expect(isPossiblyUnnecessaryContent('.tailwind.config.json', 'file')).toBe(false) + describe('configuration patterns', () => { + it('matches ESLint configuration patterns', () => { + for (const extension of ['js', 'cjs', 'mjs', 'ts', 'mts', 'cts']) { + expect(isPossiblyUnnecessaryContent(`eslint.config.${extension}`, 'file')).toBe(true) + } + expect(isPossiblyUnnecessaryContent('.eslintrc', 'file')).toBe(true) + for (const extension of ['json', 'js', 'cjs', 'yml', 'yaml']) { + expect(isPossiblyUnnecessaryContent(`.eslintrc.${extension}`, 'file')).toBe(true) + } + expect(isPossiblyUnnecessaryContent('eslint.config.json', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('.eslintrc.txt', 'file')).toBe(false) + }) + + it('matches Prettier configuration patterns', () => { + expect(isPossiblyUnnecessaryContent('.prettierrc', 'file')).toBe(true) + for (const extension of ['json', 'js', 'cjs', 'yml', 'yaml', 'toml']) { + expect(isPossiblyUnnecessaryContent(`.prettierrc.${extension}`, 'file')).toBe(true) + } + for (const extension of ['js', 'cjs', 'mjs', 'ts', 'mts', 'cts']) { + expect(isPossiblyUnnecessaryContent(`prettier.config.${extension}`, 'file')).toBe(true) + } + expect(isPossiblyUnnecessaryContent('.prettierrc.txt', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('prettier.config.json', 'file')).toBe(false) + }) + + it('matches oxlint and oxfmt configuration patterns', () => { + for (const extension of ['js', 'cjs', 'mjs', 'ts', 'mts', 'cts']) { + expect(isPossiblyUnnecessaryContent(`oxlint.config.${extension}`, 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent(`oxfmt.config.${extension}`, 'file')).toBe(true) + } + expect(isPossiblyUnnecessaryContent('.oxlintrc', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('.oxfmtrc', 'file')).toBe(true) + for (const extension of ['json', 'js', 'cjs', 'yml', 'yaml']) { + expect(isPossiblyUnnecessaryContent(`.oxlintrc.${extension}`, 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent(`.oxfmtrc.${extension}`, 'file')).toBe(true) + } + expect(isPossiblyUnnecessaryContent('oxlint.config.json', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('oxfmt.config.json', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('.oxlintrc.txt', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('.oxfmtrc.txt', 'file')).toBe(false) + }) + + it('matches jest configuration patterns', () => { + for (const extension of ['js', 'cjs', 'mjs', 'ts', 'mts', 'cts']) { + expect(isPossiblyUnnecessaryContent(`jest.config.${extension}`, 'file')).toBe(true) + } + }) + + it('matches common dot-prefixed configuration patterns without over-flagging', () => { + expect(isPossiblyUnnecessaryContent('.babelrc', 'file')).toBe(true) + for (const extension of ['json', 'js', 'cjs', 'mjs', 'yml', 'yaml', 'toml']) { + expect(isPossiblyUnnecessaryContent(`.stylelintrc.${extension}`, 'file')).toBe(true) + } + expect(isPossiblyUnnecessaryContent('.browserslistrc', 'file')).toBe(true) + for (const extension of ['js', 'cjs', 'mjs', 'ts', 'mts', 'cts']) { + expect(isPossiblyUnnecessaryContent(`.tailwind.config.${extension}`, 'file')).toBe(true) + } + // .npmrc is sometimes an intentional shipped artifact; do not flag it. + expect(isPossiblyUnnecessaryContent('.npmrc', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('.npmrc.json', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('.stylelintrc.ts', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('.tailwind.config.json', 'file')).toBe(false) + }) }) it('flags editor and CI directories', () => { @@ -141,6 +158,8 @@ describe('isPossiblyUnnecessaryContent', () => { expect(isPossiblyUnnecessaryContent('.github', 'directory')).toBe(true) expect(isPossiblyUnnecessaryContent('.idea', 'directory')).toBe(true) expect(isPossiblyUnnecessaryContent('.zed', 'directory')).toBe(true) + expect(isPossiblyUnnecessaryContent('.yarn', 'directory')).toBe(true) + expect(isPossiblyUnnecessaryContent('.hasky', 'directory')).toBe(true) }) it('flags test directories', () => { @@ -184,6 +203,7 @@ describe('isPossiblyUnnecessaryContent', () => { expect(isPossiblyUnnecessaryContent('LICENSE-MIT', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('LICENSE-MIT.txt', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('NOTICE', 'file')).toBe(false) + expect(isPossiblyUnnecessaryContent('NOTICE.md', 'file')).toBe(false) expect(isPossiblyUnnecessaryContent('UNLICENSE', 'file')).toBe(false) }) From 447e412ca1feffa11fa529fd3e44295488838bb8 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 17 Jul 2026 19:25:08 +0100 Subject: [PATCH 17/17] feat: add more patterns --- app/utils/package-content-hints.ts | 3 +++ test/unit/app/utils/package-content-hints.spec.ts | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/utils/package-content-hints.ts b/app/utils/package-content-hints.ts index a56779ce46..f934eb0b37 100644 --- a/app/utils/package-content-hints.ts +++ b/app/utils/package-content-hints.ts @@ -19,6 +19,7 @@ const POSSIBLY_UNNECESSARY_FILES: ReadonlySet = new Set([ '.verb.md', 'Makefile', 'tsconfig.json', + 'jsconfig.json', '.node-version', '.nvmrc', 'mise.toml', @@ -39,6 +40,7 @@ const POSSIBLY_UNNECESSARY_FILES: ReadonlySet = new Set([ 'tests.js', 'tests.ts', 'bench.js', + 'benchmark.js', 'yarn.lock', 'bun.lock', 'bun.lockb', @@ -53,6 +55,7 @@ const POSSIBLY_UNNECESSARY_DIRECTORIES: ReadonlySet = new Set([ '.zed', '.yarn', '.husky', + '.changeset', 'test', 'tests', 'spec', diff --git a/test/unit/app/utils/package-content-hints.spec.ts b/test/unit/app/utils/package-content-hints.spec.ts index babf599e20..1bb5aab0ab 100644 --- a/test/unit/app/utils/package-content-hints.spec.ts +++ b/test/unit/app/utils/package-content-hints.spec.ts @@ -11,6 +11,7 @@ describe('isPossiblyUnnecessaryContent', () => { expect(isPossiblyUnnecessaryContent('.jshintignore', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('.npmignore', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('tsconfig.json', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('jsconfig.json', 'file')).toBe(true) }) it('flags local environment files', () => { @@ -55,6 +56,7 @@ describe('isPossiblyUnnecessaryContent', () => { expect(isPossiblyUnnecessaryContent('index.spec.js', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('index.spec.ts', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('bench.js', 'file')).toBe(true) + expect(isPossiblyUnnecessaryContent('benchmark.js', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('example.js', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('examples.js', 'file')).toBe(true) expect(isPossiblyUnnecessaryContent('example.mjs', 'file')).toBe(true) @@ -159,7 +161,7 @@ describe('isPossiblyUnnecessaryContent', () => { expect(isPossiblyUnnecessaryContent('.idea', 'directory')).toBe(true) expect(isPossiblyUnnecessaryContent('.zed', 'directory')).toBe(true) expect(isPossiblyUnnecessaryContent('.yarn', 'directory')).toBe(true) - expect(isPossiblyUnnecessaryContent('.hasky', 'directory')).toBe(true) + expect(isPossiblyUnnecessaryContent('.husky', 'directory')).toBe(true) }) it('flags test directories', () => {