@cocaxcode/ai-context-inspector 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -2099,6 +2099,26 @@ body {
|
|
|
2099
2099
|
var JS_SCRIPTS = `
|
|
2100
2100
|
document.addEventListener('DOMContentLoaded', () => {
|
|
2101
2101
|
|
|
2102
|
+
// \u2500\u2500 Scroll helper with offset for sticky nav + search \u2500\u2500
|
|
2103
|
+
const SCROLL_OFFSET = 110
|
|
2104
|
+
|
|
2105
|
+
function scrollToSection(targetId) {
|
|
2106
|
+
const target = document.getElementById(targetId)
|
|
2107
|
+
if (!target) return
|
|
2108
|
+
if (target.classList.contains('collapsed')) {
|
|
2109
|
+
target.classList.remove('collapsed')
|
|
2110
|
+
const content = target.querySelector('.section-content')
|
|
2111
|
+
if (content) {
|
|
2112
|
+
content.style.maxHeight = content.scrollHeight + 'px'
|
|
2113
|
+
setTimeout(() => { content.style.maxHeight = '' }, 400)
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
const y = target.getBoundingClientRect().top + window.scrollY - SCROLL_OFFSET
|
|
2117
|
+
window.scrollTo({ top: y, behavior: 'smooth' })
|
|
2118
|
+
target.style.boxShadow = '0 0 0 2px var(--accent)'
|
|
2119
|
+
setTimeout(() => { target.style.boxShadow = '' }, 1500)
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2102
2122
|
// \u2500\u2500 Animated Counters \u2500\u2500
|
|
2103
2123
|
document.querySelectorAll('.stat-number').forEach(el => {
|
|
2104
2124
|
const target = parseInt(el.getAttribute('data-target') || '0')
|
|
@@ -2206,42 +2226,51 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2206
2226
|
document.querySelectorAll('.nav-link[data-target]').forEach(link => {
|
|
2207
2227
|
link.addEventListener('click', (e) => {
|
|
2208
2228
|
e.preventDefault()
|
|
2209
|
-
|
|
2210
|
-
const target = document.getElementById(targetId)
|
|
2211
|
-
if (target) {
|
|
2212
|
-
// Expand if collapsed
|
|
2213
|
-
if (target.classList.contains('collapsed')) {
|
|
2214
|
-
target.classList.remove('collapsed')
|
|
2215
|
-
const content = target.querySelector('.section-content')
|
|
2216
|
-
if (content) {
|
|
2217
|
-
content.style.maxHeight = content.scrollHeight + 'px'
|
|
2218
|
-
setTimeout(() => { content.style.maxHeight = '' }, 400)
|
|
2219
|
-
}
|
|
2220
|
-
}
|
|
2221
|
-
target.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
2222
|
-
}
|
|
2229
|
+
scrollToSection(link.getAttribute('data-target'))
|
|
2223
2230
|
})
|
|
2224
2231
|
})
|
|
2225
2232
|
|
|
2226
2233
|
// \u2500\u2500 Ecosystem Map (click to scroll) \u2500\u2500
|
|
2227
|
-
document.querySelectorAll('.eco-node[data-section]').forEach(node => {
|
|
2234
|
+
document.querySelectorAll('.eco-cat-node[data-section]').forEach(node => {
|
|
2228
2235
|
node.addEventListener('click', () => {
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
if (content) {
|
|
2236
|
-
content.style.maxHeight = content.scrollHeight + 'px'
|
|
2237
|
-
setTimeout(() => { content.style.maxHeight = '' }, 400)
|
|
2238
|
-
}
|
|
2239
|
-
}
|
|
2240
|
-
target.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
2236
|
+
scrollToSection(node.getAttribute('data-section'))
|
|
2237
|
+
})
|
|
2238
|
+
node.addEventListener('keydown', (e) => {
|
|
2239
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
2240
|
+
e.preventDefault()
|
|
2241
|
+
scrollToSection(node.getAttribute('data-section'))
|
|
2241
2242
|
}
|
|
2242
2243
|
})
|
|
2243
2244
|
})
|
|
2244
2245
|
|
|
2246
|
+
// \u2500\u2500 Ecosystem Map Tooltips \u2500\u2500
|
|
2247
|
+
const ecoTooltip = document.getElementById('eco-tooltip')
|
|
2248
|
+
const ecoTooltipText = document.getElementById('eco-tooltip-text')
|
|
2249
|
+
|
|
2250
|
+
document.querySelectorAll('.eco-item[data-tooltip]').forEach(item => {
|
|
2251
|
+
item.addEventListener('mouseenter', () => {
|
|
2252
|
+
if (!ecoTooltip || !ecoTooltipText) return
|
|
2253
|
+
const text = item.getAttribute('data-tooltip')
|
|
2254
|
+
ecoTooltipText.textContent = text
|
|
2255
|
+
const textLen = Math.min(text.length * 6.5 + 20, 220)
|
|
2256
|
+
const rect = ecoTooltip.querySelector('rect')
|
|
2257
|
+
if (rect) {
|
|
2258
|
+
rect.setAttribute('width', textLen)
|
|
2259
|
+
ecoTooltipText.setAttribute('x', textLen / 2)
|
|
2260
|
+
}
|
|
2261
|
+
const circle = item.querySelector('circle')
|
|
2262
|
+
if (circle) {
|
|
2263
|
+
const cx = parseFloat(circle.getAttribute('cx'))
|
|
2264
|
+
const cy = parseFloat(circle.getAttribute('cy'))
|
|
2265
|
+
ecoTooltip.setAttribute('transform', 'translate(' + (cx - textLen / 2) + ',' + (cy - 38) + ')')
|
|
2266
|
+
}
|
|
2267
|
+
ecoTooltip.style.display = ''
|
|
2268
|
+
})
|
|
2269
|
+
item.addEventListener('mouseleave', () => {
|
|
2270
|
+
if (ecoTooltip) ecoTooltip.style.display = 'none'
|
|
2271
|
+
})
|
|
2272
|
+
})
|
|
2273
|
+
|
|
2245
2274
|
// \u2500\u2500 Theme Toggle \u2500\u2500
|
|
2246
2275
|
const themeToggle = document.getElementById('theme-toggle')
|
|
2247
2276
|
if (themeToggle) {
|
|
@@ -2326,7 +2355,7 @@ function buildCategories(result, summary) {
|
|
|
2326
2355
|
icon: "\u2699",
|
|
2327
2356
|
count: summary.totalMcpServers,
|
|
2328
2357
|
color: "#00d4ff",
|
|
2329
|
-
items: result.mcpServers.slice(0,
|
|
2358
|
+
items: result.mcpServers.slice(0, 6).map((s) => ({
|
|
2330
2359
|
name: s.name,
|
|
2331
2360
|
detail: `${s.introspection?.tools.length ?? 0} tools`
|
|
2332
2361
|
}))
|
|
@@ -2337,7 +2366,7 @@ function buildCategories(result, summary) {
|
|
|
2337
2366
|
icon: "\u{1F4C4}",
|
|
2338
2367
|
count: summary.totalFiles,
|
|
2339
2368
|
color: "#b388ff",
|
|
2340
|
-
items: result.contextFiles.slice(0,
|
|
2369
|
+
items: result.contextFiles.slice(0, 6).map((f) => ({
|
|
2341
2370
|
name: f.path,
|
|
2342
2371
|
detail: f.tool
|
|
2343
2372
|
}))
|
|
@@ -2348,7 +2377,7 @@ function buildCategories(result, summary) {
|
|
|
2348
2377
|
icon: "\u26A1",
|
|
2349
2378
|
count: summary.totalSkills,
|
|
2350
2379
|
color: "#ffab40",
|
|
2351
|
-
items: result.skills.slice(0,
|
|
2380
|
+
items: result.skills.slice(0, 6).map((s) => ({
|
|
2352
2381
|
name: s.name
|
|
2353
2382
|
}))
|
|
2354
2383
|
},
|
|
@@ -2358,7 +2387,7 @@ function buildCategories(result, summary) {
|
|
|
2358
2387
|
icon: "\u{1F916}",
|
|
2359
2388
|
count: summary.totalAgents,
|
|
2360
2389
|
color: "#00e676",
|
|
2361
|
-
items: result.agents.slice(0,
|
|
2390
|
+
items: result.agents.slice(0, 6).map((a) => ({
|
|
2362
2391
|
name: a.name,
|
|
2363
2392
|
detail: a.model
|
|
2364
2393
|
}))
|
|
@@ -2369,96 +2398,181 @@ function buildCategories(result, summary) {
|
|
|
2369
2398
|
icon: "\u{1F9E0}",
|
|
2370
2399
|
count: summary.totalMemories,
|
|
2371
2400
|
color: "#ff80ab",
|
|
2372
|
-
items: result.memories.slice(0,
|
|
2401
|
+
items: result.memories.slice(0, 6).map((m) => ({
|
|
2373
2402
|
name: m.type,
|
|
2374
2403
|
detail: m.status
|
|
2375
2404
|
}))
|
|
2376
2405
|
}
|
|
2377
2406
|
];
|
|
2378
2407
|
}
|
|
2408
|
+
var COCAXCODE_ICON = `<g transform="translate(-16,-16)">
|
|
2409
|
+
<defs>
|
|
2410
|
+
<linearGradient id="cxc-g1" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
2411
|
+
<stop offset="0%" stop-color="#22d3ee"/>
|
|
2412
|
+
<stop offset="100%" stop-color="#06b6d4"/>
|
|
2413
|
+
</linearGradient>
|
|
2414
|
+
<linearGradient id="cxc-g2" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
2415
|
+
<stop offset="0%" stop-color="#0891b2"/>
|
|
2416
|
+
<stop offset="100%" stop-color="#0e7490"/>
|
|
2417
|
+
</linearGradient>
|
|
2418
|
+
</defs>
|
|
2419
|
+
<rect width="32" height="32" fill="#0a0a0c" rx="4"/>
|
|
2420
|
+
<rect x="9" y="7.5" width="16" height="18.5" rx="4" fill="url(#cxc-g2)" opacity="0.5"/>
|
|
2421
|
+
<rect x="8" y="6.5" width="16" height="18.5" rx="4" fill="url(#cxc-g1)"/>
|
|
2422
|
+
<path d="M11.5,11 L18,16 L11.5,21" fill="none" stroke="#0a0a0c" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
|
|
2423
|
+
<line x1="19" y1="20" x2="21.5" y2="20" stroke="#0a0a0c" stroke-width="1.8" stroke-linecap="round">
|
|
2424
|
+
<animate attributeName="x1" values="19;21.5;19" dur="1.4s" repeatCount="indefinite"/>
|
|
2425
|
+
<animate attributeName="x2" values="21.5;24;21.5" dur="1.4s" repeatCount="indefinite"/>
|
|
2426
|
+
</line>
|
|
2427
|
+
</g>`;
|
|
2379
2428
|
function renderEcosystemMap(result, summary) {
|
|
2380
2429
|
const categories = buildCategories(result, summary);
|
|
2381
2430
|
const totalItems = summary.totalMcpServers + summary.totalFiles + summary.totalSkills + summary.totalAgents + summary.totalMemories;
|
|
2382
2431
|
if (totalItems === 0) return "";
|
|
2383
|
-
const W =
|
|
2384
|
-
const H =
|
|
2432
|
+
const W = 900;
|
|
2433
|
+
const H = 480;
|
|
2385
2434
|
const cx = W / 2;
|
|
2386
2435
|
const cy = H / 2;
|
|
2387
|
-
const catRadius =
|
|
2388
|
-
const itemRadius =
|
|
2436
|
+
const catRadius = 165;
|
|
2437
|
+
const itemRadius = 55;
|
|
2389
2438
|
const startAngle = -Math.PI / 2;
|
|
2390
|
-
let
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2439
|
+
let defs = "";
|
|
2440
|
+
let connections = "";
|
|
2441
|
+
let itemNodes = "";
|
|
2442
|
+
let catNodes = "";
|
|
2443
|
+
defs += `<defs>
|
|
2444
|
+
<filter id="eco-glow" x="-40%" y="-40%" width="180%" height="180%">
|
|
2445
|
+
<feGaussianBlur stdDeviation="6" result="blur"/>
|
|
2394
2446
|
<feComposite in="SourceGraphic" in2="blur" operator="over"/>
|
|
2395
2447
|
</filter>
|
|
2396
|
-
<filter id="glow-
|
|
2397
|
-
<feGaussianBlur stdDeviation="
|
|
2448
|
+
<filter id="eco-glow-center" x="-50%" y="-50%" width="200%" height="200%">
|
|
2449
|
+
<feGaussianBlur stdDeviation="10" result="blur"/>
|
|
2398
2450
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
|
2399
2451
|
</filter>
|
|
2452
|
+
<radialGradient id="eco-bg-grad" cx="50%" cy="50%" r="55%">
|
|
2453
|
+
<stop offset="0%" stop-color="var(--accent)" stop-opacity="0.03"/>
|
|
2454
|
+
<stop offset="100%" stop-color="var(--accent)" stop-opacity="0"/>
|
|
2455
|
+
</radialGradient>
|
|
2400
2456
|
</defs>`;
|
|
2401
|
-
|
|
2402
|
-
<circle cx="
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
const catPositions = [];
|
|
2457
|
+
let bg = `<rect width="${W}" height="${H}" fill="none"/>
|
|
2458
|
+
<circle cx="${cx}" cy="${cy}" r="280" fill="url(#eco-bg-grad)"/>`;
|
|
2459
|
+
bg += `<circle cx="${cx}" cy="${cy}" r="${catRadius}" fill="none"
|
|
2460
|
+
stroke="var(--border)" stroke-width="0.5" stroke-dasharray="4 8" opacity="0.4"/>`;
|
|
2406
2461
|
categories.forEach((cat, i) => {
|
|
2407
2462
|
const angle = startAngle + i / categories.length * Math.PI * 2;
|
|
2408
2463
|
const x = cx + Math.cos(angle) * catRadius;
|
|
2409
2464
|
const y = cy + Math.sin(angle) * catRadius;
|
|
2410
|
-
catPositions.push({ x, y, cat });
|
|
2411
2465
|
const dimmed = cat.count === 0;
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2466
|
+
const opacity = dimmed ? 0.2 : 1;
|
|
2467
|
+
const midX = (cx + x) / 2;
|
|
2468
|
+
const midY = (cy + y) / 2;
|
|
2469
|
+
const perpX = -(y - cy) * 0.08;
|
|
2470
|
+
const perpY = (x - cx) * 0.08;
|
|
2471
|
+
connections += `<path d="M${cx},${cy} Q${midX + perpX},${midY + perpY} ${x},${y}"
|
|
2472
|
+
fill="none" stroke="${cat.color}" stroke-width="${dimmed ? 0.8 : 1.5}"
|
|
2473
|
+
opacity="${dimmed ? 0.15 : 0.35}"
|
|
2474
|
+
stroke-dasharray="${dimmed ? "3 6" : "6 4"}"
|
|
2475
|
+
${!dimmed ? `style="animation: eco-dash 15s linear infinite; animation-delay: ${i * 0.5}s"` : ""}/>`;
|
|
2415
2476
|
if (!dimmed && cat.items.length > 0) {
|
|
2416
|
-
const maxItems = Math.min(cat.items.length,
|
|
2417
|
-
const arcSpread = Math.min(Math.PI * 0.
|
|
2477
|
+
const maxItems = Math.min(cat.items.length, 6);
|
|
2478
|
+
const arcSpread = Math.min(Math.PI * 0.6, maxItems * 0.25);
|
|
2418
2479
|
cat.items.slice(0, maxItems).forEach((item, j) => {
|
|
2419
2480
|
const itemAngle = angle - arcSpread / 2 + (maxItems > 1 ? j / (maxItems - 1) * arcSpread : 0);
|
|
2420
2481
|
const ix = x + Math.cos(itemAngle) * itemRadius;
|
|
2421
2482
|
const iy = y + Math.sin(itemAngle) * itemRadius;
|
|
2422
|
-
|
|
2423
|
-
stroke="${cat.color}" stroke-width="0.
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
<
|
|
2427
|
-
|
|
2483
|
+
connections += `<line x1="${x}" y1="${y}" x2="${ix}" y2="${iy}"
|
|
2484
|
+
stroke="${cat.color}" stroke-width="0.7" opacity="0.2"/>`;
|
|
2485
|
+
const shortName = item.name.length > 15 ? item.name.slice(0, 13) + ".." : item.name;
|
|
2486
|
+
itemNodes += `<g class="eco-item" data-tooltip="${esc(item.name)}${item.detail ? " (" + esc(item.detail) + ")" : ""}">
|
|
2487
|
+
<circle cx="${ix}" cy="${iy}" r="4.5" fill="${cat.color}" opacity="0.5"
|
|
2488
|
+
class="eco-item-dot"/>
|
|
2489
|
+
<circle cx="${ix}" cy="${iy}" r="4.5" fill="transparent" stroke="${cat.color}"
|
|
2490
|
+
stroke-width="1" opacity="0.3"/>
|
|
2491
|
+
<title>${esc(item.name)}${item.detail ? " \u2014 " + esc(item.detail) : ""}</title>
|
|
2492
|
+
</g>`;
|
|
2428
2493
|
});
|
|
2429
|
-
if (cat.
|
|
2430
|
-
const extra = cat.count -
|
|
2431
|
-
const moreAngle = angle + arcSpread / 2 + 0.
|
|
2432
|
-
const mx = x + Math.cos(moreAngle) * (itemRadius
|
|
2433
|
-
const my = y + Math.sin(moreAngle) * (itemRadius
|
|
2434
|
-
|
|
2435
|
-
font-size="9" fill="${cat.color}"
|
|
2436
|
-
dominant-baseline="middle">+${extra}</text>`;
|
|
2494
|
+
if (cat.count > maxItems) {
|
|
2495
|
+
const extra = cat.count - maxItems;
|
|
2496
|
+
const moreAngle = angle + arcSpread / 2 + 0.35;
|
|
2497
|
+
const mx = x + Math.cos(moreAngle) * (itemRadius * 0.85);
|
|
2498
|
+
const my = y + Math.sin(moreAngle) * (itemRadius * 0.85);
|
|
2499
|
+
itemNodes += `<text x="${mx}" y="${my}"
|
|
2500
|
+
font-family="var(--font-mono)" font-size="9" fill="${cat.color}"
|
|
2501
|
+
opacity="0.5" text-anchor="middle" dominant-baseline="middle">+${extra}</text>`;
|
|
2437
2502
|
}
|
|
2438
2503
|
}
|
|
2439
|
-
const nodeR = dimmed ?
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
<
|
|
2445
|
-
|
|
2446
|
-
|
|
2504
|
+
const nodeR = dimmed ? 24 : 32;
|
|
2505
|
+
const labelY = y - nodeR - 10;
|
|
2506
|
+
catNodes += `<g class="eco-cat-node" data-section="${cat.id}"
|
|
2507
|
+
style="cursor:pointer;opacity:${opacity}" role="button" tabindex="0">
|
|
2508
|
+
<!-- Hit area -->
|
|
2509
|
+
<circle cx="${x}" cy="${y}" r="${nodeR + 8}" fill="transparent"/>
|
|
2510
|
+
<!-- Outer glow ring -->
|
|
2511
|
+
${!dimmed ? `<circle cx="${x}" cy="${y}" r="${nodeR + 3}" fill="none"
|
|
2512
|
+
stroke="${cat.color}" stroke-width="1" opacity="0.15"
|
|
2513
|
+
style="animation: eco-pulse 3s ease-in-out infinite; animation-delay: ${i * 0.4}s"/>` : ""}
|
|
2514
|
+
<!-- Main circle -->
|
|
2515
|
+
<circle cx="${x}" cy="${y}" r="${nodeR}" fill="${cat.color}"
|
|
2516
|
+
opacity="${dimmed ? 0.08 : 0.12}" stroke="${cat.color}"
|
|
2517
|
+
stroke-width="${dimmed ? 1 : 2}" class="eco-cat-circle"
|
|
2518
|
+
${!dimmed ? 'filter="url(#eco-glow)"' : ""}/>
|
|
2519
|
+
<!-- Count inside -->
|
|
2520
|
+
<text x="${x}" y="${y + 1}" text-anchor="middle" dominant-baseline="middle"
|
|
2521
|
+
font-family="var(--font-mono)" font-size="${dimmed ? 14 : 18}"
|
|
2522
|
+
font-weight="700" fill="${cat.color}" opacity="${dimmed ? 0.3 : 0.9}">${cat.count}</text>
|
|
2523
|
+
<!-- Label + icon ABOVE circle -->
|
|
2524
|
+
<text x="${x}" y="${labelY}" text-anchor="middle" dominant-baseline="auto"
|
|
2525
|
+
font-family="var(--font-mono)" font-size="11" font-weight="600"
|
|
2526
|
+
fill="${cat.color}" opacity="${dimmed ? 0.3 : 0.85}">${cat.icon} ${cat.label}</text>
|
|
2447
2527
|
</g>`;
|
|
2448
2528
|
});
|
|
2449
|
-
const projectName = result.project.name.length >
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
<
|
|
2529
|
+
const projectName = result.project.name.length > 20 ? result.project.name.slice(0, 18) + ".." : result.project.name;
|
|
2530
|
+
const centerNode = `<g class="eco-center">
|
|
2531
|
+
<!-- Outer pulse ring -->
|
|
2532
|
+
<circle cx="${cx}" cy="${cy}" r="48" fill="none" stroke="var(--accent)"
|
|
2533
|
+
stroke-width="1" opacity="0.2"
|
|
2534
|
+
style="animation: eco-pulse 4s ease-in-out infinite"/>
|
|
2535
|
+
<!-- Main circle -->
|
|
2536
|
+
<circle cx="${cx}" cy="${cy}" r="42" fill="var(--bg-alt)" stroke="var(--accent)"
|
|
2537
|
+
stroke-width="2.5" filter="url(#eco-glow-center)"/>
|
|
2538
|
+
<!-- cocaxcode icon in center -->
|
|
2539
|
+
<g transform="translate(${cx},${cy - 8}) scale(0.85)">
|
|
2540
|
+
${COCAXCODE_ICON}
|
|
2541
|
+
</g>
|
|
2542
|
+
<!-- Project name below icon -->
|
|
2543
|
+
<text x="${cx}" y="${cy + 20}" text-anchor="middle" dominant-baseline="auto"
|
|
2544
|
+
font-family="var(--font-mono)" font-size="10" font-weight="600"
|
|
2545
|
+
fill="var(--text-bright)" opacity="0.9">${esc(projectName)}</text>
|
|
2546
|
+
<!-- Total count -->
|
|
2547
|
+
<text x="${cx}" y="${cy + 32}" text-anchor="middle" dominant-baseline="auto"
|
|
2548
|
+
font-family="var(--font-mono)" font-size="8.5"
|
|
2549
|
+
fill="var(--text-dim)">${totalItems} elementos</text>
|
|
2550
|
+
</g>`;
|
|
2551
|
+
const tooltip = `<g id="eco-tooltip" style="display:none;pointer-events:none">
|
|
2552
|
+
<rect x="0" y="0" width="160" height="28" rx="4"
|
|
2553
|
+
fill="var(--bg-card)" stroke="var(--border)" stroke-width="1" opacity="0.95"/>
|
|
2554
|
+
<text x="80" y="18" text-anchor="middle" font-family="var(--font-mono)"
|
|
2555
|
+
font-size="10" fill="var(--text)" id="eco-tooltip-text"></text>
|
|
2457
2556
|
</g>`;
|
|
2557
|
+
const watermark = `<text x="${W - 12}" y="${H - 10}" text-anchor="end"
|
|
2558
|
+
font-family="var(--font-mono)" font-size="9" fill="var(--text-dim)" opacity="0.3"
|
|
2559
|
+
letter-spacing="0.05em">cocaxcode</text>`;
|
|
2560
|
+
const svgContent = `${defs}${bg}${connections}${itemNodes}${catNodes}${centerNode}${tooltip}${watermark}`;
|
|
2458
2561
|
return `
|
|
2459
2562
|
<div class="ecosystem-map">
|
|
2460
|
-
<svg class="ecosystem-svg" viewBox="0 0 ${W} ${H}" xmlns="http://www.w3.org/2000/svg"
|
|
2461
|
-
|
|
2563
|
+
<svg class="ecosystem-svg" viewBox="0 0 ${W} ${H}" xmlns="http://www.w3.org/2000/svg"
|
|
2564
|
+
role="img" aria-label="Mapa del ecosistema AI del proyecto">
|
|
2565
|
+
<style>
|
|
2566
|
+
@keyframes eco-dash { to { stroke-dashoffset: -80; } }
|
|
2567
|
+
@keyframes eco-pulse { 0%,100% { opacity: 0.15; transform-origin: center; } 50% { opacity: 0.4; } }
|
|
2568
|
+
.eco-cat-node:hover .eco-cat-circle { stroke-width: 3; opacity: 0.25; }
|
|
2569
|
+
.eco-cat-node:hover { filter: brightness(1.2); }
|
|
2570
|
+
.eco-cat-node:focus { outline: none; }
|
|
2571
|
+
.eco-cat-node:focus .eco-cat-circle { stroke-width: 3; stroke-dasharray: 4 2; }
|
|
2572
|
+
.eco-item-dot { transition: r 0.2s, opacity 0.2s; }
|
|
2573
|
+
.eco-item:hover .eco-item-dot { r: 7; opacity: 0.8; }
|
|
2574
|
+
</style>
|
|
2575
|
+
${svgContent}
|
|
2462
2576
|
</svg>
|
|
2463
2577
|
</div>`;
|
|
2464
2578
|
}
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
generateHtml,
|
|
4
4
|
runAllScanners
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-UKKIDJCN.js";
|
|
6
6
|
|
|
7
7
|
// src/cli.ts
|
|
8
8
|
import { parseArgs } from "util";
|
|
@@ -97,7 +97,7 @@ async function main() {
|
|
|
97
97
|
const options = parseCliArgs(process.argv.slice(2));
|
|
98
98
|
if (options.mcp) {
|
|
99
99
|
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
100
|
-
const { createServer } = await import("./server-
|
|
100
|
+
const { createServer } = await import("./server-AC6HNUZR.js");
|
|
101
101
|
const server = createServer();
|
|
102
102
|
const transport = new StdioServerTransport();
|
|
103
103
|
await server.connect(transport);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocaxcode/ai-context-inspector",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Scan any project to discover its complete AI ecosystem: MCP servers, tools, context files, skills, memories. Generates an interactive HTML dashboard. Works as CLI and MCP server.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|