#!/usr/bin/env node 'use strict'; const fs = require('fs'); const path = require('path'); const { execSync } = require('child_process'); const TARGET = path.join(__dirname, '..', '..', 'hooks', 'route-interceptor-bundle.js'); const SENTINEL_TAG = 'ROUTE-ACC-3D-V1'; const HELPER = [ '', ' // /* ROUTE-ACC-3D-V1 */ near-3-day route accuracy', " let routeAccuracy3d = 'N/A';", ' try {', ' const cutoff = Date.now() - 3 * 86400 * 1000;', ' const files = fs.readdirSync(DEBUG_DIR).filter(function(f){return /^route-\\d{4}-\\d{2}-\\d{2}\\.jsonl$/.test(f);});', ' let total = 0, hit = 0;', ' for (const f of files) {', " const lines = fs.readFileSync(path.join(DEBUG_DIR, f), 'utf8').split('\\n');", ' for (const L of lines) {', ' if (!L) continue;', ' try {', ' const j = JSON.parse(L);', ' const ts = new Date(j.ts).getTime();', ' if (!Number.isFinite(ts) || ts < cutoff) continue;', ' total++;', ' if (j.topConfidence && j.topConfidence > 0) hit++;', ' } catch {}', ' }', ' }', " if (total > 0) routeAccuracy3d = (hit / total * 100).toFixed(1) + '%';", ' } catch {}', '', ' const now = new Date();', ].join('\n'); function main() { const src = fs.readFileSync(TARGET, 'utf8'); if (src.includes(SENTINEL_TAG)) { console.log('[banner-acc] already applied, skip'); return; } const anchor = '\n const now = new Date();'; if (!src.includes(anchor)) { console.error('[banner-acc] anchor missing'); process.exit(1); } let next = src.replace(anchor, HELPER); const bannerOld = ' `active_skills: ${activeSkillCount}/${skillCount}`,'; const bannerNew = bannerOld + '\n `route_accuracy_3d: ${routeAccuracy3d}`,'; if (!next.includes(bannerOld)) { console.error('[banner-acc] banner anchor missing'); process.exit(1); } next = next.replace(bannerOld, bannerNew); const bak = TARGET + '.bak.banner-acc.' + Date.now(); fs.copyFileSync(TARGET, bak); const tmp = TARGET + '.tmp.' + process.pid; fs.writeFileSync(tmp, next, 'utf8'); fs.renameSync(tmp, TARGET); try { execSync('node --check "' + TARGET + '"', { stdio: 'pipe' }); console.log('[banner-acc] OK, bak:', path.basename(bak)); } catch (e) { fs.copyFileSync(bak, TARGET); console.error('[banner-acc] SYNTAX FAIL, rolled back:', String(e.stderr || e.message).split('\n').slice(0, 4).join(' | ')); process.exit(1); } } main();