From fe86a35aabcb19e4b5320aa3d18914b211779fb5 Mon Sep 17 00:00:00 2001 From: Ghita Filali <18337313+ghitafilali@users.noreply.github.com> Date: Sun, 31 May 2026 03:03:23 +0200 Subject: [PATCH] Fix skill check for skipped Claude template --- scripts/skill-check.ts | 23 +++++++++++++++++++---- test/skill-check.test.ts | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 test/skill-check.test.ts diff --git a/scripts/skill-check.ts b/scripts/skill-check.ts index 9182737ee..6807f9f39 100644 --- a/scripts/skill-check.ts +++ b/scripts/skill-check.ts @@ -10,12 +10,14 @@ import { validateSkill } from '../test/helpers/skill-parser'; import { discoverTemplates, discoverSkillFiles } from './discover-skills'; +import { ALL_HOST_CONFIGS, getExternalHosts, getHostConfig } from '../hosts/index'; import * as fs from 'fs'; import * as path from 'path'; import { execSync } from 'child_process'; const ROOT = path.resolve(import.meta.dir, '..'); const ROOT_REALPATH = fs.realpathSync(ROOT); +const PRIMARY_HOST_CONFIG = getHostConfig('claude'); function isRepoRootSymlink(candidateDir: string): boolean { try { @@ -25,6 +27,19 @@ function isRepoRootSymlink(candidateDir: string): boolean { } } +function skillDirForTemplateOutput(output: string): string | null { + const normalized = output.replace(/\\/g, '/'); + const parts = normalized.split('/'); + if (parts.length !== 2 || parts[1] !== 'SKILL.md') return null; + return parts[0]; +} + +function isSkippedForPrimaryHost(output: string): boolean { + const skillDir = skillDirForTemplateOutput(output); + if (!skillDir) return false; + return PRIMARY_HOST_CONFIG.generation.skipSkills?.includes(skillDir) ?? false; +} + // Find all SKILL.md files (dynamic discovery — no hardcoded list) const SKILL_FILES = discoverSkillFiles(ROOT); @@ -73,6 +88,10 @@ for (const { tmpl, output } of TEMPLATES) { continue; } if (!fs.existsSync(outPath)) { + if (isSkippedForPrimaryHost(output)) { + console.log(` ⏭️ ${output.padEnd(30)} — intentionally skipped for ${PRIMARY_HOST_CONFIG.displayName}`); + continue; + } hasErrors = true; console.log(` \u274c ${output.padEnd(30)} — generated file missing! Run: bun run gen:skill-docs`); continue; @@ -90,8 +109,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)) { @@ -130,8 +147,6 @@ for (const hostConfig of getExternalHosts()) { // ─── Freshness (config-driven) ────────────────────────────── -import { ALL_HOST_CONFIGS } from '../hosts/index'; - for (const hostConfig of ALL_HOST_CONFIGS) { const hostFlag = hostConfig.name === 'claude' ? '' : ` --host ${hostConfig.name}`; console.log(`\n Freshness (${hostConfig.displayName}):`); diff --git a/test/skill-check.test.ts b/test/skill-check.test.ts new file mode 100644 index 000000000..92264ebc1 --- /dev/null +++ b/test/skill-check.test.ts @@ -0,0 +1,18 @@ +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', () => { + test('accepts template outputs intentionally skipped for the primary host', () => { + const result = spawnSync('bun', ['run', 'scripts/skill-check.ts'], { + cwd: ROOT, + encoding: 'utf8', + }); + + expect(result.status).toBe(0); + expect(result.stdout).toContain('claude/SKILL.md'); + expect(result.stdout).toContain('intentionally skipped for Claude Code'); + }); +});