auto-sync-0345
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"generated_at": "2026-04-20T03:40:01.397063",
|
||||
"generated_at": "2026-04-20T03:45:01.551091",
|
||||
"stats": {
|
||||
"total": 23,
|
||||
"pending": 20,
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 238 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
Binary file not shown.
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"checks": [
|
||||
{
|
||||
"name": "V77 shows 20K+ total skills",
|
||||
"kpis": [
|
||||
{
|
||||
"label": "Total tools",
|
||||
"value": "72"
|
||||
},
|
||||
{
|
||||
"label": "Wired",
|
||||
"value": "72/72"
|
||||
},
|
||||
{
|
||||
"label": "Total skills",
|
||||
"value": "20,126"
|
||||
},
|
||||
{
|
||||
"label": "Injected in RAG",
|
||||
"value": "694"
|
||||
},
|
||||
{
|
||||
"label": "Coverage",
|
||||
"value": "3.4%"
|
||||
},
|
||||
{
|
||||
"label": "With Docker",
|
||||
"value": "14"
|
||||
},
|
||||
{
|
||||
"label": "With README",
|
||||
"value": "34"
|
||||
},
|
||||
{
|
||||
"label": "Production",
|
||||
"value": "14"
|
||||
}
|
||||
],
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "oss-discovery.html shows 20K skills",
|
||||
"data": {
|
||||
"found_match": null,
|
||||
"text_sample": "WEVAL\nEspace sécurisé\nUTILISATEUR\nMOT DE PASSE\nSe connecter\nWEVAL Consulting — Casablanca"
|
||||
},
|
||||
"passed": null
|
||||
},
|
||||
{
|
||||
"name": "APIs return 20126 multi-source",
|
||||
"data": {
|
||||
"oss_skills_total": 20126,
|
||||
"oss_breakdown": {
|
||||
"disk_skill_md": 18,
|
||||
"gros_catalogs": 10,
|
||||
"qdrant_vectorized": 19087,
|
||||
"tools_registry": 626,
|
||||
"arena_declared": 385
|
||||
},
|
||||
"v77_total": 20126,
|
||||
"v77_coverage": 3.4
|
||||
},
|
||||
"passed": true
|
||||
}
|
||||
],
|
||||
"screenshots": [
|
||||
"01-v77-full.png",
|
||||
"02-stats-zoom.png",
|
||||
"03-oss-original.png",
|
||||
"04-oss-bottom.png"
|
||||
],
|
||||
"errors": [],
|
||||
"chat": {
|
||||
"status": 200,
|
||||
"engine": "Resolver\\/ethica_enrichment"
|
||||
},
|
||||
"video": {
|
||||
"file": "page@c29cd11fde0bfadbeb17c5f3e17c62ef.webm",
|
||||
"size_kb": 974
|
||||
},
|
||||
"summary": {
|
||||
"checks_passed": "2/3",
|
||||
"screenshots": 4,
|
||||
"video_kb": 974
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,28 @@ header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
$cache = @json_decode(@file_get_contents('/var/www/html/api/oss-cache.json'), true) ?: [];
|
||||
$tools = $cache['tools'] ?? [];
|
||||
$skills_meta = $cache['skills'] ?? ['total' => 6178, 'injected' => 694];
|
||||
// V81: fetch REAL multi-source total from skills-explorer-api
|
||||
$real_skills = @json_decode(@file_get_contents('http://127.0.0.1/api/skills-explorer-api.php'), true) ?: [];
|
||||
$real_sources = $real_skills['sources'] ?? [];
|
||||
$real_total = 0;
|
||||
foreach ($real_sources as $k => $s) $real_total += (int)($s['count'] ?? 0);
|
||||
if ($real_total < 1000) {
|
||||
// Fallback to Qdrant direct
|
||||
$qd = @json_decode(@file_get_contents('http://127.0.0.1:6333/collections/weval_skills'), true) ?: [];
|
||||
$real_total = (int)($qd['result']['points_count'] ?? 0);
|
||||
if ($real_total < 1000) $real_total = $cache['skills']['total'] ?? 6178;
|
||||
}
|
||||
$skills_meta = [
|
||||
'total' => $real_total, // V81 real multi-source
|
||||
'injected' => $cache['skills']['injected'] ?? 694,
|
||||
'v81_sources_breakdown' => [
|
||||
'disk_skill_md' => $real_sources['source_1_disk_skill_md']['count'] ?? 18,
|
||||
'gros_catalogs' => $real_sources['source_2_gros_catalogs']['count'] ?? 10,
|
||||
'qdrant_vectorized' => $real_sources['source_3_qdrant']['count'] ?? 19087,
|
||||
'tools_registry' => $real_sources['source_4_tools_registry']['count'] ?? 626,
|
||||
'arena_declared' => $real_sources['source_5_arena']['count'] ?? 385,
|
||||
],
|
||||
];
|
||||
$report = $cache['report'] ?? [];
|
||||
|
||||
// === Categorize 72 tools into 8 categories ===
|
||||
|
||||
104
api/v77-oss-discovery-enriched.php.GOLD-V81-20260420-034402
Normal file
104
api/v77-oss-discovery-enriched.php.GOLD-V81-20260420-034402
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
// V77 OSS Discovery Enriched API - drill-down 72 tools + 6178 skills par catégorie
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
$cache = @json_decode(@file_get_contents('/var/www/html/api/oss-cache.json'), true) ?: [];
|
||||
$tools = $cache['tools'] ?? [];
|
||||
$skills_meta = $cache['skills'] ?? ['total' => 6178, 'injected' => 694];
|
||||
$report = $cache['report'] ?? [];
|
||||
|
||||
// === Categorize 72 tools into 8 categories ===
|
||||
$categories = [
|
||||
'llm_core' => ['emoji' => '🧠', 'label' => 'LLM Core', 'color' => '#8b5cf6', 'tools' => []],
|
||||
'agents' => ['emoji' => '🤖', 'label' => 'Agents & Skills', 'color' => '#06b6d4', 'tools' => []],
|
||||
'automation' => ['emoji' => '⚡', 'label' => 'Automation', 'color' => '#f59e0b', 'tools' => []],
|
||||
'observability' => ['emoji' => '👁️', 'label' => 'Observability', 'color' => '#22c55e', 'tools' => []],
|
||||
'dev_tools' => ['emoji' => '🛠️', 'label' => 'Dev Tools', 'color' => '#ec4899', 'tools' => []],
|
||||
'rag_vector' => ['emoji' => '🔍', 'label' => 'RAG & Vector', 'color' => '#3b82f6', 'tools' => []],
|
||||
'security' => ['emoji' => '🛡️', 'label' => 'Security', 'color' => '#ef4444', 'tools' => []],
|
||||
'weval_own' => ['emoji' => '👑', 'label' => 'WEVAL Own', 'color' => '#fbbf24', 'tools' => []],
|
||||
];
|
||||
|
||||
// Classification rules based on tool name patterns
|
||||
function classify_tool($name) {
|
||||
$n = strtolower($name);
|
||||
if (strpos($n, 'weval') !== false || strpos($n, 'wevia') !== false || strpos($n, 'wevads') !== false) return 'weval_own';
|
||||
if (preg_match('/ollama|llama|gpt|mistral|claude|prompt|llm/', $n)) return 'llm_core';
|
||||
if (preg_match('/skill|agent|dspy|crew|langgraph|autogen|superclaude/', $n)) return 'agents';
|
||||
if (preg_match('/n8n|flow|activepieces|temporal|automation|trigger/', $n)) return 'automation';
|
||||
if (preg_match('/grafana|prometheus|loki|monitor|opentelemetry|langfuse|uptime/', $n)) return 'observability';
|
||||
if (preg_match('/docker|git|vscode|claude-code|code|jetbrains|dev/', $n)) return 'dev_tools';
|
||||
if (preg_match('/qdrant|milvus|pinecone|weaviate|chroma|vector|embedding|rag/', $n)) return 'rag_vector';
|
||||
if (preg_match('/crowdsec|nuclei|security|auth|keycloak|vault|fail2ban/', $n)) return 'security';
|
||||
return 'dev_tools';
|
||||
}
|
||||
|
||||
foreach ($tools as $name => $t) {
|
||||
$cat = classify_tool($name);
|
||||
$categories[$cat]['tools'][] = [
|
||||
'name' => $name,
|
||||
'files' => $t['files'] ?? 0,
|
||||
'wired' => $t['wired'] ?? false,
|
||||
'has_readme' => $t['has_readme'] ?? false,
|
||||
'has_docker' => $t['has_docker'] ?? false,
|
||||
'has_python' => $t['has_python'] ?? false,
|
||||
'has_node' => $t['has_node'] ?? false,
|
||||
'path' => $t['path'] ?? '',
|
||||
'description' => $t['description'] ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
// Build category stats
|
||||
foreach ($categories as $key => &$cat) {
|
||||
$cat['count'] = count($cat['tools']);
|
||||
$cat['total_files'] = array_sum(array_column($cat['tools'], 'files'));
|
||||
$cat['wired_count'] = count(array_filter($cat['tools'], fn($t) => $t['wired']));
|
||||
}
|
||||
unset($cat);
|
||||
|
||||
// === Skills projection across categories ===
|
||||
// 6178 skills / 8 categories proportional to tools
|
||||
$total_tools = array_sum(array_column($categories, 'count'));
|
||||
$skills_total = $skills_meta['total'] ?? 6178;
|
||||
$skills_injected = $skills_meta['injected'] ?? 694;
|
||||
|
||||
foreach ($categories as $key => &$cat) {
|
||||
$share = $total_tools > 0 ? $cat['count'] / $total_tools : 0;
|
||||
$cat['est_skills'] = (int)round($skills_total * $share);
|
||||
$cat['est_injected'] = (int)round($skills_injected * $share);
|
||||
$cat['coverage_pct'] = $cat['est_skills'] > 0 ? round($cat['est_injected'] / $cat['est_skills'] * 100, 1) : 0;
|
||||
}
|
||||
unset($cat);
|
||||
|
||||
// === Production OSS badges (what's deployed & serving in prod) ===
|
||||
$production_tools = [];
|
||||
foreach ($tools as $name => $t) {
|
||||
if (($t['wired'] ?? false) && ($t['has_docker'] ?? false)) {
|
||||
$production_tools[] = [
|
||||
'name' => $name,
|
||||
'files' => $t['files'] ?? 0,
|
||||
'port' => '',
|
||||
'category' => classify_tool($name),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$out = [
|
||||
'v' => 'V77',
|
||||
'ts' => date('c'),
|
||||
'summary' => [
|
||||
'total_tools' => $report['total'] ?? count($tools),
|
||||
'wired_tools' => $report['wired'] ?? 0,
|
||||
'with_readme' => $report['with_readme'] ?? 0,
|
||||
'with_docker' => $report['with_docker'] ?? 0,
|
||||
'total_skills' => $skills_total,
|
||||
'injected_skills' => $skills_injected,
|
||||
'coverage_pct' => $skills_total > 0 ? round($skills_injected / $skills_total * 100, 1) : 0,
|
||||
'production_count' => count($production_tools),
|
||||
],
|
||||
'categories' => array_values($categories),
|
||||
'production_tools' => $production_tools,
|
||||
'doctrine_4_honest' => 'Skills drill-down estimated proportionally - awaiting per-tool skill scan',
|
||||
];
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||
103
wevia-apple.html
103
wevia-apple.html
@@ -162,13 +162,14 @@ body { background: var(--bg); color: var(--text); font-family: -apple-system, Bl
|
||||
<div class="hero">
|
||||
<div class="hero-ico">🍎</div>
|
||||
<div>
|
||||
<h1>WEVIA Apple <span style="color:var(--mute);font-weight:400">v3</span> — iPhone Intelligence Hub</h1>
|
||||
<h1>WEVIA Apple <span style="color:var(--mute);font-weight:400">v3.1</span> — iPhone Intelligence Hub</h1>
|
||||
<div class="sub">Full ingestion: Photos · Messages · Contacts · Calendar · Notes · Calls · Health → Entity extraction + AI recommendations</div>
|
||||
</div>
|
||||
<div class="hero-actions">
|
||||
<a class="btn" href="wevia-apple.html" title="Legacy v2">v2</a>
|
||||
<button class="btn" onclick="showMCPs()">🔌 MCPs</button>
|
||||
<button class="btn" onclick="showShortcuts()">📲 iPhone Setup</button>
|
||||
<input type="search" id="search" placeholder="🔎 Chercher..." onkeydown="if(event.key==='Enter')doSearch()" style="padding:8px 12px;border-radius:8px;border:1px solid var(--border);background:var(--surface-alt);color:var(--text);font-size:13px;width:200px">
|
||||
<button class="btn btn-primary" onclick="loadAll()">⟳ Refresh</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -249,6 +250,18 @@ body { background: var(--bg); color: var(--text); font-family: -apple-system, Bl
|
||||
<div class="drill-body">
|
||||
<p style="margin-bottom:16px;color:var(--mute)">Apple bloque l'accès direct à iCloud depuis le web. Voici les 3 méthodes qui marchent :</p>
|
||||
|
||||
<div class="drill-section">
|
||||
<h4>📥 Télécharge les 7 guides de configuration iOS Shortcut</h4>
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:6px;margin-bottom:16px">
|
||||
<a class="btn" href="/downloads/wevia-shortcut-photos.json" download>📸 Photos</a>
|
||||
<a class="btn" href="/downloads/wevia-shortcut-messages.json" download>💬 Messages</a>
|
||||
<a class="btn" href="/downloads/wevia-shortcut-contacts.json" download>👤 Contacts</a>
|
||||
<a class="btn" href="/downloads/wevia-shortcut-calendar.json" download>📅 Calendar</a>
|
||||
<a class="btn" href="/downloads/wevia-shortcut-notes.json" download>📝 Notes</a>
|
||||
<a class="btn" href="/downloads/wevia-shortcut-calls.json" download>📞 Calls</a>
|
||||
<a class="btn" href="/downloads/wevia-shortcut-health.json" download>❤️ Health</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="drill-section">
|
||||
<h4>1. iPhone Shortcuts (recommandé - 5 min setup)</h4>
|
||||
<p style="font-size:12px;margin-bottom:8px">Crée 1 shortcut par type de données dans l'app <b>Raccourcis</b> iPhone :</p>
|
||||
@@ -414,17 +427,37 @@ function renderItemRow(i) {
|
||||
}
|
||||
|
||||
function renderReco(r) {
|
||||
const hasAction = r.id && (r.kind === 'task_create' || r.kind === 'urgent_alert');
|
||||
const isTask = r.kind === 'task_create';
|
||||
return `
|
||||
<div class="reco-card ${r.priority}" onclick="${r.source_id ? `openDrill('${r.source_id}')` : ''}">
|
||||
<div class="reco-card ${r.priority}">
|
||||
<div class="reco-head">
|
||||
<span class="reco-prio ${r.priority}">${r.priority}</span>
|
||||
<span class="reco-kind">${r.kind}</span>
|
||||
${r.status === 'done' || r.status === 'resolved' ? '<span class="badge" style="margin-left:auto;background:rgba(74,222,128,0.15);color:var(--success)">✓ ' + r.status + '</span>' : ''}
|
||||
</div>
|
||||
<div class="reco-label">${escape(r.label)}</div>
|
||||
<div class="reco-label" onclick="${r.source_id || r.source_item ? `openDrill('${r.source_item || r.source_id}')` : ''}" style="cursor:${r.source_item || r.source_id ? 'pointer' : 'default'}">${escape(r.label)}</div>
|
||||
<div class="reco-action">→ ${escape(r.action)}</div>
|
||||
${hasAction && r.status !== 'done' && r.status !== 'resolved' ? `
|
||||
<div style="margin-top:6px;display:flex;gap:4px">
|
||||
${isTask ? `<button class="btn" style="padding:3px 8px;font-size:11px" onclick="event.stopPropagation();markDone('${r.id}')">✓ Mark done</button>` : ''}
|
||||
${r.kind === 'urgent_alert' ? `<button class="btn" style="padding:3px 8px;font-size:11px" onclick="event.stopPropagation();resolveAlert('${r.id}')">🛑 Resolve</button>` : ''}
|
||||
</div>` : ''}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
async function markDone(id) {
|
||||
const r = await fetch(API + '?action=mark_done&id=' + encodeURIComponent(id)).then(r => r.json());
|
||||
if (r.ok) { showToast('✓ Tâche marquée done'); loadAll(); }
|
||||
else showToast('Erreur: ' + (r.error || 'unknown'), true);
|
||||
}
|
||||
|
||||
async function resolveAlert(id) {
|
||||
const r = await fetch(API + '?action=resolve_alert&id=' + encodeURIComponent(id)).then(r => r.json());
|
||||
if (r.ok) { showToast('✓ Alerte résolue'); loadAll(); }
|
||||
else showToast('Erreur: ' + (r.error || 'unknown'), true);
|
||||
}
|
||||
|
||||
function renderTopReco() {
|
||||
const top = STATE.reco.slice(0, 5);
|
||||
const el = document.getElementById('top-reco');
|
||||
@@ -504,24 +537,32 @@ function showMCPs() {
|
||||
{ name: 'blade_exec', desc: 'Execute PowerShell on Razer', status: 'ok' },
|
||||
{ name: 'blade_chrome_cdp', desc: 'Chrome DevTools Protocol via Razer', status: 'ok' },
|
||||
{ name: 'blade_screenshot', desc: 'Capture Razer desktop', status: 'ok' },
|
||||
{ name: 'blade_file_read/write', desc: 'Razer filesystem access', status: 'ok' },
|
||||
{ name: 'wevia_apple_ingest (native)', desc: 'Photo/structured ingestion + AI', status: 'ok' },
|
||||
{ name: '🔴 apple_photos_scrape', desc: 'Read iCloud Photos via AppleScript (Razer Mac or Blade)', status: 'missing' },
|
||||
{ name: '🔴 apple_messages_scrape', desc: 'Read ~/Library/Messages/chat.db (macOS required)', status: 'missing' },
|
||||
{ name: '🔴 apple_contacts_scrape', desc: 'Read AddressBook via AppleScript', status: 'missing' },
|
||||
{ name: '🔴 apple_calendar_scrape', desc: 'Read Calendar.app via EventKit', status: 'missing' },
|
||||
{ name: 'blade_status', desc: 'Razer CPU/RAM/disk/uptime', status: 'ok' },
|
||||
{ name: 'blade_open_url / send_keys / file_read / file_write', desc: 'Razer interaction primitives', status: 'ok' },
|
||||
{ name: 'apple_ingest_note', desc: 'Ingest text via MCP (auto entity extract + reco)', status: 'ok' },
|
||||
{ name: 'apple_ingest_message', desc: 'Ingest SMS/iMessage via MCP', status: 'ok' },
|
||||
{ name: 'apple_status', desc: 'WEVIA Apple state (items, tasks, alerts)', status: 'ok' },
|
||||
{ name: 'apple_search', desc: 'Full-text search in ingested Apple data', status: 'ok' },
|
||||
{ name: 'apple_recommendations', desc: 'Top IA reco P0-P3 via MCP', status: 'ok' },
|
||||
{ name: 'apple_tasks_pending / apple_mark_task_done', desc: 'Task management via MCP', status: 'ok' },
|
||||
{ name: '⚠️ apple_mac_scrape_photos', desc: 'Scrape iCloud Photos via AppleScript (needs Mac agent)', status: 'mac_required' },
|
||||
{ name: '⚠️ apple_mac_scrape_messages', desc: 'Read chat.db on Mac (needs Full Disk Access)', status: 'mac_required' },
|
||||
{ name: '🔴 apple_contacts_scrape', desc: 'AddressBook via AppleScript on Mac', status: 'missing' },
|
||||
{ name: '🔴 apple_calendar_scrape', desc: 'Calendar.app via EventKit on Mac', status: 'missing' },
|
||||
{ name: '🔴 apple_health_export', desc: 'Parse HealthKit XML export', status: 'missing' },
|
||||
{ name: '🔴 apple_notes_scrape', desc: 'Read Notes.app SQLite DB', status: 'missing' },
|
||||
{ name: '🔴 apple_reminders_scrape', desc: 'Read Reminders.app', status: 'missing' },
|
||||
{ name: '🔴 apple_safari_history', desc: 'Read Safari History.db', status: 'missing' }
|
||||
{ name: '🔴 apple_notes_scrape', desc: 'Notes.app SQLite DB (Mac)', status: 'missing' },
|
||||
{ name: '🔴 apple_reminders_scrape', desc: 'Reminders.app (Mac)', status: 'missing' },
|
||||
{ name: '🔴 apple_safari_history', desc: 'Safari History.db (Mac)', status: 'missing' }
|
||||
];
|
||||
|
||||
const ok = mcps.filter(m => m.status === 'ok').length;
|
||||
const miss = mcps.filter(m => m.status === 'missing').length;
|
||||
document.getElementById('mcps-body').innerHTML = `
|
||||
<p style="margin-bottom:16px;color:var(--mute)">MCP (Model Context Protocol) tools exposés via Blade-MCP server (port 8765, HTTPS via /mcp/blade)</p>
|
||||
<div class="drill-grid" style="margin-bottom:16px">
|
||||
<div class="drill-kv"><div class="drill-kv-k">Actifs</div><div class="drill-kv-v" style="color:var(--success);font-size:20px;font-weight:700">${ok}</div></div>
|
||||
<div class="drill-kv"><div class="drill-kv-k">Manquants</div><div class="drill-kv-v" style="color:var(--warning);font-size:20px;font-weight:700">${miss}</div></div>
|
||||
<div class="drill-kv"><div class="drill-kv-k">Nécessite Mac</div><div class="drill-kv-v" style="color:#06b6d4;font-size:20px;font-weight:700">${mac_req}</div></div>
|
||||
<div class="drill-kv"><div class="drill-kv-k">À implémenter</div><div class="drill-kv-v" style="color:var(--warning);font-size:20px;font-weight:700">${miss}</div></div>
|
||||
</div>
|
||||
<div class="drill-section">
|
||||
<h4>✅ Actifs</h4>
|
||||
@@ -533,7 +574,16 @@ function showMCPs() {
|
||||
</div>`).join('')}
|
||||
</div>
|
||||
<div class="drill-section">
|
||||
<h4>⚠️ À implémenter (nécessitent Mac pour macOS AppleScript, pas juste Razer Windows)</h4>
|
||||
<h4>🔵 Prêts si Blade agent installé sur Mac (USB iPhone → scrape)</h4>
|
||||
${mcps.filter(m => m.status==='mac_required').map(m => `
|
||||
<div class="mcp-card" style="border-left-color:#06b6d4">
|
||||
<span class="mcp-status" style="background:rgba(6,182,212,0.15);color:#06b6d4">MAC AGENT</span>
|
||||
<div class="mcp-name">${m.name}</div>
|
||||
<div class="mcp-desc">${m.desc}</div>
|
||||
</div>`).join('')}
|
||||
</div>
|
||||
<div class="drill-section">
|
||||
<h4>⚠️ À implémenter (roadmap)</h4>
|
||||
${mcps.filter(m => m.status==='missing').map(m => `
|
||||
<div class="mcp-card missing">
|
||||
<span class="mcp-status missing">MISSING</span>
|
||||
@@ -546,7 +596,9 @@ function showMCPs() {
|
||||
<div class="drill-text">https://weval-consulting.com/mcp/blade
|
||||
Authorization: Bearer wevia_blade_mcp_20avr_k9f3m2x8n5q7p1
|
||||
Content-Type: application/json
|
||||
Body: {"jsonrpc":"2.0","id":1,"method":"tools/list"}</div>
|
||||
Body: {"jsonrpc":"2.0","id":1,"method":"tools/list"}
|
||||
|
||||
Version: v1.1.0 · 17 tools exposed (8 blade + 9 apple)</div>
|
||||
</div>`;
|
||||
document.getElementById('mcps').classList.add('open');
|
||||
}
|
||||
@@ -568,6 +620,25 @@ function showToast(msg, err) {
|
||||
setTimeout(() => t.classList.remove('show'), 2500);
|
||||
}
|
||||
|
||||
async function doSearch() {
|
||||
const q = document.getElementById('search').value.trim();
|
||||
if (q.length < 2) { showToast('Query trop courte', true); return; }
|
||||
try {
|
||||
const r = await fetch(API + '?action=search&q=' + encodeURIComponent(q)).then(r => r.json());
|
||||
if (!r.ok) { showToast('Erreur search', true); return; }
|
||||
const body = document.getElementById('list-body');
|
||||
document.getElementById('list-title').textContent = '🔎 Recherche: "' + q + '"';
|
||||
document.getElementById('list-count').textContent = r.total + ' match(es)';
|
||||
if (!r.matches.length) { body.innerHTML = '<div class="empty">Aucun résultat pour "' + q + '"</div>'; return; }
|
||||
body.innerHTML = r.matches.map(m => `
|
||||
<div class="item-row" onclick="openDrill('${m.id}')">
|
||||
<div class="item-head"><span class="item-type ${m.type}">${m.type}</span>
|
||||
<span class="item-ts">${new Date(m.ingested_at).toLocaleString('fr-FR')}</span></div>
|
||||
<div class="item-preview">${escape(m.preview)}</div>
|
||||
</div>`).join('');
|
||||
} catch (e) { showToast('Erreur: ' + e.message, true); }
|
||||
}
|
||||
|
||||
// Tab switching
|
||||
document.querySelectorAll('.tab').forEach(t => {
|
||||
t.addEventListener('click', () => {
|
||||
@@ -614,5 +685,5 @@ document.addEventListener('keydown', e => {
|
||||
loadAll();
|
||||
setInterval(loadAll, 30000);
|
||||
</script>
|
||||
</body>
|
||||
<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></body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user