bookworm-smart-assistant/scripts/patches/patch-sync-clipboard-python-path.js

91 lines
2.8 KiB
JavaScript
Raw Permalink Normal View History

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