refactor: address reviewer feedback

- Add options={} parameter to run() to match run-with-flags.js contract
- Remove case-insensitive flag from extension pre-filter for consistency
  with ADHOC_FILENAMES regex (both now case-sensitive)
- Expand warning text to list more structured paths
- Add test cases for uppercase extensions (TODO.MD, NOTES.TXT)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
This commit is contained in:
Lidang-Jiang
2026-03-29 10:09:02 +08:00
parent 27d71c9548
commit 3c3781ca43
2 changed files with 7 additions and 5 deletions

View File

@@ -28,8 +28,8 @@ function isSuspiciousDocPath(filePath) {
const normalized = filePath.replace(/\\/g, '/'); const normalized = filePath.replace(/\\/g, '/');
const basename = path.basename(normalized); const basename = path.basename(normalized);
// Only inspect .md and .txt files // Only inspect .md and .txt files (case-sensitive, consistent with ADHOC_FILENAMES)
if (!/\.(md|txt)$/i.test(basename)) return false; if (!/\.(md|txt)$/.test(basename)) return false;
// Only flag known ad-hoc filenames // Only flag known ad-hoc filenames
if (!ADHOC_FILENAMES.test(basename)) return false; if (!ADHOC_FILENAMES.test(basename)) return false;
@@ -44,7 +44,7 @@ function isSuspiciousDocPath(filePath) {
* Exportable run() for in-process execution via run-with-flags.js. * Exportable run() for in-process execution via run-with-flags.js.
* Avoids the ~50-100ms spawnSync overhead when available. * Avoids the ~50-100ms spawnSync overhead when available.
*/ */
function run(inputOrRaw) { function run(inputOrRaw, options = {}) {
let input; let input;
try { try {
input = typeof inputOrRaw === 'string' input = typeof inputOrRaw === 'string'
@@ -61,7 +61,7 @@ function run(inputOrRaw) {
stderr: stderr:
'[Hook] WARNING: Ad-hoc documentation filename detected\n' + '[Hook] WARNING: Ad-hoc documentation filename detected\n' +
`[Hook] File: ${filePath}\n` + `[Hook] File: ${filePath}\n` +
'[Hook] Consider using structured paths: docs/, .claude/commands/, skills/', '[Hook] Consider using a structured path (e.g. docs/, .claude/, skills/, .github/, benchmarks/, templates/)',
}; };
} }

View File

@@ -102,7 +102,7 @@ function runTests() {
}) ? passed++ : failed++); }) ? passed++ : failed++);
} }
// 5. Lowercase and partial-match filenames - NOT on denylist, no warning // 5. Lowercase, partial-match, and non-standard extension case - NOT on denylist
const allowedNonDenylist = [ const allowedNonDenylist = [
'random-notes.md', 'random-notes.md',
'notes.txt', 'notes.txt',
@@ -111,6 +111,8 @@ function runTests() {
'todo-list.md', 'todo-list.md',
'my-draft.md', 'my-draft.md',
'meeting-notes.txt', 'meeting-notes.txt',
'TODO.MD',
'NOTES.TXT',
]; ];
for (const file of allowedNonDenylist) { for (const file of allowedNonDenylist) {
(test(`allows non-denylist doc file: ${file}`, () => { (test(`allows non-denylist doc file: ${file}`, () => {