diff --git a/src/scan.js b/src/scan.js index 6b4719b..3297175 100644 --- a/src/scan.js +++ b/src/scan.js @@ -28,7 +28,12 @@ export function collectFiles(target) { const out = []; const st = existsSync(target) ? statSync(target) : null; if (!st) return out; - if (st.isFile()) { out.push(target); return out; } + if (st.isFile()) { + const name = basename(target); + const e = extname(name).toLowerCase(); + if (CODE_EXT.has(e) || TEXT_EXT.has(e) || (e === "" && hasShebang(target))) out.push(target); + return out; + } const walk = (dir) => { for (const name of readdirSync(dir)) { if (SKIP_DIR.has(name)) continue; diff --git a/test/fixtures/binary-target.bin b/test/fixtures/binary-target.bin new file mode 100644 index 0000000..4dd0c65 Binary files /dev/null and b/test/fixtures/binary-target.bin differ diff --git a/test/skill-audit.test.js b/test/skill-audit.test.js index f4d8b3e..de8af0a 100644 --- a/test/skill-audit.test.js +++ b/test/skill-audit.test.js @@ -101,6 +101,13 @@ test("clean skill produces zero findings", () => { assert.equal(findings.length, 0, JSON.stringify(findings, null, 2)); }); +test("single-file binary targets are not collected for scanning", () => { + const binary = fixture("binary-target.bin"); + assert.deepEqual(collectFiles(binary), []); + assert.equal(scanSkill(binary).files, 0); + assert.deepEqual(scanSkill(binary).findings, []); +}); + test("extensionless shebang scripts are scanned while plain files stay ignored", () => { const root = fixture("extensionless-shebang-skill"); const files = collectFiles(root);