// "Open guide" on a finding: skill name -> the shipped SKILL.md; the known list matches the skills/ folder. import { expect, test } from 'bun:test'; import { existsSync, readdirSync } from 'node:fs'; import { join } from 'node:path'; import { KNOWN_SKILLS, SKILLS_BASE, skillGuideUrl } from '../cli/lib/skill-guide'; const dir = join(import.meta.dir, '..', 'skills'); test('KNOWN_SKILLS is exactly the skills/ folder', () => { const real = readdirSync(dir).filter(n => existsSync(join(dir, n, 'SKILL.md'))).sort(); expect([...KNOWN_SKILLS].sort()).toEqual(real); }); test('a skill name, a skills/ path or a SKILL.md path resolve to the guide', () => { expect(skillGuideUrl('store-api')).toBe(`${SKILLS_BASE}/store-api/SKILL.md`); expect(skillGuideUrl('skills/store-api')).toBe(`${SKILLS_BASE}/store-api/SKILL.md`); expect(skillGuideUrl(' skills/game-services/SKILL.md ')).toBe(`${SKILLS_BASE}/game-services/SKILL.md`); }); test('unknown or empty: no link', () => { for (const s of ['', null, undefined, 'not-a-skill', '../etc', 'store-api/../x']) expect(skillGuideUrl(s)).toBeNull(); }); test('every skill a scan rule names is a known skill', async () => { const { readFileSync } = await import('node:fs'); const src = readdirSync(join(import.meta.dir, '..', 'cli', 'lib', 'scan')).filter(f => f.endsWith('.ts')).map(f => readFileSync(join(import.meta.dir, '..', 'cli', 'lib', 'scan', f), 'utf8')).join('\n'); const named = [...src.matchAll(/skill: '([a-z0-9-]+)'/g)].map(m => m[1]!); expect(named.length).toBeGreaterThan(0); for (const s of new Set(named)) expect(skillGuideUrl(s)).not.toBeNull(); });