Files
weval-consulting/wevia-meetings.html

261 lines
18 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:#ef444420">🔐</div><div class="info"><div class="name">Authentik</div><div class="role">SSO · 4 containers</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">126K 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}`);
const d = await r.json();
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.json()).then(d=>{
if(d.chef_synthesis) document.getElementById('last-daily').textContent=d.chef_synthesis;
}).catch(()=>{});
fetch('/api/meeting-weekly-latest.json').then(r=>r.json()).then(d=>{
if(d.chef_synthesis) document.getElementById('last-strategy').textContent=d.chef_synthesis;
}).catch(()=>{});
</script>
</body>
</html>