#!/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();