92 lines
3.6 KiB
JavaScript
92 lines
3.6 KiB
JavaScript
|
|
#!/usr/bin/env node
|
|||
|
|
/**
|
|||
|
|
* patch-x07-x08-x09-crlf-fix.js
|
|||
|
|
* 统一修复 X07/X08/X09,使用 CRLF 规范化后匹配
|
|||
|
|
*/
|
|||
|
|
'use strict';
|
|||
|
|
const fs = require('fs');
|
|||
|
|
const path = require('path');
|
|||
|
|
|
|||
|
|
const HOOKS_DIR = path.join(__dirname, '..', '..', 'hooks');
|
|||
|
|
let total = 0;
|
|||
|
|
|
|||
|
|
function patchFile(filePath, label, patches) {
|
|||
|
|
if (!fs.existsSync(filePath)) { console.log('SKIP ' + label + ': not found'); return; }
|
|||
|
|
let src = fs.readFileSync(filePath, 'utf8');
|
|||
|
|
const hadCRLF = src.includes('\r\n');
|
|||
|
|
let norm = src.replace(/\r\n/g, '\n');
|
|||
|
|
|
|||
|
|
for (const p of patches) {
|
|||
|
|
if (norm.includes(p.sentinel)) { console.log('SKIP ' + label + '/' + p.id + ': already patched'); continue; }
|
|||
|
|
if (!norm.includes(p.old)) { console.error('FAIL ' + label + '/' + p.id + ': old pattern not found'); process.exit(1); }
|
|||
|
|
norm = norm.replace(p.old, p.new);
|
|||
|
|
console.log('OK ' + p.id + ' applied');
|
|||
|
|
total++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (hadCRLF) norm = norm.replace(/\n/g, '\r\n');
|
|||
|
|
const tmp = filePath + '.tmp.' + process.pid;
|
|||
|
|
fs.writeFileSync(tmp, norm, 'utf8');
|
|||
|
|
fs.renameSync(tmp, filePath);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// === X07: agent-isolation-gate.js seq 步长 ===
|
|||
|
|
patchFile(path.join(HOOKS_DIR, 'agent-isolation-gate.js'), 'agent-isolation-gate', [{
|
|||
|
|
id: 'X07',
|
|||
|
|
sentinel: '[PATCH-X07-SEQ-STEP]',
|
|||
|
|
old: ` const seqMatch = c.match(/\\bseq\\s+(\\d+)(?:\\s+(\\d+))?(?:\\s+(\\d+))?/);
|
|||
|
|
if (seqMatch) {
|
|||
|
|
const a = parseInt(seqMatch[1], 10);
|
|||
|
|
const b = seqMatch[2] ? parseInt(seqMatch[2], 10) : null;
|
|||
|
|
const z = seqMatch[3] ? parseInt(seqMatch[3], 10) : (b !== null ? b : a);
|
|||
|
|
const n = b !== null && z !== null ? Math.max(0, z - a + 1) : a;
|
|||
|
|
if (n >= 6) return { rule: 'B2', detail: 'seq ' + n };
|
|||
|
|
}`,
|
|||
|
|
new: ` const seqMatch = c.match(/\\bseq\\s+(\\d+)(?:\\s+(\\d+))?(?:\\s+(\\d+))?/); // [PATCH-X07-SEQ-STEP]
|
|||
|
|
if (seqMatch) {
|
|||
|
|
let n;
|
|||
|
|
const g1 = parseInt(seqMatch[1], 10);
|
|||
|
|
const g2 = seqMatch[2] ? parseInt(seqMatch[2], 10) : null;
|
|||
|
|
const g3 = seqMatch[3] ? parseInt(seqMatch[3], 10) : null;
|
|||
|
|
if (g3 !== null) {
|
|||
|
|
const step = Math.max(1, g2);
|
|||
|
|
n = Math.max(0, Math.floor((g3 - g1) / step) + 1);
|
|||
|
|
} else if (g2 !== null) {
|
|||
|
|
n = Math.max(0, g2 - g1 + 1);
|
|||
|
|
} else {
|
|||
|
|
n = g1;
|
|||
|
|
}
|
|||
|
|
if (n >= 6) return { rule: 'B2', detail: 'seq ' + n };
|
|||
|
|
}`
|
|||
|
|
}]);
|
|||
|
|
|
|||
|
|
// === X08: session-heartbeat.js 原子写 ===
|
|||
|
|
patchFile(path.join(HOOKS_DIR, 'session-heartbeat.js'), 'session-heartbeat', [{
|
|||
|
|
id: 'X08-hb',
|
|||
|
|
sentinel: '[PATCH-X08-ATOMIC-WRITE]',
|
|||
|
|
old: " fs.writeFileSync(STATE_FILE, JSON.stringify(allState), 'utf8');",
|
|||
|
|
new: ` const _tmpHb = STATE_FILE + '.tmp.' + process.pid; // [PATCH-X08-ATOMIC-WRITE]
|
|||
|
|
fs.writeFileSync(_tmpHb, JSON.stringify(allState), 'utf8');
|
|||
|
|
fs.renameSync(_tmpHb, STATE_FILE);`
|
|||
|
|
}]);
|
|||
|
|
|
|||
|
|
// === X08b: pre-compact-handoff.js heartbeat 原子写 ===
|
|||
|
|
patchFile(path.join(HOOKS_DIR, 'pre-compact-handoff.js'), 'pre-compact-handoff', [{
|
|||
|
|
id: 'X08-pch',
|
|||
|
|
sentinel: '[PATCH-X08-ATOMIC-WRITE]',
|
|||
|
|
old: " fs.writeFileSync(heartbeatPath, JSON.stringify(hbAll), 'utf8');",
|
|||
|
|
new: ` const _tmpPch = heartbeatPath + '.tmp.' + process.pid; // [PATCH-X08-ATOMIC-WRITE]
|
|||
|
|
fs.writeFileSync(_tmpPch, JSON.stringify(hbAll), 'utf8');
|
|||
|
|
fs.renameSync(_tmpPch, heartbeatPath);`
|
|||
|
|
}]);
|
|||
|
|
|
|||
|
|
// === X09: context-pressure-monitor.js CJK 范围 ===
|
|||
|
|
patchFile(path.join(HOOKS_DIR, 'context-pressure-monitor.js'), 'context-pressure-monitor', [{
|
|||
|
|
id: 'X09',
|
|||
|
|
sentinel: '[PATCH-X09-CJK-KOREAN]',
|
|||
|
|
old: " if (b >= 0xE3 && b <= 0xE9) cjk += 3;",
|
|||
|
|
new: " if (b >= 0xE4 && b <= 0xED) cjk += 3; // [PATCH-X09-CJK-KOREAN]"
|
|||
|
|
}]);
|
|||
|
|
|
|||
|
|
console.log('DONE: ' + total + ' patches applied');
|