80 lines
3.2 KiB
JavaScript
80 lines
3.2 KiB
JavaScript
|
|
#!/usr/bin/env node
|
||
|
|
/**
|
||
|
|
* P0-3 Re-apply: Skill 三层分层
|
||
|
|
* 上一会话 P0-3 patch 结果被后续操作覆盖, 此 patch 用硬编码列表重新写入
|
||
|
|
* T1=21 (常驻) / T2=40 (按需) / T3=34 (归档)
|
||
|
|
* Idempotent: sentinel [P0-3] SKILL_TIERING_v1 (检查 criticality 字段)
|
||
|
|
*/
|
||
|
|
'use strict';
|
||
|
|
const fs = require('fs');
|
||
|
|
const path = require('path');
|
||
|
|
|
||
|
|
const TARGET = path.resolve(__dirname, '..', '..', 'skills-index.json');
|
||
|
|
if (!fs.existsSync(TARGET)) { process.stderr.write('[SKIP] skills-index.json not found\n'); process.exit(0); }
|
||
|
|
|
||
|
|
const src = fs.readFileSync(TARGET, 'utf8');
|
||
|
|
let index;
|
||
|
|
try { index = JSON.parse(src); } catch (e) { process.stderr.write('[FAIL] JSON parse error\n'); process.exit(1); }
|
||
|
|
|
||
|
|
if (!index.skills || !Array.isArray(index.skills)) { process.stderr.write('[FAIL] no skills array\n'); process.exit(1); }
|
||
|
|
|
||
|
|
// Idempotent check: if any skill already has criticality field, skip
|
||
|
|
const hasCriticality = index.skills.some(s => s.criticality);
|
||
|
|
if (hasCriticality) { process.stderr.write('[SKIP] already has criticality (sentinel check)\n'); process.exit(0); }
|
||
|
|
|
||
|
|
fs.writeFileSync(TARGET + '.bak-p03-reapply.' + Date.now(), src);
|
||
|
|
|
||
|
|
// T1: 21 skills (常驻, 高频或高关键度)
|
||
|
|
const T1 = new Set([
|
||
|
|
'ai-ml-expert', 'architect-expert', 'backend-builder', 'debugger-expert',
|
||
|
|
'developer-expert', 'devops-expert', 'frontend-expert', 'git-operation-master',
|
||
|
|
'guardian', 'mobile-expert', 'performance-expert', 'project-audit-expert',
|
||
|
|
'prompt-optimizer', 'qa', 'review', 'reviewer-expert', 'security-expert',
|
||
|
|
'technical-seo-expert', 'tester-expert', 'workflow-automation-expert',
|
||
|
|
'zero-defect-guardian',
|
||
|
|
]);
|
||
|
|
|
||
|
|
// HIGH criticality: 安全/审计/守护类
|
||
|
|
const HIGH_CRIT = new Set([
|
||
|
|
'security-expert', 'guardian', 'zero-defect-guardian', 'review',
|
||
|
|
'debugger-expert', 'developer-expert', 'project-audit-expert',
|
||
|
|
]);
|
||
|
|
|
||
|
|
// T3: 34 skills (归档, 极低频或已废弃边缘)
|
||
|
|
const T3 = new Set([
|
||
|
|
'browser-automation-expert', 'canvas-designer', 'code-migrator',
|
||
|
|
'competitive-analyst', 'content-strategist', 'creative-writer',
|
||
|
|
'data-engineer', 'database-expert', 'design-system-expert',
|
||
|
|
'documentation-expert', 'education-expert', 'email-composer',
|
||
|
|
'file-manager', 'finance-advisor', 'game-developer',
|
||
|
|
'graph-expert', 'healthcare-expert', 'i18n-expert',
|
||
|
|
'legal-advisor', 'marketing-expert', 'ml-ops-expert',
|
||
|
|
'presentation-expert', 'product-manager', 'project-manager',
|
||
|
|
'regex-expert', 'resume-builder', 'social-media-expert',
|
||
|
|
'spreadsheet-expert', 'startup-advisor', 'system-admin',
|
||
|
|
'technical-writer', 'terminal-expert', 'ui-ux-expert',
|
||
|
|
'video-editor',
|
||
|
|
]);
|
||
|
|
|
||
|
|
let t1 = 0, t2 = 0, t3 = 0;
|
||
|
|
for (const skill of index.skills) {
|
||
|
|
const name = skill.name || '';
|
||
|
|
if (T1.has(name)) {
|
||
|
|
skill.tier_class = 'T1';
|
||
|
|
t1++;
|
||
|
|
} else if (T3.has(name)) {
|
||
|
|
skill.tier_class = 'T3';
|
||
|
|
t3++;
|
||
|
|
} else {
|
||
|
|
skill.tier_class = 'T2';
|
||
|
|
t2++;
|
||
|
|
}
|
||
|
|
skill.criticality = HIGH_CRIT.has(name) ? 'HIGH' : T1.has(name) ? 'MEDIUM' : 'LOW';
|
||
|
|
skill.callCount30d = 0; // 无历史数据, 初始化为 0
|
||
|
|
}
|
||
|
|
|
||
|
|
const tmp = TARGET + '.tmp.' + process.pid;
|
||
|
|
fs.writeFileSync(tmp, JSON.stringify(index, null, 2), 'utf8');
|
||
|
|
fs.renameSync(tmp, TARGET);
|
||
|
|
process.stderr.write('[DONE] P0-3 re-applied: T1=' + t1 + ' T2=' + t2 + ' T3=' + t3 + '\n');
|