- VERSION file as authoritative version source - export.mjs reads VERSION with package.json fallback - bw-ota.ps1 DryRun mode for safe testing - auto-setup.ps1 bumped to v3.2.0 (Phase 8 OTA)
130 lines
5.1 KiB
JavaScript
130 lines
5.1 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* R87 penalty 清理 + L1d 业务前缀扩展 复合补丁 (2026-04-25)
|
|
*
|
|
* 两项修复:
|
|
*
|
|
* 1. R87 penalty 去除 self-auditor (与 R86 boost 语义冲突)
|
|
* - 原因: R87 触发 "bookworm 在哪/是什么/如何配置" 时 penalty self-auditor,
|
|
* 但 "bookworm 自检在哪配置/自检怎么用" 这类查询依然应锚定 self-auditor,
|
|
* penalty 导致 R86 boost 被抵消为负 → 误路由到 developer-expert 下游
|
|
* - 保留 project-audit-expert / reviewer-expert penalty (重型审计仍需降权)
|
|
*
|
|
* 2. R84 negative-lookbehind 扩展 uniapp/taro/svelte/solid/qwik
|
|
* - 原因: 当前仅排除 vue/next/react/angular/nuxt 业务前缀,
|
|
* "uniapp 路由消歧/taro 钩子管线/svelte 路由引擎" 等短语会被 R84 误吸锚定到 self-auditor
|
|
* - 新增前缀: uniapp / uni-app / taro / svelte / solid / qwik
|
|
* - 同步覆盖 R86 相同模式 (系统自检 lookbehind 不变, 仅 R84 扩展)
|
|
*
|
|
* 幂等: 两项修复各自 sentinel 检测;已应用则跳过。
|
|
* 原子: tmp + rename。
|
|
* 备份: .bak.r87-l1d.<ISO>
|
|
*/
|
|
'use strict';
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const TARGET = path.join(__dirname, '..', 'disambiguation-rules.json');
|
|
|
|
const OLD_LOOKBEHIND = '(?<!vue.?|vue\\s|next\\.?js?\\s|react\\s|angular\\s|nuxt\\s|项目|应用|这个)';
|
|
const NEW_LOOKBEHIND = '(?<!vue.?|vue\\s|next\\.?js?\\s|react\\s|angular\\s|nuxt\\s|uniapp\\s|uni-app\\s|taro\\s|svelte\\s|solid\\s|qwik\\s|项目|应用|这个)';
|
|
|
|
function main() {
|
|
if (!fs.existsSync(TARGET)) {
|
|
console.error('[patch-r87-l1d] 目标文件不存在:', TARGET);
|
|
process.exit(1);
|
|
}
|
|
|
|
const raw = fs.readFileSync(TARGET, 'utf8');
|
|
const json = JSON.parse(raw);
|
|
|
|
if (!Array.isArray(json.rules)) {
|
|
console.error('[patch-r87-l1d] rules 不是数组');
|
|
process.exit(1);
|
|
}
|
|
|
|
const r87 = json.rules.find(r => r && r.id === 'R87');
|
|
const r84 = json.rules.find(r => r && r.id === 'R84');
|
|
|
|
if (!r87) {
|
|
console.error('[patch-r87-l1d] R87 不存在, 放弃');
|
|
process.exit(1);
|
|
}
|
|
if (!r84) {
|
|
console.error('[patch-r87-l1d] R84 不存在, 放弃');
|
|
process.exit(1);
|
|
}
|
|
|
|
const actions = [];
|
|
const changelog = [];
|
|
|
|
// ==== 修复 1: R87 penalty 去 self-auditor ====
|
|
if (Array.isArray(r87.penalty) && r87.penalty.includes('self-auditor')) {
|
|
const before = r87.penalty.slice();
|
|
r87.penalty = r87.penalty.filter(p => p !== 'self-auditor');
|
|
actions.push('R87.penalty: [' + before.join(',') + '] → [' + r87.penalty.join(',') + ']');
|
|
changelog.push('R87: 修正 — 移除 penalty self-auditor (与 R86 boost 语义冲突, 导致查询型 self-auditor 场景误降权到 developer-expert)');
|
|
} else {
|
|
console.log('[patch-r87-l1d] R87 penalty 已不含 self-auditor, 跳过修复 1');
|
|
}
|
|
|
|
// ==== 修复 2: R84 trigger lookbehind 扩展 ====
|
|
if (typeof r84.trigger === 'string' && r84.trigger.includes(OLD_LOOKBEHIND) && !r84.trigger.includes('uniapp')) {
|
|
r84.trigger = r84.trigger.replace(OLD_LOOKBEHIND, NEW_LOOKBEHIND);
|
|
actions.push('R84.trigger lookbehind 扩展: +uniapp +uni-app +taro +svelte +solid +qwik');
|
|
changelog.push('R84: L1d 扩展 — trigger negative-lookbehind 增加 uniapp/uni-app/taro/svelte/solid/qwik 业务前缀排除, 防"uniapp 路由消歧"等误吸到 self-auditor');
|
|
} else if (r84.trigger && r84.trigger.includes('uniapp')) {
|
|
console.log('[patch-r87-l1d] R84 trigger 已含 uniapp, 跳过修复 2');
|
|
} else {
|
|
console.warn('[patch-r87-l1d] R84 trigger 未找到预期 lookbehind 锚点, 跳过修复 2 (可能已被其他补丁改写)');
|
|
}
|
|
|
|
if (actions.length === 0) {
|
|
console.log('[patch-r87-l1d] 所有修复均已生效, 无需改动');
|
|
process.exit(0);
|
|
}
|
|
|
|
// 备份
|
|
const bakSuffix = '.bak.r87-l1d.' + new Date().toISOString().replace(/[:.]/g, '-');
|
|
fs.writeFileSync(TARGET + bakSuffix, raw, 'utf8');
|
|
console.log('[patch-r87-l1d] backup → ' + path.basename(TARGET + bakSuffix));
|
|
|
|
// 更新 _meta
|
|
if (!json._meta) json._meta = {};
|
|
json._meta.version = '1.5.2';
|
|
json._meta.description = (json._meta.description || '') +
|
|
' | v1.5.2 (' + new Date().toISOString().slice(0, 10) + '): R87 penalty 清理 + R84 L1d 业务前缀扩展';
|
|
if (!Array.isArray(json._meta.changelog)) json._meta.changelog = [];
|
|
json._meta.changelog.push(...changelog);
|
|
|
|
// 原子写入
|
|
const tmpPath = TARGET + '.tmp.' + process.pid;
|
|
fs.writeFileSync(tmpPath, JSON.stringify(json, null, 2) + '\n', 'utf8');
|
|
fs.renameSync(tmpPath, TARGET);
|
|
|
|
console.log('[patch-r87-l1d] applied:');
|
|
actions.forEach(a => console.log(' - ' + a));
|
|
|
|
// 清缓存
|
|
try {
|
|
const treePath = path.join(__dirname, '..', 'disambiguation-tree.js');
|
|
delete require.cache[require.resolve(treePath)];
|
|
const tree = require(treePath);
|
|
if (tree && typeof tree.clearCache === 'function') {
|
|
tree.clearCache();
|
|
console.log('[patch-r87-l1d] disambiguation-tree cache cleared');
|
|
}
|
|
} catch (e) {
|
|
console.log('[patch-r87-l1d] cache clear skipped: ' + e.message);
|
|
}
|
|
}
|
|
|
|
if (require.main === module) {
|
|
try { main(); }
|
|
catch (e) {
|
|
console.error('[patch-r87-l1d] FAIL:', e.message);
|
|
process.exit(1);
|
|
}
|
|
}
|