fix Claude skill template validation

This commit is contained in:
Mattias Petersson 2026-07-16 09:39:02 +02:00
parent a3259400a3
commit 2e400ac80d
2 changed files with 34 additions and 2 deletions

View File

@ -13,6 +13,7 @@ import { discoverTemplates, discoverSkillFiles } from './discover-skills';
import * as fs from 'fs';
import * as path from 'path';
import { execSync } from 'child_process';
import { claude, getExternalHosts } from '../hosts/index';
const ROOT = path.resolve(import.meta.dir, '..');
const ROOT_REALPATH = fs.realpathSync(ROOT);
@ -64,14 +65,26 @@ for (const file of SKILL_FILES) {
console.log('\n Templates:');
const TEMPLATES = discoverTemplates(ROOT);
const CLAUDE_SKIPPED_SKILLS = new Set(claude.generation.skipSkills ?? []);
for (const { tmpl, output } of TEMPLATES) {
const tmplPath = path.join(ROOT, tmpl);
const outPath = path.join(ROOT, output);
const skillDir = path.dirname(tmpl);
const skillName = skillDir === '.' ? null : skillDir.split(path.sep)[0];
if (!fs.existsSync(tmplPath)) {
console.log(` \u26a0\ufe0f ${output.padEnd(30)} — no template`);
continue;
}
if (skillName && CLAUDE_SKIPPED_SKILLS.has(skillName)) {
if (fs.existsSync(outPath)) {
hasErrors = true;
console.log(` \u274c ${output.padEnd(30)} — generated file exists but Claude Code skips this skill`);
} else {
console.log(` \u23ed\ufe0f ${output.padEnd(30)} — intentionally skipped for Claude Code`);
}
continue;
}
if (!fs.existsSync(outPath)) {
hasErrors = true;
console.log(` \u274c ${output.padEnd(30)} — generated file missing! Run: bun run gen:skill-docs`);
@ -90,8 +103,6 @@ for (const file of SKILL_FILES) {
// ─── External Host Skills (config-driven) ───────────────────
import { getExternalHosts } from '../hosts/index';
for (const hostConfig of getExternalHosts()) {
const hostDir = path.join(ROOT, hostConfig.hostSubdir, 'skills');
if (fs.existsSync(hostDir)) {

21
test/skill-check.test.ts Normal file
View File

@ -0,0 +1,21 @@
import { describe, expect, test } from 'bun:test';
import { spawnSync } from 'child_process';
import * as path from 'path';
const ROOT = path.resolve(import.meta.dir, '..');
describe('skill-check template coverage', () => {
test('accepts skills intentionally skipped by the Claude host', () => {
const result = spawnSync('bun', ['run', 'scripts/skill-check.ts'], {
cwd: ROOT,
encoding: 'utf8',
});
const claudeTemplateLine = result.stdout
.split('\n')
.find((line) => line.includes('claude/SKILL.md'));
expect(claudeTemplateLine).toContain('intentionally skipped for Claude Code');
expect(claudeTemplateLine).not.toContain('generated file missing');
});
});