Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions tools/readiness-core/test/index.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,26 @@ test('scanSkillDirectories finds skills in target directory', async () => {

await fs.rm(fixtureDir, { recursive: true, force: true });
});

test('scanSkillDirectories deduplicates skill names across scanned roots', async () => {
// Regression test for double-counting: the same skill installed in two
// scanned roots (e.g. .grok/skills/foo and skills/foo) must count once.
// Duplicates inflate the Loop Readiness score by flipping the skillsOne
// signal to skillsTwoPlus for what is really a single skill.
const fixtureDir = path.join(process.cwd(), '.test-fixture-dedup');
await fs.rm(fixtureDir, { recursive: true, force: true });
await fs.mkdir(path.join(fixtureDir, '.grok', 'skills', 'foo'), { recursive: true });
await fs.mkdir(path.join(fixtureDir, 'skills', 'foo'), { recursive: true });
await fs.mkdir(path.join(fixtureDir, 'skills', 'bar'), { recursive: true });

const skills = await scanSkillDirectories(fixtureDir);
assert.strictEqual(
skills.filter((name) => name === 'foo').length,
1,
'Same skill name under two roots should count once',
);
assert.ok(skills.includes('bar'), 'Distinct skill names should still count separately');
assert.strictEqual(skills.length, 2, 'Should report exactly foo and bar');

await fs.rm(fixtureDir, { recursive: true, force: true });
});