101 lines
4.5 KiB
JavaScript
101 lines
4.5 KiB
JavaScript
// 生成 js/data/manifest/BASELINE.md —— 系统现状基线快照(构建后运行,AI 采集指令的「执行前自查」数据源)
|
||
// 用法:node scripts/build-baseline.js
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
const MAN = 'js/data/manifest';
|
||
const read = (f) => JSON.parse(fs.readFileSync(path.join(MAN, f), 'utf8'));
|
||
|
||
const icons = read('icons.json');
|
||
const posters = read('posters.json');
|
||
const skills = read('skills.json');
|
||
|
||
const countBy = (arr, key) => {
|
||
const m = {};
|
||
arr.forEach((x) => { m[x[key]] = (m[x[key]] || 0) + 1; });
|
||
return m;
|
||
};
|
||
|
||
// 三区覆盖:优先 workspaces 字段,缺省按 scene 关键词统计
|
||
const wsCount = (skill) => {
|
||
if (Array.isArray(skill.workspaces) && skill.workspaces.length) {
|
||
return {
|
||
logo: skill.workspaces.includes('logo'),
|
||
avatar: skill.workspaces.includes('avatar'),
|
||
poster: skill.workspaces.includes('poster'),
|
||
};
|
||
}
|
||
const sc = skill.scene || '';
|
||
return {
|
||
logo: /LOGO|logo/.test(sc),
|
||
avatar: /头像|avatar/.test(sc),
|
||
poster: /海报|poster/.test(sc),
|
||
};
|
||
};
|
||
const cover = (list) => {
|
||
const c = { logo: 0, avatar: 0, poster: 0, none: 0 };
|
||
list.forEach((s) => {
|
||
const w = wsCount(s);
|
||
if (!w.logo && !w.avatar && !w.poster) c.none++;
|
||
if (w.logo) c.logo++;
|
||
if (w.avatar) c.avatar++;
|
||
if (w.poster) c.poster++;
|
||
});
|
||
return c;
|
||
};
|
||
|
||
const sharedSkills = skills.shared.skills || [];
|
||
const posterSkills = (skills.poster && skills.poster.skills) || [];
|
||
const stickerSkills = (skills.sticker && skills.sticker.skills) || [];
|
||
const sharedCat = countBy(sharedSkills, 'category');
|
||
const posterCat = countBy(posterSkills, 'category');
|
||
const stickerCat = countBy(stickerSkills, 'category');
|
||
const sharedCover = cover(sharedSkills);
|
||
const posterCover = cover(posterSkills);
|
||
|
||
const iconTypes = countBy(icons.sources, 'type');
|
||
const posterTypes = countBy(posters.sources, 'type');
|
||
|
||
const lines = [];
|
||
lines.push('# 画个标 · 系统基线(构建自动生成,勿手改)');
|
||
lines.push('');
|
||
lines.push('> 由 `scripts/build-baseline.js` 生成。素材/技能变更并构建后,重新运行 `node scripts/build-baseline.js` 即自动更新。');
|
||
lines.push('> 执行「AI 指令库 指令一~四」前,先读本文件获取当前基线,勿依赖记忆中的数字。');
|
||
lines.push('');
|
||
lines.push('## 生成时间');
|
||
lines.push('');
|
||
lines.push(new Date().toISOString());
|
||
lines.push('');
|
||
lines.push('## ① 图标库(共享,LOGO/头像/海报共用)');
|
||
lines.push('');
|
||
lines.push(`- 源数:${icons.sources.length} | 图标总数:${icons.total}`);
|
||
lines.push(`- 类型分布:${Object.entries(iconTypes).map(([k, v]) => `${k} ${v}`).join(' / ')}`);
|
||
lines.push('- 源清单(含 count/file/workspaces):js/data/manifest/icons.json');
|
||
lines.push('');
|
||
lines.push('## ② 海报素材库');
|
||
lines.push('');
|
||
lines.push(`- 源数:${posters.sources.length} | 素材总数:${posters.total}`);
|
||
lines.push(`- 类型分布:${Object.entries(posterTypes).map(([k, v]) => `${k} ${v}`).join(' / ')}`);
|
||
lines.push('- 源清单:js/data/manifest/posters.json');
|
||
lines.push('');
|
||
lines.push('## ③ 技能库');
|
||
lines.push('');
|
||
lines.push(`- 共享技能:${sharedSkills.length}(分类:${Object.entries(sharedCat).map(([k, v]) => `${k} ${v}`).join(' / ')})`);
|
||
lines.push(`- 海报技能:${posterSkills.length}(分类:${Object.entries(posterCat).map(([k, v]) => `${k} ${v}`).join(' / ')})`);
|
||
lines.push(`- 表情技能:${stickerSkills.length}(分类:${Object.entries(stickerCat).map(([k, v]) => `${k} ${v}`).join(' / ')})`);
|
||
lines.push(`- 三区覆盖(共享,按 scene/workspaces):LOGO 向 ${sharedCover.logo} / 头像向 ${sharedCover.avatar} / 海报向 ${sharedCover.poster} / 未标注 ${sharedCover.none}`);
|
||
lines.push(`- 三区覆盖(海报专属):LOGO 向 ${posterCover.logo} / 头像向 ${posterCover.avatar} / 海报向 ${posterCover.poster}`);
|
||
lines.push('- 技能明细:js/data/manifest/skills.json');
|
||
lines.push('');
|
||
lines.push('## 指令使用提示');
|
||
lines.push('');
|
||
lines.push('- 指令一(新增图标源):去重以本文件 ① 的源清单 + icon-sources.js 现有 id 为准');
|
||
lines.push('- 指令二(新增海报源):去重以 ② + poster-sources.js 现有 id 为准');
|
||
lines.push('- 指令三(新增技能):看 ③ 三区覆盖找缺口(头像向最少则优先补头像);表情向技能看表情技能分类分布');
|
||
lines.push('');
|
||
|
||
const out = path.join(MAN, 'BASELINE.md');
|
||
fs.writeFileSync(out, lines.join('\n'), 'utf8');
|
||
console.log('已生成 ' + out);
|
||
console.log(lines.join('\n'));
|