Files
html/wevia-meetings.html
opus d5edaa769c
Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled
auto-sync via WEVIA git_sync_all intent 2026-04-21T14:56:43+02:00
2026-04-21 14:56:43 +02:00

332 lines
23 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WEVIA Meetings — Command Center</title>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;500;700;800&display=swap" rel="stylesheet">
<style>
*{margin:0;padding:0;box-sizing:border-box}
:root{--bg:#060a14;--card:#0d1525;--border:#1a2744;--accent:#06d6a0;--warn:#f59e0b;--danger:#ef4444;--opus:#8b5cf6;--text:#e2e8f0;--dim:#4a5568;--glass:rgba(13,21,37,0.85)}
body{font-family:'Plus Jakarta Sans',sans-serif;background:var(--bg);color:var(--text);min-height:100vh}
.header{padding:24px 32px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--border);background:linear-gradient(135deg,#060a14,#0d1a30)}
.header h1{font-size:1.4rem;font-weight:800;background:linear-gradient(135deg,var(--accent),#3b82f6);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.header .meta{color:var(--dim);font-size:0.78rem}
.live-dot{width:8px;height:8px;border-radius:50%;background:var(--accent);display:inline-block;animation:pulse 2s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.3}}
.tabs{display:flex;gap:6px;padding:16px 32px;border-bottom:1px solid var(--border);flex-wrap:wrap}
.tab{padding:7px 18px;border-radius:16px;border:1px solid var(--border);background:transparent;color:var(--dim);cursor:pointer;font-size:0.8rem;font-family:inherit;transition:all .25s}
.tab.active{background:var(--accent);color:#000;border-color:var(--accent);font-weight:700}
.tab:hover{border-color:var(--accent)}
.main{padding:24px 32px;max-width:1400px;margin:0 auto}
.section{display:none}.section.active{display:block}
.grid-5{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:14px;margin:16px 0}
.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin:16px 0}
@media(max-width:800px){.grid-2{grid-template-columns:1fr}}
.card{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:18px;position:relative;transition:transform .2s,box-shadow .2s}
.card:hover{transform:translateY(-2px);box-shadow:0 8px 24px rgba(6,214,160,.08)}
.card h3{font-size:0.95rem;font-weight:700;margin-bottom:10px;display:flex;align-items:center;gap:8px}
.card .status{position:absolute;top:14px;right:14px;font-size:0.65rem;padding:2px 8px;border-radius:8px;font-weight:700}
.status.up{background:#06d6a020;color:var(--accent)}.status.down{background:#ef444420;color:var(--danger)}.status.warn{background:#f59e0b20;color:var(--warn)}
.squad-card{border-left:3px solid var(--accent)}
.squad-card.infra{border-left-color:#3b82f6}.squad-card.dev{border-left-color:var(--accent)}.squad-card.security{border-left-color:var(--danger)}.squad-card.business{border-left-color:var(--warn)}.squad-card.ia{border-left-color:var(--opus)}
.participant{display:flex;align-items:center;gap:10px;padding:8px 0;border-bottom:1px solid var(--border)}
.participant:last-child{border:none}
.participant .avatar{width:36px;height:36px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:1.1rem;flex-shrink:0}
.participant .info{flex:1}.participant .name{font-weight:700;font-size:0.85rem}.participant .role{color:var(--dim);font-size:0.72rem}
.btn{padding:8px 20px;border-radius:8px;border:none;font-family:inherit;font-size:0.82rem;font-weight:700;cursor:pointer;transition:all .2s}
.btn-primary{background:var(--accent);color:#000}.btn-primary:hover{background:#05c795}
.btn-secondary{background:var(--border);color:var(--text)}.btn-secondary:hover{background:#243356}
.btn-danger{background:var(--danger);color:#fff}
.actions{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap}
.timeline{margin:16px 0}.timeline-item{display:flex;gap:12px;padding:10px 0;border-left:2px solid var(--border);margin-left:8px;padding-left:16px;position:relative}
.timeline-item::before{content:'';width:10px;height:10px;border-radius:50%;background:var(--accent);position:absolute;left:-6px;top:14px}
.timeline-item.warn::before{background:var(--warn)}.timeline-item.danger::before{background:var(--danger)}
.timeline-item .time{color:var(--dim);font-size:0.72rem;min-width:60px}.timeline-item .content{font-size:0.82rem;line-height:1.5}
.synthesis{background:#0a1020;border:1px solid var(--border);border-radius:8px;padding:14px;margin:10px 0;font-size:0.82rem;line-height:1.6;color:var(--dim)}
.kpi{text-align:center;padding:16px}.kpi .value{font-size:1.8rem;font-weight:800;color:var(--accent)}.kpi .label{font-size:0.72rem;color:var(--dim);margin-top:4px}
.schedule-row{display:flex;align-items:center;gap:16px;padding:10px 0;border-bottom:1px solid var(--border)}
.schedule-row .time{font-weight:700;font-size:0.9rem;min-width:60px;color:var(--accent)}
.schedule-row .type{font-size:0.72rem;padding:2px 8px;border-radius:6px;font-weight:700}
.type-daily{background:#3b82f620;color:#3b82f6}.type-weekly{background:#8b5cf620;color:var(--opus)}.type-strategy{background:#06d6a020;color:var(--accent)}
#loading{display:none;text-align:center;padding:40px;color:var(--dim)}
#loading.show{display:block}
.empty{text-align:center;padding:40px;color:var(--dim);font-size:0.85rem}
</style>
</head>
<body>
<div class="header">
<div>
<h1>WEVIA Meetings — Command Center</h1>
<div class="meta"><span class="live-dot"></span> 5 squads · 8 agents · 32 crons · 4 meetings/semaine</div>
</div>
<div style="display:flex;gap:8px">
<button class="btn btn-primary" onclick="runDaily()">▶ Lancer Daily</button>
<button class="btn btn-secondary" onclick="runWeekly()">📊 Weekly</button>
<button class="btn btn-secondary" onclick="runStrategy()">🏛️ Stratégie</button>
</div>
</div>
<div class="tabs">
<div class="tab active" onclick="show('overview')">Vue d'ensemble</div>
<div class="tab" onclick="show('squads')">Squads</div>
<div class="tab" onclick="show('strategy')">Stratégie</div>
<div class="tab" onclick="show('dispatch')">Actions</div>
<div class="tab" onclick="show('schedule')">Planning</div>
<div class="tab" onclick="show('history')">Historique</div>
</div>
<div class="main">
<div id="loading"><div style="font-size:2rem;margin-bottom:8px"></div>Meeting en cours...</div>
<!-- OVERVIEW -->
<div id="overview" class="section active">
<div class="grid-5">
<div class="card"><div class="kpi"><div class="value" id="kpi-squads">5</div><div class="label">Squads</div></div></div>
<div class="card"><div class="kpi"><div class="value" id="kpi-agents">8</div><div class="label">Agents autonomes</div></div></div>
<div class="card"><div class="kpi"><div class="value" id="kpi-crons">32</div><div class="label">Crons actifs</div></div></div>
<div class="card"><div class="kpi"><div class="value" id="kpi-meetings">4</div><div class="label">Meetings/semaine</div></div></div>
<div class="card"><div class="kpi"><div class="value" id="kpi-routes">313</div><div class="label">Routes chatbot</div></div></div>
</div>
<div class="grid-2">
<div class="card">
<h3>📋 Dernier Daily</h3>
<div id="last-daily" class="synthesis">Aucun daily exécuté encore. Cliquez "Lancer Daily" ou attendez 09h00.</div>
</div>
<div class="card">
<h3>🏛️ Dernière Stratégie</h3>
<div id="last-strategy" class="synthesis">Aucune stratégie exécutée. Prochain: vendredi 16h00.</div>
</div>
</div>
</div>
<!-- SQUADS -->
<div id="squads" class="section">
<div class="grid-5">
<div class="card squad-card infra" onclick="runSquad('infra')">
<h3>🏗️ INFRA</h3>
<div class="participant"><div class="avatar" style="background:#3b82f620">🧠</div><div class="info"><div class="name">CORTEX</div><div class="role">Lead · 13 checks */4h</div></div></div>
<div class="participant"><div class="avatar" style="background:#3b82f620">🔍</div><div class="info"><div class="name">Gap Detector</div><div class="role">Cross-ref · */6h</div></div></div>
<div class="participant"><div class="avatar" style="background:#3b82f620">🤖</div><div class="info"><div class="name">Agent Chef</div><div class="role">Auto-heal · */10</div></div></div>
<div class="participant"><div class="avatar" style="background:#3b82f620"></div><div class="info"><div class="name">Proactive</div><div class="role">Disk/RAM · */5</div></div></div>
<div class="actions"><button class="btn btn-primary" onclick="runSquad('infra')">▶ Run</button></div>
</div>
<div class="card squad-card dev" onclick="runSquad('dev')">
<h3>💻 DEV</h3>
<div class="participant"><div class="avatar" style="background:#06d6a020"></div><div class="info"><div class="name">NonReg Agent</div><div class="role">Auto-fix · */15</div></div></div>
<div class="participant"><div class="avatar" style="background:#06d6a020">📸</div><div class="info"><div class="name">L99 Visual</div><div class="role">Screenshots · Playwright</div></div></div>
<div class="participant"><div class="avatar" style="background:#06d6a020">🕵️</div><div class="info"><div class="name">L99 Dark</div><div class="role">Security · */8h</div></div></div>
<div class="participant"><div class="avatar" style="background:#06d6a020">🧬</div><div class="info"><div class="name">Evolution</div><div class="role">Innovation · */6h</div></div></div>
<div class="actions"><button class="btn btn-primary" onclick="runSquad('dev')">▶ Run</button></div>
</div>
<div class="card squad-card security">
<h3>🔒 SECURITY</h3>
<div class="participant"><div class="avatar" style="background:#ef444420">🛡️</div><div class="info"><div class="name">Dark Tools</div><div class="role">Lead · Nuclei+Gitleaks</div></div></div>
<div class="participant"><div class="avatar" style="background:#ef444420">🚫</div><div class="info"><div class="name">CrowdSec</div><div class="role">Ban IP · active</div></div></div>
<div class="participant"><div class="avatar" style="background:#10b98120">🔐</div><div class="info"><div class="name">PHP Auth</div><div class="role">SSO Souverain · Cookie HMAC 30j</div></div></div>
<div class="actions"><button class="btn btn-primary" onclick="runSquad('security')">▶ Run</button></div>
</div>
<div class="card squad-card business">
<h3>💼 BUSINESS</h3>
<div class="participant"><div class="avatar" style="background:#f59e0b20">📎</div><div class="info"><div class="name">Paperclip CEO</div><div class="role">Lead · 716 agents</div></div></div>
<div class="participant"><div class="avatar" style="background:#f59e0b20">🏢</div><div class="info"><div class="name">Enterprise</div><div class="role">10 modules</div></div></div>
<div class="participant"><div class="avatar" style="background:#f59e0b20">💊</div><div class="info"><div class="name">Ethica</div><div class="role">157K HCPs</div></div></div>
<div class="actions"><button class="btn btn-primary" onclick="runSquad('business')">▶ Run</button></div>
</div>
<div class="card squad-card ia">
<h3>🧠 IA</h3>
<div class="participant"><div class="avatar" style="background:#8b5cf620">🦙</div><div class="info"><div class="name">Ollama</div><div class="role">9 modèles local</div></div></div>
<div class="participant"><div class="avatar" style="background:#8b5cf620">📐</div><div class="info"><div class="name">Qdrant</div><div class="role">14,884 vectors</div></div></div>
<div class="participant"><div class="avatar" style="background:#8b5cf620">🔬</div><div class="info"><div class="name">OSS Discovery</div><div class="role">690 repos · 585 skills</div></div></div>
<div class="actions"><button class="btn btn-primary" onclick="runSquad('ia')">▶ Run</button></div>
</div>
</div>
<div class="card" style="margin-top:16px"><h3>💬 Dernière synthèse squad</h3><div id="squad-result" class="synthesis">Sélectionnez un squad et cliquez Run.</div></div>
</div>
<!-- STRATEGY -->
<div id="strategy" class="section">
<div class="card">
<h3>🏛️ Weekly Strategy — Sommet</h3>
<div class="grid-2" style="margin:12px 0">
<div class="participant"><div class="avatar" style="background:#06d6a030;font-size:1.3rem">🧠</div><div class="info"><div class="name">WEVIA Master</div><div class="role">313 routes · 585 skills · 795 wiki</div></div></div>
<div class="participant"><div class="avatar" style="background:#8b5cf630;font-size:1.3rem">♟️</div><div class="info"><div class="name">Claude Opus</div><div class="role">Architecte en chef · Contrôle · Fine-tune</div></div></div>
<div class="participant"><div class="avatar" style="background:#3b82f630;font-size:1.3rem">📧</div><div class="info"><div class="name">WEVIA Life</div><div class="role">2079 emails · 598 opps · 407 risks</div></div></div>
<div class="participant"><div class="avatar" style="background:#10b98130;font-size:1.3rem">⚔️</div><div class="info"><div class="name">Blade IA</div><div class="role">34 caps · GLM-5 · Sentinel v2.4</div></div></div>
<div class="participant"><div class="avatar" style="background:#f59e0b30;font-size:1.3rem">🐟</div><div class="info"><div class="name">MiroFish</div><div class="role">Collab IA · :3050 + :5001</div></div></div>
<div class="participant"><div class="avatar" style="background:#ef444430;font-size:1.3rem">👑</div><div class="info"><div class="name">Agent Maître</div><div class="role">8 agents · 32 crons · Auto-heal</div></div></div>
</div>
<div class="actions"><button class="btn btn-primary" onclick="runStrategy()">🏛️ Lancer Stratégie</button></div>
<div id="strategy-result" class="synthesis" style="margin-top:12px">Prochain vendredi 16h00. Ou lancez manuellement.</div>
</div>
</div>
<!-- DISPATCH -->
<div id="dispatch" class="section">
<div class="card">
<h3>📡 Dispatch Actions → Agents</h3>
<div class="timeline" id="dispatch-list">
<div class="timeline-item"><div class="time">*/10</div><div class="content"><strong>Agent Chef</strong> — Restart services DOWN, heal infra</div></div>
<div class="timeline-item"><div class="time">*/6h</div><div class="content"><strong>Agent Evolution</strong> — Développer nouvelles features (Cerebras 235B)</div></div>
<div class="timeline-item"><div class="time">*/2h</div><div class="content"><strong>Agent Scanner</strong> — Enrichir wiki (12 sections)</div></div>
<div class="timeline-item"><div class="time">*/12h</div><div class="content"><strong>Agent Factory</strong> — Créer agents manquants</div></div>
<div class="timeline-item"><div class="time">*/15</div><div class="content"><strong>NonReg Agent</strong> — Détecter régressions + auto-fix</div></div>
<div class="timeline-item"><div class="time">*/4h</div><div class="content"><strong>CORTEX</strong> — Rapport global 13 checks → Mattermost</div></div>
<div class="timeline-item"><div class="time">*/6h</div><div class="content"><strong>Gap Detector</strong> — Vérifier couverture /opt/ vs fast.php</div></div>
<div class="timeline-item"><div class="time">*/6h</div><div class="content"><strong>RND Pipeline</strong> — Chercher innovations GitHub → wire → test</div></div>
</div>
</div>
</div>
<!-- SCHEDULE -->
<div id="schedule" class="section">
<div class="card">
<h3>📅 Planning Meetings</h3>
<div class="schedule-row"><div class="time">09:00</div><span class="type type-daily">DAILY</span><div style="flex:1;font-size:.85rem">Squad meetings AM — 5 squads en parallèle</div></div>
<div class="schedule-row"><div class="time">14:00</div><span class="type type-daily">DAILY</span><div style="flex:1;font-size:.85rem">Squad meetings PM — suivi + résolutions</div></div>
<div class="schedule-row"><div class="time">Lun 10h</div><span class="type type-weekly">WEEKLY</span><div style="flex:1;font-size:.85rem">Comité — Agent Chef + 5 leads de squad</div></div>
<div class="schedule-row"><div class="time">Ven 16h</div><span class="type type-strategy">STRATEGY</span><div style="flex:1;font-size:.85rem">Sommet — WEVIA + Opus + Life + Blade + MiroFish + Maître</div></div>
</div>
</div>
<!-- HISTORY -->
<div id="history" class="section">
<div class="card"><h3>📜 Historique Meetings</h3><div id="history-list" class="empty">Chargement...</div></div>
</div>
</div>
<script>
const API = '/api/wevia-meeting.php';
function show(id) {
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
document.querySelectorAll('.section').forEach(s => s.classList.remove('active'));
document.getElementById(id).classList.add('active');
event.target.classList.add('active');
if (id === 'history') loadHistory();
}
async function apiCall(action, params = '') {
document.getElementById('loading').classList.add('show');
try {
const r = await fetch(`${API}?action=${action}${params}`);
/* HTML_GUARD_V2_BATCH */ const _t_d=await r.text(); let d=null; {var _q=(_t_d||"").trim();if(_q.startsWith("<!DOCTYPE")||_q.startsWith("<html")){d={error:"[HTTP "+(r.status||"?")+"] Backend indisponible",isHtmlError:true};}else{try{d=JSON.parse(_q)}catch(e){d={error:"[JSON] "+e.message}}}}
document.getElementById('loading').classList.remove('show');
return d;
} catch (e) {
document.getElementById('loading').classList.remove('show');
return { error: e.message };
}
}
async function runDaily() {
const d = await apiCall('daily');
if (d.chef_synthesis) {
document.getElementById('last-daily').textContent = d.chef_synthesis;
} else {
document.getElementById('last-daily').textContent = JSON.stringify(d, null, 2);
}
show('overview');
}
async function runWeekly() {
const d = await apiCall('weekly');
if (d.chef_synthesis) alert('Weekly terminé: ' + d.chef_synthesis.substring(0, 200));
}
async function runStrategy() {
const d = await apiCall('weekly');
document.getElementById('strategy-result').textContent = d.chef_synthesis || JSON.stringify(d);
show('strategy');
}
async function runSquad(name) {
const d = await apiCall('squad', `&squad=${name}`);
document.getElementById('squad-result').textContent = d.synthesis || JSON.stringify(d, null, 2);
}
async function loadHistory() {
const d = await apiCall('history');
const el = document.getElementById('history-list');
if (d.meetings && d.meetings.length) {
el.innerHTML = d.meetings.map(m => `<div class="schedule-row"><div class="time">${m.date}</div><div style="flex:1;font-size:.82rem">${m.file} (${Math.round(m.size/1024)}KB)</div></div>`).join('');
} else {
el.innerHTML = '<div class="empty">Aucun meeting archivé. Lancez un daily ou weekly.</div>';
}
}
// Auto-load last daily
fetch('/api/meeting-daily-latest.json').then(r=>r.text().then(t=>{/* HTML_GUARD_V2_BATCH */var q=(t||"").trim();if(q.startsWith("<!DOCTYPE")||q.startsWith("<html")){return{error:"[HTTP "+r.status+"]",isHtmlError:true}}try{return JSON.parse(q)}catch(e){return{error:"JSON "+e.message}}})).then(d=>{
if(d.chef_synthesis) document.getElementById('last-daily').textContent=d.chef_synthesis;
}).catch(()=>{});
fetch('/api/meeting-weekly-latest.json').then(r=>r.text().then(t=>{/* HTML_GUARD_V2_BATCH */var q=(t||"").trim();if(q.startsWith("<!DOCTYPE")||q.startsWith("<html")){return{error:"[HTTP "+r.status+"]",isHtmlError:true}}try{return JSON.parse(q)}catch(e){return{error:"JSON "+e.message}}})).then(d=>{
if(d.chef_synthesis) document.getElementById('last-strategy').textContent=d.chef_synthesis;
}).catch(()=>{});
</script>
<!-- CARTO_REMOVED -->
<!-- === OPUS UNIVERSAL DRILL-DOWN v1 19avr — append-only, doctrine #14 === -->
<script>
(function(){
if (window.__opusUniversalDrill) return; window.__opusUniversalDrill = true;
var d = document;
var m = d.createElement('div');
m.id = 'opus-udrill';
m.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.82);backdrop-filter:blur(6px);display:none;align-items:center;justify-content:center;z-index:99995;padding:20px;cursor:pointer';
var inner = d.createElement('div');
inner.id = 'opus-udrill-in';
inner.style.cssText = 'max-width:900px;width:100%;max-height:90vh;overflow:auto;background:#0b0d15;border:1px solid rgba(99,102,241,0.35);border-radius:14px;padding:28px;cursor:default;box-shadow:0 20px 60px rgba(0,0,0,0.6);color:#e2e8f0;font:14px/1.55 Inter,system-ui,sans-serif';
inner.addEventListener('click', function(e){ e.stopPropagation(); });
m.appendChild(inner);
m.addEventListener('click', function(){ m.style.display='none'; });
d.addEventListener('keydown', function(e){ if(e.key==='Escape') m.style.display='none'; });
(d.body || d.documentElement).appendChild(m);
function openCard(card) {
// Clone card content + show close btn + increase font-size
var html = '<div style="display:flex;justify-content:flex-end;margin-bottom:14px"><button id="opus-udrill-close" style="padding:6px 14px;background:#171b2a;border:1px solid rgba(99,102,241,0.25);color:#e2e8f0;border-radius:8px;cursor:pointer;font-size:12px">✕ Fermer (Esc)</button></div>';
html += '<div style="transform-origin:top left;font-size:1.05em">' + card.outerHTML + '</div>';
inner.innerHTML = html;
d.getElementById('opus-udrill-close').onclick = function(){ m.style.display='none'; };
m.style.display = 'flex';
}
function wire(root) {
var sels = '.card,[class*="card"],.kpi,[class*="kpi"],.stat,[class*="stat"],.tile,[class*="tile"],.metric,[class*="metric"],.widget,[class*="widget"]';
var cards = root.querySelectorAll(sels);
for (var i = 0; i < cards.length; i++) {
var c = cards[i];
if (c.__opusWired) continue;
if (c.closest('button, a, input, select, textarea, #opus-udrill')) continue;
var r = c.getBoundingClientRect();
if (r.width < 60 || r.height < 40) continue;
c.__opusWired = true;
c.style.cursor = 'pointer';
c.setAttribute('role','button');
c.setAttribute('tabindex','0');
c.addEventListener('click', function(ev){
// If a more-specific drill is already active (e.g. pp-card custom), let it handle
if (ev.target.closest('[data-pp-id]') && window.__opusDrillInit) return;
if (ev.target.closest('a,button,input,select')) return;
ev.preventDefault(); ev.stopPropagation();
openCard(this);
});
c.addEventListener('keydown', function(ev){ if(ev.key==='Enter'||ev.key===' '){ev.preventDefault();openCard(this);} });
}
}
// Initial + mutation observer
var initRun = function(){ wire(d.body || d.documentElement); };
if (d.readyState === 'loading') d.addEventListener('DOMContentLoaded', initRun);
else initRun();
var mo = new MutationObserver(function(muts){
var newCard = false;
for (var i=0;i<muts.length;i++) if (muts[i].addedNodes.length) { newCard = true; break; }
if (newCard) initRun();
});
mo.observe(d.body || d.documentElement, {childList:true, subtree:true});
})();
</script>
<!-- === OPUS UNIVERSAL DRILL-DOWN END === -->
<script src="/api/archi-meta-badge.js" defer></script>
<script src="/api/a11y-auto-enhancer.js" defer></script>
<!-- WTP_UDOCK_V1 (Opus 21-avr t33b5) --><script src="/wtp-unified-dock.js" defer></script>
<script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
</body>
</html>