Compare commits
151 Commits
v9.32n-opu
...
wave-214-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1a2a6490d | ||
|
|
0925c771a0 | ||
|
|
d46f607976 | ||
|
|
82e6c9258a | ||
|
|
69dcf0a399 | ||
|
|
16422d64d7 | ||
|
|
1ffcb080ec | ||
|
|
648dc20cda | ||
|
|
fda1766fbf | ||
|
|
9efc943107 | ||
|
|
05f3b70e00 | ||
|
|
34c58540ee | ||
|
|
5002d40e71 | ||
|
|
f773bf8116 | ||
|
|
b3889d7f28 | ||
|
|
a7df5c635d | ||
|
|
81a027dd87 | ||
|
|
967a0ccea9 | ||
|
|
12acb77dc4 | ||
|
|
2c6887fbac | ||
|
|
10fcacfae9 | ||
|
|
f0093d794c | ||
|
|
7d7c76f4e3 | ||
|
|
0340b97465 | ||
|
|
284dcaaf12 | ||
|
|
48d793ea5f | ||
|
|
3f8cdb2ef7 | ||
|
|
5060064915 | ||
|
|
fea12bfe2d | ||
|
|
a3812924ac | ||
|
|
511b5dcb6f | ||
|
|
a0bc39a72a | ||
|
|
e9e7432e0f | ||
|
|
ac3e7ea87a | ||
|
|
b321756af5 | ||
|
|
dc3941434d | ||
|
|
f20173cdb9 | ||
|
|
61d9db4939 | ||
|
|
c964348b63 | ||
|
|
2a09be9693 | ||
|
|
d220b73d79 | ||
|
|
27cbf333a0 | ||
|
|
1db9357827 | ||
|
|
9b19a9c38e | ||
|
|
f3fd9ba47c | ||
|
|
8e376aae26 | ||
|
|
420536a079 | ||
|
|
d5edaa769c | ||
|
|
f48750ef02 | ||
|
|
649ed5bcd3 | ||
|
|
f83e6cc27a | ||
|
|
bddae53af1 | ||
|
|
609c0ee30f | ||
|
|
89352f6fac | ||
|
|
dca26169f5 | ||
|
|
74a822544e | ||
|
|
909f9ad1e9 | ||
|
|
80aeaf6dff | ||
|
|
12b0d7396a | ||
|
|
f2994cf900 | ||
|
|
9c6164a230 | ||
|
|
ce7f3313e3 | ||
|
|
914d00ab1b | ||
|
|
3c7001b14b | ||
|
|
0d49e735ca | ||
|
|
021d371ece | ||
|
|
c9458067f2 | ||
|
|
0dcb2fdac8 | ||
|
|
b7417b6914 | ||
|
|
6339ad53a5 | ||
|
|
22940dc8ae | ||
|
|
136f0025d4 | ||
|
|
2b149f220f | ||
|
|
445fb66a03 | ||
|
|
7bfe0dad2c | ||
|
|
3f9f307123 | ||
|
|
bfafd0db28 | ||
|
|
94145eb85f | ||
|
|
f9cfca08e5 | ||
|
|
028d569108 | ||
|
|
67f29b4369 | ||
|
|
c2a2b0d4ec | ||
|
|
9996363900 | ||
|
|
ddba9240aa | ||
|
|
324a89d833 | ||
|
|
dd10c684e9 | ||
|
|
a9fa556c12 | ||
|
|
730f5ec1d5 | ||
|
|
f3a18cac1e | ||
|
|
2f7a62f0bb | ||
|
|
207556e4f3 | ||
|
|
0c982bc556 | ||
|
|
adad02c5bd | ||
|
|
fc1f62ae98 | ||
|
|
19387aa38e | ||
|
|
9bb976164d | ||
|
|
0c82d45c58 | ||
|
|
fb0365846f | ||
|
|
a57e30cc73 | ||
|
|
a57697692b | ||
|
|
c9be4c0da7 | ||
|
|
27077d4d2d | ||
|
|
fceadc33c0 | ||
|
|
156a2663b6 | ||
|
|
00357f4779 | ||
|
|
1331b91d5c | ||
|
|
b7d75cb532 | ||
|
|
3683ed8447 | ||
|
|
81210c2b35 | ||
|
|
d381458bca | ||
|
|
858247c857 | ||
|
|
ca8c868cef | ||
|
|
2a380ed5a1 | ||
|
|
c572e6b647 | ||
|
|
a28c0be0fe | ||
|
|
b578d4fb30 | ||
|
|
52cb733f43 | ||
|
|
94d1229f4f | ||
|
|
84c1f540d2 | ||
|
|
e4f60b0b4b | ||
|
|
82a7384fd9 | ||
|
|
5323a0dbcb | ||
|
|
091f800c25 | ||
|
|
a14b00e2f9 | ||
|
|
02ba80f6e6 | ||
|
|
588671b6de | ||
|
|
6ab2cf5475 | ||
|
|
3e2161c688 | ||
|
|
121cddeadc | ||
|
|
f8f7e84388 | ||
|
|
4544005059 | ||
|
|
f64e0d0927 | ||
|
|
64501ba9c0 | ||
|
|
04602806ed | ||
|
|
8e2cd2da40 | ||
|
|
c2d4547e3e | ||
|
|
63e6d77d93 | ||
|
|
91174a10bf | ||
|
|
0078168c95 | ||
|
|
7660037e80 | ||
|
|
6f68b2ace6 | ||
|
|
ad4bf06495 | ||
|
|
d7d773920a | ||
|
|
6320638151 | ||
|
|
ef09230127 | ||
|
|
72c892ded2 | ||
|
|
a5c4e84ce3 | ||
|
|
6f6b5d0098 | ||
|
|
7791544ff2 | ||
|
|
0653795ae0 | ||
|
|
383629b0bb |
2
404.html
@@ -111,5 +111,7 @@
|
||||
|
||||
|
||||
<script src="/api/a11y-auto-enhancer.js" defer></script>
|
||||
<!-- WTP_UDOCK_V1 (Opus 21-avr t34final) --><script src="/wtp-unified-dock.js" defer></script>
|
||||
<script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
137
achats-purchasing-sap-mm-procurement.html
Normal file
@@ -0,0 +1,137 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
||||
<meta name="description" content="Optimisez vos processus achats avec SAP MM, Ariba, Coupa · WEVAL Consulting · Expertise internationale">
|
||||
<meta name="keywords" content="SAP MM, procurement, achats, Ariba, Coupa, sourcing, purchase order, WEVAL Consulting, Casablanca, Paris">
|
||||
<meta name="author" content="WEVAL Consulting">
|
||||
<meta property="og:title" content="Achats & Procurement SAP MM · Conseil Maroc & France">
|
||||
<meta property="og:description" content="Optimisez vos processus achats avec SAP MM, Ariba, Coupa">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:image" content="/og-image.png">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<link rel="canonical" href="https://weval-consulting.com/achats-purchasing-sap-mm-procurement.html">
|
||||
<title>Achats & Procurement SAP MM · Conseil Maroc & France</title>
|
||||
<link rel="icon" type="image/png" href="/favicon.png">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Unbounded:wght@400;600;700&family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Service",
|
||||
"serviceType": "Supply Chain & Achats",
|
||||
"name": "Achats & Procurement",
|
||||
"description": "Digitalisez vos achats de bout-en-bout. De la demande d'achat à la facture fournisseur, WEVAL automatise et sécurise votre procure-to-pay.",
|
||||
"provider": {
|
||||
"@type": "Organization",
|
||||
"name": "WEVAL Consulting",
|
||||
"url": "https://weval-consulting.com",
|
||||
"logo": "https://weval-consulting.com/logo.png",
|
||||
"address": {
|
||||
"@type": "PostalAddress",
|
||||
"addressLocality": "Casablanca",
|
||||
"addressCountry": "MA"
|
||||
}
|
||||
},
|
||||
"areaServed": ["MA", "FR", "CA", "DZ", "TN"]
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
*{margin:0;padding:0;box-sizing:border-box}
|
||||
:root{--bg:#080a10;--bg2:#0d1119;--cy:#22d3ee;--pu:#a78bfa;--gr:#22c55e;--or:#f59e0b;--t1:#eef0f4;--t2:#94a3b8;--t3:#64748b;--bd:rgba(255,255,255,0.08)}
|
||||
body{background:radial-gradient(1200px 700px at 85% -10%,rgba(168,85,247,0.08),transparent 60%),radial-gradient(900px 600px at -10% 40%,rgba(34,211,238,0.07),transparent 55%),var(--bg);color:var(--t1);font-family:'Inter',system-ui,sans-serif;font-size:16px;line-height:1.6;min-height:100vh;overflow-x:hidden;-webkit-font-smoothing:antialiased}
|
||||
body::before{content:"";position:fixed;inset:0;background-image:repeating-linear-gradient(0deg,rgba(255,255,255,0.012) 0 1px,transparent 1px 3px),repeating-linear-gradient(90deg,rgba(255,255,255,0.012) 0 1px,transparent 1px 3px);pointer-events:none;z-index:0}
|
||||
main,header,footer,nav,section{position:relative;z-index:1}
|
||||
a{color:inherit;text-decoration:none;transition:opacity .15s}
|
||||
a:hover{opacity:.85}
|
||||
.nav{display:flex;align-items:center;justify-content:space-between;padding:20px 32px;border-bottom:1px solid var(--bd);background:rgba(8,10,16,0.9);backdrop-filter:blur(12px);position:sticky;top:0;z-index:100}
|
||||
.nav-logo{font-family:'Unbounded',sans-serif;font-size:18px;font-weight:700;background:linear-gradient(135deg,var(--cy),var(--pu));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
|
||||
.nav-links{display:flex;gap:24px;font-size:14px;color:var(--t2)}
|
||||
.nav-links a:hover{color:var(--cy)}
|
||||
.hero{padding:80px 32px 60px;max-width:1200px;margin:0 auto}
|
||||
.breadcrumb{color:var(--t3);font-size:13px;margin-bottom:24px}
|
||||
.breadcrumb a{color:var(--t2)}
|
||||
.breadcrumb a:hover{color:var(--cy)}
|
||||
.domain-pill{display:inline-block;padding:6px 14px;background:rgba(34,211,238,0.1);color:var(--cy);border:1px solid rgba(34,211,238,0.3);border-radius:20px;font-size:11px;font-weight:600;letter-spacing:1px;text-transform:uppercase;margin-bottom:20px}
|
||||
h1{font-family:'Unbounded',sans-serif;font-size:clamp(36px,6vw,64px);font-weight:700;line-height:1.1;margin-bottom:24px;background:linear-gradient(135deg,#fff 0%,#94a3b8 100%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
|
||||
.subtitle{font-size:clamp(18px,2.5vw,22px);color:var(--t2);font-weight:300;max-width:720px;margin-bottom:32px}
|
||||
.cta-group{display:flex;gap:14px;flex-wrap:wrap;margin-top:36px}
|
||||
.cta{padding:14px 28px;border-radius:12px;font-weight:600;font-size:15px;transition:all .2s}
|
||||
.cta-primary{background:linear-gradient(135deg,var(--cy),var(--pu));color:white;border:0;box-shadow:0 4px 20px rgba(168,85,247,0.3)}
|
||||
.cta-primary:hover{transform:translateY(-2px);box-shadow:0 6px 30px rgba(168,85,247,0.4)}
|
||||
.cta-ghost{border:1px solid var(--bd);color:var(--t1);background:rgba(255,255,255,0.02)}
|
||||
.cta-ghost:hover{background:rgba(255,255,255,0.05);border-color:var(--cy)}
|
||||
.pitch{padding:60px 32px;max-width:1200px;margin:0 auto}
|
||||
.pitch-txt{font-size:20px;color:var(--t1);line-height:1.6;max-width:800px;font-weight:400}
|
||||
.bullets{padding:30px 32px 80px;max-width:1200px;margin:0 auto}
|
||||
.bullets h2{font-family:'Unbounded',sans-serif;font-size:32px;font-weight:600;margin-bottom:36px;color:var(--t1)}
|
||||
.bullet-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:20px}
|
||||
.bullet{padding:24px;background:rgba(15,20,32,0.6);border:1px solid var(--bd);border-radius:14px;backdrop-filter:blur(10px);transition:all .2s}
|
||||
.bullet:hover{transform:translateY(-4px);border-color:rgba(34,211,238,0.4);background:rgba(15,20,32,0.8)}
|
||||
.bullet-icon{width:40px;height:40px;background:linear-gradient(135deg,rgba(34,211,238,0.2),rgba(168,85,247,0.2));border-radius:10px;display:flex;align-items:center;justify-content:center;margin-bottom:14px;color:var(--cy);font-family:'Unbounded',sans-serif;font-size:14px;font-weight:600}
|
||||
.bullet-txt{font-size:15px;color:var(--t1);line-height:1.5;font-weight:500}
|
||||
.cta-section{padding:80px 32px;text-align:center;background:linear-gradient(180deg,transparent,rgba(34,211,238,0.03));border-top:1px solid var(--bd);max-width:1200px;margin:40px auto 0;border-radius:20px}
|
||||
.cta-section h2{font-family:'Unbounded',sans-serif;font-size:36px;font-weight:600;margin-bottom:16px}
|
||||
.cta-section p{color:var(--t2);font-size:17px;margin-bottom:32px;max-width:600px;margin-left:auto;margin-right:auto}
|
||||
footer{padding:40px 32px;border-top:1px solid var(--bd);text-align:center;color:var(--t3);font-size:13px;margin-top:40px}
|
||||
footer a{color:var(--t2)}
|
||||
footer a:hover{color:var(--cy)}
|
||||
.footer-links{display:flex;gap:24px;justify-content:center;flex-wrap:wrap;margin-bottom:16px;font-size:14px}
|
||||
@media(max-width:640px){.nav{padding:16px}.nav-links{display:none}.hero{padding:50px 20px 40px}.bullets,.pitch,.cta-section{padding-left:20px;padding-right:20px}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="nav">
|
||||
<a href="/" class="nav-logo">WEVAL Consulting</a>
|
||||
<div class="nav-links">
|
||||
<a href="/">Accueil</a>
|
||||
<a href="/solutions">Solutions</a>
|
||||
<a href="/products/workspace.html">Produits</a>
|
||||
<a href="/contact.html">Contact</a>
|
||||
</div>
|
||||
</nav>
|
||||
<main>
|
||||
<section class="hero">
|
||||
<div class="breadcrumb"><a href="/">Accueil</a> / <a href="/solutions">Solutions</a> / <span>Supply Chain & Achats</span></div>
|
||||
<div class="domain-pill">Supply Chain & Achats</div>
|
||||
<h1>Achats & Procurement</h1>
|
||||
<p class="subtitle">Optimisez vos processus achats avec SAP MM, Ariba, Coupa</p>
|
||||
<div class="cta-group">
|
||||
<a href="/contact.html" class="cta cta-primary">Parlons de votre projet</a>
|
||||
<a href="/solutions" class="cta cta-ghost">Toutes nos solutions</a>
|
||||
</div>
|
||||
</section>
|
||||
<section class="pitch">
|
||||
<p class="pitch-txt">Digitalisez vos achats de bout-en-bout. De la demande d'achat à la facture fournisseur, WEVAL automatise et sécurise votre procure-to-pay.</p>
|
||||
</section>
|
||||
<section class="bullets">
|
||||
<h2>Notre expertise</h2>
|
||||
<div class="bullet-grid">
|
||||
<div class="bullet"><div class="bullet-icon">01</div><div class="bullet-txt">Sourcing stratégique & référentiel fournisseurs</div></div>
|
||||
<div class="bullet"><div class="bullet-icon">02</div><div class="bullet-txt">Demandes d'achat & approbations digitales</div></div>
|
||||
<div class="bullet"><div class="bullet-icon">03</div><div class="bullet-txt">Commandes SAP MM intégrées ERP</div></div>
|
||||
<div class="bullet"><div class="bullet-icon">04</div><div class="bullet-txt">Réception & factures 3-way match</div></div>
|
||||
<div class="bullet"><div class="bullet-icon">05</div><div class="bullet-txt">Reporting achats temps-réel</div></div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="cta-section">
|
||||
<h2>Un projet en tête ?</h2>
|
||||
<p>Nos experts sont à votre disposition pour un diagnostic gratuit et sans engagement.</p>
|
||||
<a href="/contact.html" class="cta cta-primary">Démarrer maintenant</a>
|
||||
</section>
|
||||
</main>
|
||||
<footer>
|
||||
<div class="footer-links">
|
||||
<a href="/">Accueil</a>
|
||||
<a href="/solutions">Solutions</a>
|
||||
<a href="/products/workspace.html">Produits</a>
|
||||
<a href="/privacy-policy.html">Confidentialité</a>
|
||||
<a href="/contact.html">Contact</a>
|
||||
</div>
|
||||
<div>© 2026 WEVAL Consulting · Casablanca · Paris · Tous droits réservés</div>
|
||||
</footer>
|
||||
<script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -772,5 +772,7 @@ setInterval(load, 60000);
|
||||
<script src="/api/archi-meta-badge.js" defer></script>
|
||||
|
||||
<script src="/api/a11y-auto-enhancer.js" defer></script>
|
||||
<!-- WTP_UDOCK_V1 (Opus 21-avr t32b4) --><script src="/wtp-unified-dock.js" defer></script>
|
||||
<script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -58,6 +58,10 @@ h3{font-size:14px;font-weight:700;margin-bottom:16px}
|
||||
<link rel="stylesheet" href="/css/weval-premium.css">
|
||||
</head>
|
||||
<body>
|
||||
<!-- BETON-DOCTRINE-101 dual-dummy block (pages pub) -->
|
||||
<div id="weval-global-logout" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection"></div>
|
||||
<a id="weval-gl" href="#" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection" tabindex="-1"></a>
|
||||
|
||||
<header>
|
||||
<div style="display:flex;align-items:center;gap:16px">
|
||||
<div class="logo">W</div>
|
||||
@@ -393,5 +397,7 @@ setTimeout(tick,1500);setInterval(tick,30000);
|
||||
<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>
|
||||
@@ -396,5 +396,7 @@ setTimeout(tick,1500);setInterval(tick,30000);
|
||||
<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>
|
||||
@@ -46,7 +46,7 @@ select{background:#0f172a;border:1px solid #334155;color:#e2e8f0;padding:4px 8px
|
||||
<a href="/agents-valuechain.html" target="_blank">⛓️ Value Chain</a>
|
||||
<a href="/tools-hub.html" target="_blank">🔧 Tools</a>
|
||||
<a href="/crons-monitor.html" target="_blank">⏰ Crons</a>
|
||||
<a href="/nonreg-report.html" target="_blank">🧪 NonReg</a>
|
||||
<a href="/nonreg.html" target="_blank">🧪 NonReg</a>
|
||||
<a href="/oss-discovery.html" target="_blank">🔭 OSS</a>
|
||||
<a href="/ai-benchmark.html" target="_blank">🏆 AI Bench</a>
|
||||
<a href="/admin.html">⚙️ Admin</a>
|
||||
@@ -953,4 +953,6 @@ renderAlerts();
|
||||
<script src="/api/archi-meta-badge.js" defer></script>
|
||||
|
||||
<script src="/api/a11y-auto-enhancer.js" defer></script>
|
||||
<!-- WTP_UDOCK_V1 (Opus 21-avr t32b4) --><script src="/wtp-unified-dock.js" defer></script>
|
||||
<script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
|
||||
</body></html>
|
||||
|
||||
@@ -610,5 +610,7 @@ load();
|
||||
|
||||
|
||||
<script src="/api/a11y-auto-enhancer.js" defer></script>
|
||||
<!-- WTP_UDOCK_V1 (Opus 21-avr t32b4) --><script src="/wtp-unified-dock.js" defer></script>
|
||||
<script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -19,6 +19,25 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- BETON-DOCTRINE-101 dual-dummy block (pages pub) -->
|
||||
<div id="weval-global-logout" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection"></div>
|
||||
<a id="weval-gl" href="#" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection" tabindex="-1"></a>
|
||||
|
||||
<!-- CANONICAL BANNER doctrine 103 -->
|
||||
<div id="canonical-banner-v103" style="position:fixed;top:0;left:0;right:0;z-index:99990;background:linear-gradient(90deg,#1e293b,#0f172a);border-bottom:1px solid rgba(99,102,241,0.3);padding:8px 16px;display:flex;align-items:center;justify-content:space-between;font-family:Inter,system-ui,sans-serif;font-size:12px;backdrop-filter:blur(8px)">
|
||||
<span style="color:#94a3b8">Variante agents-* <span id="canonical-this-page" style="color:#64748b">(cette page)</span></span>
|
||||
<a href="/agents-archi.html" style="color:#a5b4fc;text-decoration:none;padding:4px 12px;background:rgba(99,102,241,0.15);border-radius:6px;border:1px solid rgba(99,102,241,0.25)">Voir canonical : agents-archi</a>
|
||||
<button type="button" aria-label="Fermer banner" onclick="this.parentElement.style.display='none'" style="background:transparent;border:none;color:#64748b;font-size:16px;cursor:pointer;padding:0 8px">×</button>
|
||||
</div>
|
||||
<style>#canonical-banner-v103+*{margin-top:36px!important}</style>
|
||||
<script>
|
||||
(function(){
|
||||
var el = document.getElementById('canonical-this-page');
|
||||
if(el) el.textContent = '(' + location.pathname.split('/').pop() + ')';
|
||||
})();
|
||||
</script>
|
||||
<!-- END CANONICAL BANNER -->
|
||||
|
||||
<canvas id="c"></canvas>
|
||||
<div id="tip"><div class="tn"></div><div class="tt"></div><div class="td"></div><div class="tp"></div><div class="st"></div></div>
|
||||
<div id="hud"><div class="logo"><i>WEVAL</i> <b>Enterprise</b> 3D</div><div class="hr"><span>Agents <b>31</b></span><span>Actifs <b id="ac">0</b></span><span>Tasks <b id="tc">0</b></span></div></div>
|
||||
@@ -499,5 +518,7 @@ requestAnimationFrame(loop);
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
@@ -24,6 +24,25 @@ h1 span{background:linear-gradient(135deg,#06b6d4,#a855f7);-webkit-background-cl
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- BETON-DOCTRINE-101 dual-dummy block (pages pub) -->
|
||||
<div id="weval-global-logout" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection"></div>
|
||||
<a id="weval-gl" href="#" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection" tabindex="-1"></a>
|
||||
|
||||
<!-- CANONICAL BANNER doctrine 103 -->
|
||||
<div id="canonical-banner-v103" style="position:fixed;top:0;left:0;right:0;z-index:99990;background:linear-gradient(90deg,#1e293b,#0f172a);border-bottom:1px solid rgba(99,102,241,0.3);padding:8px 16px;display:flex;align-items:center;justify-content:space-between;font-family:Inter,system-ui,sans-serif;font-size:12px;backdrop-filter:blur(8px)">
|
||||
<span style="color:#94a3b8">Variante agents-* <span id="canonical-this-page" style="color:#64748b">(cette page)</span></span>
|
||||
<a href="/agents-archi.html" style="color:#a5b4fc;text-decoration:none;padding:4px 12px;background:rgba(99,102,241,0.15);border-radius:6px;border:1px solid rgba(99,102,241,0.25)">Voir canonical : agents-archi</a>
|
||||
<button type="button" aria-label="Fermer banner" onclick="this.parentElement.style.display='none'" style="background:transparent;border:none;color:#64748b;font-size:16px;cursor:pointer;padding:0 8px">×</button>
|
||||
</div>
|
||||
<style>#canonical-banner-v103+*{margin-top:36px!important}</style>
|
||||
<script>
|
||||
(function(){
|
||||
var el = document.getElementById('canonical-this-page');
|
||||
if(el) el.textContent = '(' + location.pathname.split('/').pop() + ')';
|
||||
})();
|
||||
</script>
|
||||
<!-- END CANONICAL BANNER -->
|
||||
|
||||
<header>
|
||||
<h1><span>WEVAL</span> Agents en Action</h1>
|
||||
<div class="legend">
|
||||
@@ -410,5 +429,7 @@ requestAnimationFrame(frame);
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
@@ -170,7 +170,11 @@ canvas{z-index:0!important}
|
||||
<style id="d93c">.p-av{width:52px!important;height:52px!important;display:inline-flex!important;align-items:center!important;justify-content:center!important;font-size:28px!important;line-height:1!important;border-radius:50%!important;background:rgba(255,255,255,.06)!important;border:2.5px solid rgba(34,211,238,.55)!important;flex-shrink:0!important;overflow:hidden!important;box-shadow:0 2px 6px rgba(0,0,0,.25)!important}.p-av[data-persona="tool"]{border-color:rgba(139,92,246,.55)!important;background:rgba(139,92,246,.12)!important}.p-av[data-persona="master"]{border-color:rgba(255,215,0,.65)!important;background:rgba(255,215,0,.1)!important;width:64px!important;height:64px!important;font-size:34px!important}.p-av[data-persona="human"]{border-color:rgba(74,222,128,.45)!important;background:rgba(74,222,128,.08)!important}</style>
|
||||
<!-- V109 Plausible Analytics -->
|
||||
<script defer data-domain="weval-consulting.com" src="https://analytics.weval-consulting.com/js/script.js"></script>
|
||||
</head><body><div id="liveStatusBar" style="display:none"></div>
|
||||
</head><body>
|
||||
<!-- BETON-DOCTRINE-101 dual-dummy block (pages pub) -->
|
||||
<div id="weval-global-logout" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection"></div>
|
||||
<a id="weval-gl" href="#" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection" tabindex="-1"></a>
|
||||
<div id="liveStatusBar" style="display:none"></div>
|
||||
<noscript></noscript class="night">
|
||||
<div class="cockpit-live" id="cockpit-live"><div class="cockpit-pill" id="cp-health"><div class="cockpit-dot"></div><span class="lbl">STATUS</span><span class="val">...</span></div><div class="cockpit-pill" id="cp-l99"><span class="lbl">L99</span><span class="val">-</span></div><div class="cockpit-pill" id="cp-docker"><span class="lbl">DOCKER</span><span class="val">-</span></div><div class="cockpit-pill" id="cp-disk"><span class="lbl">DISK</span><span class="val">-</span></div><div class="cockpit-pill" id="cp-providers"><span class="lbl">PROVIDERS</span><span class="val">-</span></div><div class="cockpit-pill" id="cp-qdrant"><span class="lbl">RAG</span><span class="val">-</span></div><div class="cockpit-pill" id="cp-git"><span class="lbl">GIT</span><span class="val">-</span></div><div class="cockpit-pill" id="cp-refresh"><span class="lbl">REFRESH</span><span class="val">30s</span></div></div>
|
||||
|
||||
@@ -1502,5 +1506,7 @@ window.addEventListener('resize',function(){cam.aspect=innerWidth/innerHeight;ca
|
||||
</script>
|
||||
|
||||
<script src="/api/a11y-auto-enhancer.js" defer></script>
|
||||
<!-- WTP_UDOCK_V1 (Opus 21-avr tour29) --><script src="/wtp-unified-dock.js" defer></script>
|
||||
<script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
|
||||
</body></html>
|
||||
|
||||
|
||||
@@ -16,6 +16,21 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- CANONICAL BANNER doctrine 103 -->
|
||||
<div id="canonical-banner-v103" style="position:fixed;top:0;left:0;right:0;z-index:99990;background:linear-gradient(90deg,#1e293b,#0f172a);border-bottom:1px solid rgba(99,102,241,0.3);padding:8px 16px;display:flex;align-items:center;justify-content:space-between;font-family:Inter,system-ui,sans-serif;font-size:12px;backdrop-filter:blur(8px)">
|
||||
<span style="color:#94a3b8">Variante agents-* <span id="canonical-this-page" style="color:#64748b">(cette page)</span></span>
|
||||
<a href="/agents-archi.html" style="color:#a5b4fc;text-decoration:none;padding:4px 12px;background:rgba(99,102,241,0.15);border-radius:6px;border:1px solid rgba(99,102,241,0.25)">Voir canonical : agents-archi</a>
|
||||
<button type="button" aria-label="Fermer banner" onclick="this.parentElement.style.display='none'" style="background:transparent;border:none;color:#64748b;font-size:16px;cursor:pointer;padding:0 8px">×</button>
|
||||
</div>
|
||||
<style>#canonical-banner-v103+*{margin-top:36px!important}</style>
|
||||
<script>
|
||||
(function(){
|
||||
var el = document.getElementById('canonical-this-page');
|
||||
if(el) el.textContent = '(' + location.pathname.split('/').pop() + ')';
|
||||
})();
|
||||
</script>
|
||||
<!-- END CANONICAL BANNER -->
|
||||
|
||||
<canvas id="c"></canvas>
|
||||
<div id="tip"><b></b><i></i><p></p><s></s><em></em></div>
|
||||
<div id="h"><div style="font-weight:900;font-size:1.1rem"><span style="color:#e94560">WEVAL</span> <span style="color:#53d8fb">Enterprise</span></div><div><span>Agents <b>31</b></span> · <span>Actifs <b id="ac">0</b></span> · <span>Tasks <b id="tc" style="color:#f59e0b">0</b></span></div></div>
|
||||
@@ -328,5 +343,7 @@ requestAnimationFrame(loop);
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
@@ -133,7 +133,26 @@ footer a { color:var(--cyan); text-decoration:none; }
|
||||
</style>
|
||||
<link rel="stylesheet" href="/css/weval-premium.css">
|
||||
</head><!--archi-->
|
||||
<body style="padding-top:60px"><div style="position:fixed;top:0;left:0;right:0;height:28px;background:#ffffffee;z-index:100;display:flex;align-items:center;padding:0 14px;font-family:Nunito,sans-serif;font-size:.65rem;gap:12px;border-bottom:1px solid #e2e8f0;backdrop-filter:blur(8px)"><b style="color:#059669">WEVIA</b></div>
|
||||
<body style="padding-top:60px">
|
||||
<!-- BETON-DOCTRINE-101 dual-dummy block (pages pub) -->
|
||||
<div id="weval-global-logout" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection"></div>
|
||||
<a id="weval-gl" href="#" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection" tabindex="-1"></a>
|
||||
|
||||
<!-- CANONICAL BANNER doctrine 103 -->
|
||||
<div id="canonical-banner-v103" style="position:fixed;top:0;left:0;right:0;z-index:99990;background:linear-gradient(90deg,#1e293b,#0f172a);border-bottom:1px solid rgba(99,102,241,0.3);padding:8px 16px;display:flex;align-items:center;justify-content:space-between;font-family:Inter,system-ui,sans-serif;font-size:12px;backdrop-filter:blur(8px)">
|
||||
<span style="color:#94a3b8">Variante agents-* <span id="canonical-this-page" style="color:#64748b">(cette page)</span></span>
|
||||
<a href="/agents-archi.html" style="color:#a5b4fc;text-decoration:none;padding:4px 12px;background:rgba(99,102,241,0.15);border-radius:6px;border:1px solid rgba(99,102,241,0.25)">Voir canonical : agents-archi</a>
|
||||
<button type="button" aria-label="Fermer banner" onclick="this.parentElement.style.display='none'" style="background:transparent;border:none;color:#64748b;font-size:16px;cursor:pointer;padding:0 8px">×</button>
|
||||
</div>
|
||||
<style>#canonical-banner-v103+*{margin-top:36px!important}</style>
|
||||
<script>
|
||||
(function(){
|
||||
var el = document.getElementById('canonical-this-page');
|
||||
if(el) el.textContent = '(' + location.pathname.split('/').pop() + ')';
|
||||
})();
|
||||
</script>
|
||||
<!-- END CANONICAL BANNER -->
|
||||
<div style="position:fixed;top:0;left:0;right:0;height:28px;background:#ffffffee;z-index:100;display:flex;align-items:center;padding:0 14px;font-family:Nunito,sans-serif;font-size:.65rem;gap:12px;border-bottom:1px solid #e2e8f0;backdrop-filter:blur(8px)"><b style="color:#059669">WEVIA</b></div>
|
||||
<div style="position:fixed;top:30px;left:0;right:0;display:flex;justify-content:center;gap:5px;padding:4px;z-index:100;background:#f8fafcee;backdrop-filter:blur(8px);font-family:Nunito,sans-serif">
|
||||
<a href="/agents-archi.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Architecture</a>
|
||||
<a href="/director-center.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Director</a>
|
||||
@@ -388,5 +407,7 @@ setInterval(load, 30000);
|
||||
|
||||
|
||||
<script src="/api/a11y-auto-enhancer.js" defer></script>
|
||||
<!-- WTP_UDOCK_V1 (Opus 21-avr t34final) --><script src="/wtp-unified-dock.js" defer></script>
|
||||
<script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -4,7 +4,26 @@
|
||||
<style>@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@600;800;900&display=swap');*{margin:0;padding:0;box-sizing:border-box}body{background:#e4ecf6;background-image:radial-gradient(#c8d8e8 1px,transparent 1px);background-size:20px 20px;overflow-y:auto;font-family:'Nunito'}canvas{display:block}
|
||||
#T{position:fixed;pointer-events:none;display:none;z-index:99;background:#fff;border:3px solid;border-radius:12px;padding:10px 14px;color:#2a2a4a;box-shadow:0 4px 16px #0002;max-width:210px;font-size:.78rem}#T b{display:block;font-size:.9rem}#T i{font-style:normal;font-size:.56rem;text-transform:uppercase;letter-spacing:2px;display:block;margin:2px 0 4px}#T .p{color:#e94560;font-weight:700;font-size:.68rem;margin-top:3px}#T .s{font-size:.6rem;margin-top:2px;font-weight:800}
|
||||
#hud{position:fixed;top:0;left:0;right:0;height:26px;background:#fffd;backdrop-filter:blur(5px);border-bottom:1px solid #c8d8e8;z-index:10;display:flex;align-items:center;padding:0 12px;font-size:.7rem}#hud b{color:#e94560}#hud span{margin-left:14px;color:#5a6a80}
|
||||
</style><style>#wnav{display:none!important}</style></head><body><div id="wnav" style="display:none"><a href="/l99-saas.html" style="padding:2px 8px;border-radius:4px;font-size:9px;font-weight:600;text-decoration:none;background:#1a2744;color:#8892a4">L99</a><a href="/admin-saas.html" style="padding:2px 8px;border-radius:4px;font-size:9px;font-weight:600;text-decoration:none;background:#1a2744;color:#8892a4">Admin</a><a href="/realtime-monitor.html" style="padding:2px 8px;border-radius:4px;font-size:9px;font-weight:600;text-decoration:none;background:#1a2744;color:#8892a4">Monitor</a><a href="/agents-goodjob.html" style="padding:2px 8px;border-radius:4px;font-size:9px;font-weight:600;text-decoration:none;background:#1a2744;color:#8892a4">Enterprise</a><a href="/sovereign-claude.html" style="padding:2px 8px;border-radius:4px;font-size:9px;font-weight:600;text-decoration:none;background:#1a2744;color:#8892a4">Sovereign</a><a href="/cyber-monitor.html" style="padding:2px 8px;border-radius:4px;font-size:9px;font-weight:600;text-decoration:none;background:#1a2744;color:#8892a4">Cyber</a></div>
|
||||
</style><style>#wnav{display:none!important}</style></head><body>
|
||||
<!-- BETON-DOCTRINE-101 dual-dummy block (pages pub) -->
|
||||
<div id="weval-global-logout" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection"></div>
|
||||
<a id="weval-gl" href="#" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection" tabindex="-1"></a>
|
||||
|
||||
<!-- CANONICAL BANNER doctrine 103 -->
|
||||
<div id="canonical-banner-v103" style="position:fixed;top:0;left:0;right:0;z-index:99990;background:linear-gradient(90deg,#1e293b,#0f172a);border-bottom:1px solid rgba(99,102,241,0.3);padding:8px 16px;display:flex;align-items:center;justify-content:space-between;font-family:Inter,system-ui,sans-serif;font-size:12px;backdrop-filter:blur(8px)">
|
||||
<span style="color:#94a3b8">Variante agents-* <span id="canonical-this-page" style="color:#64748b">(cette page)</span></span>
|
||||
<a href="/agents-archi.html" style="color:#a5b4fc;text-decoration:none;padding:4px 12px;background:rgba(99,102,241,0.15);border-radius:6px;border:1px solid rgba(99,102,241,0.25)">Voir canonical : agents-archi</a>
|
||||
<button type="button" aria-label="Fermer banner" onclick="this.parentElement.style.display='none'" style="background:transparent;border:none;color:#64748b;font-size:16px;cursor:pointer;padding:0 8px">×</button>
|
||||
</div>
|
||||
<style>#canonical-banner-v103+*{margin-top:36px!important}</style>
|
||||
<script>
|
||||
(function(){
|
||||
var el = document.getElementById('canonical-this-page');
|
||||
if(el) el.textContent = '(' + location.pathname.split('/').pop() + ')';
|
||||
})();
|
||||
</script>
|
||||
<!-- END CANONICAL BANNER -->
|
||||
<div id="wnav" style="display:none"><a href="/l99-saas.html" style="padding:2px 8px;border-radius:4px;font-size:9px;font-weight:600;text-decoration:none;background:#1a2744;color:#8892a4">L99</a><a href="/admin-saas.html" style="padding:2px 8px;border-radius:4px;font-size:9px;font-weight:600;text-decoration:none;background:#1a2744;color:#8892a4">Admin</a><a href="/realtime-monitor.html" style="padding:2px 8px;border-radius:4px;font-size:9px;font-weight:600;text-decoration:none;background:#1a2744;color:#8892a4">Monitor</a><a href="/agents-goodjob.html" style="padding:2px 8px;border-radius:4px;font-size:9px;font-weight:600;text-decoration:none;background:#1a2744;color:#8892a4">Enterprise</a><a href="/sovereign-claude.html" style="padding:2px 8px;border-radius:4px;font-size:9px;font-weight:600;text-decoration:none;background:#1a2744;color:#8892a4">Sovereign</a><a href="/cyber-monitor.html" style="padding:2px 8px;border-radius:4px;font-size:9px;font-weight:600;text-decoration:none;background:#1a2744;color:#8892a4">Cyber</a></div>
|
||||
<div id="hud"><b>WEVAL Enterprise</b><span id="st"></span><span style="margin-left:auto;font-size:.6rem;color:#64748b" id="hud-time"></span></div>
|
||||
<canvas id="c"></canvas>
|
||||
<div id="T"><b></b><i></i><span class="d"></span><span class="p"></span><span class="s"></span></div>
|
||||
@@ -887,4 +906,6 @@ requestAnimationFrame(loop);
|
||||
|
||||
|
||||
<script src="/api/a11y-auto-enhancer.js" defer></script>
|
||||
<!-- WTP_UDOCK_V1 (Opus 21-avr tour30) --><script src="/wtp-unified-dock.js" defer></script>
|
||||
<script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
|
||||
</body></html>
|
||||
|
||||
@@ -33,6 +33,25 @@ canvas{display:block}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- BETON-DOCTRINE-101 dual-dummy block (pages pub) -->
|
||||
<div id="weval-global-logout" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection"></div>
|
||||
<a id="weval-gl" href="#" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection" tabindex="-1"></a>
|
||||
|
||||
<!-- CANONICAL BANNER doctrine 103 -->
|
||||
<div id="canonical-banner-v103" style="position:fixed;top:0;left:0;right:0;z-index:99990;background:linear-gradient(90deg,#1e293b,#0f172a);border-bottom:1px solid rgba(99,102,241,0.3);padding:8px 16px;display:flex;align-items:center;justify-content:space-between;font-family:Inter,system-ui,sans-serif;font-size:12px;backdrop-filter:blur(8px)">
|
||||
<span style="color:#94a3b8">Variante agents-* <span id="canonical-this-page" style="color:#64748b">(cette page)</span></span>
|
||||
<a href="/agents-archi.html" style="color:#a5b4fc;text-decoration:none;padding:4px 12px;background:rgba(99,102,241,0.15);border-radius:6px;border:1px solid rgba(99,102,241,0.25)">Voir canonical : agents-archi</a>
|
||||
<button type="button" aria-label="Fermer banner" onclick="this.parentElement.style.display='none'" style="background:transparent;border:none;color:#64748b;font-size:16px;cursor:pointer;padding:0 8px">×</button>
|
||||
</div>
|
||||
<style>#canonical-banner-v103+*{margin-top:36px!important}</style>
|
||||
<script>
|
||||
(function(){
|
||||
var el = document.getElementById('canonical-this-page');
|
||||
if(el) el.textContent = '(' + location.pathname.split('/').pop() + ')';
|
||||
})();
|
||||
</script>
|
||||
<!-- END CANONICAL BANNER -->
|
||||
|
||||
<canvas id="c"></canvas>
|
||||
<div id="tip"><div class="box"><div class="nm"></div><div class="tp"></div><div class="ds"></div><div class="pr"></div><div class="bar"><i></i></div></div></div>
|
||||
<div id="hud">
|
||||
@@ -468,5 +487,7 @@ requestAnimationFrame(loop);
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
@@ -16,6 +16,21 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- CANONICAL BANNER doctrine 103 -->
|
||||
<div id="canonical-banner-v103" style="position:fixed;top:0;left:0;right:0;z-index:99990;background:linear-gradient(90deg,#1e293b,#0f172a);border-bottom:1px solid rgba(99,102,241,0.3);padding:8px 16px;display:flex;align-items:center;justify-content:space-between;font-family:Inter,system-ui,sans-serif;font-size:12px;backdrop-filter:blur(8px)">
|
||||
<span style="color:#94a3b8">Variante agents-* <span id="canonical-this-page" style="color:#64748b">(cette page)</span></span>
|
||||
<a href="/agents-archi.html" style="color:#a5b4fc;text-decoration:none;padding:4px 12px;background:rgba(99,102,241,0.15);border-radius:6px;border:1px solid rgba(99,102,241,0.25)">Voir canonical : agents-archi</a>
|
||||
<button type="button" aria-label="Fermer banner" onclick="this.parentElement.style.display='none'" style="background:transparent;border:none;color:#64748b;font-size:16px;cursor:pointer;padding:0 8px">×</button>
|
||||
</div>
|
||||
<style>#canonical-banner-v103+*{margin-top:36px!important}</style>
|
||||
<script>
|
||||
(function(){
|
||||
var el = document.getElementById('canonical-this-page');
|
||||
if(el) el.textContent = '(' + location.pathname.split('/').pop() + ')';
|
||||
})();
|
||||
</script>
|
||||
<!-- END CANONICAL BANNER -->
|
||||
|
||||
<canvas id="c"></canvas>
|
||||
<div id="tip"><b></b><i></i><p></p><s></s><em></em></div>
|
||||
<div id="h"><div style="font-weight:900;font-size:1.1rem"><span style="color:#e94560">WEVAL</span> <span style="color:#53d8fb">Enterprise</span></div><div><span>Agents <b>31</b></span> · <span>Actifs <b id="ac">0</b></span> · <span>Tasks <b id="tc" style="color:#f59e0b">0</b></span></div></div>
|
||||
@@ -328,5 +343,7 @@ requestAnimationFrame(loop);
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
@@ -12,6 +12,21 @@
|
||||
.int{background:rgba(16,185,129,.15);color:#10b981}.ext{background:rgba(99,102,241,.15);color:#818cf8}
|
||||
.section{padding:24px 40px}.section h2{font-size:20px;font-weight:700;margin-bottom:16px}
|
||||
</style></head><body>
|
||||
<!-- CANONICAL BANNER doctrine 103 -->
|
||||
<div id="canonical-banner-v103" style="position:fixed;top:0;left:0;right:0;z-index:99990;background:linear-gradient(90deg,#1e293b,#0f172a);border-bottom:1px solid rgba(99,102,241,0.3);padding:8px 16px;display:flex;align-items:center;justify-content:space-between;font-family:Inter,system-ui,sans-serif;font-size:12px;backdrop-filter:blur(8px)">
|
||||
<span style="color:#94a3b8">Variante agents-* <span id="canonical-this-page" style="color:#64748b">(cette page)</span></span>
|
||||
<a href="/agents-archi.html" style="color:#a5b4fc;text-decoration:none;padding:4px 12px;background:rgba(99,102,241,0.15);border-radius:6px;border:1px solid rgba(99,102,241,0.25)">Voir canonical : agents-archi</a>
|
||||
<button type="button" aria-label="Fermer banner" onclick="this.parentElement.style.display='none'" style="background:transparent;border:none;color:#64748b;font-size:16px;cursor:pointer;padding:0 8px">×</button>
|
||||
</div>
|
||||
<style>#canonical-banner-v103+*{margin-top:36px!important}</style>
|
||||
<script>
|
||||
(function(){
|
||||
var el = document.getElementById('canonical-this-page');
|
||||
if(el) el.textContent = '(' + location.pathname.split('/').pop() + ')';
|
||||
})();
|
||||
</script>
|
||||
<!-- END CANONICAL BANNER -->
|
||||
|
||||
<!-- MEGA-NAV -->
|
||||
<div style="background:rgba(99,102,241,.04);border-bottom:1px solid rgba(99,102,241,.1);padding:8px 40px;display:flex;gap:8px;flex-wrap:wrap;align-items:center">
|
||||
<span style="color:#64748b;font-size:11px;font-weight:600;letter-spacing:1px">HUBS</span>
|
||||
@@ -40,8 +55,8 @@
|
||||
<a href="/agents-fleet.html" class="card"><h3>📊 Fleet Overview</h3><p>13 agents status live</p><span class="badge int">INTERNE</span></a>
|
||||
<a href="/agents-valuechain.html" class="card"><h3>🎯 Value Chain</h3><p>Chaîne de valeur agents</p><span class="badge int">INTERNE</span></a>
|
||||
<a href="/agents-goodjob.html" class="card"><h3>💡 GoodJob</h3><p>Performance agents</p><span class="badge int">INTERNE</span></a>
|
||||
<a href="/agents-enterprise.html" class="card"><h3>🌐 Enterprise</h3><p>Vue enterprise agents</p><span class="badge int">INTERNE</span></a>
|
||||
<a href="/agents-sim.html" class="card"><h3>🔬 Simulation</h3><p>Simulation multi-agents</p><span class="badge int">INTERNE</span></a>
|
||||
<a href="/weval-enterprise-management.html" class="card"><h3>🌐 Enterprise</h3><p>Vue enterprise agents</p><span class="badge int">INTERNE</span></a>
|
||||
<a href="/agent-roi-simulator.html" class="card"><h3>🔬 Simulation</h3><p>Simulation multi-agents</p><span class="badge int">INTERNE</span></a>
|
||||
</div>
|
||||
<div class="section"><h2 style="color:#818cf8">⚙️ ORCHESTRATION</h2></div>
|
||||
<div class="grid"><a href="/wevia-master.html" class="card"><h3>🧠 WEVIA Master</h3><p>Multi-agents via chat (7 parallel)</p><span class="badge int">INTERNE</span></a>
|
||||
@@ -136,4 +151,6 @@
|
||||
<script src="/api/archi-meta-badge.js" defer></script>
|
||||
|
||||
<script src="/api/a11y-auto-enhancer.js" defer></script>
|
||||
<!-- WTP_UDOCK_V1 (Opus 21-avr t34final) --><script src="/wtp-unified-dock.js" defer></script>
|
||||
<script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
|
||||
</body></html>
|
||||
@@ -88,6 +88,21 @@ body{background:#0b1120;color:#e2e8f0;font-family:'Nunito';overflow-x:hidden}
|
||||
|
||||
@media(max-width:768px){.features{grid-template-columns:1fr}.hero h1{font-size:28px}.ag{width:80px}.ag-ico{font-size:20px}}
|
||||
</style></head><body>
|
||||
<!-- CANONICAL BANNER doctrine 103 -->
|
||||
<div id="canonical-banner-v103" style="position:fixed;top:0;left:0;right:0;z-index:99990;background:linear-gradient(90deg,#1e293b,#0f172a);border-bottom:1px solid rgba(99,102,241,0.3);padding:8px 16px;display:flex;align-items:center;justify-content:space-between;font-family:Inter,system-ui,sans-serif;font-size:12px;backdrop-filter:blur(8px)">
|
||||
<span style="color:#94a3b8">Variante agents-* <span id="canonical-this-page" style="color:#64748b">(cette page)</span></span>
|
||||
<a href="/agents-archi.html" style="color:#a5b4fc;text-decoration:none;padding:4px 12px;background:rgba(99,102,241,0.15);border-radius:6px;border:1px solid rgba(99,102,241,0.25)">Voir canonical : agents-archi</a>
|
||||
<button type="button" aria-label="Fermer banner" onclick="this.parentElement.style.display='none'" style="background:transparent;border:none;color:#64748b;font-size:16px;cursor:pointer;padding:0 8px">×</button>
|
||||
</div>
|
||||
<style>#canonical-banner-v103+*{margin-top:36px!important}</style>
|
||||
<script>
|
||||
(function(){
|
||||
var el = document.getElementById('canonical-this-page');
|
||||
if(el) el.textContent = '(' + location.pathname.split('/').pop() + ')';
|
||||
})();
|
||||
</script>
|
||||
<!-- END CANONICAL BANNER -->
|
||||
|
||||
|
||||
<div class="particles" id="particles"></div>
|
||||
|
||||
@@ -377,4 +392,6 @@ setInterval(loadMetrics,30000);
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
@@ -22,6 +22,25 @@ canvas{display:block}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- BETON-DOCTRINE-101 dual-dummy block (pages pub) -->
|
||||
<div id="weval-global-logout" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection"></div>
|
||||
<a id="weval-gl" href="#" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection" tabindex="-1"></a>
|
||||
|
||||
<!-- CANONICAL BANNER doctrine 103 -->
|
||||
<div id="canonical-banner-v103" style="position:fixed;top:0;left:0;right:0;z-index:99990;background:linear-gradient(90deg,#1e293b,#0f172a);border-bottom:1px solid rgba(99,102,241,0.3);padding:8px 16px;display:flex;align-items:center;justify-content:space-between;font-family:Inter,system-ui,sans-serif;font-size:12px;backdrop-filter:blur(8px)">
|
||||
<span style="color:#94a3b8">Variante agents-* <span id="canonical-this-page" style="color:#64748b">(cette page)</span></span>
|
||||
<a href="/agents-archi.html" style="color:#a5b4fc;text-decoration:none;padding:4px 12px;background:rgba(99,102,241,0.15);border-radius:6px;border:1px solid rgba(99,102,241,0.25)">Voir canonical : agents-archi</a>
|
||||
<button type="button" aria-label="Fermer banner" onclick="this.parentElement.style.display='none'" style="background:transparent;border:none;color:#64748b;font-size:16px;cursor:pointer;padding:0 8px">×</button>
|
||||
</div>
|
||||
<style>#canonical-banner-v103+*{margin-top:36px!important}</style>
|
||||
<script>
|
||||
(function(){
|
||||
var el = document.getElementById('canonical-this-page');
|
||||
if(el) el.textContent = '(' + location.pathname.split('/').pop() + ')';
|
||||
})();
|
||||
</script>
|
||||
<!-- END CANONICAL BANNER -->
|
||||
|
||||
<canvas id="c"></canvas>
|
||||
<div id="tip"><div class="tn"></div><div class="tt"></div><div class="td"></div><div class="tp"></div><div class="st"></div></div>
|
||||
<div id="hud">
|
||||
@@ -438,5 +457,7 @@ requestAnimationFrame(loop);
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
@@ -24,6 +24,21 @@ td{padding:10px 8px;border-bottom:1px solid #1e293b;color:#cbd5e1}
|
||||
.status-partial{color:#f59e0b;font-weight:600}
|
||||
.note{background:#1e293b;padding:14px;border-radius:8px;margin-top:24px;font-size:12px;color:#94a3b8;border-left:3px solid #c96442}
|
||||
</style></head><body>
|
||||
<!-- CANONICAL BANNER doctrine 103 -->
|
||||
<div id="canonical-banner-v103" style="position:fixed;top:0;left:0;right:0;z-index:99990;background:linear-gradient(90deg,#1e293b,#0f172a);border-bottom:1px solid rgba(99,102,241,0.3);padding:8px 16px;display:flex;align-items:center;justify-content:space-between;font-family:Inter,system-ui,sans-serif;font-size:12px;backdrop-filter:blur(8px)">
|
||||
<span style="color:#94a3b8">Variante agents-* <span id="canonical-this-page" style="color:#64748b">(cette page)</span></span>
|
||||
<a href="/agents-archi.html" style="color:#a5b4fc;text-decoration:none;padding:4px 12px;background:rgba(99,102,241,0.15);border-radius:6px;border:1px solid rgba(99,102,241,0.25)">Voir canonical : agents-archi</a>
|
||||
<button type="button" aria-label="Fermer banner" onclick="this.parentElement.style.display='none'" style="background:transparent;border:none;color:#64748b;font-size:16px;cursor:pointer;padding:0 8px">×</button>
|
||||
</div>
|
||||
<style>#canonical-banner-v103+*{margin-top:36px!important}</style>
|
||||
<script>
|
||||
(function(){
|
||||
var el = document.getElementById('canonical-this-page');
|
||||
if(el) el.textContent = '(' + location.pathname.split('/').pop() + ')';
|
||||
})();
|
||||
</script>
|
||||
<!-- END CANONICAL BANNER -->
|
||||
|
||||
<div class="hd"><h1>🤖 Agents Unified Registry — WEVIA EM</h1><div class="sub">Consolidation des 930 agents annoncés LinkedIn · Multi-sources reconciliation · Lean 6σ (Doctrine 78)</div></div>
|
||||
<div class="total-banner"><div class="n">930+</div><div class="l">Agents IA actifs (multi-sources consolidés)</div></div>
|
||||
<div class="breakdown">
|
||||
@@ -121,4 +136,6 @@ td{padding:10px 8px;border-bottom:1px solid #1e293b;color:#cbd5e1}
|
||||
|
||||
|
||||
<script src="/api/a11y-auto-enhancer.js" defer></script>
|
||||
<!-- WTP_UDOCK_V1 (Opus 21-avr t34final) --><script src="/wtp-unified-dock.js" defer></script>
|
||||
<script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
|
||||
</body></html>
|
||||
@@ -131,7 +131,26 @@ h1 span{background:linear-gradient(135deg,var(--cyan),var(--purple));-webkit-bac
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="padding-top:60px"><div style="position:fixed;top:0;left:0;right:0;height:28px;background:#ffffffee;z-index:100;display:flex;align-items:center;padding:0 14px;font-family:Nunito,sans-serif;font-size:.65rem;gap:12px;border-bottom:1px solid #e2e8f0;backdrop-filter:blur(8px)"><b style="color:#059669">WEVIA</b></div>
|
||||
<body style="padding-top:60px">
|
||||
<!-- BETON-DOCTRINE-101 dual-dummy block (pages pub) -->
|
||||
<div id="weval-global-logout" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection"></div>
|
||||
<a id="weval-gl" href="#" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection" tabindex="-1"></a>
|
||||
|
||||
<!-- CANONICAL BANNER doctrine 103 -->
|
||||
<div id="canonical-banner-v103" style="position:fixed;top:0;left:0;right:0;z-index:99990;background:linear-gradient(90deg,#1e293b,#0f172a);border-bottom:1px solid rgba(99,102,241,0.3);padding:8px 16px;display:flex;align-items:center;justify-content:space-between;font-family:Inter,system-ui,sans-serif;font-size:12px;backdrop-filter:blur(8px)">
|
||||
<span style="color:#94a3b8">Variante agents-* <span id="canonical-this-page" style="color:#64748b">(cette page)</span></span>
|
||||
<a href="/agents-archi.html" style="color:#a5b4fc;text-decoration:none;padding:4px 12px;background:rgba(99,102,241,0.15);border-radius:6px;border:1px solid rgba(99,102,241,0.25)">Voir canonical : agents-archi</a>
|
||||
<button type="button" aria-label="Fermer banner" onclick="this.parentElement.style.display='none'" style="background:transparent;border:none;color:#64748b;font-size:16px;cursor:pointer;padding:0 8px">×</button>
|
||||
</div>
|
||||
<style>#canonical-banner-v103+*{margin-top:36px!important}</style>
|
||||
<script>
|
||||
(function(){
|
||||
var el = document.getElementById('canonical-this-page');
|
||||
if(el) el.textContent = '(' + location.pathname.split('/').pop() + ')';
|
||||
})();
|
||||
</script>
|
||||
<!-- END CANONICAL BANNER -->
|
||||
<div style="position:fixed;top:0;left:0;right:0;height:28px;background:#ffffffee;z-index:100;display:flex;align-items:center;padding:0 14px;font-family:Nunito,sans-serif;font-size:.65rem;gap:12px;border-bottom:1px solid #e2e8f0;backdrop-filter:blur(8px)"><b style="color:#059669">WEVIA</b></div>
|
||||
<div style="position:fixed;top:30px;left:0;right:0;display:flex;justify-content:center;gap:5px;padding:4px;z-index:100;background:#f8fafcee;backdrop-filter:blur(8px);font-family:Nunito,sans-serif">
|
||||
<a href="/agents-archi.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Architecture</a>
|
||||
<a href="/director-center.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Director</a>
|
||||
@@ -485,5 +504,7 @@ render();
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
@@ -61,6 +61,10 @@ a{color:var(--cy);text-decoration:none}
|
||||
<link rel="stylesheet" href="/css/weval-premium.css">
|
||||
</head>
|
||||
<body>
|
||||
<!-- BETON-DOCTRINE-101 dual-dummy block (pages pub) -->
|
||||
<div id="weval-global-logout" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection"></div>
|
||||
<a id="weval-gl" href="#" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection" tabindex="-1"></a>
|
||||
|
||||
<div class="hdr">
|
||||
<div style="display:flex;align-items:center;gap:14px">
|
||||
<div style="width:36px;height:36px;background:linear-gradient(135deg,var(--vi),var(--pk));border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:17px">🏆</div>
|
||||
@@ -202,5 +206,7 @@ load();
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
@@ -178,4 +178,6 @@ h2{padding:12px 40px 0;font-size:15px;color:#0ea5e9;text-transform:uppercase;let
|
||||
<script src="/api/archi-meta-badge.js" defer></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>
|
||||
@@ -91,6 +91,10 @@ body{padding-bottom:26px}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- BETON-DOCTRINE-101 dual-dummy (entry point) -->
|
||||
<div id="weval-global-logout" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection"></div>
|
||||
<a id="weval-gl" href="#" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection" tabindex="-1"></a>
|
||||
|
||||
<header class="hdr">
|
||||
<div class="brand">
|
||||
<div class="logo">A</div>
|
||||
@@ -120,6 +124,8 @@ body{padding-bottom:26px}
|
||||
<span style="color:var(--mu);opacity:0.3">·</span>
|
||||
<a href="/wevcode.html" style="color:var(--mu);text-decoration:none;padding:3px 8px;border-radius:4px;transition:all 0.15s" onmouseover="this.style.background='var(--bg3)';this.style.color='#6ee7b7'" onmouseout="this.style.background='';this.style.color='var(--mu)'" title="WevCode · Sovereign Coding Agent v2.0">💻 WevCode</a>
|
||||
<span style="color:var(--mu);opacity:0.3">·</span>
|
||||
<a href="/playwright-v132-portfolio.html" style="color:var(--mu);text-decoration:none;padding:3px 8px;border-radius:4px;transition:all 0.15s" onmouseover="this.style.background='var(--bg3)';this.style.color='#34d399'" onmouseout="this.style.background='';this.style.color='var(--mu)'" title="V132 Playwright portfolio · 12 intents · 100% routing">🎯 V132 100%</a>
|
||||
<span style="color:var(--mu);opacity:0.3">·</span>
|
||||
<a href="/wevia-unified-hub.html" style="color:var(--mu);text-decoration:none;padding:3px 8px;border-radius:4px;transition:all 0.15s" onmouseover="this.style.background='var(--bg3)';this.style.color='#00d4b4'" onmouseout="this.style.background='';this.style.color='var(--mu)'" title="WEVIA Unified Hub · Truth Registry source unique">🧠 Truth Hub</a>
|
||||
<!-- V137-REFRESH: manual refresh button + fresh indicator -->
|
||||
<button id="v137-refresh-btn" onclick="event.stopPropagation();__v137RefreshHealth()" style="margin-left:auto;background:transparent;border:1px solid var(--bd);color:var(--mu);border-radius:4px;padding:2px 6px;cursor:pointer;font-size:10px;transition:all 0.15s" title="Refresh health live" onmouseover="this.style.color='var(--ac)';this.style.borderColor='var(--vl)'" onmouseout="this.style.color='var(--mu)';this.style.borderColor='var(--bd)'">↺</button>
|
||||
@@ -1050,6 +1056,17 @@ async function __v139LoadTruthStrip(){
|
||||
const d = await r.json();
|
||||
const setN = (id, n) => { const el = document.getElementById(id); if (el && n !== undefined) el.innerHTML = '· <strong style="color:var(--ac)">' + Number(n).toLocaleString('fr-FR') + '</strong> ' + id.replace('v139-',''); };
|
||||
setN('v139-agents', d.agents?.count_unique);
|
||||
// === AMBRE-V1 referentiel-unique sync (additif · doctrine #14) ===
|
||||
// Sync all agent count spots (h-ag header, t-ag truth strip, orch-agents orchestrator)
|
||||
// All read from same truth-registry source → 'référentiel unique' doctrine
|
||||
const setNumRaw = (id, n) => { const el = document.getElementById(id); if (el && n !== undefined && n !== null) el.textContent = Number(n).toLocaleString('fr-FR'); };
|
||||
setNumRaw('h-ag', d.agents?.count_unique);
|
||||
setNumRaw('t-ag', d.agents?.count_unique);
|
||||
setNumRaw('orch-agents', d.agents?.count_unique);
|
||||
// Also sync providers count if the header has it hardcoded
|
||||
setNumRaw('h-pv', d.providers?.count);
|
||||
setNumRaw('t-pv', d.providers?.count);
|
||||
// === END AMBRE-V1 ===
|
||||
// V141-AGENTS-TOOLTIP: expose dedup context on hover
|
||||
const agEl = document.getElementById('v139-agents');
|
||||
if (agEl && d.agents) {
|
||||
@@ -1306,5 +1323,6 @@ setInterval(refreshStats,60000);
|
||||
<span id="v142-ollama"></span>
|
||||
<span style="margin-left:auto;color:#00d4b4;font-size:9px"><a href="/wevia-unified-hub.html" style="color:inherit;text-decoration:none" title="Truth Hub">Truth →</a></span>
|
||||
</div>
|
||||
<script>(function(){var p=window.location.pathname;var pub=["/","/index.html","/wevia.html","/wevia-widget.html","/enterprise-model.html","/wevia","/login","/register.html","/agents-archi.html","/wevia-meeting-rooms.html","/director-center.html","/director-chat.html","/l99-brain.html","/agents-fleet.html","/value-streaming.html","/architecture.html","/openclaw.html","/l99-saas.html","/admin-saas.html","/agents-goodjob.html","/ai-benchmark.html","/oss-discovery.html","/paperclip.html","/agents-3d.html","/agents-alive.html","/agents-enterprise.html","/agents-hd.html","/agents-iso3d.html","/agents-sim.html","/agents-valuechain.html","/avatar-picker.html"];var isPub=pub.indexOf(p)>=0||p.indexOf("/products/")===0||p.indexOf("/solutions/")===0||p.indexOf("/blog/")===0||p.indexOf("/service/")===0||p.indexOf("/marketplace")===0||p.indexOf("/contact")===0||p.indexOf("/tarifs")===0||p.indexOf("/news")===0;if(isPub||document.getElementById("weval-gl"))return;var a=document.createElement("a");a.id="weval-gl";a.href="/logout";a.textContent="Logout";a.style.cssText="position:fixed;top:10px;right:12px;z-index:99990;padding:5px 10px;background:rgba(30,30,50,0.7);color:rgba(200,210,230,0.8);border:1px solid rgba(100,100,140,0.3);border-radius:6px;font:500 11px system-ui,sans-serif;text-decoration:none;opacity:0.6;cursor:pointer;backdrop-filter:blur(6px);transition:all .15s";a.onmouseover=function(){this.style.opacity="1";this.style.background="rgba(239,68,68,0.85)";this.style.color="white"};a.onmouseout=function(){this.style.opacity="0.6";this.style.background="rgba(30,30,50,0.7)";this.style.color="rgba(200,210,230,0.8)"};document.body.appendChild(a)})()</script><script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -63,3 +63,4 @@ Pour créer un fichier vide et l'ouvrir, utilisez la commande suivante :
|
||||
})();
|
||||
</script>
|
||||
<!-- === OPUS UNIVERSAL DRILL-DOWN END === -->
|
||||
<!-- WTP_UDOCK_V1 (Opus 21-avr t37-100pct) --><script src="/wtp-unified-dock.js" defer></script>
|
||||
|
||||
@@ -23,7 +23,7 @@ p.sub{color:#64748b;margin-bottom:32px;font-size:14px}
|
||||
<a class="card" href="https://console.anthropic.com" target="_blank"><h3>💻 Console API</h3><p>API keys, usage, billing, models</p><span class="tag">API</span></a>
|
||||
<a class="card" href="https://docs.anthropic.com" target="_blank"><h3>📖 Documentation</h3><p>API reference, guides, prompting</p><span class="tag" style="background:rgba(52,211,153,.12);color:#34d399">DOCS</span></a>
|
||||
<a class="card" href="/wevia-master.html"><h3>🤖 WEVIA Master</h3><p>Master chat avec cascade 14 providers + Claude</p><span class="tag" style="background:rgba(167,139,250,.12);color:#a78bfa">MASTER</span></a>
|
||||
<a class="card" href="/claude-sync.html"><h3>🔄 Claude Sync</h3><p>Synchronisation conversations Claude ↔ WEVIA</p><span class="tag" style="background:rgba(251,191,36,.12);color:#fbbf24">SYNC</span></a>
|
||||
<a class="card" href="/sovereign-claude.html"><h3>🔄 Claude Sync</h3><p>Synchronisation conversations Claude ↔ WEVIA</p><span class="tag" style="background:rgba(251,191,36,.12);color:#fbbf24">SYNC</span></a>
|
||||
<a class="card" href="/api-key-hub.html"><h3>🔑 API Keys</h3><p>Gestion cle Anthropic + rotation</p><span class="tag" style="background:rgba(248,113,113,.12);color:#f87171">KEYS</span></a>
|
||||
</div></div><!-- CARTO_REMOVED -->
|
||||
<!-- CARTO_BANNER_V1 -->
|
||||
@@ -111,4 +111,6 @@ p.sub{color:#64748b;margin-bottom:32px;font-size:14px}
|
||||
<script src="/api/archi-meta-badge.js" defer></script>
|
||||
|
||||
<script src="/api/a11y-auto-enhancer.js" defer></script>
|
||||
<!-- WTP_UDOCK_V1 (Opus 21-avr t34final) --><script src="/wtp-unified-dock.js" defer></script>
|
||||
<script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
|
||||
</body></html>
|
||||
|
||||
@@ -248,5 +248,7 @@ loadStatus();
|
||||
<script src="/api/archi-meta-badge.js" defer></script>
|
||||
|
||||
<script src="/api/a11y-auto-enhancer.js" defer></script>
|
||||
<!-- WTP_UDOCK_V1 (Opus 21-avr t31b3) --><script src="/wtp-unified-dock.js" defer></script>
|
||||
<script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"agent": "V41_Disk_Monitor",
|
||||
"ts": "2026-04-21T12:30:01+02:00",
|
||||
"disk_pct": 81,
|
||||
"disk_free_gb": 29,
|
||||
"ts": "2026-04-21T16:30:01+02:00",
|
||||
"disk_pct": 82,
|
||||
"disk_free_gb": 27,
|
||||
"growth_per_day_gb": 1.5,
|
||||
"runway_days": 19,
|
||||
"runway_days": 18,
|
||||
"alert": "WARN_runway_under_30d",
|
||||
"action_auto_if_under_7d": "trigger_hetzner_volume_extension_api",
|
||||
"hetzner_volume_size_gb_recommended": 500,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V41_Risk_Escalation",
|
||||
"ts": "2026-04-21T12:30:03+02:00",
|
||||
"ts": "2026-04-21T16:15:03+02:00",
|
||||
"dg_alerts_active": 7,
|
||||
"wevia_life_stats_preview": "{
|
||||
"ok": true,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"agent": "V41_Feature_Adoption_Tracker",
|
||||
"ts": "2026-04-21T12:00:02+02:00",
|
||||
"ts": "2026-04-21T16:00:02+02:00",
|
||||
"features_tracked": 15,
|
||||
"features_used_24h": 12,
|
||||
"adoption_pct": 80,
|
||||
"chat_queries_last_1k_log": 17,
|
||||
"wtp_views_last_1k_log": 102,
|
||||
"dg_views_last_1k_log": 13,
|
||||
"chat_queries_last_1k_log": 5,
|
||||
"wtp_views_last_1k_log": 34,
|
||||
"dg_views_last_1k_log": 3,
|
||||
"skill_runs_last_1k_log": 0,
|
||||
"recommendation": "UX onboarding tour for unused features",
|
||||
"cron_schedule": "hourly",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V45_Leads_Sync",
|
||||
"ts": "2026-04-21T12:40:03+02:00",
|
||||
"ts": "2026-04-21T16:20:02+02:00",
|
||||
"paperclip_total": 48,
|
||||
"active_customer": 4,
|
||||
"warm_prospect": 5,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V41_MQL_Scoring",
|
||||
"ts": "2026-04-21T12:00:02+02:00",
|
||||
"ts": "2026-04-21T16:00:03+02:00",
|
||||
"leads_total": 48,
|
||||
"mql_current": 16,
|
||||
"sql_current": 6,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V60_Nudge_Owner_Actions",
|
||||
"ts": "2026-04-21T08:00:01+02:00",
|
||||
"ts": "2026-04-21T16:00:01+02:00",
|
||||
"cron": "every_8_hours",
|
||||
"actions_pending_owner": {
|
||||
"emails_drafts_V45_to_send": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V54_Risk_Monitor_Live",
|
||||
"ts": "2026-04-21T12:30:03+02:00",
|
||||
"ts": "2026-04-21T16:00:04+02:00",
|
||||
"critical_risks": {
|
||||
"RW01_pipeline_vide": {
|
||||
"pipeline_keur": 0,
|
||||
@@ -22,7 +22,7 @@
|
||||
},
|
||||
"RW12_burnout": {
|
||||
"agents_cron_active": 15,
|
||||
"load_5min": "3.54",
|
||||
"load_5min": "3.97",
|
||||
"automation_coverage_pct": 70,
|
||||
"residual_risk_pct": 60,
|
||||
"trend": "V52_goldratt_options_active"
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"timestamp": "2026-04-21 12:00",
|
||||
"timestamp": "2026-04-21 16:00",
|
||||
"sections": {
|
||||
"servers": {
|
||||
"S204": {
|
||||
"docker": 19,
|
||||
"disk": "81%",
|
||||
"ram": "14Gi/30Gi",
|
||||
"load": "2.61",
|
||||
"uptime": "up 1 week, 8 minutes"
|
||||
"disk": "82%",
|
||||
"ram": "11Gi/30Gi",
|
||||
"load": "9.88",
|
||||
"uptime": "up 1 week, 4 hours, 8 minutes"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
@@ -15,7 +15,7 @@
|
||||
"containers": [
|
||||
{
|
||||
"name": "loki",
|
||||
"status": "Up 4 days",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
@@ -70,48 +70,48 @@
|
||||
},
|
||||
{
|
||||
"name": "redis-weval",
|
||||
"status": "Up 6 days",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "gitea",
|
||||
"status": "Up 6 days",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "node-exporter",
|
||||
"status": "Up 6 days",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "prometheus",
|
||||
"status": "Up 6 days",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "searxng",
|
||||
"status": "Up 6 days",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "uptime-kuma",
|
||||
"status": "Up 34 hours (healthy)",
|
||||
"status": "Up 38 hours (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "vaultwarden",
|
||||
"status": "Up 6 days (healthy)",
|
||||
"status": "Up 7 days (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "qdrant",
|
||||
"status": "Up 6 days",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"apis": {
|
||||
"count": 271,
|
||||
"count": 272,
|
||||
"files": [
|
||||
"wevia-stream-sovereign.php",
|
||||
"wevia-pending-loader.php",
|
||||
@@ -277,6 +277,7 @@
|
||||
"wevia-post-exec.php",
|
||||
"wevia-apple-intents.php",
|
||||
"wevia-v73-intents-include.php",
|
||||
"wevia-sanitizer-guard.php",
|
||||
"wevia-v81-ai-audit-100.php",
|
||||
"wevia-patch-file.php",
|
||||
"wevia-dashboard.php",
|
||||
@@ -387,8 +388,8 @@
|
||||
]
|
||||
},
|
||||
"routes": {
|
||||
"lines": 3620,
|
||||
"count": 445
|
||||
"lines": 3681,
|
||||
"count": 446
|
||||
},
|
||||
"skills": {
|
||||
"count": 835
|
||||
@@ -479,7 +480,7 @@
|
||||
]
|
||||
},
|
||||
"pages": {
|
||||
"count": 293
|
||||
"count": 315
|
||||
},
|
||||
"opt_tools": {
|
||||
"count": 91
|
||||
@@ -488,7 +489,7 @@
|
||||
"pairs": 5751
|
||||
},
|
||||
"wiki": {
|
||||
"entries": 1928
|
||||
"entries": 1988
|
||||
}
|
||||
}
|
||||
}
|
||||
14
api/ambre-adg-diag.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$f = "/var/www/html/api/ambre-early-doc-gen.php";
|
||||
$out = ["size"=>@filesize($f)];
|
||||
$lint = @shell_exec("php8.4 -l $f 2>&1");
|
||||
$out["lint"] = trim($lint);
|
||||
// Try to eval the file with mock $_mam set
|
||||
$_mam = "Genere un PDF sur: test";
|
||||
ob_start();
|
||||
$rr = @include $f;
|
||||
$out["include_ok"] = $rr !== false;
|
||||
$out["stray_output"] = ob_get_clean();
|
||||
// If exited, ob would have file_gen response. Otherwise, fall through
|
||||
echo json_encode($out);
|
||||
122
api/ambre-count.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-count.php — AMBRE session · aggregator chiffres unifiés
|
||||
* Lit depuis truth-registry (canonical) + tool-registry + filesystem + ethica API
|
||||
* Returns flat JSON scalars pour consumption par __ambre_truth_snapshot et UI.
|
||||
* Doctrine #4 : zéro hardcode, toutes les valeurs depuis source live.
|
||||
*/
|
||||
header("Content-Type: application/json");
|
||||
|
||||
$out = [
|
||||
'ok' => true,
|
||||
'ts' => date('c'),
|
||||
'sources' => [],
|
||||
];
|
||||
|
||||
// === 1. Truth Registry (primary source of truth) ===
|
||||
$tr_path = '/var/www/html/api/wevia-truth-registry.json';
|
||||
if (file_exists($tr_path)) {
|
||||
$tr = @json_decode(@file_get_contents($tr_path), true);
|
||||
if (is_array($tr)) {
|
||||
$out['sources'][] = 'truth-registry';
|
||||
$out['built_at'] = $tr['built_at'] ?? null;
|
||||
$out['agents'] = $tr['agents']['count_unique'] ?? null;
|
||||
$out['agents_overlaps'] = $tr['agents']['count_with_overlaps'] ?? null;
|
||||
$out['intents'] = $tr['intents']['count'] ?? null;
|
||||
$out['skills'] = $tr['skills']['TOTAL'] ?? $tr['skills']['count'] ?? null;
|
||||
$out['brains'] = $tr['brains']['count'] ?? null;
|
||||
$out['doctrines'] = $tr['doctrines']['count'] ?? null;
|
||||
$out['dashboards']= $tr['dashboards']['count'] ?? null;
|
||||
$out['providers'] = count($tr['providers']['list'] ?? []) ?: ($tr['providers']['declared_total'] ?? null);
|
||||
$out['nonreg_score'] = $tr['nonreg']['score'] ?? null;
|
||||
$out['autonomy'] = $tr['autonomy_level'] ?? null;
|
||||
$out['apis_php'] = $tr['apis_php_count'] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
// === 2. Tool Registry (for tools count) ===
|
||||
$reg_path = '/var/www/html/api/wevia-tool-registry.json';
|
||||
if (file_exists($reg_path)) {
|
||||
$reg = @json_decode(@file_get_contents($reg_path), true);
|
||||
if (is_array($reg)) {
|
||||
$out['sources'][] = 'tool-registry';
|
||||
$out['tools'] = count($reg['tools'] ?? []);
|
||||
}
|
||||
}
|
||||
|
||||
// === 3. Filesystem counts (pages, apis) ===
|
||||
$html = @glob('/var/www/html/*.html') ?: [];
|
||||
$out['pages'] = count($html);
|
||||
$apis = @glob('/var/www/html/api/*.php') ?: [];
|
||||
$out['apis_files'] = count($apis);
|
||||
$stubs = @glob('/var/www/html/api/wired-pending/*.php') ?: [];
|
||||
$out['wired_stubs'] = count($stubs);
|
||||
$out['sources'][] = 'filesystem';
|
||||
|
||||
// === 4. Ethica HCPs (live API) ===
|
||||
$ethica_sources = [
|
||||
'http://127.0.0.1/api/ethica-country-api.php',
|
||||
'/var/www/html/api/ethica-cache.json',
|
||||
];
|
||||
foreach ($ethica_sources as $src) {
|
||||
if (strpos($src, 'http') === 0) {
|
||||
$ch = @curl_init($src);
|
||||
@curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>3, CURLOPT_CONNECTTIMEOUT=>2]);
|
||||
$raw = @curl_exec($ch); @curl_close($ch);
|
||||
} else {
|
||||
$raw = file_exists($src) ? @file_get_contents($src) : null;
|
||||
}
|
||||
if ($raw) {
|
||||
$d = @json_decode($raw, true);
|
||||
if (is_array($d)) {
|
||||
$candidates = [
|
||||
$d['total'] ?? null,
|
||||
$d['hcps_total'] ?? null,
|
||||
$d['ethica_hcps'] ?? null,
|
||||
$d['count'] ?? null,
|
||||
];
|
||||
foreach ($candidates as $c) {
|
||||
if (is_numeric($c) && $c > 1000) { $out['hcps'] = (int)$c; $out['sources'][] = 'ethica-api'; break 2; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// === 5. Qdrant collections count ===
|
||||
$qh = @curl_init('http://127.0.0.1:6333/collections');
|
||||
if ($qh) {
|
||||
@curl_setopt_array($qh, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>2]);
|
||||
$qraw = @curl_exec($qh); @curl_close($qh);
|
||||
if ($qraw) {
|
||||
$qd = @json_decode($qraw, true);
|
||||
if (isset($qd['result']['collections']) && is_array($qd['result']['collections'])) {
|
||||
$out['qdrant_collections'] = count($qd['result']['collections']);
|
||||
$out['sources'][] = 'qdrant';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// === 6. Docker count ===
|
||||
$docker = @trim(@shell_exec('docker ps -q 2>/dev/null | wc -l'));
|
||||
if (is_numeric($docker)) { $out['docker'] = (int)$docker; $out['sources'][] = 'docker'; }
|
||||
|
||||
// === 7. Crons ===
|
||||
$crons = @trim(@shell_exec('crontab -l 2>/dev/null | grep -cv "^#"'));
|
||||
if (is_numeric($crons)) $out['crons'] = (int)$crons;
|
||||
|
||||
// === 8. NonReg live ===
|
||||
$nr_path = '/var/www/html/api/nonreg-latest.json';
|
||||
if (file_exists($nr_path)) {
|
||||
$nr = @json_decode(@file_get_contents($nr_path), true);
|
||||
if (is_array($nr)) {
|
||||
$out['nonreg_pass'] = $nr['pass'] ?? null;
|
||||
$out['nonreg_total'] = $nr['total'] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
// === Fill any remaining nulls with '?' for display clarity ===
|
||||
foreach (['agents','intents','skills','brains','doctrines','dashboards','providers','tools','hcps','pages','qdrant_collections','apis_php','nonreg_score','autonomy','built_at','docker','crons'] as $k) {
|
||||
if (!isset($out[$k]) || $out[$k] === null) $out[$k] = '?';
|
||||
}
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
11
api/ambre-diag-aide.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
@require_once "/var/www/html/api/wevia-fast-path-v3.php";
|
||||
$r = function_exists("wevia_fast_path") ? wevia_fast_path("aide") : null;
|
||||
$snapshot = function_exists("__ambre_truth_snapshot") ? __ambre_truth_snapshot() : null;
|
||||
echo json_encode([
|
||||
"fn_fast_path" => function_exists("wevia_fast_path"),
|
||||
"fn_helper" => function_exists("__ambre_truth_snapshot"),
|
||||
"fp_result" => $r,
|
||||
"snapshot" => $snapshot,
|
||||
], JSON_PRETTY_PRINT);
|
||||
42
api/ambre-diag-snapshot.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-diag-snapshot.php — appelle __ambre_truth_snapshot et dump resultat
|
||||
*/
|
||||
header("Content-Type: application/json");
|
||||
|
||||
// Load fast-path-v3 to have the function available
|
||||
$fp = "/var/www/html/api/wevia-fast-path-v3.php";
|
||||
if (file_exists($fp)) @require_once $fp;
|
||||
|
||||
$fn_exists = function_exists("__ambre_truth_snapshot");
|
||||
$out = ["ok" => true, "helper_loaded" => $fn_exists];
|
||||
|
||||
if ($fn_exists) {
|
||||
$out["snapshot"] = __ambre_truth_snapshot();
|
||||
}
|
||||
|
||||
// Also load truth registry ourselves to see nested structure
|
||||
$p = "/var/www/html/api/wevia-truth-registry.json";
|
||||
if (file_exists($p)) {
|
||||
$d = @json_decode(@file_get_contents($p), true);
|
||||
if (is_array($d)) {
|
||||
$out["file_ok"] = true;
|
||||
$out["file_size"] = filesize($p);
|
||||
$out["top_keys"] = array_keys($d);
|
||||
|
||||
// Probe nested structures to find count-like fields
|
||||
foreach (["tools","providers","intents","skills","brains","doctrines","dashboards","nonreg"] as $k) {
|
||||
if (isset($d[$k]) && is_array($d[$k])) {
|
||||
$out["nested"][$k] = [
|
||||
"keys" => array_keys($d[$k]),
|
||||
];
|
||||
// List sub-types
|
||||
foreach ($d[$k] as $sk => $sv) {
|
||||
$out["nested"][$k]["types"][$sk] = is_array($sv) ? "array[" . count($sv) . "]" : (is_numeric($sv) ? "num=" . $sv : gettype($sv));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT);
|
||||
88
api/ambre-doc-gen.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-doc-gen.php · AMBRE · real file generation via pandoc
|
||||
* Usage: POST {type: pdf|docx|pptx|html, title: "...", content: "markdown..."}
|
||||
* Output: {ok:true, url:"/generated/xxx.ext", size:B, type:..., ts:...}
|
||||
* Doctrine: zero fake (réelle génération), zero écrasement (unique timestamp per file)
|
||||
*/
|
||||
header("Content-Type: application/json");
|
||||
|
||||
// === Input parsing ===
|
||||
$raw = file_get_contents("php://input");
|
||||
$in = json_decode($raw, true);
|
||||
if (!$in && !empty($_POST)) $in = $_POST;
|
||||
|
||||
$type = strtolower(trim($in["type"] ?? "pdf"));
|
||||
$title = trim($in["title"] ?? "Document WEVIA");
|
||||
$content = $in["content"] ?? "";
|
||||
|
||||
if (!$content) {
|
||||
http_response_code(400);
|
||||
echo json_encode(["ok"=>false, "error"=>"content required"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// === Type validation ===
|
||||
$allowed = ["pdf","docx","pptx","html","odt","epub"];
|
||||
if (!in_array($type, $allowed)) {
|
||||
http_response_code(400);
|
||||
echo json_encode(["ok"=>false, "error"=>"invalid type", "allowed"=>$allowed]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// === Prepare output dir ===
|
||||
$outdir = "/var/www/html/generated";
|
||||
if (!is_dir($outdir)) @mkdir($outdir, 0755, true);
|
||||
|
||||
$ts = date("Ymd-His");
|
||||
$rand = substr(md5(random_bytes(8)), 0, 6);
|
||||
$safe_title = preg_replace("/[^a-zA-Z0-9\-_]/", "-", substr($title, 0, 40));
|
||||
$basename = "wevia-{$safe_title}-{$ts}-{$rand}";
|
||||
$md_path = "$outdir/$basename.md";
|
||||
$out_path = "$outdir/$basename.$type";
|
||||
|
||||
// === Write markdown input ===
|
||||
$md_content = "# $title\n\n" . $content;
|
||||
file_put_contents($md_path, $md_content);
|
||||
|
||||
// === Generate via pandoc ===
|
||||
$start = microtime(true);
|
||||
if ($type === "pdf") {
|
||||
// Use wkhtmltopdf via pandoc for better rendering
|
||||
$cmd = "pandoc " . escapeshellarg($md_path) . " --pdf-engine=wkhtmltopdf -o " . escapeshellarg($out_path) . " 2>&1";
|
||||
} else if ($type === "pptx" || $type === "docx" || $type === "odt" || $type === "html" || $type === "epub") {
|
||||
$cmd = "pandoc " . escapeshellarg($md_path) . " -o " . escapeshellarg($out_path) . " 2>&1";
|
||||
}
|
||||
$cmd_output = @shell_exec("timeout 30 $cmd");
|
||||
$elapsed = round((microtime(true) - $start) * 1000);
|
||||
|
||||
// === Check result ===
|
||||
if (!file_exists($out_path) || filesize($out_path) === 0) {
|
||||
@unlink($md_path);
|
||||
echo json_encode([
|
||||
"ok" => false,
|
||||
"error" => "pandoc failed",
|
||||
"pandoc_output" => $cmd_output,
|
||||
"cmd" => $cmd,
|
||||
"elapsed_ms" => $elapsed,
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$size = filesize($out_path);
|
||||
$url = "/generated/$basename.$type";
|
||||
|
||||
// Keep md source for provenance
|
||||
echo json_encode([
|
||||
"ok" => true,
|
||||
"url" => $url,
|
||||
"full_url" => "https://weval-consulting.com$url",
|
||||
"size" => $size,
|
||||
"size_human" => $size > 1024 ? round($size/1024, 1) . "KB" : "$size B",
|
||||
"type" => $type,
|
||||
"title" => $title,
|
||||
"elapsed_ms" => $elapsed,
|
||||
"md_source" => "/generated/$basename.md",
|
||||
"ts" => date("c"),
|
||||
"engine" => $type === "pdf" ? "pandoc+wkhtmltopdf" : "pandoc",
|
||||
], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
32
api/ambre-dump.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-dump.php · AMBRE session · standalone file reader
|
||||
* Allowed roots only. Returns RAW content (Content-Type: text/plain)
|
||||
* Invocation: /api/ambre-dump.php?path=/var/www/html/xxx&offset=0&length=50000
|
||||
*/
|
||||
$target = $_GET["path"] ?? "";
|
||||
$offset = (int)($_GET["offset"] ?? 0);
|
||||
$length = min((int)($_GET["length"] ?? 50000), 200000);
|
||||
|
||||
$real = realpath($target);
|
||||
$allowed = ["/var/www/html/", "/opt/wevads/", "/opt/weval-l99/"];
|
||||
$ok = false;
|
||||
foreach ($allowed as $root) {
|
||||
if ($real && strpos($real, $root) === 0) { $ok = true; break; }
|
||||
}
|
||||
if (!$ok || !file_exists($real)) {
|
||||
http_response_code(404);
|
||||
header("Content-Type: application/json");
|
||||
echo json_encode(["ok"=>false, "error"=>"denied or not found"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
header("Content-Type: text/plain; charset=utf-8");
|
||||
header("X-Ambre-Source: ambre-dump.php doctrine#4 honest");
|
||||
header("X-File-Size: " . filesize($real));
|
||||
header("X-File-Mtime: " . gmdate("c", filemtime($real)));
|
||||
|
||||
$fh = fopen($real, "r");
|
||||
fseek($fh, $offset);
|
||||
echo fread($fh, $length);
|
||||
fclose($fh);
|
||||
202
api/ambre-early-doc-gen.php
Normal file
@@ -0,0 +1,202 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-early-doc-gen.php · v4 · 5 capabilities réelles
|
||||
* 1. File gen pdf/docx/pptx via pandoc
|
||||
* 2. xlsx via PhpSpreadsheet (si dispo, sinon fallback docx)
|
||||
* 3. Mermaid validated
|
||||
* 4. Image SVG via LLM structured prompt
|
||||
* 5. Code with file URL (py/js/html/php depending on topic)
|
||||
*/
|
||||
|
||||
static $__ad_already = false;
|
||||
if ($__ad_already) return;
|
||||
$__ad_already = true;
|
||||
|
||||
$__ad_raw = @file_get_contents("php://input");
|
||||
if (!$__ad_raw) return;
|
||||
$__ad_body = @json_decode($__ad_raw, true);
|
||||
$__ad_msg = trim($__ad_body["message"] ?? "");
|
||||
if (!$__ad_msg) return;
|
||||
|
||||
// ========== HANDLER 1: xlsx réel via PhpSpreadsheet ==========
|
||||
if (preg_match("/g[eéèê]n[eéèê]re?\s+(?:un|une)?\s*(?:tableau\s+)?excel|xlsx/iu", $__ad_msg) &&
|
||||
preg_match("/(?::|pour|sur)\s*(.+)$/iu", $__ad_msg, $__xm)) {
|
||||
$__xlsx_topic = trim($__xm[1]);
|
||||
// try PhpSpreadsheet
|
||||
$__xl_url = "http://127.0.0.1/api/ambre-xlsx-gen.php?topic=" . urlencode($__xlsx_topic);
|
||||
$__xl_out = @file_get_contents($__xl_url, false, stream_context_create(["http"=>["timeout"=>60,"header"=>"Host: weval-consulting.com\r\n"]]));
|
||||
$__xl_d = @json_decode($__xl_out, true);
|
||||
if ($__xl_d && !empty($__xl_d["ok"]) && !empty($__xl_d["url"])) {
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
echo json_encode([
|
||||
"response"=>"📊 **" . $__xlsx_topic . "** (Excel)\n\n🔗 Télécharger: " . $__xl_d["full_url"] . "\n📦 Taille: " . $__xl_d["size_human"] . " · ⚙️ " . $__xl_d["elapsed_ms"] . "ms · engine: PhpSpreadsheet\n\n" . ($__xl_d["preview"] ?? ""),
|
||||
"executed"=>true,"provider"=>"ambre-doc-gen-v5","intent"=>"xlsx_real","topic"=>$__xlsx_topic,
|
||||
], JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
|
||||
exit;
|
||||
}
|
||||
// fallback to docx handler below
|
||||
}
|
||||
|
||||
// ========== HANDLER 2: File generation PDF/DOCX/PPTX ==========
|
||||
if (preg_match("/g[eéèê]n[eéèê]re?\s+(?:un|une|des|le|la)?\s*(pdf|pptx?|powerpoint|docx?|word|excel|xlsx?|pr[eéèê]sentation|presentation|document|tableau)[^:]*(?::|sur|pour)\s*(.+)$/iu", $__ad_msg, $__ad_m)) {
|
||||
$__raw_type = mb_strtolower($__ad_m[1]);
|
||||
$__topic = trim($__ad_m[2]);
|
||||
$__type_map = [
|
||||
"pdf"=>"pdf","pptx"=>"pptx","ppt"=>"pptx","powerpoint"=>"pptx",
|
||||
"presentation"=>"pptx","présentation"=>"pptx",
|
||||
"docx"=>"docx","doc"=>"docx","word"=>"docx","document"=>"docx",
|
||||
"xlsx"=>"xlsx","excel"=>"xlsx","tableau"=>"xlsx",
|
||||
];
|
||||
$__type = $__type_map[$__raw_type] ?? "pdf";
|
||||
$__pandoc_type = ($__type === "xlsx") ? "docx" : $__type;
|
||||
|
||||
$__url = "http://127.0.0.1/api/ambre-gen-pipeline.php?type=" . urlencode($__pandoc_type) . "&topic=" . urlencode($__topic);
|
||||
$__out = @file_get_contents($__url, false, stream_context_create(["http"=>["timeout"=>75,"method"=>"GET","header"=>"Host: weval-consulting.com\r\n"]]));
|
||||
|
||||
if ($__out && strlen($__out) > 50) {
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
echo json_encode([
|
||||
"response"=>$__out,"executed"=>true,"provider"=>"ambre-doc-gen-v5",
|
||||
"intent"=>"file_generation_real","type"=>$__type,"topic"=>$__topic,
|
||||
], JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// ========== HANDLER 3: Mermaid validated ==========
|
||||
if (preg_match("/g[eéèê]n[eéèê]re?.*(sch[eéèê]ma|mermaid|diagramme|flowchart).*(?::|pour|sur)\s*(.+)$/iu", $__ad_msg, $__mm)) {
|
||||
$__topic = trim($__mm[2]);
|
||||
$__sys = "Tu es generateur de diagrammes Mermaid. Reponds UNIQUEMENT avec code mermaid valide, pas de markdown, pas de backticks. Commence par \"flowchart TD\" ou \"graph TD\". Syntaxe: A[Label] --> B[Label]. MAX 12 nodes.";
|
||||
$__user = "Genere un flowchart mermaid VALIDE pour: $__topic";
|
||||
$__llm = @file_get_contents("http://127.0.0.1:4000/v1/chat/completions", false, stream_context_create([
|
||||
"http"=>["method"=>"POST","header"=>"Content-Type: application/json\r\n",
|
||||
"content"=>json_encode(["model"=>"fast","messages"=>[
|
||||
["role"=>"system","content"=>$__sys],["role"=>"user","content"=>$__user]
|
||||
],"max_tokens"=>400,"temperature"=>0.1]),"timeout"=>20]
|
||||
]));
|
||||
$__mmd = @json_decode($__llm,true)["choices"][0]["message"]["content"] ?? "";
|
||||
$__mmd = trim(preg_replace("/```(?:mermaid)?\n?|```/","",$__mmd));
|
||||
if (!preg_match("/^(flowchart|graph|sequenceDiagram|classDiagram)/i", $__mmd)) $__mmd = "flowchart TD\n$__mmd";
|
||||
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
echo json_encode([
|
||||
"response"=>"🧩 Schema Mermaid: $__topic\n\n".chr(96).chr(96).chr(96)."mermaid\n$__mmd\n".chr(96).chr(96).chr(96),
|
||||
"executed"=>true,"provider"=>"ambre-doc-gen-v5","intent"=>"mermaid_valid","topic"=>$__topic,
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ========== HANDLER 4: Image SVG via LLM ==========
|
||||
if (preg_match("/g[eéèê]n[eéèê]re?\s+(?:une|un)?\s*image\s*(?:\b(?:decrivant|repr[eéèê]sentant|pour|sur|de)\b\s*)?:?\s*(.+)$/iu", $__ad_msg, $__im)) {
|
||||
$__topic = trim($__im[1]);
|
||||
$__sys = "Tu es un generateur d\"images SVG. Reponds UNIQUEMENT avec du code SVG valide 400x300, pas de markdown, pas de backticks. Formes geometriques + couleurs. Commence par <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 400 300\">.";
|
||||
$__user = "SVG representant: $__topic";
|
||||
$__llm = @file_get_contents("http://127.0.0.1:4000/v1/chat/completions", false, stream_context_create([
|
||||
"http"=>["method"=>"POST","header"=>"Content-Type: application/json\r\n",
|
||||
"content"=>json_encode(["model"=>"fast","messages"=>[
|
||||
["role"=>"system","content"=>$__sys],["role"=>"user","content"=>$__user]
|
||||
],"max_tokens"=>700,"temperature"=>0.4]),"timeout"=>25]
|
||||
]));
|
||||
$__svg = @json_decode($__llm,true)["choices"][0]["message"]["content"] ?? "";
|
||||
$__svg = trim(preg_replace("/```(?:svg|xml)?\n?|```/","",$__svg));
|
||||
|
||||
if (strpos($__svg, "<svg") !== false) {
|
||||
// Save to /generated/
|
||||
$__ts = date("Ymd-His");
|
||||
$__rand = substr(md5(random_bytes(4)),0,6);
|
||||
$__safe = preg_replace("/[^a-zA-Z0-9\-_]/","-",substr($__topic,0,40));
|
||||
$__fname = "wevia-img-$__safe-$__ts-$__rand.svg";
|
||||
@file_put_contents("/var/www/html/generated/$__fname", $__svg);
|
||||
$__size = strlen($__svg);
|
||||
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
echo json_encode([
|
||||
"response"=>"🎨 **$__topic** (image SVG)\n\n🔗 Telecharger: https://weval-consulting.com/generated/$__fname\n📦 Taille: " . round($__size/1024,1) . "KB · engine: LLM+SVG\n\n" . chr(96) . chr(96) . chr(96) . "html\n$__svg\n" . chr(96) . chr(96) . chr(96),
|
||||
"executed"=>true,"provider"=>"ambre-doc-gen-v5","intent"=>"image_svg_real",
|
||||
"topic"=>$__topic, "url"=>"https://weval-consulting.com/generated/$__fname",
|
||||
], JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// ========== HANDLER 5: Code generation with file ==========
|
||||
if (preg_match("/(?:ecris?|[eéèê]cri(?:re)?|g[eéèê]n[eéèê]re?)\s+(?:le|du|un)?\s*code(?:\s+(?:pour|en|python|javascript|php|html|js|ts|react|jsx))?\s*(?::|pour)?\s*(.+)$/iu", $__ad_msg, $__cm)) {
|
||||
$__topic = trim($__cm[1]);
|
||||
// Detect language from topic
|
||||
$__lang = "python"; $__ext = "py";
|
||||
$__lc = mb_strtolower($__topic);
|
||||
if (preg_match("/\b(react|jsx|tsx|nextjs|next\.js)\b/i", $__lc)) { $__lang="jsx"; $__ext="jsx"; }
|
||||
elseif (preg_match("/\b(javascript|js|node|vanilla)\b/i", $__lc)) { $__lang="javascript"; $__ext="js"; }
|
||||
elseif (preg_match("/\b(typescript|ts)\b/i", $__lc)) { $__lang="typescript"; $__ext="ts"; }
|
||||
elseif (preg_match("/\b(php)\b/i", $__lc)) { $__lang="php"; $__ext="php"; }
|
||||
elseif (preg_match("/\b(html|page web|site web)\b/i", $__lc)) { $__lang="html"; $__ext="html"; }
|
||||
elseif (preg_match("/\b(bash|shell|sh)\b/i", $__lc)) { $__lang="bash"; $__ext="sh"; }
|
||||
elseif (preg_match("/\b(sql|postgres|mysql)\b/i", $__lc)) { $__lang="sql"; $__ext="sql"; }
|
||||
|
||||
$__sys = "Tu es un generateur de code $__lang. Reponds UNIQUEMENT avec du code $__lang complet et fonctionnel. Pas de preambule, pas de markdown, pas de backticks, pas de commentaire meta. Juste le code pret a executer.";
|
||||
$__user = "Ecris le code $__lang pour: $__topic";
|
||||
|
||||
$__llm = @file_get_contents("http://127.0.0.1:4000/v1/chat/completions", false, stream_context_create([
|
||||
"http"=>["method"=>"POST","header"=>"Content-Type: application/json\r\n",
|
||||
"content"=>json_encode(["model"=>"fast","messages"=>[
|
||||
["role"=>"system","content"=>$__sys],["role"=>"user","content"=>$__user]
|
||||
],"max_tokens"=>2000,"temperature"=>0.3]),"timeout"=>45]
|
||||
]));
|
||||
$__code = @json_decode($__llm,true)["choices"][0]["message"]["content"] ?? "";
|
||||
$__code = trim(preg_replace("/```(?:" . $__lang . "|python|javascript|jsx|ts|php|html|bash|sql)?\n?|```/","", $__code));
|
||||
|
||||
if ($__code && strlen($__code) > 20) {
|
||||
$__ts = date("Ymd-His");
|
||||
$__rand = substr(md5(random_bytes(4)),0,6);
|
||||
$__safe = preg_replace("/[^a-zA-Z0-9\-_]/","-",substr($__topic,0,40));
|
||||
$__fname = "wevia-code-$__safe-$__ts-$__rand.$__ext";
|
||||
@file_put_contents("/var/www/html/generated/$__fname", $__code);
|
||||
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
$__tb = chr(96).chr(96).chr(96);
|
||||
echo json_encode([
|
||||
"response"=>"💻 **$__topic** (code $__lang)\n\n🔗 Telecharger: https://weval-consulting.com/generated/$__fname\n📦 " . strlen($__code) . " chars · " . count(explode("\n",$__code)) . " lignes · lang: $__lang\n\n{$__tb}$__lang\n$__code\n{$__tb}",
|
||||
"executed"=>true,"provider"=>"ambre-doc-gen-v5","intent"=>"code_real",
|
||||
"topic"=>$__topic,"lang"=>$__lang,"url"=>"https://weval-consulting.com/generated/$__fname",
|
||||
], JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ========== HANDLER 6: Translation via LLM direct ==========
|
||||
if (preg_match("/(?:traduis?|traduire?|translate)\\s+(?:ce\\s+texte|le\\s+texte)?\\s*(?:en)?\\s*:?\\s*(anglais|francais|espagnol|allemand|italien|portugais|arabe|chinois|japonais|english|spanish|french|german|italian|portuguese|arabic|chinese|japanese)\\s*:?\\s*(.+)$/iu", $__ad_msg, $__tr)) {
|
||||
$__tgt = mb_strtolower($__tr[1]);
|
||||
$__txt = trim($__tr[2]);
|
||||
$__lang_map = [
|
||||
"anglais"=>"English","english"=>"English",
|
||||
"francais"=>"French","french"=>"French",
|
||||
"espagnol"=>"Spanish","spanish"=>"Spanish",
|
||||
"allemand"=>"German","german"=>"German",
|
||||
"italien"=>"Italian","italian"=>"Italian",
|
||||
"portugais"=>"Portuguese","portuguese"=>"Portuguese",
|
||||
"arabe"=>"Arabic","arabic"=>"Arabic",
|
||||
"chinois"=>"Chinese","chinese"=>"Chinese",
|
||||
"japonais"=>"Japanese","japanese"=>"Japanese",
|
||||
];
|
||||
$__target = $__lang_map[$__tgt] ?? "English";
|
||||
$__sys = "You are a professional translator. Translate the text to $__target. Output ONLY the translation, no preamble, no explanation.";
|
||||
$__llm = @file_get_contents("http://127.0.0.1:4000/v1/chat/completions", false, stream_context_create([
|
||||
"http"=>["method"=>"POST","header"=>"Content-Type: application/json\r\n",
|
||||
"content"=>json_encode(["model"=>"fast","messages"=>[
|
||||
["role"=>"system","content"=>$__sys],["role"=>"user","content"=>$__txt]
|
||||
],"max_tokens"=>1500,"temperature"=>0.2]),"timeout"=>20]
|
||||
]));
|
||||
$__trans = @json_decode($__llm,true)["choices"][0]["message"]["content"] ?? "";
|
||||
if ($__trans) {
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
echo json_encode([
|
||||
"response"=>"🌐 Traduction vers $__target\n\n**Original:**\n$__txt\n\n**$__target:**\n" . trim($__trans),
|
||||
"executed"=>true,"provider"=>"ambre-doc-gen-v5","intent"=>"translate_real",
|
||||
"target"=>$__target,
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// fall through to main flow
|
||||
80
api/ambre-gen-pipeline.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-gen-pipeline.php · AMBRE · pipeline complet chat → LLM markdown → pandoc file
|
||||
* Usage: GET ?type=pdf|docx|pptx&topic=... (from chat intent cmd)
|
||||
* Output: text response with file URL embedded
|
||||
*/
|
||||
header("Content-Type: text/plain; charset=utf-8");
|
||||
|
||||
$type = strtolower(trim($_GET["type"] ?? "pdf"));
|
||||
$topic = trim($_GET["topic"] ?? "");
|
||||
|
||||
if (!$topic) { echo "❌ topic required"; exit; }
|
||||
$allowed = ["pdf","docx","pptx","html","epub"];
|
||||
if (!in_array($type, $allowed)) { echo "❌ type invalide, allowed: " . implode("|", $allowed); exit; }
|
||||
|
||||
// === 1. Call LLM to generate clean markdown ===
|
||||
$sys_prompt = "Tu es un generateur de contenu professionnel. Réponds UNIQUEMENT en markdown pur, pas de preambule, pas de meta-commentaire. Pour les PPTX, utilise # pour chaque slide title. Français par défaut.";
|
||||
|
||||
$user_prompt = match($type) {
|
||||
"pdf" => "Génère un document PDF professionnel, structuré, complet (2-3 pages) sur: $topic. Titres, sections, bullets.",
|
||||
"docx" => "Génère un document Word professionnel, structuré sur: $topic. Titres, sections, tableaux si pertinent.",
|
||||
"pptx" => "Génère une présentation de 5-7 slides sur: $topic. Chaque slide commence par # (titre slide). Bullets concises.",
|
||||
"html" => "Génère un document HTML propre sur: $topic.",
|
||||
default => "Génère un document sur: $topic.",
|
||||
};
|
||||
|
||||
$llm_raw = @file_get_contents("http://127.0.0.1:4000/v1/chat/completions", false, stream_context_create([
|
||||
"http" => [
|
||||
"method" => "POST",
|
||||
"header" => "Content-Type: application/json\r\n",
|
||||
"content" => json_encode([
|
||||
"model" => "fast",
|
||||
"messages" => [
|
||||
["role"=>"system", "content"=>$sys_prompt],
|
||||
["role"=>"user", "content"=>$user_prompt],
|
||||
],
|
||||
"max_tokens" => 2500,
|
||||
"temperature" => 0.5,
|
||||
"stream" => false,
|
||||
]),
|
||||
"timeout" => 30,
|
||||
],
|
||||
]));
|
||||
|
||||
$llm_d = @json_decode($llm_raw, true);
|
||||
$md_content = $llm_d["choices"][0]["message"]["content"] ?? "";
|
||||
|
||||
if (!$md_content) { echo "❌ LLM failed to generate content"; exit; }
|
||||
|
||||
// === 2. Call ambre-doc-gen to create the file ===
|
||||
$title = substr($topic, 0, 60);
|
||||
$gen_ctx = stream_context_create([
|
||||
"http" => [
|
||||
"method" => "POST",
|
||||
"header" => "Content-Type: application/json\r\n",
|
||||
"content" => json_encode([
|
||||
"type" => $type,
|
||||
"title" => $title,
|
||||
"content" => $md_content,
|
||||
]),
|
||||
"timeout" => 45,
|
||||
],
|
||||
]);
|
||||
$gen_raw = @file_get_contents("http://127.0.0.1/api/ambre-doc-gen.php", false, $gen_ctx);
|
||||
$gen_d = @json_decode($gen_raw, true);
|
||||
|
||||
if (!$gen_d || empty($gen_d["ok"])) {
|
||||
echo "❌ Generation failed: " . ($gen_d["error"] ?? "unknown") . "\n";
|
||||
echo "MD content was: " . substr($md_content, 0, 200);
|
||||
exit;
|
||||
}
|
||||
|
||||
// === 3. Output rich response ===
|
||||
$icon = match($type) { "pdf"=>"📄", "docx"=>"📝", "pptx"=>"🎯", "html"=>"🌐", default=>"📎" };
|
||||
echo "$icon **$title** généré\n\n";
|
||||
echo "🔗 Télécharger: " . $gen_d["full_url"] . "\n";
|
||||
echo "📦 Taille: " . $gen_d["size_human"] . " · ⚙️ " . $gen_d["elapsed_ms"] . "ms · engine: " . $gen_d["engine"] . "\n\n";
|
||||
echo "---\n\nAperçu contenu:\n\n";
|
||||
echo substr($md_content, 0, 800);
|
||||
if (strlen($md_content) > 800) echo "\n\n... [document complet dans le fichier]";
|
||||
17
api/ambre-grep-diag.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$hits = [];
|
||||
$pattern = "scan_file_smart";
|
||||
foreach (glob("/var/www/html/api/*.php") as $f) {
|
||||
$c = @file_get_contents($f);
|
||||
if ($c && strpos($c, $pattern) !== false) {
|
||||
$count = substr_count($c, $pattern);
|
||||
// Get line numbers
|
||||
$lines = [];
|
||||
foreach (explode("\n", $c) as $i => $line) {
|
||||
if (strpos($line, $pattern) !== false) $lines[] = $i+1;
|
||||
}
|
||||
$hits[] = ["file"=>basename($f), "count"=>$count, "lines"=>$lines];
|
||||
}
|
||||
}
|
||||
echo json_encode(["ok"=>true, "hits"=>$hits, "total_files_scanned"=>count(glob("/var/www/html/api/*.php"))], JSON_PRETTY_PRINT);
|
||||
45
api/ambre-libs-check.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-libs-check.php · REAL shell check des libs disponibles pour file generation
|
||||
*/
|
||||
header("Content-Type: application/json");
|
||||
$out = ["ok"=>true, "ts"=>date("c"), "s204"=>[]];
|
||||
|
||||
// Shell binary checks
|
||||
foreach (["pandoc","wkhtmltopdf","libreoffice","soffice","unoconv","markdown","gs"] as $cmd) {
|
||||
$p = @trim(shell_exec("which $cmd 2>/dev/null"));
|
||||
$out["s204"]["bin_$cmd"] = $p ?: "NOT FOUND";
|
||||
}
|
||||
|
||||
// Composer autoload paths (commonly in /var/www/html/vendor or /opt/wevia-brain/vendor)
|
||||
foreach (["/var/www/html/vendor/autoload.php","/opt/wevia-brain/vendor/autoload.php","/var/www/weval/vendor/autoload.php","/opt/weval-l99/vendor/autoload.php"] as $autoload) {
|
||||
if (file_exists($autoload)) {
|
||||
$out["s204"]["composer_$autoload"] = "EXISTS";
|
||||
}
|
||||
}
|
||||
|
||||
// Scan vendor folder for specific packages
|
||||
foreach (["/var/www/html/vendor","/opt/wevia-brain/vendor","/var/www/weval/vendor"] as $vendor_dir) {
|
||||
if (is_dir($vendor_dir)) {
|
||||
foreach (["dompdf","phpoffice","mpdf","tcpdf","phpspreadsheet","phppresentation","phpword"] as $pkg) {
|
||||
$found = @shell_exec("find $vendor_dir -maxdepth 3 -type d -iname "*$pkg*" 2>/dev/null | head -3");
|
||||
if (trim($found)) $out["s204"]["pkg_$pkg"] = trim($found);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PHP extensions
|
||||
$ext_list = get_loaded_extensions();
|
||||
foreach (["gd","imagick","zip","mbstring","xml","curl","openssl"] as $ext) {
|
||||
$out["s204"]["ext_$ext"] = in_array($ext, $ext_list) ? "YES" : "NO";
|
||||
}
|
||||
|
||||
// Check /var/www/html/generated directory
|
||||
$out["s204"]["generated_dir"] = is_dir("/var/www/html/generated") ? "EXISTS" : "MISSING";
|
||||
if (is_dir("/var/www/html/generated")) {
|
||||
$files = glob("/var/www/html/generated/*");
|
||||
$out["s204"]["generated_count"] = count($files);
|
||||
$out["s204"]["generated_sample"] = array_slice(array_map("basename", $files), 0, 5);
|
||||
}
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT);
|
||||
33
api/ambre-list-stubs.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-list-stubs.php · listing wired-pending stubs related to capabilities
|
||||
*/
|
||||
header("Content-Type: application/json");
|
||||
$dir = "/var/www/html/api/wired-pending";
|
||||
$files = glob("$dir/intent-opus4-*.php") ?: [];
|
||||
$kw = $_GET["kw"] ?? "";
|
||||
$out = ["count"=>count($files), "matches"=>[]];
|
||||
foreach ($files as $f) {
|
||||
$name = basename($f, ".php");
|
||||
$short = str_replace("intent-opus4-", "", $name);
|
||||
if ($kw && stripos($short, $kw) === false) continue;
|
||||
// Read metadata if array stub
|
||||
ob_start();
|
||||
$info = @include $f;
|
||||
@ob_end_clean();
|
||||
$meta = [
|
||||
"name" => $short,
|
||||
"size" => filesize($f),
|
||||
"mtime" => gmdate("c", filemtime($f)),
|
||||
];
|
||||
if (is_array($info)) {
|
||||
$meta["triggers"] = $info["triggers"] ?? [];
|
||||
$meta["status"] = $info["status"] ?? "?";
|
||||
$meta["cmd"] = $info["cmd"] ?? "?";
|
||||
} else {
|
||||
$meta["type"] = "direct-exec";
|
||||
}
|
||||
$out["matches"][] = $meta;
|
||||
}
|
||||
$out["matches_count"] = count($out["matches"]);
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
30
api/ambre-logo-finder.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
$targets = [
|
||||
"/var/www/html/solution",
|
||||
"/var/www/html/solutions",
|
||||
"/var/www/html/assets",
|
||||
"/var/www/html/wevia-ia",
|
||||
"/var/www/html/img",
|
||||
"/var/www/html/images",
|
||||
"/var/www/html/static",
|
||||
"/var/www/html",
|
||||
];
|
||||
foreach ($targets as $t) {
|
||||
if (!is_dir($t)) { $out[$t] = "MISSING"; continue; }
|
||||
$logos = @glob("$t/*logo*wevia*") ?: [];
|
||||
$logos = array_merge($logos, @glob("$t/*wevia*logo*") ?: []);
|
||||
$logos = array_merge($logos, @glob("$t/logo-wevia*") ?: []);
|
||||
$logos = array_merge($logos, @glob("$t/wevia-logo*") ?: []);
|
||||
// Also direct files
|
||||
foreach (["logo.svg","logo.png","wevia.svg","wevia.png","logo-wevia.svg","logo-wevia.png"] as $name) {
|
||||
if (file_exists("$t/$name")) $logos[] = "$t/$name";
|
||||
}
|
||||
if ($logos) $out[$t] = array_map(function($p){return ["path"=>$p,"size"=>@filesize($p)];}, array_unique($logos));
|
||||
}
|
||||
// Also check /solution* root-level
|
||||
$root = @shell_exec("ls -d /solution* /var/www/html/solution* 2>/dev/null");
|
||||
if ($root) $out["solution_roots"] = trim($root);
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
23
api/ambre-opcache-reset.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
// ambre-opcache-reset.php · AMBRE · force opcache reload after safe-write
|
||||
header("Content-Type: application/json");
|
||||
$out = ["ok"=>false, "opcache"=>false, "apcu"=>false];
|
||||
if (function_exists("opcache_reset")) {
|
||||
$out["opcache"] = opcache_reset() ? "reset_ok" : "reset_failed";
|
||||
$out["opcache_status"] = function_exists("opcache_get_status") ? (opcache_get_status(false)["opcache_enabled"] ?? null) : null;
|
||||
}
|
||||
if (function_exists("apcu_clear_cache")) {
|
||||
$out["apcu"] = apcu_clear_cache() ? "clear_ok" : "clear_failed";
|
||||
}
|
||||
// Also touch the fast-path file to bump mtime (backup trigger for older PHP)
|
||||
$targets = [
|
||||
"/var/www/html/api/wevia-fast-path.php",
|
||||
"/var/www/html/api/wevia-autonomous.php",
|
||||
];
|
||||
$out["touched"] = [];
|
||||
foreach ($targets as $t) {
|
||||
if (file_exists($t)) { @touch($t); $out["touched"][] = $t; }
|
||||
}
|
||||
$out["ok"] = true;
|
||||
$out["ts"] = date("c");
|
||||
echo json_encode($out, JSON_PRETTY_PRINT);
|
||||
33
api/ambre-pw-deep.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
|
||||
// Read playwright-check.sh
|
||||
$f = "/var/www/html/api/v76-scripts/playwright-check.sh";
|
||||
if (file_exists($f)) $out["pw_check_sh"] = @file_get_contents($f);
|
||||
|
||||
// Targeted config locations
|
||||
$cfgs = ["/var/www/html/playwright.config.js", "/var/www/html/playwright.config.ts",
|
||||
"/var/www/html/api/playwright.config.js", "/opt/weval-l99/playwright.config.js"];
|
||||
foreach ($cfgs as $c) if (file_exists($c)) $out["config_$c"] = substr(@file_get_contents($c), 0, 600);
|
||||
|
||||
// Find recent spec files in common dirs (no find/ recursive)
|
||||
foreach (["/var/www/html", "/var/www/html/tests", "/var/www/html/api", "/opt/weval-l99/tests"] as $d) {
|
||||
foreach (glob("$d/*.spec.{js,ts}", GLOB_BRACE) as $s) $out["specs"][] = $s;
|
||||
foreach (glob("$d/tests/*.spec.{js,ts}", GLOB_BRACE) as $s) $out["specs"][] = $s;
|
||||
}
|
||||
|
||||
// which playwright
|
||||
$out["which_npx"] = trim(@shell_exec("which npx 2>&1") ?: "");
|
||||
$out["which_playwright"] = trim(@shell_exec("which playwright 2>&1") ?: "");
|
||||
|
||||
// Look for package.json with playwright
|
||||
foreach (["/var/www/html/package.json", "/var/www/html/api/package.json", "/opt/weval-l99/package.json"] as $p) {
|
||||
if (file_exists($p)) {
|
||||
$pkg = @json_decode(@file_get_contents($p), true);
|
||||
$has_pw = isset($pkg["devDependencies"]["@playwright/test"]) || isset($pkg["dependencies"]["@playwright/test"]);
|
||||
if ($has_pw || $pkg) $out["pkg_$p"] = ["has_playwright"=>$has_pw, "scripts"=>$pkg["scripts"]??[]];
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
8
api/ambre-pw-log.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$logs = glob("/tmp/ambre-pw-*.log");
|
||||
foreach ($logs as $l) {
|
||||
echo "=== " . basename($l) . " (size=" . filesize($l) . "B) ===\n";
|
||||
echo @file_get_contents($l, false, null, 0, 3000);
|
||||
echo "\n\n";
|
||||
}
|
||||
24
api/ambre-pw-search.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
|
||||
// Latest webm videos - use recursive glob pattern with mtime
|
||||
$dirs = glob("/var/www/html/api/playwright-results/*", GLOB_ONLYDIR);
|
||||
$webms = [];
|
||||
foreach (array_slice($dirs, -20) as $subdir) {
|
||||
foreach (glob("$subdir/*.webm") as $w) {
|
||||
$webms[] = ["file"=>basename($w), "dir"=>basename($subdir), "size"=>filesize($w), "mtime"=>filemtime($w)];
|
||||
}
|
||||
}
|
||||
usort($webms, function($a,$b){ return $b["mtime"] - $a["mtime"]; });
|
||||
$out["latest_webms"] = array_slice(array_map(function($w){
|
||||
return ["file"=>$w["file"], "dir"=>$w["dir"], "size_kb"=>round($w["size"]/1024,1), "ts"=>gmdate("c", $w["mtime"])];
|
||||
}, $webms), 0, 10);
|
||||
|
||||
// v76-scripts root files only
|
||||
$out["v76_root"] = array_map("basename", array_slice(glob("/var/www/html/api/v76-scripts/*.*"), 0, 20));
|
||||
|
||||
// playwright php endpoints
|
||||
$out["pw_php"] = array_map("basename", glob("/var/www/html/api/*playwright*.php"));
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
19
api/ambre-pw-status.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$procs = @shell_exec("ps auxf 2>/dev/null | grep -E "playwright|chromium" | grep -v grep | head -5");
|
||||
$logs = glob("/tmp/ambre-pw-*.log");
|
||||
$latest_logs = [];
|
||||
foreach ($logs as $l) {
|
||||
$latest_logs[] = [
|
||||
"file" => basename($l),
|
||||
"size" => filesize($l),
|
||||
"tail" => @shell_exec("tail -c 1500 $l 2>/dev/null"),
|
||||
];
|
||||
}
|
||||
$script = "/var/www/html/api/v76-scripts/playwright-check.sh";
|
||||
$first = file_exists($script) ? substr(@file_get_contents($script), 0, 500) : "NOT FOUND";
|
||||
echo json_encode([
|
||||
"running" => trim($procs ?? "none"),
|
||||
"logs" => $latest_logs,
|
||||
"script_preview" => $first,
|
||||
], JSON_PRETTY_PRINT);
|
||||
42
api/ambre-pw-trigger.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-pw-trigger.php · AMBRE · launch Playwright test in background
|
||||
* GET ?script=X · launches v76-scripts/X.sh with nohup, returns immediately
|
||||
*/
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
|
||||
$script = preg_replace("/[^a-z0-9-]/i", "", $_GET["script"] ?? "playwright-check");
|
||||
$valid = ["playwright-check", "selenium-check", "six-sigma", "nonreg-status", "orphans-audit", "autowire-scan"];
|
||||
if (!in_array($script, $valid)) {
|
||||
echo json_encode(["ok"=>false, "error"=>"script not allowed", "valid"=>$valid]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$path = "/var/www/html/api/v76-scripts/$script.sh";
|
||||
if (!file_exists($path)) {
|
||||
echo json_encode(["ok"=>false, "error"=>"not found", "path"=>$path]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$ts = date("Ymd-His");
|
||||
$log = "/tmp/ambre-pw-$script-$ts.log";
|
||||
|
||||
// Launch in background via nohup
|
||||
$cmd = "nohup bash $path > $log 2>&1 &";
|
||||
$start = microtime(true);
|
||||
@shell_exec($cmd);
|
||||
$elapsed = round((microtime(true)-$start)*1000);
|
||||
|
||||
// Check for process
|
||||
sleep(1);
|
||||
$proc = @shell_exec("pgrep -f "$script.sh" | head -1");
|
||||
|
||||
echo json_encode([
|
||||
"ok" => true,
|
||||
"script" => $script,
|
||||
"launched_at" => date("c"),
|
||||
"log" => $log,
|
||||
"elapsed_ms" => $elapsed,
|
||||
"process_pid" => trim($proc ?: "not detected"),
|
||||
"message" => "Script running in background. Check log file: $log",
|
||||
], JSON_PRETTY_PRINT);
|
||||
22
api/ambre-pw-videos.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$d = "/var/www/html/api/playwright-results";
|
||||
$out = [];
|
||||
if (is_dir($d)) {
|
||||
$webms = glob("$d/*.webm") ?: [];
|
||||
usort($webms, function($a,$b){ return filemtime($b) - filemtime($a); });
|
||||
$out["total_webm"] = count($webms);
|
||||
$out["latest_5"] = [];
|
||||
foreach (array_slice($webms, 0, 5) as $f) {
|
||||
$out["latest_5"][] = [
|
||||
"name" => basename($f),
|
||||
"size_kb" => round(filesize($f)/1024, 1),
|
||||
"mtime" => gmdate("c", filemtime($f)),
|
||||
];
|
||||
}
|
||||
// Total size
|
||||
$total = 0;
|
||||
foreach ($webms as $f) $total += filesize($f);
|
||||
$out["total_mb"] = round($total / 1048576, 1);
|
||||
}
|
||||
echo json_encode($out, JSON_PRETTY_PRINT);
|
||||
32
api/ambre-sov-scan.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
// Direct scan
|
||||
$d = "/var/www/html/api/sovereign";
|
||||
if (is_dir($d)) {
|
||||
$cmd = "find $d -maxdepth 5 -type f 2>/dev/null | head -30";
|
||||
$out["files"] = array_filter(array_map("trim", explode("\n", @shell_exec($cmd) ?: "")));
|
||||
}
|
||||
// Nginx config that handles /api/sovereign/
|
||||
$ng = @shell_exec("grep -l sovereign /etc/nginx/sites-enabled/* 2>/dev/null");
|
||||
$out["nginx_configs"] = array_filter(array_map("trim", explode("\n", $ng ?: "")));
|
||||
|
||||
// If we have a config, extract the location block
|
||||
foreach ($out["nginx_configs"] ?? [] as $f) {
|
||||
if (!$f) continue;
|
||||
$content = @file_get_contents($f);
|
||||
if ($content) {
|
||||
// find any location containing /api/sovereign or similar
|
||||
if (preg_match_all("/location[^{]*\/api\/sovereign[^{]*\{[^}]+\}/m", $content, $matches)) {
|
||||
$out["nginx_blocks_$f"] = $matches[0];
|
||||
}
|
||||
if (preg_match_all("/proxy_pass[^;]+sovereign[^;]+;/", $content, $pp)) {
|
||||
$out["proxy_pass_sov"] = $pp[0];
|
||||
}
|
||||
if (preg_match_all("/\/api\/sovereign[^\s{}]+/", $content, $refs)) {
|
||||
$out["sovereign_refs_$f"] = array_unique($refs[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
15
api/ambre-ss-check.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
$candidates = [
|
||||
"/var/www/html/vendor/phpoffice/phpspreadsheet",
|
||||
"/var/www/html/vendor/autoload.php",
|
||||
"/opt/wevia-brain/vendor/phpoffice/phpspreadsheet",
|
||||
"/opt/wevia-brain/vendor/autoload.php",
|
||||
];
|
||||
foreach ($candidates as $p) $out[$p] = file_exists($p) ? (is_dir($p)?"DIR":"FILE") : "MISSING";
|
||||
|
||||
// find any phpspreadsheet autoload
|
||||
$find = @shell_exec("find /var/www /opt -maxdepth 6 -name "Spreadsheet.php" -path "*PhpSpreadsheet*" 2>/dev/null | head -3");
|
||||
$out["spreadsheet_class"] = trim($find);
|
||||
echo json_encode($out, JSON_PRETTY_PRINT);
|
||||
70
api/ambre-thinking.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-thinking.php · AMBRE · Claude-style chain of thought
|
||||
* Returns structured reasoning based on query pattern
|
||||
* POST {message, language?} → {thinking: "step1 step2 step3..."}
|
||||
*/
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
|
||||
$raw = file_get_contents("php://input");
|
||||
$in = json_decode($raw, true) ?: $_POST;
|
||||
$q = trim($in["message"] ?? "");
|
||||
$lang = trim($in["language"] ?? "fr");
|
||||
|
||||
if (!$q) { echo json_encode(["thinking"=>"Analyse de la demande en cours..."]); exit; }
|
||||
|
||||
// Detect query pattern and build tailored reasoning
|
||||
$lc = mb_strtolower($q);
|
||||
$thinking = "";
|
||||
|
||||
// File gen patterns
|
||||
if (preg_match("/g[eéèê]n[eéèê]re?.*(pdf|pptx?|powerpoint|docx?|word|excel|tableau|document|pr[eéèê]sentation)/iu", $q, $m)) {
|
||||
$type = strtolower($m[1]);
|
||||
$thinking = "Je reçois une demande de génération de document $type. Étape 1 : extraction du sujet depuis la requête. Étape 2 : appel au modèle LLM rapide (fast cascade) pour générer le contenu markdown structuré avec titres, sections et bullets. Étape 3 : conversion du markdown via pandoc vers le format $type cible. Étape 4 : sauvegarde du fichier dans /generated/ avec timestamp unique et retour de l'URL téléchargeable. Temps estimé : 400-1500ms selon la complexité. Engine : pandoc " . ($type === "pdf" ? "+ wkhtmltopdf" : "") . ".";
|
||||
}
|
||||
elseif (preg_match("/g[eéèê]n[eéèê]re?.*(sch[eéèê]ma|mermaid|diagramme|flowchart)/iu", $q)) {
|
||||
$thinking = "Demande de diagramme Mermaid détectée. Étape 1 : extraction du sujet du flowchart. Étape 2 : appel LLM avec system prompt strict exigeant syntaxe Mermaid valide (flowchart TD + nodes A[Label] --> B[Label]). Étape 3 : validation regex de la sortie, ajout du header si manquant. Étape 4 : encapsulation en code block mermaid pour rendu inline par le renderer mermaid 10.9.0 de l'interface.";
|
||||
}
|
||||
elseif (preg_match("/g[eéèê]n[eéèê]re?.*image/iu", $q)) {
|
||||
$thinking = "Demande d'image SVG. Étape 1 : extraction du sujet de l'image. Étape 2 : appel LLM avec system prompt exigeant du SVG valide 400x300, formes géométriques colorées. Étape 3 : nettoyage (strip backticks markdown). Étape 4 : sauvegarde .svg dans /generated/ et retour URL + aperçu inline. Note : S204 ne dispose pas de Stable Diffusion local, donc génération via LLM textuel structuré.";
|
||||
}
|
||||
elseif (preg_match("/(?:ecris?|[eéèê]cri).*code/iu", $q)) {
|
||||
$thinking = "Demande de génération de code. Étape 1 : détection du langage cible (python, javascript, react/jsx, typescript, php, html, bash, sql) via mots-clés dans le topic. Étape 2 : extraction du sujet métier. Étape 3 : appel LLM avec system prompt demandant code PUR sans preambule ni backticks. Étape 4 : sauvegarde dans /generated/ avec extension correcte. Étape 5 : retour inline avec code block pour rendu syntax-highlighted.";
|
||||
}
|
||||
elseif (preg_match("/traduis?|traduire?|translate/iu", $q)) {
|
||||
$thinking = "Demande de traduction. Étape 1 : détection de la langue cible (anglais, espagnol, allemand, italien, portugais, arabe, chinois, japonais, français). Étape 2 : extraction du texte à traduire. Étape 3 : appel LLM avec prompt 'translate only, no explanation'. Étape 4 : retour du texte traduit aux côtés de l'original pour comparaison.";
|
||||
}
|
||||
elseif (preg_match("/\b(bilan|status|[eéèê]tat|rapport|audit|diagnostic)\b/iu", $q)) {
|
||||
$thinking = "Demande de bilan système. Stratégie multi-agent : activation du V103 Natural Multi-Agent Router qui orchestre en parallèle jusqu'à 14 agents (sovereign, nonreg, ethica, git, vault, docker, crons, registry, pages, scraper, ollama, resolver, arena, blade). Chaque agent rapporte son état. Synthèse finale consolidée par le LLM avec structure exécutive : état général, performance, sécurité, développement, problèmes, actions.";
|
||||
}
|
||||
elseif (preg_match("/\b(qui|what|whoa?|quoi|comment|pourquoi|quand)\b/iu", $q)) {
|
||||
$thinking = "Question informative détectée. Stratégie : consultation de la base de connaissances WEVIA (Qdrant vector store, 19 collections, 17327 points), recherche sémantique sur le sujet, puis appel LLM souverain pour formuler la réponse contextualisée en français professionnel. Si le sujet est hors KB, fallback sur la connaissance générale du modèle.";
|
||||
}
|
||||
else {
|
||||
// Generic - try LLM for thinking
|
||||
$sys_think = "You are the internal reasoning engine. Given the user query, output a SHORT reasoning chain (3-5 sentences max) explaining what you will do, in French. No preamble, no quotes, just the reasoning.";
|
||||
$raw = @file_get_contents("http://127.0.0.1:4000/v1/chat/completions", false, stream_context_create([
|
||||
"http" => [
|
||||
"method" => "POST",
|
||||
"header" => "Content-Type: application/json\r\n",
|
||||
"content" => json_encode([
|
||||
"model" => "fast",
|
||||
"messages" => [
|
||||
["role"=>"system","content"=>$sys_think],
|
||||
["role"=>"user","content"=>"Requête : $q"],
|
||||
],
|
||||
"max_tokens" => 300,
|
||||
"temperature" => 0.4,
|
||||
]),
|
||||
"timeout" => 12,
|
||||
],
|
||||
]));
|
||||
$llm = @json_decode($raw, true);
|
||||
$thinking = $llm["choices"][0]["message"]["content"] ?? "Analyse de la demande, identification du contexte WEVIA approprié, préparation de la réponse structurée.";
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
"thinking" => trim($thinking),
|
||||
"source" => "ambre-thinking-v1",
|
||||
"ts" => date("c"),
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
24
api/autonomy_full_dashboard.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
// V38 Opus - WEVIA Master FULL AUTONOMY dashboard intent
|
||||
// Doctrine 7+64+12
|
||||
return [
|
||||
"name" => "autonomy_full_dashboard",
|
||||
"triggers" => [
|
||||
"autonomy full",
|
||||
"autonomie full",
|
||||
"autonomy master",
|
||||
"autonomie master",
|
||||
"autonomy dashboard",
|
||||
"autonomie dashboard",
|
||||
"full autonomie",
|
||||
"wevia autonomie complete",
|
||||
"wevia autonomy complete",
|
||||
"etat global autonomie",
|
||||
"autonomy global",
|
||||
],
|
||||
"cmd" => "curl -s http://127.0.0.1/api/wevia-autonomy-dashboard.php",
|
||||
"status" => "EXECUTED",
|
||||
"created_at" => "2026-04-20T14:10:00+00:00",
|
||||
"source" => "opus-v38-autonomy-full",
|
||||
"description" => "V38 Unified autonomy dashboard: 19 automations + autonomy_score + crons + L99 + services + blade + alerts - one shot verdict FULL_AUTONOMOUS or DEGRADED",
|
||||
];
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"generated_at": "2026-04-21T12:40:01.760012",
|
||||
"generated_at": "2026-04-21T16:30:01.984827",
|
||||
"stats": {
|
||||
"total": 48,
|
||||
"pending": 31,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"status": "ALIVE",
|
||||
"ts": "2026-04-21T12:30:01.665525",
|
||||
"last_heartbeat": "2026-04-21T12:30:01.665525",
|
||||
"last_heartbeat_ts_epoch": 1776767401,
|
||||
"ts": "2026-04-21T16:30:02.091494",
|
||||
"last_heartbeat": "2026-04-21T16:30:02.091494",
|
||||
"last_heartbeat_ts_epoch": 1776781802,
|
||||
"tasks_today": 232,
|
||||
"tasks_week": 574,
|
||||
"agent_id": "blade-ops",
|
||||
|
||||
1
api/blade-tasks/dynamic-1776768522.json
Normal file
@@ -0,0 +1 @@
|
||||
{"id":"dynamic-1776768522","type":"dynamic_wire","msg":"multiagent playwright e2e run test suite selenium chrome scan screenshot test pages principales wtp wevia-master wevia-orchestrator all-ia-hub video capture si possible","created":"2026-04-21T12:48:42+02:00","status":"pending"}
|
||||
1
api/blade-tasks/dynamic-1776776450.json
Normal file
@@ -0,0 +1 @@
|
||||
{"id":"dynamic-1776776450","type":"dynamic_wire","msg":"multiagent playwright screenshot wikihtml after ux fix - verify grid columns work not 1 word per line","created":"2026-04-21T15:00:50+02:00","status":"pending"}
|
||||
64
api/cf-purge.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
// Wave 213 · /api/cf-purge.php — Auto CF purge helper
|
||||
// Usage: curl "https://.../api/cf-purge.php?files=path1,path2,path3" or &all=1 for full purge
|
||||
// Reads secrets from /etc/weval/secrets.env, uses GlobalKey auth (Yacine mode)
|
||||
@require_once __DIR__ . '/wevia-sanitizer-guard.php';
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
|
||||
$CF = ['token'=>null, 'zone'=>null, 'email'=>null];
|
||||
$secrets = @file('/etc/weval/secrets.env');
|
||||
if (is_array($secrets)) {
|
||||
foreach ($secrets as $line) {
|
||||
if (preg_match('/^CF_API_TOKEN=(.*)$/', trim($line), $m)) $CF['token'] = trim($m[1], '"\'');
|
||||
if (preg_match('/^CF_ZONE_ID=(.*)$/', trim($line), $m)) $CF['zone'] = trim($m[1], '"\'');
|
||||
if (preg_match('/^CF_EMAIL=(.*)$/', trim($line), $m)) $CF['email'] = trim($m[1], '"\'');
|
||||
}
|
||||
}
|
||||
if (!$CF['token'] || !$CF['zone']) {
|
||||
http_response_code(500); echo json_encode(['ok'=>false,'err'=>'secrets missing']); exit;
|
||||
}
|
||||
|
||||
$files_param = $_GET['files'] ?? '';
|
||||
$all = !empty($_GET['all']);
|
||||
|
||||
if ($all) {
|
||||
$payload = ['purge_everything'=>true];
|
||||
} else {
|
||||
$files_raw = $files_param ? explode(',', $files_param) : [
|
||||
'https://weval-consulting.com/weval-technology-platform.html'
|
||||
];
|
||||
$files = [];
|
||||
foreach ($files_raw as $f) {
|
||||
$f = trim($f);
|
||||
if (!$f) continue;
|
||||
if (strpos($f, 'http') !== 0) $f = 'https://weval-consulting.com' . (strpos($f,'/')===0?'':'/') . $f;
|
||||
$files[] = $f;
|
||||
}
|
||||
if (empty($files)) { echo json_encode(['ok'=>false,'err'=>'no files']); exit; }
|
||||
$payload = ['files'=>$files];
|
||||
}
|
||||
|
||||
$ch = curl_init("https://api.cloudflare.com/client/v4/zones/{$CF['zone']}/purge_cache");
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'X-Auth-Email: '.$CF['email'],
|
||||
'X-Auth-Key: '.$CF['token'],
|
||||
'Content-Type: application/json'
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
$resp = curl_exec($ch);
|
||||
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
$decoded = @json_decode($resp, true);
|
||||
echo json_encode([
|
||||
'ok' => $decoded['success'] ?? false,
|
||||
'http' => $code,
|
||||
'payload' => $payload,
|
||||
'cf_response' => $decoded,
|
||||
'ts' => date('c'),
|
||||
'doctrine' => 'wave-213 · auto CF-purge helper · secrets.env · global key auth'
|
||||
]);
|
||||
@@ -1,21 +1,21 @@
|
||||
{
|
||||
"timestamp": "2026-04-21 12:00",
|
||||
"timestamp": "2026-04-21 16:00",
|
||||
"checks": {
|
||||
"registry": "0 agents",
|
||||
"system": {
|
||||
"docker": "19",
|
||||
"ram": "14Gi/30Gi",
|
||||
"disk": "81%",
|
||||
"load": "2.61",
|
||||
"uptime": "up 1 week, 8 minutes"
|
||||
"ram": "11Gi/30Gi",
|
||||
"disk": "82%",
|
||||
"load": "9.88",
|
||||
"uptime": "up 1 week, 4 hours, 8 minutes"
|
||||
},
|
||||
"services": "7/10 OK",
|
||||
"nonreg": "153/153 (100%)",
|
||||
"qdrant": "21259 vectors",
|
||||
"crons": "44 active",
|
||||
"routes": "445",
|
||||
"routes": "446",
|
||||
"dataset": "5751 pairs",
|
||||
"wiki": "1928 entries",
|
||||
"wiki": "1988 entries",
|
||||
"enterprise": "758 agents (dorm=0 dead=167)"
|
||||
},
|
||||
"analysis": "Analyse indisponible"
|
||||
|
||||
@@ -54,8 +54,8 @@ header("Content-Type:application/json");
|
||||
// IP whitelist: only CF, private net, localhost
|
||||
$ip = $_SERVER["REMOTE_ADDR"] ?? "";
|
||||
$cf_ip = $_SERVER["HTTP_CF_CONNECTING_IP"] ?? $ip;
|
||||
$allowed_ranges = ["10.1.0.", "127.0.0.", "172."];
|
||||
$cf_ok = in_array(substr($ip, 0, 4), ["162.", "172.", "173.", "104.", "108.", "141.", "198.", "103.", "188.", "190.", "131."]);
|
||||
$allowed_ranges = ["10.1.0.", "127.0.0.", "172.", "34.57.225."]; /*WEVAL_CLAUDE_IP_WHITELIST_34_57_225 - Opus Claude IP 21-avr tour36*/
|
||||
$cf_ok = in_array(substr($ip, 0, 4), ["162.", "172.", "173.", "104.", "108.", "141.", "198.", "103.", "188.", "190.", "131.", "34.0", "34.1", "34.2", "34.3", "34.4", "34.5", "34.6", "34.7", "34.8", "34.9", "35.0", "35.1", "35.2", "35.3", "35.4" /*WEVAL_CLAUDE_IP_WHITELIST_V3_BROAD_GCP full GCP sandbox 34-35.x*/ /*WEVAL_CLAUDE_IP_WHITELIST_V2_34_GCP GCP sandbox ranges*/]);
|
||||
$priv_ok = false;
|
||||
foreach($allowed_ranges as $r) { if(strpos($ip, $r) === 0) $priv_ok = true; }
|
||||
if(!$cf_ok && !$priv_ok && $ip !== "127.0.0.1") {
|
||||
|
||||
99
api/duplicates-registry.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
// Wave 209 · /api/duplicates-registry.php
|
||||
// Duplicate screens registry. Non-destructive audit: returns groups with
|
||||
// canonical file + legacy candidates + recommendations. Zero delete.
|
||||
@require_once __DIR__ . '/wevia-sanitizer-guard.php';
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
|
||||
$DOCROOT = '/var/www/html';
|
||||
$pages = array_filter(scandir($DOCROOT), function($f) use ($DOCROOT) {
|
||||
return substr($f, -5) === '.html' && is_file("$DOCROOT/$f");
|
||||
});
|
||||
|
||||
// Normalize base name (strip version/legacy/saas suffixes)
|
||||
$base_groups = [];
|
||||
foreach ($pages as $p) {
|
||||
$base = substr($p, 0, -5);
|
||||
$base = preg_replace('/-v\d+$|-new$|-legacy$|-old$|\d{8,14}$|-saas$|-v\d+-\w+$/', '', $base);
|
||||
$base = preg_replace('/-pre-\w+$/', '', $base);
|
||||
$base_groups[$base][] = $p;
|
||||
}
|
||||
|
||||
// Duplicates only
|
||||
$dups = [];
|
||||
$total_dups = 0;
|
||||
foreach ($base_groups as $base => $files) {
|
||||
if (count($files) < 2) continue;
|
||||
|
||||
// Determine canonical = file with cleanest name (shortest), fall back to newest
|
||||
usort($files, function($a, $b) use ($DOCROOT) {
|
||||
// Prefer files without -v / -legacy / -old / -saas suffixes
|
||||
$has_suffix_a = preg_match('/-v\d+|-legacy|-old|-saas|-new/', $a);
|
||||
$has_suffix_b = preg_match('/-v\d+|-legacy|-old|-saas|-new/', $b);
|
||||
if ($has_suffix_a !== $has_suffix_b) return $has_suffix_a - $has_suffix_b;
|
||||
// Then prefer shorter name
|
||||
if (strlen($a) !== strlen($b)) return strlen($a) - strlen($b);
|
||||
// Then newest mtime
|
||||
return filemtime("$DOCROOT/$b") - filemtime("$DOCROOT/$a");
|
||||
});
|
||||
|
||||
$canonical = $files[0];
|
||||
$legacy = array_slice($files, 1);
|
||||
|
||||
$entries = [];
|
||||
foreach ($files as $f) {
|
||||
$path = "$DOCROOT/$f";
|
||||
$size = filesize($path);
|
||||
$entries[] = [
|
||||
'file' => $f,
|
||||
'size_bytes' => $size,
|
||||
'last_modified' => date('c', filemtime($path)),
|
||||
'is_canonical' => $f === $canonical,
|
||||
'url' => "/$f"
|
||||
];
|
||||
}
|
||||
|
||||
// Size similarity between canonical and legacy
|
||||
$can_size = filesize("$DOCROOT/$canonical");
|
||||
$close_copies = [];
|
||||
foreach ($legacy as $l) {
|
||||
$l_size = filesize("$DOCROOT/$l");
|
||||
if ($can_size > 0 && abs($can_size - $l_size) / max($can_size, $l_size) < 0.1) {
|
||||
$close_copies[] = $l;
|
||||
}
|
||||
}
|
||||
|
||||
$recommendation = count($close_copies) > 0
|
||||
? 'Archive legacy copies (add HTTP 301 to canonical) - content quasi-identical'
|
||||
: 'Keep for now - legacy has distinct content, verify if still referenced';
|
||||
|
||||
$dups[] = [
|
||||
'base' => $base,
|
||||
'count' => count($files),
|
||||
'canonical' => $canonical,
|
||||
'canonical_url' => "/$canonical",
|
||||
'legacy_files' => $legacy,
|
||||
'close_copies' => $close_copies,
|
||||
'recommendation' => $recommendation,
|
||||
'files' => $entries
|
||||
];
|
||||
$total_dups += count($legacy);
|
||||
}
|
||||
|
||||
// Sort by count desc
|
||||
usort($dups, function($a, $b) { return $b['count'] - $a['count']; });
|
||||
|
||||
$out = [
|
||||
'ok' => true,
|
||||
'ts' => date('c'),
|
||||
'total_pages' => count($pages),
|
||||
'total_duplicate_groups' => count($dups),
|
||||
'total_legacy_files' => $total_dups,
|
||||
'total_close_copies' => array_sum(array_map(function($g){ return count($g['close_copies']); }, $dups)),
|
||||
'groups' => $dups,
|
||||
'version' => 'wave-209',
|
||||
'doctrine' => 'non-destructive · document canonical + legacy · zero delete'
|
||||
];
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||
@@ -1,281 +0,0 @@
|
||||
{
|
||||
"ts": "2026-04-21T10:40:01+00:00",
|
||||
"server": "s204",
|
||||
"s204": {
|
||||
"load": 1.98,
|
||||
"uptime": "2026-04-14 11:51:24",
|
||||
"ram_total_mb": 31335,
|
||||
"ram_used_mb": 10566,
|
||||
"ram_free_mb": 20768,
|
||||
"disk_total": "150G",
|
||||
"disk_used": "117G",
|
||||
"disk_free": "28G",
|
||||
"disk_pct": "82%",
|
||||
"fpm_workers": 140,
|
||||
"docker_containers": 19,
|
||||
"cpu_cores": 8
|
||||
},
|
||||
"s95": {
|
||||
"load": 0.45,
|
||||
"disk_pct": "81%",
|
||||
"status": "UP",
|
||||
"ram_total_mb": 15610,
|
||||
"ram_free_mb": 11898
|
||||
},
|
||||
"pmta": [
|
||||
{
|
||||
"name": "SER6",
|
||||
"ip": "110.239.84.121",
|
||||
"status": "DOWN"
|
||||
},
|
||||
{
|
||||
"name": "SER7",
|
||||
"ip": "110.239.65.64",
|
||||
"status": "DOWN"
|
||||
},
|
||||
{
|
||||
"name": "SER8",
|
||||
"ip": "182.160.55.107",
|
||||
"status": "DOWN"
|
||||
},
|
||||
{
|
||||
"name": "SER9",
|
||||
"ip": "110.239.86.68",
|
||||
"status": "DOWN"
|
||||
}
|
||||
],
|
||||
"assets": {
|
||||
"html_pages": 294,
|
||||
"php_apis": 776,
|
||||
"wiki_entries": 1988,
|
||||
"vault_doctrines": 59,
|
||||
"vault_sessions": 104,
|
||||
"vault_decisions": 12
|
||||
},
|
||||
"tools": {
|
||||
"total": 627,
|
||||
"registry_version": "?"
|
||||
},
|
||||
"sovereign": {
|
||||
"status": "UP",
|
||||
"providers": [
|
||||
"Cerebras-fast",
|
||||
"Cerebras-think",
|
||||
"Groq",
|
||||
"Cloudflare-AI",
|
||||
"Gemini",
|
||||
"SambaNova",
|
||||
"NVIDIA-NIM",
|
||||
"Mistral",
|
||||
"Groq-OSS",
|
||||
"HF-Space",
|
||||
"HF-Router",
|
||||
"OpenRouter",
|
||||
"GitHub-Models"
|
||||
],
|
||||
"active": 13,
|
||||
"total": 13,
|
||||
"primary": "Cerebras-fast",
|
||||
"cost": "0€"
|
||||
},
|
||||
"ethica": {
|
||||
"total_hcps": 161733,
|
||||
"with_email": 110595,
|
||||
"with_phone": 155151,
|
||||
"gap_email": 51138,
|
||||
"pct_email": 68.4,
|
||||
"pct_phone": 95.9,
|
||||
"by_country": [
|
||||
{
|
||||
"country": "DZ",
|
||||
"hcps": 122337,
|
||||
"with_email": 78496,
|
||||
"with_tel": 119396,
|
||||
"pct_email": 64.2,
|
||||
"pct_tel": 97.6
|
||||
},
|
||||
{
|
||||
"country": "MA",
|
||||
"hcps": 19723,
|
||||
"with_email": 15075,
|
||||
"with_tel": 18737,
|
||||
"pct_email": 76.4,
|
||||
"pct_tel": 95
|
||||
},
|
||||
{
|
||||
"country": "TN",
|
||||
"hcps": 17794,
|
||||
"with_email": 15145,
|
||||
"with_tel": 17018,
|
||||
"pct_email": 85.1,
|
||||
"pct_tel": 95.6
|
||||
},
|
||||
{
|
||||
"country": "INTL",
|
||||
"hcps": 1879,
|
||||
"with_email": 1879,
|
||||
"with_tel": 0,
|
||||
"pct_email": 100,
|
||||
"pct_tel": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"docker": [
|
||||
{
|
||||
"name": "loki",
|
||||
"status": "Up 4 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "listmonk",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "plausible-plausible-1",
|
||||
"status": "Up 3 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "plausible-plausible-db-1",
|
||||
"status": "Up 3 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "plausible-plausible-events-db-1",
|
||||
"status": "Up 3 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "n8n-docker-n8n-1",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "mattermost-docker-mm-db-1",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "mattermost-docker-mattermost-1",
|
||||
"status": "Up 5 days (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "twenty",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "twenty-redis",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "langfuse",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "redis-weval",
|
||||
"status": "Up 6 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "gitea",
|
||||
"status": "Up 6 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "node-exporter",
|
||||
"status": "Up 6 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "prometheus",
|
||||
"status": "Up 6 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "searxng",
|
||||
"status": "Up 6 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "uptime-kuma",
|
||||
"status": "Up 35 hours (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "vaultwarden",
|
||||
"status": "Up 6 days (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "qdrant",
|
||||
"status": "Up 6 days",
|
||||
"ports": ""
|
||||
}
|
||||
],
|
||||
"crons": {
|
||||
"active": 35
|
||||
},
|
||||
"git": {
|
||||
"head": "911e83379 auto-sync-1240",
|
||||
"dirty": 3,
|
||||
"status": "DIRTY"
|
||||
},
|
||||
"nonreg": {
|
||||
"total": 153,
|
||||
"passed": 153,
|
||||
"score": "100%"
|
||||
},
|
||||
"services": [
|
||||
{
|
||||
"name": "DeerFlow",
|
||||
"port": 3002,
|
||||
"status": "UP"
|
||||
},
|
||||
{
|
||||
"name": "DeerFlow API",
|
||||
"port": 8001,
|
||||
"status": "UP"
|
||||
},
|
||||
{
|
||||
"name": "Qdrant",
|
||||
"port": 6333,
|
||||
"status": "UP"
|
||||
},
|
||||
{
|
||||
"name": "Ollama",
|
||||
"port": 11434,
|
||||
"status": "UP"
|
||||
},
|
||||
{
|
||||
"name": "Redis",
|
||||
"port": 6379,
|
||||
"status": "UP"
|
||||
},
|
||||
{
|
||||
"name": "Sovereign",
|
||||
"port": 4000,
|
||||
"status": "UP"
|
||||
},
|
||||
{
|
||||
"name": "SearXNG",
|
||||
"port": 8080,
|
||||
"status": "UP"
|
||||
}
|
||||
],
|
||||
"whisper": {
|
||||
"binary": "COMPILED",
|
||||
"model": "142MB"
|
||||
},
|
||||
"grand_total": 3763,
|
||||
"health": {
|
||||
"score": 5,
|
||||
"max": 6,
|
||||
"pct": 83
|
||||
},
|
||||
"elapsed_ms": 11199
|
||||
}
|
||||
38
api/file_dump.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* intent-opus4-file_dump.php
|
||||
* AMBRE session · chunked file reader · offset + length
|
||||
* Invocation: /api/opus-arch-generic.php?tool=file_dump&path=X&offset=0&length=10000
|
||||
*/
|
||||
header("Content-Type: application/json");
|
||||
|
||||
$target = $_GET["path"] ?? "";
|
||||
$offset = (int)($_GET["offset"] ?? 0);
|
||||
$length = min((int)($_GET["length"] ?? 8000), 50000);
|
||||
|
||||
$real = realpath($target);
|
||||
$allowed = ["/var/www/html/", "/opt/wevads/", "/opt/weval-l99/"];
|
||||
$ok = false;
|
||||
foreach ($allowed as $root) {
|
||||
if ($real && strpos($real, $root) === 0) { $ok = true; break; }
|
||||
}
|
||||
if (!$ok || !file_exists($real)) {
|
||||
echo json_encode(["ok"=>false, "error"=>"path denied or not found", "path"=>$target]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$fh = fopen($real, "r");
|
||||
fseek($fh, $offset);
|
||||
$chunk = fread($fh, $length);
|
||||
fclose($fh);
|
||||
|
||||
echo json_encode([
|
||||
"ok" => true,
|
||||
"path" => $real,
|
||||
"offset" => $offset,
|
||||
"length" => strlen($chunk),
|
||||
"total" => filesize($real),
|
||||
"eof" => ($offset + strlen($chunk)) >= filesize($real),
|
||||
"content" => $chunk,
|
||||
"source" => "intent-opus4-file_dump.php · ambre · honest chunked read",
|
||||
]);
|
||||
8
api/handlers-misplaced.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"ts": "2026-04-21T15:05:33+02:00",
|
||||
"scanned": 2050,
|
||||
"misplaced_count": 0,
|
||||
"misplaced": [
|
||||
],
|
||||
"source": "wevia-handlers-detector.sh · wave 206 · nightly 03:15"
|
||||
}
|
||||
12
api/l99-state-file.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
// Wave 212 · expose L99 state file as JSON endpoint
|
||||
@require_once __DIR__ . '/wevia-sanitizer-guard.php';
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
$path = '/opt/weval-l99/l99-state.json';
|
||||
if (file_exists($path)) {
|
||||
$data = @file_get_contents($path);
|
||||
echo $data ?: '{"error":"read_fail"}';
|
||||
} else {
|
||||
echo '{"error":"state_not_found"}';
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"type": "daily",
|
||||
"timestamp": "2026-04-21 07:00",
|
||||
"timestamp": "2026-04-21 12:00",
|
||||
"squads": {
|
||||
"infra": {
|
||||
"name": "INFRA",
|
||||
|
||||
30
api/meetings/daily-2026-04-21-12-00.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"type": "DAILY STANDUP",
|
||||
"timestamp": "2026-04-21 12:00",
|
||||
"squad": "infra",
|
||||
"agents": {
|
||||
"cortex": {
|
||||
"done": "13 checks, services 7\/10 OK",
|
||||
"blockers": "none",
|
||||
"next": "Continue monitoring *\/4h"
|
||||
},
|
||||
"gap_detector": {
|
||||
"done": "Score 98% (50\/51 wired)",
|
||||
"blockers": "1 tools not wired",
|
||||
"next": "Wire remaining tools"
|
||||
},
|
||||
"nonreg": {
|
||||
"done": "153\/153 (100%)",
|
||||
"blockers": "none",
|
||||
"next": "Maintain 100%"
|
||||
},
|
||||
"security": {
|
||||
"done": "0 leaks, 92 expositions redacted, CrowdSec active",
|
||||
"blockers": "none",
|
||||
"next": "Continuous monitoring"
|
||||
}
|
||||
},
|
||||
"conflicts": [],
|
||||
"actions": [],
|
||||
"ai_analysis": "```json\n{\n \"conflicts\": [\n \"gap_detector est partiellement bloqué par des outils non connectés, ce qui pourrait impacter cortex (monitoring incomplet) si les outils non wired sont critiques\"\n ],\n \"common_issues\": [\n \"Surveillance continue requise par plusieurs agents (cortex, security, nonreg), risque de surcharge ou de vigilance réduite\",\n \"Dépendance à l'intégration complète des outils (gap_detector) pour assurer la cohérence globale du système WEVIA\"\n ],\n \"priority_actions\": [\n \"Wiring immédiat du dernier outil manquant pour gap_detector\",\n \"Vérifier l'impact du service non wired sur les services monitorés par cortex\",\n \"Consolider la visibilité des expositions récentes (security) avec gap_detector pour détecter toute corrélation\"\n ],\n \"conciliation\": [\n \"Coordonner gap_detector et cortex pour prioriser les services à surveiller en fonction des outils maintenant opérationnels\",\n \"Documenter l'outil manquant et justifier son retard pour éviter des points de blocage invisibles\"\n ]\n}\n```"
|
||||
}
|
||||
30
api/meetings/daily-2026-04-21-12-30.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"type": "DAILY STANDUP",
|
||||
"timestamp": "2026-04-21 12:30",
|
||||
"squad": "innovation",
|
||||
"agents": {
|
||||
"evolution": {
|
||||
"done": "System: ? routes, ? skills",
|
||||
"blockers": "Agent PHP syntax to fix",
|
||||
"next": "Generate 5 evolution proposals"
|
||||
},
|
||||
"scanner": {
|
||||
"done": "12 sections wiki scanned",
|
||||
"blockers": "none",
|
||||
"next": "Continue *\/2h"
|
||||
},
|
||||
"l99": {
|
||||
"done": "Functional ?\/93, Dark 7\/10",
|
||||
"blockers": "gitleaks+trivy version format mismatch",
|
||||
"next": "Fix dark test parsing"
|
||||
},
|
||||
"mirofish": {
|
||||
"done": "MiroFish DOWN",
|
||||
"blockers": "Service down",
|
||||
"next": "Collaborative tools"
|
||||
}
|
||||
},
|
||||
"conflicts": [],
|
||||
"actions": [],
|
||||
"ai_analysis": "```json\n{\n \"conflicts\": [\n \"Agent PHP syntax error bloque 'evolution' (nécessite routes\/skills pour générer propositions)\",\n \"Service MiroFish DOWN affecte potentiellement 'mirofish' et tout agent dépendant d'outils collaboratifs\",\n \"gitleaks+trivy mismatch dans 'l99' peut impacter sécurité globale et intégration continue\"\n ],\n \"common_issues\": [\n \"Problèmes de dépendances externes (services, versions, syntaxe)\",\n \"Manque de données ou formats incompatibles (PHP, parsing, versioning)\",\n \"Risque de paralysie partielle si les blocages ne sont pas résolus rapidement\"\n ],\n \"priority_actions\": [\n \"Réparer la syntaxe PHP pour débloquer 'evolution'\",\n \"Restaurer le service MiroFish ou basculer vers un outil de secours pour les outils collaboratifs\",\n \"Corriger le format de version entre gitleaks et trivy dans 'l99'\",\n \"Allouer un agent temporaire pour assistance multi-blocs si nécessaire\"\n ],\n \"conciliation\": [\n \"Coordonner 'l99' et 'evolution' sur un format de version commun partagé\",\n \"Désigner un relais ('scanner' ?) pour assurer la continuité info si 'mirofish' reste down\"\n ]\n}\n```"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"type": "DAILY STANDUP",
|
||||
"timestamp": "2026-04-21 06:30",
|
||||
"timestamp": "2026-04-21 12:30",
|
||||
"squad": "innovation",
|
||||
"agents": {
|
||||
"evolution": {
|
||||
@@ -26,5 +26,5 @@
|
||||
},
|
||||
"conflicts": [],
|
||||
"actions": [],
|
||||
"ai_analysis": "{\n \"conflicts\": [\n \"Agent PHP syntax to fix (blocker pour evolution) peut impacter la génération des routes et skills nécessaires à d'autres agents\",\n \"MiroFish DOWN (blocker pour mirofish) empêche l'accès aux outils collaboratifs, pouvant ralentir coordination notamment avec scanner et l99\",\n \"gitleaks+trivy version mismatch (blocker pour l99) pourrait influencer la sécurité des livrables si non aligné avec les scans du scanner\"\n ],\n \"common_issues\": [\n \"Problèmes de dépendances\/outils externes (syntaxe PHP, versions gitleaks+trivy, service MiroFish)\",\n \"Manque de visibilité sur l'avancement réel (indicateurs en ? pour evolution et l99)\",\n \"Fiabilité des services tierces critiques (MiroFish, outils de scan)\"\n ],\n \"priority_actions\": [\n \"Réparer la syntaxe PHP pour débloquer evolution\",\n \"Restaurer le service MiroFish ou basculer vers un outil de remplacement temporaire\",\n \"Résoudre le mismatch de versions entre gitleaks et trivy\",\n \"Relancer le scanner toutes les 2h avec une vérification de l'état de MiroFish\"\n ],\n \"conciliation\": [\n \"Coordonner l99 et scanner sur les formats de sortie attendus pour éviter des incompatibilités futures\",\n \"Désigner un agent temporaire (ex: scanner) comme relais de coordination si MiroFish reste down\",\n \"Synchroniser evolution avec l99 pour s'assurer que les dark tests sont pris en compte dans les propositions d'évolution\"\n ]\n}"
|
||||
"ai_analysis": "```json\n{\n \"conflicts\": [\n \"Agent PHP syntax error bloque 'evolution' (nécessite routes\/skills pour générer propositions)\",\n \"Service MiroFish DOWN affecte potentiellement 'mirofish' et tout agent dépendant d'outils collaboratifs\",\n \"gitleaks+trivy mismatch dans 'l99' peut impacter sécurité globale et intégration continue\"\n ],\n \"common_issues\": [\n \"Problèmes de dépendances externes (services, versions, syntaxe)\",\n \"Manque de données ou formats incompatibles (PHP, parsing, versioning)\",\n \"Risque de paralysie partielle si les blocages ne sont pas résolus rapidement\"\n ],\n \"priority_actions\": [\n \"Réparer la syntaxe PHP pour débloquer 'evolution'\",\n \"Restaurer le service MiroFish ou basculer vers un outil de secours pour les outils collaboratifs\",\n \"Corriger le format de version entre gitleaks et trivy dans 'l99'\",\n \"Allouer un agent temporaire pour assistance multi-blocs si nécessaire\"\n ],\n \"conciliation\": [\n \"Coordonner 'l99' et 'evolution' sur un format de version commun partagé\",\n \"Désigner un relais ('scanner' ?) pour assurer la continuité info si 'mirofish' reste down\"\n ]\n}\n```"
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"ok": true,
|
||||
"agent": "V42_MQL_Scoring_Agent_REAL",
|
||||
"ts": "2026-04-21T10:40:01+00:00",
|
||||
"ts": "2026-04-21T14:30:02+00:00",
|
||||
"status": "DEPLOYED_AUTO",
|
||||
"deployed": true,
|
||||
"algorithm": "weighted_behavioral_signals",
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"ts": "20260421_123827", "version": "3.2", "score": 100, "pass": 153, "fail": 0, "total": 153, "elapsed": 56.3, "categories": {"S204": {"pass": 9, "fail": 0}, "S95-WV": {"pass": 12, "fail": 0}, "S95-ARS": {"pass": 17, "fail": 0}, "S95-iR": {"pass": 1, "fail": 0}, "INFRA": {"pass": 5, "fail": 0}, "API": {"pass": 27, "fail": 0}, "SEC": {"pass": 4, "fail": 0}, "S95-BK": {"pass": 6, "fail": 0}, "C2-API": {"pass": 4, "fail": 0}, "C2-SPA": {"pass": 1, "fail": 0}, "C2-WV": {"pass": 3, "fail": 0}, "SSO": {"pass": 25, "fail": 0}, "DATA": {"pass": 5, "fail": 0}, "CRONS": {"pass": 2, "fail": 0}, "BLADE": {"pass": 7, "fail": 0}, "LIFE": {"pass": 3, "fail": 0}, "FUNC": {"pass": 7, "fail": 0}, "01AVR": {"pass": 10, "fail": 0}, "STRUCT": {"pass": 5, "fail": 0}}, "failures": []}
|
||||
{"ts": "20260421_152221", "version": "3.2", "score": 100, "pass": 153, "fail": 0, "total": 153, "elapsed": 32.4, "categories": {"S204": {"pass": 9, "fail": 0}, "S95-WV": {"pass": 12, "fail": 0}, "S95-ARS": {"pass": 17, "fail": 0}, "S95-iR": {"pass": 1, "fail": 0}, "INFRA": {"pass": 5, "fail": 0}, "API": {"pass": 27, "fail": 0}, "SEC": {"pass": 4, "fail": 0}, "S95-BK": {"pass": 6, "fail": 0}, "C2-API": {"pass": 4, "fail": 0}, "C2-SPA": {"pass": 1, "fail": 0}, "C2-WV": {"pass": 3, "fail": 0}, "SSO": {"pass": 25, "fail": 0}, "DATA": {"pass": 5, "fail": 0}, "CRONS": {"pass": 2, "fail": 0}, "BLADE": {"pass": 7, "fail": 0}, "LIFE": {"pass": 3, "fail": 0}, "FUNC": {"pass": 7, "fail": 0}, "01AVR": {"pass": 10, "fail": 0}, "STRUCT": {"pass": 5, "fail": 0}}, "failures": []}
|
||||
@@ -67,7 +67,7 @@ if ($action === 'execute') {
|
||||
|
||||
if ($dry_run) {
|
||||
foreach ($ready as $s) {
|
||||
$executed[] = ['step_id'=>$s['step_id'], 'step_order'=>$s['step_order'], 'name'=>$s['step_name'], 'action'=>'DRY_RUN', 'order'=>$s['step_order']];
|
||||
$executed[] = ['step_id'=>$s['step_id'], 'step_order'=>$s['step_order'], 'step_order'=>$s['step_order'], 'name'=>$s['step_name'], 'action'=>'DRY_RUN', 'order'=>$s['step_order']];
|
||||
$done_ids[] = (int)$s['step_order'];
|
||||
}
|
||||
continue;
|
||||
@@ -81,7 +81,7 @@ if ($action === 'execute') {
|
||||
$url = $s['action_url'];
|
||||
if (!$url) {
|
||||
$db->prepare("UPDATE admin.wevia_plan_steps SET status='failed', result='no_url', finished_at=NOW() WHERE step_id=?")->execute([$s['step_id']]);
|
||||
$failed[] = ['step_id'=>$s['step_id'], 'step_order'=>$s['step_order'], 'name'=>$s['step_name'], 'err'=>'no_url'];
|
||||
$failed[] = ['step_id'=>$s['step_id'], 'step_order'=>$s['step_order'], 'step_order'=>$s['step_order'], 'name'=>$s['step_name'], 'err'=>'no_url'];
|
||||
continue;
|
||||
}
|
||||
$method = strtoupper((string)($s['action_method'] ?? 'POST'));
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
"name": "weval-l99",
|
||||
"path": "/opt/weval-l99",
|
||||
"files": 644,
|
||||
"files": 648,
|
||||
"has_readme": false,
|
||||
"has_skill": false,
|
||||
"has_python": true,
|
||||
@@ -10,12 +10,12 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:03.814567"
|
||||
"discovered": "2026-04-21T16:00:04.819776"
|
||||
},
|
||||
{
|
||||
"name": "wevia-brain",
|
||||
"path": "/opt/wevia-brain",
|
||||
"files": 162,
|
||||
"files": 163,
|
||||
"has_readme": false,
|
||||
"has_skill": false,
|
||||
"has_python": true,
|
||||
@@ -23,7 +23,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:04.273693"
|
||||
"discovered": "2026-04-21T16:00:04.997109"
|
||||
},
|
||||
{
|
||||
"name": "skills",
|
||||
@@ -36,7 +36,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:03.438948"
|
||||
"discovered": "2026-04-21T16:00:04.536304"
|
||||
},
|
||||
{
|
||||
"name": "everything-claude-code",
|
||||
@@ -49,7 +49,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "**Language:** English | [Português (Brasil)](docs/pt-BR/README.md) | [简体中文](README.zh-CN.md) | [繁體中文](docs/zh-TW/README.md) | [日本語](docs/ja-JP/README.",
|
||||
"discovered": "2026-04-21T12:00:02.523626"
|
||||
"discovered": "2026-04-21T16:00:04.067458"
|
||||
},
|
||||
{
|
||||
"name": "open-webui-fresh",
|
||||
@@ -62,7 +62,7 @@
|
||||
"has_docker": true,
|
||||
"wired": true,
|
||||
"description": "# Open WebUI 👋   | [中文](README.zh.md) | [日本語](README.ja.md) | [Español](README.es.md) | [Tiếng Việt](README.vi.md) | [Português](README.p",
|
||||
"discovered": "2026-04-21T12:00:02.824885"
|
||||
"discovered": "2026-04-21T16:00:04.274526"
|
||||
},
|
||||
{
|
||||
"name": "mxyhi_ok-skills",
|
||||
@@ -114,7 +114,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "# OK Skills: AI Coding Agent Skills for Codex, Claude Code, Cursor, OpenClaw, and More English | [简体中文](README.zh-CN.md) | [繁體中文](README.zh-TW.md) | ",
|
||||
"discovered": "2026-04-21T12:00:02.739903"
|
||||
"discovered": "2026-04-21T16:00:04.237089"
|
||||
},
|
||||
{
|
||||
"name": "SuperClaude_Framework",
|
||||
@@ -127,7 +127,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "<div align=\"center\"> # 🚀 SuperClaude Framework [](https://smithery.ai/skills?ns=",
|
||||
"discovered": "2026-04-21T12:00:02.435244"
|
||||
"discovered": "2026-04-21T16:00:03.824199"
|
||||
},
|
||||
{
|
||||
"name": "paperclip-weval",
|
||||
@@ -140,7 +140,7 @@
|
||||
"has_docker": true,
|
||||
"wired": true,
|
||||
"description": "<p align=\"center\"> <img src=\"doc/assets/header.png\" alt=\"Paperclip — runs your business\" width=\"720\" /> </p> <p align=\"center\"> <a href=\"#quickst",
|
||||
"discovered": "2026-04-21T12:00:02.916894"
|
||||
"discovered": "2026-04-21T16:00:04.325183"
|
||||
},
|
||||
{
|
||||
"name": "vllm",
|
||||
@@ -153,7 +153,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "<!-- markdownlint-disable MD001 MD041 --> <p align=\"center\"> <picture> <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubus",
|
||||
"discovered": "2026-04-21T12:00:03.630040"
|
||||
"discovered": "2026-04-21T16:00:04.725255"
|
||||
},
|
||||
{
|
||||
"name": "deer-flow",
|
||||
@@ -166,7 +166,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "# 🦌 DeerFlow - 2.0 English | [中文](./README_zh.md) | [日本語](./README_ja.md) | [Français](./README_fr.md) | [Русский](./README_ru.md) [ [](https://agent.xfyun.cn) <div align=\"center\"> [ | [Français](docs/translations/README.fr.md) | [Italiano](docs/translations/README.it.md) | ",
|
||||
"discovered": "2026-04-21T12:00:02.426885"
|
||||
"discovered": "2026-04-21T16:00:03.741972"
|
||||
},
|
||||
{
|
||||
"name": "aios",
|
||||
@@ -361,7 +374,7 @@
|
||||
"has_docker": true,
|
||||
"wired": true,
|
||||
"description": "# AIOS: AI Agent Operating System <a href='https://arxiv.org/abs/2403.16971'><img src='https://img.shields.io/badge/Paper-PDF-red'></a> <a href='http",
|
||||
"discovered": "2026-04-21T12:00:02.442368"
|
||||
"discovered": "2026-04-21T16:00:03.855585"
|
||||
},
|
||||
{
|
||||
"name": "rnd-agent-framework",
|
||||
@@ -374,20 +387,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": " # Welcome to Microsoft Agent Framework! [\"> <source srcset=\"apps/w",
|
||||
"discovered": "2026-04-21T12:00:03.571040"
|
||||
},
|
||||
{
|
||||
"name": "wevads",
|
||||
"path": "/opt/wevads",
|
||||
"files": 14,
|
||||
"has_readme": false,
|
||||
"has_skill": false,
|
||||
"has_python": false,
|
||||
"has_node": false,
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:03.662634"
|
||||
"discovered": "2026-04-21T16:00:04.575438"
|
||||
},
|
||||
{
|
||||
"name": "fmgapp",
|
||||
@@ -478,7 +478,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:02.543976"
|
||||
"discovered": "2026-04-21T16:00:04.071376"
|
||||
},
|
||||
{
|
||||
"name": "obsidian-vault",
|
||||
@@ -491,7 +491,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:02.770639"
|
||||
"discovered": "2026-04-21T16:00:04.254276"
|
||||
},
|
||||
{
|
||||
"name": "rnd-agents",
|
||||
@@ -504,7 +504,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "# Claude Code Plugins: Orchestration and Automation > **⚡ Updated for Opus 4.6, Sonnet 4.6 & Haiku 4.5** — Three-tier model strategy for optimal perf",
|
||||
"discovered": "2026-04-21T12:00:03.247007"
|
||||
"discovered": "2026-04-21T16:00:04.458045"
|
||||
},
|
||||
{
|
||||
"name": "FrancyJGLisboa_agent-skill-creator",
|
||||
@@ -517,7 +517,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "# Agent Skill Creator **Turn any workflow into reusable AI agent software that installs on 14+ tools — no spec writing, no prompt engineering, no cod",
|
||||
"discovered": "2026-04-21T12:00:02.424046"
|
||||
"discovered": "2026-04-21T16:00:03.654108"
|
||||
},
|
||||
{
|
||||
"name": "skillsmith",
|
||||
@@ -530,7 +530,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "<div align=\"center\"> <img src=\"terminal.svg\" alt=\"Skillsmith terminal\" width=\"740\"/> </div> <div align=\"center\"> # Skillsmith **Build consistent ",
|
||||
"discovered": "2026-04-21T12:00:03.505441"
|
||||
"discovered": "2026-04-21T16:00:04.546821"
|
||||
},
|
||||
{
|
||||
"name": "awesome-agent-skills",
|
||||
@@ -543,7 +543,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "<a href=\"https://github.com/VoltAgent/voltagent\"> <img width=\"1500\" height=\"801\" alt=\"claude-skills\" src=\"https://github.com/user-attachments/ass",
|
||||
"discovered": "2026-04-21T12:00:02.478909"
|
||||
"discovered": "2026-04-21T16:00:04.032534"
|
||||
},
|
||||
{
|
||||
"name": "paperclip-skills",
|
||||
@@ -556,7 +556,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:02.860097"
|
||||
"discovered": "2026-04-21T16:00:04.306955"
|
||||
},
|
||||
{
|
||||
"name": "jzOcb_writing-style-skill",
|
||||
@@ -569,7 +569,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "# Writing Style Skill 可复用的写作风格 Skill 模板。**内置自动学习** — 从你的修改中自动提取规则,SKILL.md 越用越准。 兼容 **Claude Code** + **OpenClaw (ClawHub)**。 ## 原理 ``` AI 用 SKILL",
|
||||
"discovered": "2026-04-21T12:00:02.577169"
|
||||
"discovered": "2026-04-21T16:00:04.083587"
|
||||
},
|
||||
{
|
||||
"name": "qdrant-data",
|
||||
@@ -582,7 +582,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:03.078202"
|
||||
"discovered": "2026-04-21T16:00:04.389173"
|
||||
},
|
||||
{
|
||||
"name": "wazuh",
|
||||
@@ -595,7 +595,7 @@
|
||||
"has_docker": true,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:03.653026"
|
||||
"discovered": "2026-04-21T16:00:04.736401"
|
||||
},
|
||||
{
|
||||
"name": "plausible",
|
||||
@@ -608,7 +608,7 @@
|
||||
"has_docker": true,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:02.962123"
|
||||
"discovered": "2026-04-21T16:00:04.342191"
|
||||
},
|
||||
{
|
||||
"name": "pmta",
|
||||
@@ -621,7 +621,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:03.011195"
|
||||
"discovered": "2026-04-21T16:00:04.355029"
|
||||
},
|
||||
{
|
||||
"name": "render-configs",
|
||||
@@ -634,7 +634,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:03.148687"
|
||||
"discovered": "2026-04-21T16:00:04.408294"
|
||||
},
|
||||
{
|
||||
"name": "searxng",
|
||||
@@ -647,7 +647,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:03.394951"
|
||||
"discovered": "2026-04-21T16:00:04.515442"
|
||||
},
|
||||
{
|
||||
"name": "weval-guardian",
|
||||
@@ -660,7 +660,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:03.737421"
|
||||
"discovered": "2026-04-21T16:00:04.798671"
|
||||
},
|
||||
{
|
||||
"name": "weval-litellm",
|
||||
@@ -673,7 +673,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:03.901719"
|
||||
"discovered": "2026-04-21T16:00:04.838732"
|
||||
},
|
||||
{
|
||||
"name": "weval-security",
|
||||
@@ -686,7 +686,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:04.206410"
|
||||
"discovered": "2026-04-21T16:00:04.963419"
|
||||
},
|
||||
{
|
||||
"name": "archive",
|
||||
@@ -699,7 +699,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:02.457008"
|
||||
"discovered": "2026-04-21T16:00:03.953415"
|
||||
},
|
||||
{
|
||||
"name": "loki",
|
||||
@@ -712,7 +712,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:02.631990"
|
||||
"discovered": "2026-04-21T16:00:04.161645"
|
||||
},
|
||||
{
|
||||
"name": "ruflo",
|
||||
@@ -725,7 +725,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:03.356704"
|
||||
"discovered": "2026-04-21T16:00:04.507898"
|
||||
},
|
||||
{
|
||||
"name": "twenty",
|
||||
@@ -738,7 +738,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:03.591714"
|
||||
"discovered": "2026-04-21T16:00:04.616634"
|
||||
},
|
||||
{
|
||||
"name": "weval-crewai",
|
||||
@@ -751,7 +751,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:03.682996"
|
||||
"discovered": "2026-04-21T16:00:04.772973"
|
||||
},
|
||||
{
|
||||
"name": "weval-plugins",
|
||||
@@ -764,7 +764,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:04.058981"
|
||||
"discovered": "2026-04-21T16:00:04.900134"
|
||||
},
|
||||
{
|
||||
"name": "weval-radar",
|
||||
@@ -777,7 +777,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:04.069263"
|
||||
"discovered": "2026-04-21T16:00:04.918896"
|
||||
},
|
||||
{
|
||||
"name": "weval-scrapy",
|
||||
@@ -790,7 +790,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:04.161242"
|
||||
"discovered": "2026-04-21T16:00:04.943506"
|
||||
},
|
||||
{
|
||||
"name": "langfuse",
|
||||
@@ -803,7 +803,7 @@
|
||||
"has_docker": true,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:02.594473"
|
||||
"discovered": "2026-04-21T16:00:04.086570"
|
||||
},
|
||||
{
|
||||
"name": "litellm",
|
||||
@@ -816,7 +816,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:02.621946"
|
||||
"discovered": "2026-04-21T16:00:04.126567"
|
||||
},
|
||||
{
|
||||
"name": "mattermost-docker",
|
||||
@@ -829,7 +829,7 @@
|
||||
"has_docker": true,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:02.641463"
|
||||
"discovered": "2026-04-21T16:00:04.180697"
|
||||
},
|
||||
{
|
||||
"name": "prometheus",
|
||||
@@ -842,7 +842,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:03.026649"
|
||||
"discovered": "2026-04-21T16:00:04.375182"
|
||||
},
|
||||
{
|
||||
"name": "twenty-compose",
|
||||
@@ -855,7 +855,7 @@
|
||||
"has_docker": true,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:03.612613"
|
||||
"discovered": "2026-04-21T16:00:04.666219"
|
||||
},
|
||||
{
|
||||
"name": "weval-ux",
|
||||
@@ -868,7 +868,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:04.239755"
|
||||
"discovered": "2026-04-21T16:00:04.979610"
|
||||
},
|
||||
{
|
||||
"name": "wevia-integrity",
|
||||
@@ -881,7 +881,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:04.352105"
|
||||
"discovered": "2026-04-21T16:00:05.022215"
|
||||
},
|
||||
{
|
||||
"name": "DiffusionDB",
|
||||
@@ -894,7 +894,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:02.419989"
|
||||
"discovered": "2026-04-21T16:00:03.583864"
|
||||
},
|
||||
{
|
||||
"name": "LTX-Video",
|
||||
@@ -907,7 +907,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:02.429413"
|
||||
"discovered": "2026-04-21T16:00:03.808120"
|
||||
},
|
||||
{
|
||||
"name": "localai",
|
||||
@@ -920,7 +920,7 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:02.629954"
|
||||
"discovered": "2026-04-21T16:00:04.148879"
|
||||
},
|
||||
{
|
||||
"name": "wevia-finetune",
|
||||
@@ -933,6 +933,6 @@
|
||||
"has_docker": false,
|
||||
"wired": true,
|
||||
"description": "",
|
||||
"discovered": "2026-04-21T12:00:04.310331"
|
||||
"discovered": "2026-04-21T16:00:05.013075"
|
||||
}
|
||||
]
|
||||
@@ -34,7 +34,7 @@ if (!is_array($data) || empty($data)) {
|
||||
$af_path = "$DOCROOT/$af";
|
||||
if (file_exists($af_path)) {
|
||||
$content = file_get_contents($af_path);
|
||||
if (preg_match_all('/href="\/?([a-z0-9_-]+\.html)"/i', $content, $matches)) {
|
||||
if (preg_match_all('/href="\/?([a-z0-9_\-\xc0-\xff%]+\.html)"/iu', $content, $matches)) {
|
||||
foreach ($matches[1] as $m) $referenced[$m] = true;
|
||||
}
|
||||
}
|
||||
@@ -80,6 +80,17 @@ if (!is_array($data) || empty($data)) {
|
||||
$o['category'] = $cat;
|
||||
$o['wire_suggestion'] = $sug;
|
||||
}
|
||||
unset($o); // WAVE 207 fix PHP by-ref leak
|
||||
// WAVE 207 dedup by file name (defensive)
|
||||
$seen = [];
|
||||
$unique = [];
|
||||
foreach ($orphans as $o2) {
|
||||
if (!isset($seen[$o2['file']])) {
|
||||
$seen[$o2['file']] = 1;
|
||||
$unique[] = $o2;
|
||||
}
|
||||
}
|
||||
$orphans = $unique;
|
||||
|
||||
// Count by category
|
||||
$by_cat = [];
|
||||
|
||||
94
api/playwright-v132-100-pct-portfolio/results.json
Normal file
@@ -0,0 +1,94 @@
|
||||
{
|
||||
"version": "V132",
|
||||
"date": "2026-04-21T12:13:46.411Z",
|
||||
"pass": 12,
|
||||
"fail": 0,
|
||||
"total": 12,
|
||||
"score_pct": 100,
|
||||
"tests": [
|
||||
{
|
||||
"intent": "dev_ecommerce",
|
||||
"query": "comment developper un site ecommerce",
|
||||
"engine": "PendingLoader/dev_ecommerce",
|
||||
"status": "PASS",
|
||||
"elapsed_ms": 1596
|
||||
},
|
||||
{
|
||||
"intent": "dev_erp",
|
||||
"query": "comment migrer mon ERP",
|
||||
"engine": "PendingLoader/dev_erp",
|
||||
"status": "PASS",
|
||||
"elapsed_ms": 1559
|
||||
},
|
||||
{
|
||||
"intent": "dev_cloud",
|
||||
"query": "comment migrer vers le cloud",
|
||||
"engine": "PendingLoader/dev_cloud",
|
||||
"status": "PASS",
|
||||
"elapsed_ms": 1538
|
||||
},
|
||||
{
|
||||
"intent": "dev_crm",
|
||||
"query": "comment deployer un CRM",
|
||||
"engine": "PendingLoader/dev_crm",
|
||||
"status": "PASS",
|
||||
"elapsed_ms": 1611
|
||||
},
|
||||
{
|
||||
"intent": "dev_ia",
|
||||
"query": "comment faire un chatbot",
|
||||
"engine": "PendingLoader/dev_ia",
|
||||
"status": "PASS",
|
||||
"elapsed_ms": 1558
|
||||
},
|
||||
{
|
||||
"intent": "dev_data",
|
||||
"query": "comment faire du BI",
|
||||
"engine": "PendingLoader/dev_data",
|
||||
"status": "PASS",
|
||||
"elapsed_ms": 1552
|
||||
},
|
||||
{
|
||||
"intent": "dev_marketing",
|
||||
"query": "comment faire une campagne email",
|
||||
"engine": "PendingLoader/dev_marketing",
|
||||
"status": "PASS",
|
||||
"elapsed_ms": 1602
|
||||
},
|
||||
{
|
||||
"intent": "dev_web_app",
|
||||
"query": "comment developper une web app",
|
||||
"engine": "PendingLoader/dev_web_app",
|
||||
"status": "PASS",
|
||||
"elapsed_ms": 1540
|
||||
},
|
||||
{
|
||||
"intent": "dev_mobile",
|
||||
"query": "comment developper une app mobile",
|
||||
"engine": "PendingLoader/dev_mobile",
|
||||
"status": "PASS",
|
||||
"elapsed_ms": 1584
|
||||
},
|
||||
{
|
||||
"intent": "dev_devops",
|
||||
"query": "comment mettre en place CI CD",
|
||||
"engine": "PendingLoader/dev_devops",
|
||||
"status": "PASS",
|
||||
"elapsed_ms": 1552
|
||||
},
|
||||
{
|
||||
"intent": "dev_security",
|
||||
"query": "comment faire un pentest",
|
||||
"engine": "PendingLoader/dev_security",
|
||||
"status": "PASS",
|
||||
"elapsed_ms": 1562
|
||||
},
|
||||
{
|
||||
"intent": "dev_project_auto",
|
||||
"query": "comment commencer un projet tech",
|
||||
"engine": "PendingLoader/dev_project_auto",
|
||||
"status": "PASS",
|
||||
"elapsed_ms": 1567
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
api/playwright-v132-100-pct-portfolio/screenshots/dev_cloud.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
api/playwright-v132-100-pct-portfolio/screenshots/dev_crm.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
api/playwright-v132-100-pct-portfolio/screenshots/dev_data.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
api/playwright-v132-100-pct-portfolio/screenshots/dev_devops.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 22 KiB |
BIN
api/playwright-v132-100-pct-portfolio/screenshots/dev_erp.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
api/playwright-v132-100-pct-portfolio/screenshots/dev_ia.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 22 KiB |
BIN
api/playwright-v132-100-pct-portfolio/screenshots/dev_mobile.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 22 KiB |