#!/usr/bin/env node /** * patch-r2-claudemd-doc.js · 2026-04-26 * 在 CLAUDE.md §上下文管理 追加 R2 PreCompact tier 输出说明 * Idempotent: sentinel 'TOOL_OUTPUT_TIER_V1' (恰好出现在新规则中) * v2: 修复 sentinel 错位 + 自愈去重 (清理任意条数的重复行只保留 1 条) */ 'use strict'; const fs = require('fs'); const path = require('path'); const CLAUDE_MD = path.join(process.env.HOME || process.env.USERPROFILE || 'C:/Users/leesu', '.claude', 'CLAUDE.md'); const SENTINEL = 'TOOL_OUTPUT_TIER_V1'; const ANCHOR = '- **批量任务切片**(>5 个独立子项的 Write/Edit/Bash 操作)'; const NEW_LINE = '- **PreCompact 工具输出分级** (R2): TOOL_OUTPUT_TIER_V1 已自动捕获 transcript 中 ≥500B 的 tool_result, 按 write/read/bash/agent/glob_grep 五类启发式分级, 取 top-10 大输出截断摘要写入 `~/.claude/session-state/handoff.json`, SessionStart 时自动注入恢复; 模型不直接消费, 用于 compact 后定位重型工具调用源'; try { let raw = fs.readFileSync(CLAUDE_MD, 'utf8'); fs.writeFileSync(CLAUDE_MD + '.bak.r2doc.' + Date.now(), raw, 'utf8'); // 自愈: 移除所有 NEW_LINE 重复行 (含上轮重复注入的) const lines = raw.split('\n'); const cleaned = []; let seenNewLine = false; for (const ln of lines) { if (ln.includes(SENTINEL)) { if (seenNewLine) continue; seenNewLine = true; cleaned.push(ln); } else { cleaned.push(ln); } } raw = cleaned.join('\n'); if (seenNewLine) { fs.writeFileSync(CLAUDE_MD, raw, 'utf8'); console.log('[r2-doc] already applied, skip (cleaned ' + (lines.length - cleaned.length) + ' duplicates)'); process.exit(0); } if (!raw.includes(ANCHOR)) { console.error('[r2-doc] anchor not found, abort'); process.exit(1); } const next = raw.replace(ANCHOR, NEW_LINE + '\n' + ANCHOR); fs.writeFileSync(CLAUDE_MD, next, 'utf8'); console.log('[r2-doc] applied'); } catch (e) { console.error('[r2-doc] error:', e.message); process.exit(1); }