- VERSION file as authoritative version source - export.mjs reads VERSION with package.json fallback - bw-ota.ps1 DryRun mode for safe testing - auto-setup.ps1 bumped to v3.2.0 (Phase 8 OTA)
91 lines
3.5 KiB
JavaScript
91 lines
3.5 KiB
JavaScript
#!/usr/bin/env node
|
||
/**
|
||
* patch-p1-fast-cache-fields-fix.js
|
||
*
|
||
* P1.5 微调: 修正 fast-cache.js 的字段映射,匹配实际 stats-compiled.json 结构。
|
||
*
|
||
* stats.summary.hooks = 46 (总数)
|
||
* stats.summary.hooksRegistered = 22 (已注册子集)
|
||
* stats.summary.mcpTotal = 26
|
||
*
|
||
* settings.json 顶层无 mcpServers (MCP 配置在 ~/.claude.json),需从 stats.summary 读
|
||
*/
|
||
|
||
'use strict';
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
const TARGET = path.join(__dirname, '..', '..', 'hooks', 'lib', 'fast-cache.js');
|
||
const SENTINEL_OLD = 'P1-FAST-CACHE-V1';
|
||
const SENTINEL_NEW = 'P1-FAST-CACHE-V1-FIELDS-FIX';
|
||
|
||
function main() {
|
||
if (!fs.existsSync(TARGET)) {
|
||
process.stderr.write('[ERROR] fast-cache.js not found, run patch-p1-fast-cache-lib.js first\n');
|
||
process.exit(1);
|
||
}
|
||
let src = fs.readFileSync(TARGET, 'utf8');
|
||
|
||
if (src.includes(SENTINEL_NEW)) {
|
||
process.stdout.write('[SKIP] already fixed\n');
|
||
process.exit(0);
|
||
}
|
||
if (!src.includes(SENTINEL_OLD)) {
|
||
process.stderr.write('[ERROR] base v1 not deployed\n');
|
||
process.exit(1);
|
||
}
|
||
|
||
const ts = new Date().toISOString().replace(/[:.]/g, '-');
|
||
fs.copyFileSync(TARGET, TARGET + '.bak.' + ts);
|
||
process.stdout.write('[BACKUP] ' + TARGET + '.bak.' + ts + '\n');
|
||
|
||
// 修正派生字段
|
||
const OLD_BLOCK =
|
||
" rebuilt.mcpCount = Object.keys(rebuilt.mcpServers || {}).length;\n" +
|
||
" rebuilt.skillCount = (rebuilt.summary || {}).skills || 0;\n" +
|
||
" rebuilt.hookCount = (rebuilt.summary || {}).hooksRegistered || (rebuilt.summary || {}).hooks || 0;\n" +
|
||
" rebuilt.agentCount = (rebuilt.summary || {}).agents || 0;";
|
||
|
||
const NEW_BLOCK =
|
||
" // " + SENTINEL_NEW + ": stats.summary 字段名修正\n" +
|
||
" const _sum = rebuilt.summary || {};\n" +
|
||
" rebuilt.skillCount = _sum.skills || 0;\n" +
|
||
" rebuilt.hookCount = _sum.hooks || 0; // 总数\n" +
|
||
" rebuilt.hookRegisteredCount = _sum.hooksRegistered || 0;\n" +
|
||
" rebuilt.agentCount = _sum.agents || 0;\n" +
|
||
" rebuilt.mcpCount = _sum.mcpTotal || _sum.mcp || 0;";
|
||
|
||
if (!src.includes(OLD_BLOCK)) {
|
||
process.stderr.write('[ERROR] expected block not found\n');
|
||
process.exit(1);
|
||
}
|
||
|
||
const updated = src.replace(OLD_BLOCK, NEW_BLOCK);
|
||
|
||
// 同时移除原 SOURCES 中 settings.json 的 mcpServers 字段(无效)
|
||
const SRC_OLD = " { file: path.join(ROOT, 'settings.json'), fields: ['mcpServers'] },";
|
||
const SRC_NEW = " // settings.json 不再读取 mcpServers (MCP 配置在 ~/.claude.json,由 stats 编译)";
|
||
const final = updated.includes(SRC_OLD) ? updated.replace(SRC_OLD, SRC_NEW) : updated;
|
||
|
||
const tmpPath = TARGET + '.tmp.' + process.pid;
|
||
fs.writeFileSync(tmpPath, final);
|
||
|
||
try {
|
||
delete require.cache[require.resolve(tmpPath)];
|
||
const mod = require(tmpPath);
|
||
const c = mod.readFastCache();
|
||
if (c.skillCount !== 94) throw new Error('skillCount expected 94 got ' + c.skillCount);
|
||
if (c.hookCount !== 46) throw new Error('hookCount expected 46 got ' + c.hookCount);
|
||
if (c.mcpCount !== 26) throw new Error('mcpCount expected 26 got ' + c.mcpCount);
|
||
fs.renameSync(tmpPath, TARGET);
|
||
process.stdout.write('[OK] fast-cache.js fields fixed\n');
|
||
process.stdout.write(' skills=' + c.skillCount + ' hooks=' + c.hookCount + ' mcp=' + c.mcpCount + ' agents=' + c.agentCount + '\n');
|
||
} catch (e) {
|
||
fs.unlinkSync(tmpPath);
|
||
process.stderr.write('[ERROR] self-test: ' + e.message + '\n');
|
||
process.exit(1);
|
||
}
|
||
}
|
||
|
||
if (require.main === module) main();
|