#!/usr/bin/env python3 """V135 (pivot) - Add KPI banner in all-ia-hub breadcrumb area showing live platform health Uses /api/screens-health.json (already exists, maintained by other Claude) Shows: 🟢 NN% healthy · NN UP · NN BROKEN (updated auto) """ import sys src, dst = sys.argv[1], sys.argv[2] with open(src, "r", encoding="utf-8") as f: c = f.read() if "V135-KPI-BANNER" in c: print("ALREADY", file=sys.stderr) sys.exit(0) # Inject a small KPI span in v130-xnav right side (where "All-IA Hub · consolidation 84 dashboards" sits) old = 'All-IA Hub · consolidation 84 dashboards' new = 'All-IA Hub · consolidation 84 dashboards' if old not in c: print("xnav anchor missing", file=sys.stderr) sys.exit(1) c = c.replace(old, new, 1) # Add JS fetcher (one-shot on load) marker = "setTimeout(() => {\n const btn = document.querySelector('[data-view=\"dashboards\"]');" js_add = """/* V135-KPI-BANNER: load screens-health summary and update banner (zero impact on UX if fetch fails) */ (function(){ const kpi = document.getElementById('v135-kpi-live'); if (!kpi) return; fetch('/api/screens-health.json', {cache: 'no-store'}).then(r => r.ok ? r.json() : null).then(d => { if (!d || !d.counts) return; const c = d.counts; const total = d.total || 0; const up = c.UP || 0; const broken = c.BROKEN || 0; const down = c.DOWN || 0; const phantom = c.PHANTOM || 0; const active = total - phantom; const healthPct = active ? Math.round((up / active) * 100) : 0; const dot = (broken + down === 0) ? '\\u{1F7E2}' : (broken + down < 20 ? '\\u{1F7E1}' : '\\u{1F534}'); kpi.innerHTML = 'All-IA Hub · ' + dot + ' ' + healthPct + '% (' + up + ' UP · ' + broken + ' broken)'; kpi.title = 'Platform health: ' + up + ' UP / ' + broken + ' BROKEN / ' + down + ' DOWN / ' + phantom + ' phantom (total ' + total + ')'; }).catch(_ => {}); })(); """ + marker if marker in c: c = c.replace(marker, js_add, 1) with open(dst, "w", encoding="utf-8") as f: f.write(c) print(f"OK size={len(c)}", file=sys.stderr)