Files
ClassIsland Prompt Kit 22c1784bab feat: ClassIsland / ClassHelper 灵动岛提示词套件
- 重构版主提示词(14 parts,面向 ClassHelper 灵动岛重构)
- ClassIsland 全量规格提示词(20 parts,含分卷与逐章版本)
- 投喂指南、分卷、逐节文件
- 调研记录、一致性基线、生成与质检脚本
2026-11-12 21:59:58 +08:00

79 lines
3.9 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.
#!/usr/bin/env node
/** 汇总 parts-r/00..13 为《ClassHelper灵动岛重构-给ChatGPT的完整提示词.md》 */
import { readdirSync, readFileSync, writeFileSync, mkdirSync, copyFileSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const root = join(dirname(fileURLToPath(import.meta.url)), '..');
const partsDir = join(root, 'parts-r');
const outFile = join(root, 'ClassHelper灵动岛重构-给ChatGPT的完整提示词.md');
const files = readdirSync(partsDir)
.filter((f) => /^\d{2}-.+\.md$/.test(f))
.sort((a, b) => a.localeCompare(b, 'en'));
if (files.length !== 14) console.warn(`警告:parts-r 文件数 ${files.length},预期 14`);
if (!files.some((f) => f.startsWith('00-'))) throw new Error('缺少 parts-r/00-preamble.md');
const sections = [];
const toc = [];
const stats = [];
let preamble = '';
for (const file of files) {
const content = readFileSync(join(partsDir, file), 'utf8').replace(/\r\n/g, '\n').trimEnd();
if (file.startsWith('00-')) {
preamble = content;
for (const line of content.split('\n')) if (/^## /.test(line)) toc.push(`- ${line.replace(/^##\s+/, '').trim()}`);
continue;
}
for (const line of content.split('\n')) {
if (/^## /.test(line)) toc.push(`- ${line.replace(/^##\s+/, '').trim()}`);
else if (/^### /.test(line)) toc.push(` - ${line.replace(/^###\s+/, '').trim()}`);
}
const chars = [...content.replace(/\s/g, '')].length;
const cjk = (content.match(/[\u4e00-\u9fff]/g) || []).length;
stats.push({ file, chars, cjk, lines: content.split('\n').length });
sections.push(content);
}
if (!preamble.includes('<!-- TOC -->')) throw new Error('preamble 缺少 TOC 占位符');
const tocBlock = ['## 目录', '', ...toc, ''].join('\n');
const body = [preamble.replace('<!-- TOC -->', tocBlock), ...sections].join('\n\n---\n\n');
writeFileSync(outFile, body + '\n', 'utf8');
const totalChars = [...body.replace(/\s/g, '')].length;
const totalCjk = (body.match(/[\u4e00-\u9fff]/g) || []).length;
console.log(`输出:${outFile}`);
console.log(`去空白字符:${totalChars};汉字:${totalCjk};行数:${body.split('\n').length}`);
console.log(`粗略 token:${Math.round(totalCjk * 0.9 + (totalChars - totalCjk) * 0.3)}`);
for (const s of stats) console.log(` ${s.file.padEnd(26)} ${String(s.chars).padStart(7)} 字符 ${String(s.cjk).padStart(6)} 汉字`);
console.log(` 00-preamble.md ${String([...preamble.replace(/\s/g, '')].length).padStart(7)} 字符 ${String((preamble.match(/[\u4e00-\u9fff]/g) || []).length).padStart(6)} 汉字`);
if (process.argv.includes('--split')) {
const outDir = join(root, 'out');
const sectionsDir = join(outDir, 'refactor-sections');
mkdirSync(sectionsDir, { recursive: true });
const volumes = [
{ name: 'vol1-任务声明与现状基线(00-02)', nums: [0, 1, 2] },
{ name: 'vol2-基准语义与文件数据改造(03-05)', nums: [3, 4, 5] },
{ name: 'vol3-tokens与组件规格(06-07)', nums: [6, 7] },
{ name: 'vol4-消息课程与编辑器(08-09)', nums: [8, 9] },
{ name: 'vol5-动画兼容与验收里程碑(10-13)', nums: [10, 11, 12, 13] },
];
for (const v of volumes) {
const chunks = [];
if (v.nums.includes(0)) chunks.push(preamble.replace('<!-- TOC -->', tocBlock));
for (const n of v.nums) {
if (n === 0) continue;
const f = files.find((x) => Number(x.slice(0, 2)) === n);
if (f) chunks.push(readFileSync(join(partsDir, f), 'utf8').replace(/\r\n/g, '\n').trimEnd());
else console.warn(`警告:缺少 part ${n}`);
}
const p = join(outDir, `${v.name}.md`);
writeFileSync(p, chunks.join('\n\n---\n\n') + '\n', 'utf8');
const c = readFileSync(p, 'utf8');
console.log(`分卷:${p}(${[...c.replace(/\s/g, '')].length} 字符)`);
}
for (const f of files) copyFileSync(join(partsDir, f), join(sectionsDir, f));
console.log(`逐节文件:${sectionsDir}(${files.length} 个)`);
}