#!/usr/bin/env node /** * Skill Cleanup: Remove 22 low-value skills * - 14 delete (irrelevant/niche/overlapping) * - 8 merge-remove (redundant groups) * Moves skill dirs to skills/_archived/, removes from skills-index.json */ 'use strict'; const fs = require('fs'); const path = require('path'); const CLAUDE_ROOT = path.resolve(__dirname, '..', '..'); const INDEX = path.join(CLAUDE_ROOT, 'skills-index.json'); const SKILLS_DIR = path.join(CLAUDE_ROOT, 'skills'); const ARCHIVE_DIR = path.join(SKILLS_DIR, '_archived'); const TO_REMOVE = [ // Cat 1: language/framework mismatch (6) 'angular-architect', 'flutter-expert', 'golang-pro', 'rust-engineer', 'swift-expert', 'vue-expert', // Cat 1: extremely niche (4) 'ai-philosophy-expert', 'edge-computing-expert', 'graphql-architect', 'evolution-tracker', // Cat 1: overlapping with T1 (4) 'ultimate-code-expert', 'frontend-design', 'design-consultation', 'design-review', // Cat 2: plan variants → planning-with-files covers (3) 'plan-ceo-review', 'plan-design-review', 'plan-eng-review', // Cat 2: design duplicates → frontend-expert T1 covers (3) 'designer-expert', 'ui-ux-pro-max', 'ux-researcher', // Cat 2: setup tools → devops-expert covers (2) 'setup-browser-cookies', 'setup-deploy', ]; if (!fs.existsSync(INDEX)) { process.stderr.write('[FAIL] skills-index.json not found\n'); process.exit(1); } const src = fs.readFileSync(INDEX, 'utf8'); let index; try { index = JSON.parse(src); } catch { process.stderr.write('[FAIL] parse\n'); process.exit(1); } fs.writeFileSync(INDEX + '.bak-cleanup.' + Date.now(), src); const removeSet = new Set(TO_REMOVE); const before = index.skills.length; index.skills = index.skills.filter(s => !removeSet.has(s.name)); const removed = before - index.skills.length; // Write updated index const tmp = INDEX + '.tmp.' + process.pid; fs.writeFileSync(tmp, JSON.stringify(index, null, 2), 'utf8'); fs.renameSync(tmp, INDEX); process.stderr.write('[INDEX] Removed ' + removed + '/' + TO_REMOVE.length + ' from skills-index.json (' + before + ' -> ' + index.skills.length + ')\n'); // Move skill directories to _archived if (!fs.existsSync(ARCHIVE_DIR)) fs.mkdirSync(ARCHIVE_DIR, { recursive: true }); let moved = 0; for (const name of TO_REMOVE) { const src = path.join(SKILLS_DIR, name); const dst = path.join(ARCHIVE_DIR, name); if (fs.existsSync(src) && !fs.existsSync(dst)) { try { fs.renameSync(src, dst); moved++; } catch (e) { process.stderr.write('[WARN] Failed to move ' + name + ': ' + e.message + '\n'); } } } process.stderr.write('[FILES] Moved ' + moved + ' skill dirs to _archived/\n'); // Summary const tiers = {}; for (const s of index.skills) tiers[s.tier_class] = (tiers[s.tier_class] || 0) + 1; process.stderr.write('[DONE] Final: ' + index.skills.length + ' skills (T1=' + (tiers.T1||0) + ' T2=' + (tiers.T2||0) + ' T3=' + (tiers.T3||0) + ')\n');