mirror of
https://github.com/rmyndharis/antigravity-skills.git
synced 2026-09-19 02:19:16 +08:00
82 lines
2.8 KiB
JavaScript
82 lines
2.8 KiB
JavaScript
// One-shot fixer: removes lines that reference a backticked helper file
|
|
// (resources/ references/ assets/ scripts/ examples/) which does not exist in the
|
|
// skill's directory, and prunes a `## Resources` or `### Reference Files` heading
|
|
// that becomes empty as a result. Skips lines inside fenced code blocks.
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const { listSkillIds } = require('../lib/skill-utils');
|
|
|
|
const ROOT = path.resolve(__dirname, '..');
|
|
const SKILLS_DIR = path.join(ROOT, 'skills');
|
|
const REF_RE = /`((?:resources|references|assets|scripts|examples)\/[A-Za-z0-9._/-]+)`/g;
|
|
|
|
function lineReferencesMissingFile(line, skillDir) {
|
|
REF_RE.lastIndex = 0;
|
|
let match;
|
|
let hasMissing = false;
|
|
while ((match = REF_RE.exec(line)) !== null) {
|
|
if (!fs.existsSync(path.join(skillDir, match[1]))) {
|
|
hasMissing = true;
|
|
}
|
|
}
|
|
return hasMissing;
|
|
}
|
|
|
|
function pruneEmptyResources(lines) {
|
|
const out = [];
|
|
for (let i = 0; i < lines.length; i += 1) {
|
|
const line = lines[i];
|
|
const headingMatch = /^(#{2,3})\s+(?:\w+\s+)*(?:resources?|reference\s+files?|references?|examples?|example\s+files?)\s*$/i.exec(line.trim());
|
|
if (headingMatch) {
|
|
const level = headingMatch[1].length;
|
|
let j = i + 1;
|
|
while (j < lines.length && lines[j].trim() === '') j += 1;
|
|
let sectionEmpty = j >= lines.length;
|
|
if (!sectionEmpty) {
|
|
const nextHeading = /^(#{1,6})\s/.exec(lines[j].trim());
|
|
if (nextHeading && nextHeading[1].length <= level) sectionEmpty = true;
|
|
}
|
|
if (sectionEmpty) {
|
|
i = j - 1;
|
|
continue;
|
|
}
|
|
}
|
|
out.push(line);
|
|
}
|
|
return out;
|
|
}
|
|
|
|
function cleanLines(lines, skillDir) {
|
|
const kept = [];
|
|
let inFence = false;
|
|
for (const line of lines) {
|
|
if (/^```/.test(line.trim())) { inFence = !inFence; kept.push(line); continue; }
|
|
if (!inFence && lineReferencesMissingFile(line, skillDir)) continue;
|
|
kept.push(line);
|
|
}
|
|
return kept;
|
|
}
|
|
|
|
function run() {
|
|
let fixedSkills = 0;
|
|
let removedLines = 0;
|
|
for (const skillId of listSkillIds(SKILLS_DIR)) {
|
|
const dir = path.join(SKILLS_DIR, skillId);
|
|
const mdPath = path.join(dir, 'SKILL.md');
|
|
const content = fs.readFileSync(mdPath, 'utf8');
|
|
const lines = content.split(/\r?\n/);
|
|
const kept = cleanLines(lines, dir);
|
|
const prunedLines = pruneEmptyResources(kept);
|
|
const changed = kept.length !== lines.length || prunedLines.length !== kept.length;
|
|
let next = prunedLines.join('\n');
|
|
if (changed) next = next.replace(/\n{3,}/g, '\n\n');
|
|
if (next === content) continue;
|
|
fs.writeFileSync(mdPath, next);
|
|
fixedSkills += 1;
|
|
removedLines += lines.length - kept.length;
|
|
}
|
|
console.log(`Removed dangling references / pruned empty resource headings in ${fixedSkills} skills (${removedLines} ref lines removed).`);
|
|
}
|
|
|
|
run();
|