#!/usr/bin/env node /** * 同步项目脱敏补丁 — 2026-04-21 * * 问题: hooks/clipboard-image-hook.js:48 硬编码 'C:/Users/leesu/AppData/...' * 导致跨机同步时仅特定账户可命中, 不可移植 * * 修复方案: 改为 os.homedir() + PYTHON_EXE env 覆盖 * 旧: const candidates = [ * 'C:/Users/leesu/AppData/Local/Programs/Python/Python312/python.exe', * 'python', 'python3' * ]; * 新: const os = require('os'); const path = require('path'); * const candidates = [ * process.env.PYTHON_EXE, * path.join(os.homedir(), 'AppData/Local/Programs/Python/Python312/python.exe'), * 'python', 'python3' * ].filter(Boolean); * * 行为: 同硬编码原值, 同机用户名仍 leesu, 路径解析结果完全一致, 零行为变更 * 幂等: sentinel = 'CLIPBOARD_PYTHON_PORTABLE_2026_04_21' * 原子性: .bak 备份 + tmp + rename */ 'use strict'; const fs = require('fs'); const path = require('path'); const CLAUDE_ROOT = path.join(__dirname, '..', '..'); const TARGET = path.join(CLAUDE_ROOT, 'hooks', 'clipboard-image-hook.js'); const BACKUP = TARGET + '.bak.sync-portable'; const TMP = TARGET + '.tmp.sync-portable'; const SENTINEL = 'CLIPBOARD_PYTHON_PORTABLE_2026_04_21'; function main() { if (!fs.existsSync(TARGET)) { console.error('[patch-sync-clipboard] 目标不存在:', TARGET); process.exit(1); } const before = fs.readFileSync(TARGET, 'utf8'); // 幂等: 已含 sentinel 直接跳过 if (before.includes(SENTINEL)) { console.log('[patch-sync-clipboard] 已打过补丁,跳过'); process.exit(0); } const oldBlock = ` // 优先使用完整路径,避免 PATH 查找开销 const candidates = [ 'C:/Users/leesu/AppData/Local/Programs/Python/Python312/python.exe', 'python', 'python3', ];`; const newBlock = ` // 优先使用完整路径,避免 PATH 查找开销 [${SENTINEL}] const _os = require('os'); const _path = require('path'); const candidates = [ process.env.PYTHON_EXE, _path.join(_os.homedir(), 'AppData/Local/Programs/Python/Python312/python.exe'), 'python', 'python3', ].filter(Boolean);`; if (!before.includes(oldBlock)) { console.error('[patch-sync-clipboard] 锚点未找到, 文件已变更, 拒绝盲改'); process.exit(2); } // 备份 if (!fs.existsSync(BACKUP)) { fs.copyFileSync(TARGET, BACKUP); } const after = before.replace(oldBlock, newBlock); if (after === before || !after.includes(SENTINEL)) { console.error('[patch-sync-clipboard] 替换未生效'); process.exit(3); } fs.writeFileSync(TMP, after, 'utf8'); fs.renameSync(TMP, TARGET); console.log('[patch-sync-clipboard] OK · 脱敏 Python 路径硬编码 (sentinel 已写入)'); console.log('[patch-sync-clipboard] 备份:', path.relative(CLAUDE_ROOT, BACKUP)); } main();