mirror of https://github.com/garrytan/gstack.git
fix Claude skill template validation
This commit is contained in:
parent
e9fb8f311b
commit
eccb4aef49
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
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',
|
||||
});
|
||||
|
||||
expect(result.status).toBe(0);
|
||||
expect(result.stdout).toContain('claude/SKILL.md');
|
||||
expect(result.stdout).toContain('intentionally skipped for Claude Code');
|
||||
expect(result.stdout).not.toContain('generated file missing');
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue