Files

64 lines
2.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// bin/convert.mjs — SKILL.md → 规则文件转换器
import { readdirSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { parseFrontmatterDocument } from '../lib/frontmatter.mjs';
export function skillDirs(skillsRoot) {
return readdirSync(skillsRoot, { withFileTypes: true })
.filter(e => e.isDirectory() && e.name.startsWith('re-'))
.map(e => join(skillsRoot, e.name));
}
export function readSkill(dir) {
const md = readFileSync(join(dir, 'SKILL.md'), 'utf8');
const { fm, body } = parseFrontmatterDocument(md); // 与 validate.mjs 同一解析器(lib/frontmatter.mjs)
return { name: fm.name, description: fm.description, body };
}
// parseSkill:readSkill 的别名,保持调用方兼容
export function parseSkill(dir) { return readSkill(dir); }
const HERE = dirname(fileURLToPath(import.meta.url));
export function convertAll(type, destDir) {
// 初版:cursor/windsurf 每技能一文件;copilot 聚合单文件
const skills = skillDirs(join(HERE, '..', '.claude', 'skills'))
.map(readSkill);
mkdirSync(destDir, { recursive: true });
const files = [];
if (type === 'cursor') {
for (const s of skills) {
const p = join(destDir, `${s.name}.mdc`);
writeFileSync(p, `---\ndescription: ${JSON.stringify(s.description)}\nglobs: **/*\n---\n\n${s.body}`);
files.push(p);
}
} else if (type === 'windsurf') {
for (const s of skills) {
const p = join(destDir, `${s.name}.md`);
writeFileSync(p, `# ${s.name}\n\n${s.description}\n\n${s.body}`);
files.push(p);
}
} else if (type === 'copilot') {
const p = join(destDir, 'copilot-instructions.md');
const head = '# 逆向工程技能库(AI 助手指令)\n\n本文件由技能库自动聚合生成,作为分析时的知识参考。\n\n';
writeFileSync(p, head + skills.map(s =>
`## ${s.name}\n\n${s.description}\n\n${s.body}`).join('\n\n---\n\n'));
files.push(p);
} else {
throw new Error(`unknown rule type: ${type}`);
}
return files;
}
// —— 追加到 convert.mjs 末尾 ——
function cli() {
const args = process.argv.slice(2);
const type = args[args.indexOf('--target') + 1];
const out = args[args.indexOf('--out') + 1];
if (!type || !out) { console.error('usage: node bin/convert.mjs --target cursor|copilot|windsurf --out <dir>'); process.exit(1); }
const files = convertAll(type, out);
console.log(`generated ${files.length} file(s) in ${out}`);
}
if (process.argv[1] && process.argv[1].endsWith('convert.mjs')) cli();