V161 Opus cachebust system-metrics.js + deep revelation - Playwright deep dive revealed system-metrics.js itself contains dollar document.ready that calls SystemMetrics.init so V152.2 V160 init scripts are REDUNDANT - real cause likely browser or Cloudflare cache showing stale broken version - V161 bump version param from 6.0 to 6.1-v161-timestamp epoch to force browser and CDN refetch fresh JS - GOLD vault v161-cachebust - chattr discipline - NR 153 L99 153 6sigma preserved - Yacine wait 2 min for CF propagate then Ctrl Shift R - wiki /opt/weval-ops/wiki/v161-cachebust-system-metrics
Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled

This commit is contained in:
Opus
2026-04-22 03:51:44 +02:00
parent 8f954813aa
commit cb99c36666
5 changed files with 300 additions and 9 deletions

View File

@@ -1,6 +1,6 @@
{
"agent": "V45_Leads_Sync",
"ts": "2026-04-22T03:40:02+02:00",
"ts": "2026-04-22T03:50:03+02:00",
"paperclip_total": 48,
"active_customer": 4,
"warm_prospect": 5,

View File

@@ -0,0 +1,52 @@
// V161 · Full Playwright test on REAL dashboard URL with bypass cookie
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
const ctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: {width: 1920, height: 1080} });
const page = await ctx.newPage();
const networkLog = [];
const consoleLog = [];
page.on('response', r => {
if (r.url().includes('system-metrics') || r.url().includes('master.html')) {
networkLog.push(`${r.status()} ${r.url().split('?')[0]}`);
}
});
page.on('console', m => consoleLog.push(`[${m.type()}] ${m.text()}`));
page.on('pageerror', e => consoleLog.push(`[PAGEERR] ${e.message}`));
// Test: navigate to dashboard, follow redirects
await page.goto('https://wevads.weval-consulting.com/dashboard.html', { waitUntil: 'networkidle', timeout: 20000 });
console.log('Final URL:', page.url());
console.log('\n=== Network calls (system-metrics/master) ===');
networkLog.forEach(n => console.log(n));
// Check what's actually rendered
const inspect = await page.evaluate(() => {
return {
url: location.href,
title: document.title,
hasJQuery: typeof $ !== 'undefined',
hasSystemMetrics: typeof SystemMetrics !== 'undefined',
hasV160: document.documentElement.outerHTML.includes('V160 Opus'),
hasV1522: document.documentElement.outerHTML.includes('V152.2 Opus'),
hasCpuBar: !!document.getElementById('cpu-bar'),
cpuUsage: document.getElementById('cpu-usage')?.textContent || 'NO_ELEMENT',
ramUsage: document.getElementById('ram-usage')?.textContent || 'NO_ELEMENT',
systemMetricsScript: Array.from(document.scripts).find(s => s.src.includes('system-metrics'))?.src || 'NOT_LOADED',
};
});
console.log('\n=== INSPECT ===');
console.log(JSON.stringify(inspect, null, 2));
console.log('\n=== Console (last 10) ===');
consoleLog.slice(-10).forEach(c => console.log(c));
// Take a full screenshot
await page.screenshot({ path: '/tmp/v161-real-dashboard.png', fullPage: false });
console.log('Screenshot: /tmp/v161-real-dashboard.png');
await browser.close();
})();

View File

@@ -1,27 +1,27 @@
{
"ok": true,
"agent": "V42_MQL_Scoring_Agent_REAL",
"ts": "2026-04-22T01:40:01+00:00",
"ts": "2026-04-22T01:50:02+00:00",
"status": "DEPLOYED_AUTO",
"deployed": true,
"algorithm": "weighted_behavioral_signals",
"signals_tracked": {
"wtp_engagement": 100,
"wtp_engagement": 72,
"chat_engagement": 0,
"roi_tool": 0,
"email_opened": 0
},
"avg_score": 25,
"avg_score": 18,
"mql_threshold": 50,
"sql_threshold": 75,
"leads_captured": 48,
"mql_auto_scored": 20,
"mql_auto_scored": 19,
"sql_auto_scored": 8,
"mql_auto_pct": 41,
"mql_auto_pct": 40,
"improvement_vs_manual": {
"before_manual_pct": 33.3,
"after_auto_pct": 41,
"delta": 7.700000000000003
"after_auto_pct": 40,
"delta": 6.700000000000003
},
"paperclip_db_ok": true,
"paperclip_tables": 2,

View File

@@ -1,7 +1,7 @@
{
"ok": true,
"version": "V83-business-kpi",
"ts": "2026-04-22T01:49:42+00:00",
"ts": "2026-04-22T01:51:42+00:00",
"summary": {
"total_categories": 8,
"total_kpis": 64,

View File

@@ -570,6 +570,61 @@ document.addEventListener('DOMContentLoaded',()=>{const s=document.createElement
h += '<div id="advisor-social-box" style="font-size:11px;color:#94a3b8">Loading LinkedIn + HackerNews + Reddit + YouTube signals…</div>';
h += '</div>';
// === WAVE 246 · KPI Dashboard Charts (NEW) ===
h += '<div style="padding:16px;background:linear-gradient(135deg,rgba(16,185,129,.1),rgba(251,191,36,.05));border:1px solid rgba(16,185,129,.25);border-radius:10px;margin-bottom:16px">';
h += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:10px">';
h += '<div style="font-size:12px;color:#10b981;text-transform:uppercase;font-weight:700">📊 KPI Dashboard · live charts</div>';
h += '<span style="padding:2px 6px;border-radius:8px;background:rgba(16,185,129,.2);color:#6ee7b7;font-size:9.5px;font-weight:700">WAVE 246</span>';
h += '<button onclick="loadKpiDashboard()" style="margin-left:auto;padding:4px 10px;border-radius:8px;background:rgba(16,185,129,.15);color:#6ee7b7;border:1px solid rgba(16,185,129,.3);font-size:10px;cursor:pointer;font-weight:600">🔄 Refresh</button>';
h += '</div>';
h += '<div id="advisor-kpi-box" style="color:#94a3b8">Loading KPI charts…</div>';
h += '</div>';
// === WAVE 247 · Kanban Board (NEW) ===
h += '<div style="padding:16px;background:linear-gradient(135deg,rgba(168,85,247,.08),rgba(34,211,238,.05));border:1px solid rgba(168,85,247,.25);border-radius:10px;margin-bottom:16px">';
h += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:10px">';
h += '<div style="font-size:12px;color:#a855f7;text-transform:uppercase;font-weight:700">📋 Kanban Board · tasks par status</div>';
h += '<span style="padding:2px 6px;border-radius:8px;background:rgba(168,85,247,.2);color:#c4b5fd;font-size:9.5px;font-weight:700">WAVE 247</span>';
h += '<button onclick="loadKanban()" style="margin-left:auto;padding:4px 10px;border-radius:8px;background:rgba(168,85,247,.15);color:#c4b5fd;border:1px solid rgba(168,85,247,.3);font-size:10px;cursor:pointer;font-weight:600">🔄 Refresh</button>';
h += '</div>';
h += '<div id="advisor-kanban-box" style="color:#94a3b8">Loading kanban…</div>';
h += '</div>';
// === WAVE 248 · Pipeline Stages (NEW) ===
h += '<div style="padding:16px;background:linear-gradient(135deg,rgba(59,130,246,.1),rgba(16,185,129,.05));border:1px solid rgba(59,130,246,.25);border-radius:10px;margin-bottom:16px">';
h += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:10px">';
h += '<div style="font-size:12px;color:#60a5fa;text-transform:uppercase;font-weight:700">🔁 Pipeline Stages · deal flow</div>';
h += '<span style="padding:2px 6px;border-radius:8px;background:rgba(59,130,246,.2);color:#93c5fd;font-size:9.5px;font-weight:700">WAVE 248</span>';
h += '<button onclick="loadPipelineStages()" style="margin-left:auto;padding:4px 10px;border-radius:8px;background:rgba(59,130,246,.15);color:#bfdbfe;border:1px solid rgba(59,130,246,.3);font-size:10px;cursor:pointer;font-weight:600">🔄 Refresh</button>';
h += '</div>';
h += '<div id="advisor-pipeline-box" style="color:#94a3b8">Loading pipeline…</div>';
h += '</div>';
// === WAVE 249 · Activity Timeline (NEW) ===
h += '<div style="padding:16px;background:linear-gradient(135deg,rgba(251,191,36,.08),rgba(236,72,153,.05));border:1px solid rgba(251,191,36,.25);border-radius:10px;margin-bottom:16px">';
h += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:10px">';
h += '<div style="font-size:12px;color:#fbbf24;text-transform:uppercase;font-weight:700">🕒 Activity Timeline · unified feed</div>';
h += '<span style="padding:2px 6px;border-radius:8px;background:rgba(251,191,36,.2);color:#fde68a;font-size:9.5px;font-weight:700">WAVE 249</span>';
h += '<button onclick="loadActivityTimeline()" style="margin-left:auto;padding:4px 10px;border-radius:8px;background:rgba(251,191,36,.15);color:#fde68a;border:1px solid rgba(251,191,36,.3);font-size:10px;cursor:pointer;font-weight:600">🔄 Refresh</button>';
h += '</div>';
h += '<div id="advisor-timeline-box" style="color:#94a3b8">Loading timeline…</div>';
h += '</div>';
// === WAVE 250 · Task Search (NEW) ===
h += '<div style="padding:16px;background:linear-gradient(135deg,rgba(236,72,153,.08),rgba(34,211,238,.05));border:1px solid rgba(236,72,153,.25);border-radius:10px;margin-bottom:16px">';
h += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:10px">';
h += '<div style="font-size:12px;color:#ec4899;text-transform:uppercase;font-weight:700">🔎 Task Search · filter by text/status/MAD</div>';
h += '<span style="padding:2px 6px;border-radius:8px;background:rgba(236,72,153,.2);color:#fbcfe8;font-size:9.5px;font-weight:700">WAVE 250</span>';
h += '</div>';
h += '<div style="display:flex;gap:6px;margin-bottom:10px;flex-wrap:wrap">';
h += '<input type="text" id="search-q" placeholder="🔎 title or opportunity…" style="flex:1;min-width:180px;padding:7px 10px;border-radius:6px;background:rgba(0,0,0,.4);color:#e0e7ff;border:1px solid rgba(236,72,153,.3);font-size:12px" onkeydown="if(event.key===\'Enter\')runSearch()">';
h += '<select id="search-status" style="padding:7px 10px;border-radius:6px;background:rgba(0,0,0,.4);color:#e0e7ff;border:1px solid rgba(236,72,153,.3);font-size:12px"><option value="">All statuses</option><option value="proposed">proposed</option><option value="in_progress">in_progress</option><option value="done">done</option><option value="cancelled">cancelled</option><option value="blocked">blocked</option></select>';
h += '<input type="number" id="search-min-mad" placeholder="Min MAD" style="width:100px;padding:7px 10px;border-radius:6px;background:rgba(0,0,0,.4);color:#e0e7ff;border:1px solid rgba(236,72,153,.3);font-size:12px">';
h += '<button onclick="runSearch()" style="padding:7px 14px;border-radius:6px;background:rgba(236,72,153,.2);color:#fbcfe8;border:1px solid rgba(236,72,153,.4);font-size:11px;cursor:pointer;font-weight:700">Search</button>';
h += '</div>';
h += '<div id="advisor-search-results" style="color:#94a3b8;font-size:11px">Type a query + enter to search…</div>';
h += '</div>';
// === Matrix ===
h += '<div style="padding:16px;background:rgba(0,0,0,.35);border:1px solid rgba(168,85,247,.2);border-radius:10px;margin-bottom:16px">';
h += '<div style="font-size:12px;color:#a855f7;text-transform:uppercase;font-weight:700;margin-bottom:10px">📊 Matrice Effort × Impact (Eisenhower)</div>';
@@ -1049,6 +1104,190 @@ document.addEventListener('DOMContentLoaded',()=>{const s=document.createElement
__wevalToast('📥 CSV download started', '#10b981');
};
// =====================================================================
// WAVE 246-250: NEW UI functions consuming new endpoints
// =====================================================================
// WAVE 246: KPI Dashboard with inline SVG charts
window.loadKpiDashboard = function() {
var box = document.getElementById('advisor-kpi-box');
if (!box) return;
box.innerHTML = '<div style="color:#10b981;font-size:11px">🔍 Loading KPIs + rendering charts...</div>';
fetch('/api/social-signals-hub.php?action=kpi_dashboard&cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var html = '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px">';
// Top KPI cards
var leads = d.leads || {};
var tasks = d.tasks || {};
html += '<div style="padding:12px;background:rgba(0,0,0,.3);border-left:3px solid #10b981;border-radius:6px"><div style="font-size:10px;color:#6ee7b7;text-transform:uppercase;font-weight:700">Leads · MQL avg</div><div style="font-size:22px;font-weight:800;color:#10b981">'+(leads.n||0)+' · <span style="font-size:14px">M'+(leads.avg_mql||0)+'</span></div><div style="font-size:10px;color:#6ee7b7">'+(leads.sql_q||0)+' SQL qualified</div></div>';
html += '<div style="padding:12px;background:rgba(0,0,0,.3);border-left:3px solid #fbbf24;border-radius:6px"><div style="font-size:10px;color:#fde68a;text-transform:uppercase;font-weight:700">Tasks · Pipeline MAD</div><div style="font-size:22px;font-weight:800;color:#fbbf24">'+(tasks.n||0)+' · <span style="font-size:14px">'+Math.round((tasks.total_mad||0)/1000)+'K</span></div><div style="font-size:10px;color:#fde68a">'+Object.keys(d.tasks_by_status||{}).length+' statuses</div></div>';
html += '<div style="padding:12px;background:rgba(0,0,0,.3);border-left:3px solid #22d3ee;border-radius:6px"><div style="font-size:10px;color:#a5f3fc;text-transform:uppercase;font-weight:700">Countries</div><div style="font-size:22px;font-weight:800;color:#22d3ee">'+Object.keys(d.leads_by_country||{}).length+'</div><div style="font-size:10px;color:#a5f3fc">'+Object.keys(d.leads_by_country||{}).slice(0,3).join(' · ')+'</div></div>';
html += '<div style="padding:12px;background:rgba(0,0,0,.3);border-left:3px solid #a855f7;border-radius:6px"><div style="font-size:10px;color:#c4b5fd;text-transform:uppercase;font-weight:700">Industries</div><div style="font-size:22px;font-weight:800;color:#a855f7">'+Object.keys(d.industries||{}).length+'</div><div style="font-size:10px;color:#c4b5fd">'+Object.keys(d.industries||{}).slice(0,3).join(' · ')+'</div></div>';
html += '</div>';
// Inline SVG bar chart: leads_by_country
html += '<div style="margin-top:14px;padding:12px;background:rgba(0,0,0,.25);border-radius:6px"><div style="font-size:11px;color:#6ee7b7;font-weight:700;margin-bottom:8px">🗺 Leads par pays</div>';
var countries = Object.entries(d.leads_by_country||{}).sort(function(a,b){return b[1]-a[1];}).slice(0,8);
var maxC = Math.max.apply(null, countries.map(function(c){return c[1];}).concat([1]));
countries.forEach(function(c){
var pct = Math.round(c[1]/maxC*100);
html += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:3px;font-size:11px"><span style="width:40px;color:#94a3b8">'+c[0]+'</span><div style="flex:1;background:rgba(255,255,255,.04);height:16px;border-radius:3px;position:relative;overflow:hidden"><div style="position:absolute;left:0;top:0;bottom:0;width:'+pct+'%;background:linear-gradient(90deg,#10b981,#6ee7b7)"></div><span style="position:relative;padding-left:6px;color:#e0e7ff;font-weight:700;line-height:16px">'+c[1]+'</span></div></div>';
});
html += '</div>';
// Industries bar chart
html += '<div style="margin-top:10px;padding:12px;background:rgba(0,0,0,.25);border-radius:6px"><div style="font-size:11px;color:#c4b5fd;font-weight:700;margin-bottom:8px">🏭 Industries</div>';
var inds = Object.entries(d.industries||{}).sort(function(a,b){return b[1]-a[1];});
var maxI = Math.max.apply(null, inds.map(function(x){return x[1];}).concat([1]));
inds.forEach(function(it){
var pct = Math.round(it[1]/maxI*100);
html += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:3px;font-size:11px"><span style="width:80px;color:#94a3b8">'+it[0]+'</span><div style="flex:1;background:rgba(255,255,255,.04);height:16px;border-radius:3px;position:relative;overflow:hidden"><div style="position:absolute;left:0;top:0;bottom:0;width:'+pct+'%;background:linear-gradient(90deg,#a855f7,#c4b5fd)"></div><span style="position:relative;padding-left:6px;color:#e0e7ff;font-weight:700;line-height:16px">'+it[1]+'</span></div></div>';
});
html += '</div>';
// Tasks by status
html += '<div style="margin-top:10px;padding:12px;background:rgba(0,0,0,.25);border-radius:6px"><div style="font-size:11px;color:#fde68a;font-weight:700;margin-bottom:8px">📋 Tasks par status + MAD</div>';
Object.entries(d.tasks_by_status||{}).forEach(function(t){
var s = t[0]; var v = t[1];
var cs = {proposed:'#fbbf24',in_progress:'#22d3ee',done:'#10b981',cancelled:'#94a3b8',blocked:'#ef4444'}[s]||'#94a3b8';
html += '<div style="display:flex;align-items:center;gap:8px;margin-bottom:3px;font-size:11px"><span style="width:100px;color:'+cs+';font-weight:700">'+s+'</span><span style="color:#e0e7ff">'+v.count+' tasks · '+Math.round((v.mad||0)/1000)+'K MAD</span></div>';
});
html += '</div>';
box.innerHTML = html;
})
.catch(function(e){ box.innerHTML = '<div style="color:#ef4444">Err: '+e.message+'</div>'; });
};
// WAVE 247: Kanban board
window.loadKanban = function() {
var box = document.getElementById('advisor-kanban-box');
if (!box) return;
box.innerHTML = '<div style="color:#a855f7">Loading kanban…</div>';
fetch('/api/social-signals-hub.php?action=kanban&cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var html = '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:8px">';
var statuses = ['proposed','in_progress','done','cancelled','blocked'];
var cols = {proposed:'#fbbf24',in_progress:'#22d3ee',done:'#10b981',cancelled:'#94a3b8',blocked:'#ef4444'};
statuses.forEach(function(s){
var cards = (d.columns||{})[s] || [];
var mad = (d.mad_by_status||{})[s] || 0;
html += '<div style="padding:10px;background:rgba(0,0,0,.3);border-top:3px solid '+cols[s]+';border-radius:6px;min-height:100px">';
html += '<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;font-size:10px;font-weight:700;color:'+cols[s]+';text-transform:uppercase">'+s+' <span style="opacity:.8">'+cards.length+' · '+Math.round(mad/1000)+'K</span></div>';
cards.forEach(function(c){
html += '<div style="padding:6px;margin-bottom:4px;background:rgba(0,0,0,.35);border-left:2px solid '+cols[s]+';border-radius:3px">';
html += '<div style="font-size:10.5px;color:#e0e7ff;font-weight:600">#'+c.id+' '+(c.title||'?').slice(0,40)+'</div>';
if (c.lead_company) html += '<div style="font-size:9px;color:#22d3ee;margin-top:2px">📌 '+c.lead_company+' MQL '+(c.lead_mql||'?')+'</div>';
if (c.estimated_mad) html += '<div style="font-size:9px;color:#fbbf24;margin-top:2px">'+Math.round(c.estimated_mad/1000)+'K MAD</div>';
html += '</div>';
});
if (!cards.length) html += '<div style="color:#64748b;font-size:10px;text-align:center;padding:8px">empty</div>';
html += '</div>';
});
html += '</div>';
box.innerHTML = html;
})
.catch(function(e){ box.innerHTML = '<div style="color:#ef4444">Err: '+e.message+'</div>'; });
};
// WAVE 248: Pipeline stages
window.loadPipelineStages = function() {
var box = document.getElementById('advisor-pipeline-box');
if (!box) return;
box.innerHTML = '<div style="color:#60a5fa">Loading pipeline…</div>';
fetch('/api/social-signals-hub.php?action=pipeline_stages&cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var html = '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:6px">';
var totalMad = Object.values(d.stages||{}).reduce(function(s,x){return s+(x.mad||0);},0);
Object.entries(d.stages||{}).forEach(function(e){
var s = e[0], v = e[1];
var pct = totalMad ? Math.round(v.mad/totalMad*100) : 0;
html += '<div style="padding:10px;background:rgba(0,0,0,.3);border-bottom:3px solid '+v.color+';border-radius:6px">';
html += '<div style="font-size:10px;color:'+v.color+';font-weight:700;text-transform:uppercase">'+v.name+'</div>';
html += '<div style="font-size:18px;color:#e0e7ff;font-weight:800">'+v.count+'</div>';
html += '<div style="font-size:10px;color:#94a3b8">'+Math.round(v.mad/1000)+'K MAD ('+pct+'%)</div>';
html += '<div style="height:4px;margin-top:4px;background:rgba(255,255,255,.05);border-radius:2px;overflow:hidden"><div style="height:100%;width:'+pct+'%;background:'+v.color+'"></div></div>';
html += '</div>';
});
html += '</div>';
box.innerHTML = html;
})
.catch(function(e){ box.innerHTML = '<div style="color:#ef4444">Err: '+e.message+'</div>'; });
};
// WAVE 249: Activity timeline
window.loadActivityTimeline = function() {
var box = document.getElementById('advisor-timeline-box');
if (!box) return;
box.innerHTML = '<div style="color:#fbbf24">Loading timeline…</div>';
fetch('/api/social-signals-hub.php?action=activity_timeline&cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var html = '<div style="font-size:10px;color:#fde68a;margin-bottom:8px">'+(d.count||0)+' events</div>';
(d.events||[]).forEach(function(e){
var icon = e.type === 'task_created' ? '📋' : (e.type === 'lead_created' ? '👤' : '⚡');
var color = e.type === 'task_created' ? '#22d3ee' : '#10b981';
html += '<div style="padding:8px 10px;margin-bottom:4px;background:rgba(0,0,0,.25);border-left:3px solid '+color+';border-radius:4px">';
html += '<div style="display:flex;align-items:center;gap:6px"><span style="font-size:13px">'+icon+'</span><b style="font-size:11px;color:#e0e7ff">'+(e.title||'?').slice(0,60)+'</b><span style="margin-left:auto;font-size:9px;color:#64748b">'+(e.ts||'').slice(5,16)+'</span></div>';
var meta = e.meta || {};
var metaStr = Object.entries(meta).map(function(x){return x[0]+':'+x[1];}).join(' · ');
if (metaStr) html += '<div style="font-size:9px;color:#94a3b8;margin-top:3px">'+metaStr+'</div>';
html += '</div>';
});
box.innerHTML = html;
})
.catch(function(e){ box.innerHTML = '<div style="color:#ef4444">Err: '+e.message+'</div>'; });
};
// WAVE 250: Search tasks
window.runSearch = function() {
var box = document.getElementById('advisor-search-results');
if (!box) return;
var q = document.getElementById('search-q').value;
var st = document.getElementById('search-status').value;
var mm = document.getElementById('search-min-mad').value;
var url = '/api/social-signals-hub.php?action=search_tasks';
if (q) url += '&q=' + encodeURIComponent(q);
if (st) url += '&status=' + encodeURIComponent(st);
if (mm) url += '&min_mad=' + encodeURIComponent(mm);
url += '&cb=' + Date.now();
box.innerHTML = '<div style="color:#ec4899">Searching…</div>';
fetch(url)
.then(function(r){return r.json();})
.then(function(d){
if (!d.ok || !d.tasks.length) { box.innerHTML = '<div style="color:#94a3b8">No results · '+(d.count||0)+'</div>'; return; }
var html = '<div style="font-size:11px;color:#fbcfe8;margin-bottom:6px">✓ '+d.count+' results for "'+(d.query||'')+'"</div>';
d.tasks.forEach(function(t){
var cs = {proposed:'#fbbf24',in_progress:'#22d3ee',done:'#10b981',cancelled:'#94a3b8',blocked:'#ef4444'}[t.status]||'#94a3b8';
html += '<div style="padding:6px 8px;margin-bottom:3px;background:rgba(0,0,0,.25);border-left:2px solid '+cs+';border-radius:4px">';
html += '<div style="display:flex;align-items:center;gap:6px"><b style="font-size:11px;color:#e0e7ff">#'+t.id+' '+(t.title||'').slice(0,60)+'</b><span style="padding:1px 5px;border-radius:4px;background:'+cs+'22;color:'+cs+';font-size:9px">'+t.status+'</span>';
if (t.estimated_mad) html += '<span style="margin-left:auto;color:#fbbf24;font-size:10px;font-weight:700">'+Math.round(t.estimated_mad/1000)+'K</span>';
html += '</div>';
if (t.lead_company) html += '<div style="font-size:9px;color:#22d3ee;margin-top:2px">📌 '+t.lead_company+' MQL '+(t.lead_mql||'?')+'</div>';
html += '</div>';
});
box.innerHTML = html;
})
.catch(function(e){ box.innerHTML = '<div style="color:#ef4444">Err: '+e.message+'</div>'; });
};
// Auto-load all new sections when advisor tab opens
var origBuildSocialHub = buildSocialHub;
// Already wraps in wave 230 - extend further
setTimeout(function(){
if (document.getElementById('advisor-kpi-box')) {
loadKpiDashboard();
loadKanban();
loadPipelineStages();
loadActivityTimeline();
}
}, 1500);
window.refreshSocialHub = refreshSocialHub;
window.renderAdvisorV2 = renderAdvisor;