reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,283 @@
#!/usr/bin/env node
'use strict';
const fs = require('fs');
const path = require('path');
const REQUIRED_FIELDS = [
'修改前逻辑',
'问题证据',
'本次修改',
'修改理由',
'已失败尝试',
'禁止回退',
'验证命令',
'验证结果',
'当前验证范围',
'遗留风险',
'当前状态',
];
function parseArgs(argv) {
const args = {
caseDir: 'case',
changed: [],
init: false,
requireEntry: false,
json: false,
markdown: false,
help: false,
};
for (let i = 2; i < argv.length; i++) {
const a = argv[i];
if (a === '--case-dir' || a === '--dir' || a === '-d') args.caseDir = argv[++i] || '';
else if (a === '--changed' || a === '--file') args.changed.push(argv[++i] || '');
else if (a === '--init') args.init = true;
else if (a === '--require-entry') args.requireEntry = true;
else if (a === '--json') args.json = true;
else if (a === '--markdown') args.markdown = true;
else if (a === '--help' || a === '-h') args.help = true;
else throw new Error(`未知参数:${a}`);
}
return args;
}
function usage() {
return `用法:
node scripts/check_change_memory.js --case-dir case --init --markdown
node scripts/check_change_memory.js --case-dir case --markdown
node scripts/check_change_memory.js --case-dir case --changed result/src/env/install-env.js --require-entry --markdown
node scripts/check_change_memory.js --case-dir case --changed result/src/signer/index.js --json
说明:检查复杂 case 是否维护 case/notes/代码变更记忆.md,并确认关键源码修改后记录了修改原因、失败尝试、禁止回退、验证范围和遗留风险。`;
}
function normalizeSlash(v) {
return String(v || '').replace(/\\/g, '/');
}
function exists(p) {
try { fs.accessSync(p); return true; } catch { return false; }
}
function memoryPath(caseDir) {
return path.join(path.resolve(caseDir), 'notes', '代码变更记忆.md');
}
function createTemplate() {
return `# 代码变更记忆
本文件由通用代码变更记忆机制维护,用于记录复杂 case 中关键源码修改的事实、原因、失败尝试、禁止回退、验证范围和遗留风险。不要把“当前报错消失”直接写成永久结论。
## 使用规则
- 修改关键源码前先读取本文件,并搜索文件名、函数名、错误关键词和参数名。
- 修改关键源码后立即追加一条“变更”记录。
- 不删除失败记录;如历史记录被新证据替代,新增记录说明替代原因。
- 状态只能使用:临时修复 / 当前验证通过 / 已失败 / 被替代 / 稳定基线。
## 变更 001 - 待填写
- 时间:YYYY-MM-DD HH:mm
- 涉及文件:
- 涉及函数 / 模块:
- 当前状态:临时修复
### 修改前逻辑
待填写。
### 问题证据
待填写。
### 本次修改
待填写。
### 修改理由
待填写。
### 已失败尝试
待填写。
### 禁止回退
待填写。
### 验证命令
\`\`\`bash
# 待填写
\`\`\`
### 验证结果
待填写。
### 当前验证范围
待填写。
### 遗留风险
待填写。
`;
}
function initMemory(file) {
fs.mkdirSync(path.dirname(file), { recursive: true });
if (!exists(file)) {
fs.writeFileSync(file, createTemplate(), 'utf8');
return 'created';
}
return 'kept';
}
function hasEntry(text) {
return /^##\s+变更\s+\d+/m.test(text);
}
function fieldMissing(text) {
return REQUIRED_FIELDS.filter(field => !text.includes(field));
}
function changedMatched(text, changedFile) {
const normalized = normalizeSlash(changedFile).replace(/^\.\//, '');
const basename = path.basename(normalized);
const textSlash = normalizeSlash(text);
if (normalized && textSlash.includes(normalized)) return true;
if (basename && textSlash.includes(basename)) return true;
return false;
}
function check(args) {
const caseDir = path.resolve(args.caseDir || 'case');
const file = memoryPath(caseDir);
const problems = [];
const warnings = [];
const actions = [];
if (args.init) actions.push({ action: initMemory(file), path: file });
if (!exists(file)) {
problems.push(`未找到通用代码变更记忆文件:${file}`);
return {
caseDir,
memoryFile: file,
exists: false,
clean: false,
actions,
requiredFields: REQUIRED_FIELDS,
missingFields: REQUIRED_FIELDS.slice(),
changed: args.changed,
matchedChanged: [],
problems,
warnings,
};
}
const text = fs.readFileSync(file, 'utf8');
const missingFields = fieldMissing(text);
if (missingFields.length) problems.push(`代码变更记忆缺少必要字段:${missingFields.join('、')}`);
const entryExists = hasEntry(text);
if (args.requireEntry && !entryExists) problems.push('已要求至少一条变更记录,但未发现 “## 变更 001” 这类记录。');
if (!entryExists) warnings.push('尚未发现正式变更记录;如果已经修改关键源码,请立即追加记录。');
const matchedChanged = [];
for (const changed of args.changed.filter(Boolean)) {
const matched = changedMatched(text, changed);
matchedChanged.push({ file: changed, matched });
if (args.requireEntry && !matched) {
problems.push(`已修改关键文件但代码变更记忆中未提到该文件:${changed}`);
} else if (!matched) {
warnings.push(`代码变更记忆中未提到变更文件:${changed}`);
}
}
if (/正确方案/.test(text)) {
warnings.push('发现“正确方案”表述;建议改为“当前验证通过 / 稳定基线”,并写明验证范围和遗留风险。');
}
return {
caseDir,
memoryFile: file,
exists: true,
clean: problems.length === 0,
actions,
requiredFields: REQUIRED_FIELDS,
missingFields,
hasEntry: entryExists,
changed: args.changed,
matchedChanged,
problems,
warnings,
};
}
function renderMarkdown(result) {
const lines = [
'# 通用代码变更记忆检查',
'',
`- case 目录:${result.caseDir}`,
`- 记忆文件:${result.memoryFile}`,
`- 文件存在:${result.exists ? '是' : '否'}`,
`- 是否通过:${result.clean ? '是' : '否'}`,
'',
];
if (result.actions.length) {
lines.push('## 初始化动作');
for (const item of result.actions) {
lines.push(`- ${item.action === 'created' ? '已创建' : '已存在'}:${item.path}`);
}
lines.push('');
}
lines.push('## 必要字段');
for (const field of result.requiredFields) {
lines.push(`- ${field}:${result.missingFields.includes(field) ? '缺失' : '存在'}`);
}
lines.push('');
if (result.matchedChanged && result.matchedChanged.length) {
lines.push('## 变更文件命中');
for (const item of result.matchedChanged) {
lines.push(`- ${item.file}:${item.matched ? '已记录' : '未记录'}`);
}
lines.push('');
}
if (result.problems.length) {
lines.push('## 问题');
for (const p of result.problems) lines.push(`- ${p}`);
lines.push('');
}
if (result.warnings.length) {
lines.push('## 提醒');
for (const w of result.warnings) lines.push(`- ${w}`);
lines.push('');
}
return lines.join('\n') + '\n';
}
try {
const args = parseArgs(process.argv);
if (args.help) {
console.log(usage());
process.exit(0);
}
const result = check(args);
if (args.json) console.log(JSON.stringify(result, null, 2));
if (args.markdown || !args.json) process.stdout.write(renderMarkdown(result));
process.exit(result.clean ? 0 : 1);
} catch (err) {
console.error(err.message || String(err));
console.error(usage());
process.exit(1);
}