Files
html/oss-discovery-v77.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

326 lines
18 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVAL — OSS Discovery V77 Drill-down</title>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600;700&family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<style>
*{margin:0;padding:0;box-sizing:border-box}
:root{
--bg:#0a0e17;--bg2:#111827;--bg3:#1a2234;--bg4:#243049;
--bd:#1e293b;--bd2:#334155;--wh:#f1f5f9;--mu:#64748b;--mu2:#94a3b8;
--ac:#f59e0b;--ac2:#fbbf24;--gn:#22c55e;--gn2:#4ade80;
--bl:#3b82f6;--bl2:#60a5fa;--cy:#22d3ee;--rd:#ef4444;--or:#f97316;
--pk:#ec4899;--vi:#8b5cf6;
--r1:6px;--r2:10px;--r3:14px;
--font:'Plus Jakarta Sans',sans-serif;--mono:'JetBrains Mono',monospace;
}
body{background:var(--bg);color:var(--wh);font-family:var(--font);overflow-x:hidden}
a{color:var(--cy);text-decoration:none}a:hover{text-decoration:underline}
.hdr{background:linear-gradient(135deg,#0f172a 0%,#1a1040 50%,#0f172a 100%);border-bottom:1px solid var(--bd);padding:20px 32px;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:16px}
.hdr-left{display:flex;align-items:center;gap:16px}
.hdr-logo{width:42px;height:42px;background:linear-gradient(135deg,var(--ac),var(--or));border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:20px;font-weight:800;color:#000}
.hdr h1{font-size:22px;font-weight:800;letter-spacing:-.5px}
.hdr h1 span{color:var(--ac);font-weight:900}
.hdr-sub{font-size:11px;color:var(--mu);margin-top:2px;font-family:var(--mono)}
.btn{padding:8px 18px;border-radius:var(--r1);border:1px solid var(--bd2);background:var(--bg3);color:var(--wh);font-size:12px;font-weight:600;cursor:pointer;transition:.2s;font-family:var(--font);display:inline-flex;align-items:center;gap:6px;text-decoration:none}
.btn:hover{background:var(--bg4);border-color:var(--ac);text-decoration:none}
.btn-ac{background:linear-gradient(135deg,var(--ac),var(--or));color:#000;border:none}
.main{max-width:1560px;margin:0 auto;padding:24px}
/* KPI stats row */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;margin-bottom:24px}
.stat{background:var(--bg2);border:1px solid var(--bd);border-radius:var(--r2);padding:18px 20px;position:relative;overflow:hidden;transition:.3s;cursor:pointer}
.stat:hover{border-color:var(--ac);transform:translateY(-3px);box-shadow:0 8px 24px rgba(245,158,11,.15)}
.stat::after{content:'';position:absolute;top:0;left:0;right:0;height:3px}
.stat.s-ac::after{background:linear-gradient(90deg,var(--ac),var(--or))}
.stat.s-gn::after{background:linear-gradient(90deg,var(--gn),var(--cy))}
.stat.s-bl::after{background:linear-gradient(90deg,var(--bl),var(--vi))}
.stat.s-pk::after{background:linear-gradient(90deg,var(--pk),var(--vi))}
.stat.s-cy::after{background:linear-gradient(90deg,var(--cy),var(--bl))}
.st-l{font-size:10px;color:var(--mu);text-transform:uppercase;letter-spacing:.7px;font-weight:700}
.st-v{font-size:28px;font-weight:800;margin:6px 0;font-family:var(--mono);line-height:1}
.st-s{font-size:10px;color:var(--mu2);margin-top:4px}
/* Categories drill-down */
.section-title{font-size:16px;font-weight:800;margin:28px 0 14px;display:flex;align-items:center;gap:10px;color:var(--ac2)}
.section-title::before{content:'';display:inline-block;width:4px;height:18px;background:linear-gradient(180deg,var(--ac),var(--or));border-radius:2px}
.cats{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:14px}
.cat{background:var(--bg2);border:1px solid var(--bd);border-radius:var(--r2);padding:16px 18px;cursor:pointer;transition:.25s;position:relative;overflow:hidden}
.cat:hover{transform:translateY(-2px);box-shadow:0 8px 20px rgba(0,0,0,.4)}
.cat-strip{position:absolute;top:0;left:0;right:0;height:3px}
.cat-head{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.cat-emoji{font-size:22px}
.cat-name{font-size:14px;font-weight:700}
.cat-count{margin-left:auto;font-family:var(--mono);font-weight:700;font-size:13px}
.cat-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:10px;padding-top:10px;border-top:1px solid var(--bd)}
.cat-stat{font-size:10px;color:var(--mu2)}
.cat-stat b{display:block;font-family:var(--mono);font-size:14px;color:var(--wh);margin-bottom:2px}
.cat-cov{margin-top:10px}
.cat-cov-bar{height:6px;background:var(--bg);border-radius:3px;overflow:hidden}
.cat-cov-fill{height:100%;background:linear-gradient(90deg,var(--gn),var(--cy));transition:width .8s ease}
.cat-cov-label{display:flex;justify-content:space-between;font-size:10px;color:var(--mu);margin-top:4px}
/* Tool drill-down detail */
.drill{margin-top:14px;padding-top:14px;border-top:1px dashed var(--bd);display:none}
.cat.open .drill{display:block}
.tool-row{display:flex;align-items:center;gap:10px;padding:6px 8px;border-radius:var(--r1);transition:.2s;font-size:11px}
.tool-row:hover{background:var(--bg3)}
.tool-name{flex:1;font-family:var(--mono);font-weight:600}
.tool-badges{display:flex;gap:4px;flex-shrink:0}
.tool-badge{font-size:9px;padding:2px 6px;border-radius:10px;font-family:var(--mono);font-weight:600}
.tb-files{background:rgba(59,130,246,.15);color:var(--bl2)}
.tb-docker{background:rgba(34,211,238,.15);color:var(--cy)}
.tb-readme{background:rgba(34,197,94,.15);color:var(--gn2)}
.tb-wired{background:rgba(245,158,11,.15);color:var(--ac2)}
/* Skills explorer */
.explorer{background:var(--bg2);border:1px solid var(--bd);border-radius:var(--r2);margin-top:14px;padding:18px 20px}
.explorer-head{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:14px}
.search-wrap{display:flex;align-items:center;gap:8px;background:var(--bg);border:1px solid var(--bd2);border-radius:var(--r1);padding:8px 12px;flex:1;max-width:420px}
.search-wrap input{flex:1;background:none;border:none;color:var(--wh);font-family:var(--mono);font-size:12px;outline:none}
.filter-pills{display:flex;gap:6px;flex-wrap:wrap}
.pill{padding:5px 12px;border-radius:20px;border:1px solid var(--bd2);background:var(--bg3);color:var(--mu2);font-size:10px;font-weight:700;cursor:pointer;transition:.2s}
.pill:hover{border-color:var(--ac);color:var(--wh)}
.pill.active{background:var(--ac);color:#000;border-color:var(--ac)}
.skills-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:8px;max-height:400px;overflow-y:auto;padding-right:8px}
.skill-item{background:var(--bg3);border:1px solid var(--bd);border-radius:var(--r1);padding:10px 12px;font-size:11px;transition:.2s;cursor:pointer}
.skill-item:hover{border-color:var(--cy);background:var(--bg4);transform:translateY(-1px)}
.skill-name{font-family:var(--mono);font-weight:600;margin-bottom:3px}
.skill-cat{font-size:9px;color:var(--mu);text-transform:uppercase}
/* Production OSS */
.prod-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:10px;margin-top:10px}
.prod-item{background:var(--bg2);border:1px solid var(--gn);border-radius:var(--r1);padding:12px 14px;position:relative}
.prod-item::before{content:'';position:absolute;top:6px;right:6px;width:8px;height:8px;background:var(--gn);border-radius:50%;box-shadow:0 0 8px var(--gn);animation:pulse 2s ease-in-out infinite}
@keyframes pulse{50%{opacity:.4}}
.prod-name{font-family:var(--mono);font-weight:700;font-size:12px;margin-bottom:2px}
.prod-info{font-size:10px;color:var(--mu)}
.loading{text-align:center;padding:40px;color:var(--mu)}
.footer-n{font-size:10px;color:var(--mu);text-align:center;margin-top:32px;padding-top:14px;border-top:1px solid var(--bd)}
@media(max-width:768px){
.stats{grid-template-columns:repeat(2,1fr)}
.main{padding:14px}
.hdr{padding:14px}
}
</style>
</head>
<body>
<header class="hdr">
<div class="hdr-left">
<div class="hdr-logo">OSS</div>
<div>
<h1>WEVAL <span>OSS Discovery</span> V77</h1>
<div class="hdr-sub">72 tools · 6 178 skills · drill-down par catégorie · Enterprise Model UX</div>
</div>
</div>
<div style="display:flex;gap:8px">
<a class="btn" href="/weval-technology-platform.html">← WTP</a>
<a class="btn" href="/enterprise-model.html">🏢 Enterprise Model</a>
<a class="btn btn-ac" href="/agents-archi.html">🤖 Agents Archi</a>
</div>
</header>
<main class="main">
<!-- KPI Summary -->
<div class="stats" id="stats"><div class="loading">Loading...</div></div>
<!-- Categories drill-down -->
<div class="section-title">📦 Catégories (cliquer pour drill-down)</div>
<div class="cats" id="cats"></div>
<!-- Skills Explorer -->
<div class="section-title" style="margin-top:32px">🔎 Skills Explorer · 6 178 skills</div>
<div class="explorer">
<div class="explorer-head">
<div class="search-wrap">
<span>🔍</span>
<input type="text" id="search" placeholder="Search skills by name or category...">
</div>
<div class="filter-pills" id="filter-pills">
<div class="pill active" data-cat="all">All</div>
</div>
</div>
<div class="skills-grid" id="skills-grid">
<div class="loading">Loading skills...</div>
</div>
<div style="font-size:10px;color:var(--mu);margin-top:12px;text-align:center">
Affichage de <b id="skills-count">0</b> skills · 694 injected in Qdrant vectors (coverage 11.2%)
</div>
</div>
<!-- Production OSS -->
<div class="section-title" style="margin-top:32px">🟢 Production OSS (Docker déployé live)</div>
<div class="prod-grid" id="prod-grid"></div>
<div class="footer-n">
V77 OSS Discovery enriched · Style Enterprise Model · Doctrine #60 UX premium · Cross-linked with WTP+Enterprise+Archi
</div>
</main>
<script>
// Sample skills list from category names (real skills stored in Qdrant, sample here for UX)
const SAMPLE_SKILLS_PER_CAT = {
llm_core: ['gpt-wrapper','claude-bridge','mistral-adapter','ollama-local','vllm-server','text-generation-webui','prompt-optimizer','token-counter','llm-proxy','fallback-cascade'],
agents: ['dspy-agent','crewai-swarm','langgraph-flow','autogen-team','superclaude-framework','claude-skills','agent-router','mcp-server','tool-dispatcher','skill-injector','task-planner','reasoning-agent','retrieval-agent','code-agent'],
automation: ['n8n-workflow','activepieces-flow','temporal-pipeline','cron-scheduler','webhook-dispatch','event-router'],
observability: ['grafana-dash','prometheus-scrape','loki-logs','langfuse-trace','uptime-kuma','opentelemetry-tracer'],
dev_tools: ['claude-code','vscode-ext','docker-compose','git-hooks','jetbrains-plugin','eslint-config','prettier-setup','typescript-types','pytest-runner','jest-suite'],
rag_vector: ['qdrant-client','milvus-index','pinecone-wrapper','weaviate-client','chroma-store','embeddings-batch','semantic-search','hybrid-rerank'],
security: ['crowdsec-rules','nuclei-templates','keycloak-sso','vault-secrets','fail2ban-config','auth-middleware'],
weval_own: ['wevia-master','wevia-brain','weval-l99','weval-nonreg','wevads-arsenal','ethica-pipeline','paperclip-db','deerflow','mirofish','blade-ops','sentinel-lite','dynamic-resolver']
};
let ALL_DATA = null;
let FILTER_CAT = 'all';
let SEARCH = '';
async function load() {
try {
const r = await fetch('/api/v77-oss-discovery-enriched.php?t=' + Date.now());
ALL_DATA = await r.json();
renderStats();
renderCategories();
renderSkills();
renderProduction();
} catch(e) {
document.getElementById('stats').innerHTML = '<div class="loading" style="color:#ef4444">Error loading: ' + e.message + '</div>';
}
}
function renderStats() {
const s = ALL_DATA.summary;
document.getElementById('stats').innerHTML = `
<div class="stat s-ac" data-k="total_tools" data-intent="v77 oss discovery enriched" onclick="v93Drill(this)" style="cursor:pointer"<div class="st-l">Total tools</div><div class="st-v">${s.total_tools}</div><div class="st-s">OSS integrated in stack</div></div>
<div class="stat s-gn" data-k="wired" data-intent="oss wired tools list" onclick="v93Drill(this)" style="cursor:pointer"<div class="st-l">Wired</div><div class="st-v">${s.wired_tools}/${s.total_tools}</div><div class="st-s">All connected to WEVIA</div></div>
<div class="stat s-cy" data-k="total_skills" data-intent="oss 20126 skills breakdown" onclick="v93Drill(this)" style="cursor:pointer"<div class="st-l">Total skills</div><div class="st-v">${s.total_skills.toLocaleString()}</div><div class="st-s">Across 72 tools</div></div>
<div class="stat s-bl" data-k="injected_in_rag" data-intent="qdrant injection status" onclick="v93Drill(this)" style="cursor:pointer"<div class="st-l">Injected in RAG</div><div class="st-v">${s.injected_skills.toLocaleString()}</div><div class="st-s">Qdrant vectors live</div></div>
<div class="stat s-pk" data-k="coverage" data-intent="oss coverage analysis" onclick="v93Drill(this)" style="cursor:pointer"<div class="st-l">Coverage</div><div class="st-v">${s.coverage_pct}%</div><div class="st-s">Injected / Total</div></div>
<div class="stat s-gn" data-k="with_docker" data-intent="oss production tools" onclick="v93Drill(this)" style="cursor:pointer"<div class="st-l">With Docker</div><div class="st-v">${s.with_docker}</div><div class="st-s">Production-ready</div></div>
<div class="stat s-ac" data-k="with_readme" data-intent="oss documented tools" onclick="v93Drill(this)" style="cursor:pointer"<div class="st-l">With README</div><div class="st-v">${s.with_readme}</div><div class="st-s">Documented</div></div>
<div class="stat s-cy" data-k="production" data-intent="oss production live" onclick="v93Drill(this)" style="cursor:pointer"<div class="st-l">Production</div><div class="st-v">${s.production_count}</div><div class="st-s">Docker + wired live</div></div>
`;
}
function renderCategories() {
const pills = document.getElementById('filter-pills');
const cats = document.getElementById('cats');
cats.innerHTML = '';
// Add filter pills
const existingPills = pills.querySelectorAll('.pill:not([data-cat="all"])');
existingPills.forEach(p => p.remove());
ALL_DATA.categories.forEach((c, i) => {
// Category card
const el = document.createElement('div');
el.className = 'cat';
el.dataset.catIdx = i;
el.innerHTML = `
<div class="cat-strip" style="background:${c.color}"></div>
<div class="cat-head">
<div class="cat-emoji">${c.emoji}</div>
<div class="cat-name">${c.label}</div>
<div class="cat-count" style="color:${c.color}">${c.count}</div>
</div>
<div class="cat-stats">
<div class="cat-stat"><b>${c.total_files}</b>files</div>
<div class="cat-stat"><b>${c.est_skills.toLocaleString()}</b>skills est.</div>
<div class="cat-stat"><b>${c.est_injected}</b>injected</div>
</div>
<div class="cat-cov">
<div class="cat-cov-bar"><div class="cat-cov-fill" style="width:${c.coverage_pct}%;background:linear-gradient(90deg,${c.color},var(--cy))"></div></div>
<div class="cat-cov-label"><span>Coverage</span><span>${c.coverage_pct}%</span></div>
</div>
<div class="drill">
<div style="font-size:10px;color:var(--mu);text-transform:uppercase;margin-bottom:6px;font-weight:700">Tools (${c.tools.length})</div>
${c.tools.map(t => `
<div class="tool-row">
<div class="tool-name">${t.name}</div>
<div class="tool-badges">
<span class="tool-badge tb-files">${t.files}f</span>
${t.has_docker ? '<span class="tool-badge tb-docker">🐳</span>' : ''}
${t.has_readme ? '<span class="tool-badge tb-readme">📖</span>' : ''}
${t.wired ? '<span class="tool-badge tb-wired">⚡</span>' : ''}
</div>
</div>
`).join('')}
</div>
`;
el.onclick = (ev) => {
if (ev.target.closest('.tool-row')) return;
el.classList.toggle('open');
};
cats.appendChild(el);
// Filter pill
const p = document.createElement('div');
p.className = 'pill';
p.dataset.cat = Object.keys({llm_core:1,agents:1,automation:1,observability:1,dev_tools:1,rag_vector:1,security:1,weval_own:1})[i];
p.textContent = c.emoji + ' ' + c.label;
p.onclick = () => {
document.querySelectorAll('.pill').forEach(x => x.classList.remove('active'));
p.classList.add('active');
FILTER_CAT = p.dataset.cat;
renderSkills();
};
pills.appendChild(p);
});
}
function renderSkills() {
const grid = document.getElementById('skills-grid');
const catKeys = ['llm_core','agents','automation','observability','dev_tools','rag_vector','security','weval_own'];
let items = [];
catKeys.forEach((k,i) => {
(SAMPLE_SKILLS_PER_CAT[k]||[]).forEach(s => {
items.push({ name: s, cat: k, catLabel: ALL_DATA.categories[i]?.label || k, color: ALL_DATA.categories[i]?.color || '#64748b' });
});
});
// Filter
if (FILTER_CAT !== 'all') items = items.filter(x => x.cat === FILTER_CAT);
if (SEARCH) items = items.filter(x => x.name.toLowerCase().includes(SEARCH) || x.catLabel.toLowerCase().includes(SEARCH));
document.getElementById('skills-count').textContent = items.length;
grid.innerHTML = items.map(x => `
<div class="skill-item" style="border-left:3px solid ${x.color}">
<div class="skill-name">${x.name}</div>
<div class="skill-cat">${x.catLabel}</div>
</div>
`).join('') || '<div class="loading">No skills match filter</div>';
}
function renderProduction() {
const grid = document.getElementById('prod-grid');
const CAT_EMOJI = {llm_core:'🧠',agents:'🤖',automation:'⚡',observability:'👁️',dev_tools:'🛠️',rag_vector:'🔍',security:'🛡️',weval_own:'👑'};
grid.innerHTML = ALL_DATA.production_tools.map(t => `
<div class="prod-item">
<div class="prod-name">${CAT_EMOJI[t.category]||'📦'} ${t.name}</div>
<div class="prod-info">${t.files} files · ${t.category.replace('_',' ')}</div>
</div>
`).join('') || '<div class="loading">No production tools</div>';
}
document.getElementById('search').addEventListener('input', e => {
SEARCH = e.target.value.toLowerCase();
renderSkills();
});
load();
setInterval(load, 60000);
</script>
<script src="/api/a11y-auto-enhancer.js" defer></script>
<!-- WTP_UDOCK_V1 (Opus 21-avr t33b6) --><script src="/wtp-unified-dock.js" defer></script>
<script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
</body>
</html>