@cocaxcode/ai-context-inspector 0.3.0 → 0.3.2
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.
|
@@ -1343,6 +1343,20 @@ body {
|
|
|
1343
1343
|
align-items: center;
|
|
1344
1344
|
}
|
|
1345
1345
|
|
|
1346
|
+
.nav-brand {
|
|
1347
|
+
display: inline-flex;
|
|
1348
|
+
align-items: center;
|
|
1349
|
+
gap: 0.3rem;
|
|
1350
|
+
margin-right: 0.3rem;
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
.nav-separator {
|
|
1354
|
+
width: 1px;
|
|
1355
|
+
height: 16px;
|
|
1356
|
+
background: var(--border);
|
|
1357
|
+
margin: 0 0.4rem;
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1346
1360
|
.nav-link {
|
|
1347
1361
|
padding: 0.3rem 0.7rem;
|
|
1348
1362
|
border-radius: var(--radius-sm);
|
|
@@ -2099,6 +2113,26 @@ body {
|
|
|
2099
2113
|
var JS_SCRIPTS = `
|
|
2100
2114
|
document.addEventListener('DOMContentLoaded', () => {
|
|
2101
2115
|
|
|
2116
|
+
// \u2500\u2500 Scroll helper with offset for sticky nav + search \u2500\u2500
|
|
2117
|
+
const SCROLL_OFFSET = 110
|
|
2118
|
+
|
|
2119
|
+
function scrollToSection(targetId) {
|
|
2120
|
+
const target = document.getElementById(targetId)
|
|
2121
|
+
if (!target) return
|
|
2122
|
+
if (target.classList.contains('collapsed')) {
|
|
2123
|
+
target.classList.remove('collapsed')
|
|
2124
|
+
const content = target.querySelector('.section-content')
|
|
2125
|
+
if (content) {
|
|
2126
|
+
content.style.maxHeight = content.scrollHeight + 'px'
|
|
2127
|
+
setTimeout(() => { content.style.maxHeight = '' }, 400)
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
const y = target.getBoundingClientRect().top + window.scrollY - SCROLL_OFFSET
|
|
2131
|
+
window.scrollTo({ top: y, behavior: 'smooth' })
|
|
2132
|
+
target.style.boxShadow = '0 0 0 2px var(--accent)'
|
|
2133
|
+
setTimeout(() => { target.style.boxShadow = '' }, 1500)
|
|
2134
|
+
}
|
|
2135
|
+
|
|
2102
2136
|
// \u2500\u2500 Animated Counters \u2500\u2500
|
|
2103
2137
|
document.querySelectorAll('.stat-number').forEach(el => {
|
|
2104
2138
|
const target = parseInt(el.getAttribute('data-target') || '0')
|
|
@@ -2206,42 +2240,51 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2206
2240
|
document.querySelectorAll('.nav-link[data-target]').forEach(link => {
|
|
2207
2241
|
link.addEventListener('click', (e) => {
|
|
2208
2242
|
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
|
-
}
|
|
2243
|
+
scrollToSection(link.getAttribute('data-target'))
|
|
2223
2244
|
})
|
|
2224
2245
|
})
|
|
2225
2246
|
|
|
2226
2247
|
// \u2500\u2500 Ecosystem Map (click to scroll) \u2500\u2500
|
|
2227
|
-
document.querySelectorAll('.eco-node[data-section]').forEach(node => {
|
|
2248
|
+
document.querySelectorAll('.eco-cat-node[data-section]').forEach(node => {
|
|
2228
2249
|
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' })
|
|
2250
|
+
scrollToSection(node.getAttribute('data-section'))
|
|
2251
|
+
})
|
|
2252
|
+
node.addEventListener('keydown', (e) => {
|
|
2253
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
2254
|
+
e.preventDefault()
|
|
2255
|
+
scrollToSection(node.getAttribute('data-section'))
|
|
2241
2256
|
}
|
|
2242
2257
|
})
|
|
2243
2258
|
})
|
|
2244
2259
|
|
|
2260
|
+
// \u2500\u2500 Ecosystem Map Tooltips \u2500\u2500
|
|
2261
|
+
const ecoTooltip = document.getElementById('eco-tooltip')
|
|
2262
|
+
const ecoTooltipText = document.getElementById('eco-tooltip-text')
|
|
2263
|
+
|
|
2264
|
+
document.querySelectorAll('.eco-item[data-tooltip]').forEach(item => {
|
|
2265
|
+
item.addEventListener('mouseenter', () => {
|
|
2266
|
+
if (!ecoTooltip || !ecoTooltipText) return
|
|
2267
|
+
const text = item.getAttribute('data-tooltip')
|
|
2268
|
+
ecoTooltipText.textContent = text
|
|
2269
|
+
const textLen = Math.min(text.length * 6.5 + 20, 220)
|
|
2270
|
+
const rect = ecoTooltip.querySelector('rect')
|
|
2271
|
+
if (rect) {
|
|
2272
|
+
rect.setAttribute('width', textLen)
|
|
2273
|
+
ecoTooltipText.setAttribute('x', textLen / 2)
|
|
2274
|
+
}
|
|
2275
|
+
const circle = item.querySelector('circle')
|
|
2276
|
+
if (circle) {
|
|
2277
|
+
const cx = parseFloat(circle.getAttribute('cx'))
|
|
2278
|
+
const cy = parseFloat(circle.getAttribute('cy'))
|
|
2279
|
+
ecoTooltip.setAttribute('transform', 'translate(' + (cx - textLen / 2) + ',' + (cy - 38) + ')')
|
|
2280
|
+
}
|
|
2281
|
+
ecoTooltip.style.display = ''
|
|
2282
|
+
})
|
|
2283
|
+
item.addEventListener('mouseleave', () => {
|
|
2284
|
+
if (ecoTooltip) ecoTooltip.style.display = 'none'
|
|
2285
|
+
})
|
|
2286
|
+
})
|
|
2287
|
+
|
|
2245
2288
|
// \u2500\u2500 Theme Toggle \u2500\u2500
|
|
2246
2289
|
const themeToggle = document.getElementById('theme-toggle')
|
|
2247
2290
|
if (themeToggle) {
|
|
@@ -2326,7 +2369,7 @@ function buildCategories(result, summary) {
|
|
|
2326
2369
|
icon: "\u2699",
|
|
2327
2370
|
count: summary.totalMcpServers,
|
|
2328
2371
|
color: "#00d4ff",
|
|
2329
|
-
items: result.mcpServers.slice(0,
|
|
2372
|
+
items: result.mcpServers.slice(0, 6).map((s) => ({
|
|
2330
2373
|
name: s.name,
|
|
2331
2374
|
detail: `${s.introspection?.tools.length ?? 0} tools`
|
|
2332
2375
|
}))
|
|
@@ -2337,7 +2380,7 @@ function buildCategories(result, summary) {
|
|
|
2337
2380
|
icon: "\u{1F4C4}",
|
|
2338
2381
|
count: summary.totalFiles,
|
|
2339
2382
|
color: "#b388ff",
|
|
2340
|
-
items: result.contextFiles.slice(0,
|
|
2383
|
+
items: result.contextFiles.slice(0, 6).map((f) => ({
|
|
2341
2384
|
name: f.path,
|
|
2342
2385
|
detail: f.tool
|
|
2343
2386
|
}))
|
|
@@ -2348,7 +2391,7 @@ function buildCategories(result, summary) {
|
|
|
2348
2391
|
icon: "\u26A1",
|
|
2349
2392
|
count: summary.totalSkills,
|
|
2350
2393
|
color: "#ffab40",
|
|
2351
|
-
items: result.skills.slice(0,
|
|
2394
|
+
items: result.skills.slice(0, 6).map((s) => ({
|
|
2352
2395
|
name: s.name
|
|
2353
2396
|
}))
|
|
2354
2397
|
},
|
|
@@ -2358,7 +2401,7 @@ function buildCategories(result, summary) {
|
|
|
2358
2401
|
icon: "\u{1F916}",
|
|
2359
2402
|
count: summary.totalAgents,
|
|
2360
2403
|
color: "#00e676",
|
|
2361
|
-
items: result.agents.slice(0,
|
|
2404
|
+
items: result.agents.slice(0, 6).map((a) => ({
|
|
2362
2405
|
name: a.name,
|
|
2363
2406
|
detail: a.model
|
|
2364
2407
|
}))
|
|
@@ -2369,7 +2412,7 @@ function buildCategories(result, summary) {
|
|
|
2369
2412
|
icon: "\u{1F9E0}",
|
|
2370
2413
|
count: summary.totalMemories,
|
|
2371
2414
|
color: "#ff80ab",
|
|
2372
|
-
items: result.memories.slice(0,
|
|
2415
|
+
items: result.memories.slice(0, 6).map((m) => ({
|
|
2373
2416
|
name: m.type,
|
|
2374
2417
|
detail: m.status
|
|
2375
2418
|
}))
|
|
@@ -2380,85 +2423,146 @@ function renderEcosystemMap(result, summary) {
|
|
|
2380
2423
|
const categories = buildCategories(result, summary);
|
|
2381
2424
|
const totalItems = summary.totalMcpServers + summary.totalFiles + summary.totalSkills + summary.totalAgents + summary.totalMemories;
|
|
2382
2425
|
if (totalItems === 0) return "";
|
|
2383
|
-
const W =
|
|
2384
|
-
const H =
|
|
2426
|
+
const W = 900;
|
|
2427
|
+
const H = 530;
|
|
2385
2428
|
const cx = W / 2;
|
|
2386
|
-
const cy = H / 2;
|
|
2387
|
-
const catRadius =
|
|
2388
|
-
const itemRadius =
|
|
2429
|
+
const cy = H / 2 + 25;
|
|
2430
|
+
const catRadius = 165;
|
|
2431
|
+
const itemRadius = 55;
|
|
2389
2432
|
const startAngle = -Math.PI / 2;
|
|
2390
|
-
let
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2433
|
+
let defs = "";
|
|
2434
|
+
let connections = "";
|
|
2435
|
+
let itemNodes = "";
|
|
2436
|
+
let catNodes = "";
|
|
2437
|
+
defs += `<defs>
|
|
2438
|
+
<filter id="eco-glow" x="-40%" y="-40%" width="180%" height="180%">
|
|
2439
|
+
<feGaussianBlur stdDeviation="6" result="blur"/>
|
|
2394
2440
|
<feComposite in="SourceGraphic" in2="blur" operator="over"/>
|
|
2395
2441
|
</filter>
|
|
2396
|
-
<filter id="glow-
|
|
2397
|
-
<feGaussianBlur stdDeviation="
|
|
2442
|
+
<filter id="eco-glow-center" x="-50%" y="-50%" width="200%" height="200%">
|
|
2443
|
+
<feGaussianBlur stdDeviation="10" result="blur"/>
|
|
2398
2444
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
|
2399
2445
|
</filter>
|
|
2446
|
+
<radialGradient id="eco-bg-grad" cx="50%" cy="50%" r="55%">
|
|
2447
|
+
<stop offset="0%" stop-color="var(--accent)" stop-opacity="0.03"/>
|
|
2448
|
+
<stop offset="100%" stop-color="var(--accent)" stop-opacity="0"/>
|
|
2449
|
+
</radialGradient>
|
|
2400
2450
|
</defs>`;
|
|
2401
|
-
|
|
2402
|
-
<circle cx="
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
const catPositions = [];
|
|
2451
|
+
let bg = `<rect width="${W}" height="${H}" fill="none"/>
|
|
2452
|
+
<circle cx="${cx}" cy="${cy}" r="280" fill="url(#eco-bg-grad)"/>`;
|
|
2453
|
+
bg += `<circle cx="${cx}" cy="${cy}" r="${catRadius}" fill="none"
|
|
2454
|
+
stroke="var(--border)" stroke-width="0.5" stroke-dasharray="4 8" opacity="0.4"/>`;
|
|
2406
2455
|
categories.forEach((cat, i) => {
|
|
2407
2456
|
const angle = startAngle + i / categories.length * Math.PI * 2;
|
|
2408
2457
|
const x = cx + Math.cos(angle) * catRadius;
|
|
2409
2458
|
const y = cy + Math.sin(angle) * catRadius;
|
|
2410
|
-
catPositions.push({ x, y, cat });
|
|
2411
2459
|
const dimmed = cat.count === 0;
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2460
|
+
const opacity = dimmed ? 0.2 : 1;
|
|
2461
|
+
const midX = (cx + x) / 2;
|
|
2462
|
+
const midY = (cy + y) / 2;
|
|
2463
|
+
const perpX = -(y - cy) * 0.08;
|
|
2464
|
+
const perpY = (x - cx) * 0.08;
|
|
2465
|
+
connections += `<path d="M${cx},${cy} Q${midX + perpX},${midY + perpY} ${x},${y}"
|
|
2466
|
+
fill="none" stroke="${cat.color}" stroke-width="${dimmed ? 0.8 : 1.5}"
|
|
2467
|
+
opacity="${dimmed ? 0.15 : 0.35}"
|
|
2468
|
+
stroke-dasharray="${dimmed ? "3 6" : "6 4"}"
|
|
2469
|
+
${!dimmed ? `style="animation: eco-dash 15s linear infinite; animation-delay: ${i * 0.5}s"` : ""}/>`;
|
|
2415
2470
|
if (!dimmed && cat.items.length > 0) {
|
|
2416
|
-
const maxItems = Math.min(cat.items.length,
|
|
2417
|
-
const arcSpread = Math.min(Math.PI * 0.
|
|
2471
|
+
const maxItems = Math.min(cat.items.length, 6);
|
|
2472
|
+
const arcSpread = Math.min(Math.PI * 0.6, maxItems * 0.25);
|
|
2418
2473
|
cat.items.slice(0, maxItems).forEach((item, j) => {
|
|
2419
2474
|
const itemAngle = angle - arcSpread / 2 + (maxItems > 1 ? j / (maxItems - 1) * arcSpread : 0);
|
|
2420
2475
|
const ix = x + Math.cos(itemAngle) * itemRadius;
|
|
2421
2476
|
const iy = y + Math.sin(itemAngle) * itemRadius;
|
|
2422
|
-
|
|
2423
|
-
stroke="${cat.color}" stroke-width="0.
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
<
|
|
2427
|
-
|
|
2477
|
+
connections += `<line x1="${x}" y1="${y}" x2="${ix}" y2="${iy}"
|
|
2478
|
+
stroke="${cat.color}" stroke-width="0.7" opacity="0.2"/>`;
|
|
2479
|
+
const shortName = item.name.length > 15 ? item.name.slice(0, 13) + ".." : item.name;
|
|
2480
|
+
itemNodes += `<g class="eco-item" data-tooltip="${esc(item.name)}${item.detail ? " (" + esc(item.detail) + ")" : ""}">
|
|
2481
|
+
<circle cx="${ix}" cy="${iy}" r="4.5" fill="${cat.color}" opacity="0.5"
|
|
2482
|
+
class="eco-item-dot"/>
|
|
2483
|
+
<circle cx="${ix}" cy="${iy}" r="4.5" fill="transparent" stroke="${cat.color}"
|
|
2484
|
+
stroke-width="1" opacity="0.3"/>
|
|
2485
|
+
<title>${esc(item.name)}${item.detail ? " \u2014 " + esc(item.detail) : ""}</title>
|
|
2486
|
+
</g>`;
|
|
2428
2487
|
});
|
|
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>`;
|
|
2488
|
+
if (cat.count > maxItems) {
|
|
2489
|
+
const extra = cat.count - maxItems;
|
|
2490
|
+
const moreAngle = angle + arcSpread / 2 + 0.35;
|
|
2491
|
+
const mx = x + Math.cos(moreAngle) * (itemRadius * 0.85);
|
|
2492
|
+
const my = y + Math.sin(moreAngle) * (itemRadius * 0.85);
|
|
2493
|
+
itemNodes += `<text x="${mx}" y="${my}"
|
|
2494
|
+
font-family="var(--font-mono)" font-size="9" fill="${cat.color}"
|
|
2495
|
+
opacity="0.5" text-anchor="middle" dominant-baseline="middle">+${extra}</text>`;
|
|
2437
2496
|
}
|
|
2438
2497
|
}
|
|
2439
|
-
const nodeR = dimmed ?
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
<
|
|
2445
|
-
|
|
2446
|
-
|
|
2498
|
+
const nodeR = dimmed ? 24 : 32;
|
|
2499
|
+
const labelY = y - nodeR - 10;
|
|
2500
|
+
catNodes += `<g class="eco-cat-node" data-section="${cat.id}"
|
|
2501
|
+
style="cursor:pointer;opacity:${opacity}" role="button" tabindex="0">
|
|
2502
|
+
<!-- Hit area -->
|
|
2503
|
+
<circle cx="${x}" cy="${y}" r="${nodeR + 8}" fill="transparent"/>
|
|
2504
|
+
<!-- Outer glow ring -->
|
|
2505
|
+
${!dimmed ? `<circle cx="${x}" cy="${y}" r="${nodeR + 3}" fill="none"
|
|
2506
|
+
stroke="${cat.color}" stroke-width="1" opacity="0.15"
|
|
2507
|
+
style="animation: eco-pulse 3s ease-in-out infinite; animation-delay: ${i * 0.4}s"/>` : ""}
|
|
2508
|
+
<!-- Main circle -->
|
|
2509
|
+
<circle cx="${x}" cy="${y}" r="${nodeR}" fill="${cat.color}"
|
|
2510
|
+
opacity="${dimmed ? 0.08 : 0.12}" stroke="${cat.color}"
|
|
2511
|
+
stroke-width="${dimmed ? 1 : 2}" class="eco-cat-circle"
|
|
2512
|
+
${!dimmed ? 'filter="url(#eco-glow)"' : ""}/>
|
|
2513
|
+
<!-- Count inside -->
|
|
2514
|
+
<text x="${x}" y="${y + 1}" text-anchor="middle" dominant-baseline="middle"
|
|
2515
|
+
font-family="var(--font-mono)" font-size="${dimmed ? 14 : 18}"
|
|
2516
|
+
font-weight="700" fill="${cat.color}" opacity="${dimmed ? 0.3 : 0.9}">${cat.count}</text>
|
|
2517
|
+
<!-- Label + icon ABOVE circle -->
|
|
2518
|
+
<text x="${x}" y="${labelY}" text-anchor="middle" dominant-baseline="auto"
|
|
2519
|
+
font-family="var(--font-mono)" font-size="11" font-weight="600"
|
|
2520
|
+
fill="${cat.color}" opacity="${dimmed ? 0.3 : 0.85}">${cat.icon} ${cat.label}</text>
|
|
2447
2521
|
</g>`;
|
|
2448
2522
|
});
|
|
2449
|
-
const projectName = result.project.name.length >
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
<
|
|
2523
|
+
const projectName = result.project.name.length > 20 ? result.project.name.slice(0, 18) + ".." : result.project.name;
|
|
2524
|
+
const centerNode = `<g class="eco-center">
|
|
2525
|
+
<!-- Outer pulse ring -->
|
|
2526
|
+
<circle cx="${cx}" cy="${cy}" r="48" fill="none" stroke="var(--accent)"
|
|
2527
|
+
stroke-width="1" opacity="0.2"
|
|
2528
|
+
style="animation: eco-pulse 4s ease-in-out infinite"/>
|
|
2529
|
+
<!-- Main circle -->
|
|
2530
|
+
<circle cx="${cx}" cy="${cy}" r="42" fill="var(--bg-alt)" stroke="var(--accent)"
|
|
2531
|
+
stroke-width="2.5" filter="url(#eco-glow-center)"/>
|
|
2532
|
+
<!-- Project name -->
|
|
2533
|
+
<text x="${cx}" y="${cy - 2}" text-anchor="middle" dominant-baseline="auto"
|
|
2534
|
+
font-family="var(--font-mono)" font-size="11" font-weight="700"
|
|
2535
|
+
fill="var(--text-bright)" opacity="0.95">${esc(projectName)}</text>
|
|
2536
|
+
<!-- Total count -->
|
|
2537
|
+
<text x="${cx}" y="${cy + 14}" text-anchor="middle" dominant-baseline="auto"
|
|
2538
|
+
font-family="var(--font-mono)" font-size="9"
|
|
2539
|
+
fill="var(--text-dim)">${totalItems} elementos</text>
|
|
2540
|
+
</g>`;
|
|
2541
|
+
const tooltip = `<g id="eco-tooltip" style="display:none;pointer-events:none">
|
|
2542
|
+
<rect x="0" y="0" width="160" height="28" rx="4"
|
|
2543
|
+
fill="var(--bg-card)" stroke="var(--border)" stroke-width="1" opacity="0.95"/>
|
|
2544
|
+
<text x="80" y="18" text-anchor="middle" font-family="var(--font-mono)"
|
|
2545
|
+
font-size="10" fill="var(--text)" id="eco-tooltip-text"></text>
|
|
2457
2546
|
</g>`;
|
|
2547
|
+
const watermark = `<text x="${W - 12}" y="${H - 10}" text-anchor="end"
|
|
2548
|
+
font-family="var(--font-mono)" font-size="9" fill="var(--text-dim)" opacity="0.3"
|
|
2549
|
+
letter-spacing="0.05em">cocaxcode</text>`;
|
|
2550
|
+
const svgContent = `${defs}${bg}${connections}${itemNodes}${catNodes}${centerNode}${tooltip}${watermark}`;
|
|
2458
2551
|
return `
|
|
2459
2552
|
<div class="ecosystem-map">
|
|
2460
|
-
<svg class="ecosystem-svg" viewBox="0 0 ${W} ${H}" xmlns="http://www.w3.org/2000/svg"
|
|
2461
|
-
|
|
2553
|
+
<svg class="ecosystem-svg" viewBox="0 0 ${W} ${H}" xmlns="http://www.w3.org/2000/svg"
|
|
2554
|
+
role="img" aria-label="Mapa del ecosistema AI del proyecto">
|
|
2555
|
+
<style>
|
|
2556
|
+
@keyframes eco-dash { to { stroke-dashoffset: -80; } }
|
|
2557
|
+
@keyframes eco-pulse { 0%,100% { opacity: 0.15; transform-origin: center; } 50% { opacity: 0.4; } }
|
|
2558
|
+
.eco-cat-node:hover .eco-cat-circle { stroke-width: 3; opacity: 0.25; }
|
|
2559
|
+
.eco-cat-node:hover { filter: brightness(1.2); }
|
|
2560
|
+
.eco-cat-node:focus { outline: none; }
|
|
2561
|
+
.eco-cat-node:focus .eco-cat-circle { stroke-width: 3; stroke-dasharray: 4 2; }
|
|
2562
|
+
.eco-item-dot { transition: r 0.2s, opacity 0.2s; }
|
|
2563
|
+
.eco-item:hover .eco-item-dot { r: 7; opacity: 0.8; }
|
|
2564
|
+
</style>
|
|
2565
|
+
${svgContent}
|
|
2462
2566
|
</svg>
|
|
2463
2567
|
</div>`;
|
|
2464
2568
|
}
|
|
@@ -2486,7 +2590,21 @@ function renderNavBar(summary) {
|
|
|
2486
2590
|
return `
|
|
2487
2591
|
<nav class="nav-bar">
|
|
2488
2592
|
<div class="nav-links">
|
|
2489
|
-
<span
|
|
2593
|
+
<span class="nav-brand">
|
|
2594
|
+
<svg viewBox="0 0 32 32" width="18" height="18" style="vertical-align:middle;margin-right:4px">
|
|
2595
|
+
<defs>
|
|
2596
|
+
<linearGradient id="nav-g1" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#22d3ee"/><stop offset="100%" stop-color="#06b6d4"/></linearGradient>
|
|
2597
|
+
<linearGradient id="nav-g2" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#0891b2"/><stop offset="100%" stop-color="#0e7490"/></linearGradient>
|
|
2598
|
+
</defs>
|
|
2599
|
+
<rect width="32" height="32" fill="#0a0a0c" rx="4"/>
|
|
2600
|
+
<rect x="9" y="7.5" width="16" height="18.5" rx="4" fill="url(#nav-g2)" opacity="0.5"/>
|
|
2601
|
+
<rect x="8" y="6.5" width="16" height="18.5" rx="4" fill="url(#nav-g1)"/>
|
|
2602
|
+
<path d="M11.5,11 L18,16 L11.5,21" fill="none" stroke="#0a0a0c" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
|
|
2603
|
+
<line x1="19" y1="20" x2="21.5" y2="20" stroke="#0a0a0c" stroke-width="1.8" stroke-linecap="round"/>
|
|
2604
|
+
</svg>
|
|
2605
|
+
<span style="font-family:var(--font-mono);font-size:0.8rem"><span style="color:var(--text-dim)">by</span> <span style="color:var(--accent)">cocaxcode</span></span>
|
|
2606
|
+
</span>
|
|
2607
|
+
<span class="nav-separator"></span>
|
|
2490
2608
|
${navLinks}
|
|
2491
2609
|
</div>
|
|
2492
2610
|
<div class="nav-actions">
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
generateHtml,
|
|
4
4
|
runAllScanners
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-G57UDS2C.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-BSHVSE33.js");
|
|
101
101
|
const server = createServer();
|
|
102
102
|
const transport = new StdioServerTransport();
|
|
103
103
|
await server.connect(transport);
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
introspectServers,
|
|
5
5
|
runAllScanners,
|
|
6
6
|
scanMcpConfigs
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-G57UDS2C.js";
|
|
8
8
|
|
|
9
9
|
// src/server.ts
|
|
10
10
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -116,15 +116,17 @@ function registerReportTool(server) {
|
|
|
116
116
|
{
|
|
117
117
|
dir: z3.string().optional().describe("Directorio a escanear (default: cwd)"),
|
|
118
118
|
output: z3.string().optional().describe("Ruta del archivo HTML (default: ai-context-report.html)"),
|
|
119
|
-
|
|
119
|
+
include_user: z3.boolean().optional().describe("Incluir configuraci\xF3n del usuario (~/.claude, skills, memorias, agentes)"),
|
|
120
|
+
no_introspect: z3.boolean().optional().describe("No conectar a MCP servers"),
|
|
121
|
+
timeout: z3.number().optional().describe("Timeout de introspecci\xF3n en ms (default: 10000)")
|
|
120
122
|
},
|
|
121
|
-
async ({ dir, output, no_introspect }) => {
|
|
123
|
+
async ({ dir, output, include_user, no_introspect, timeout }) => {
|
|
122
124
|
try {
|
|
123
125
|
const result = await runAllScanners({
|
|
124
126
|
dir: dir ?? process.cwd(),
|
|
125
|
-
includeUser: false,
|
|
127
|
+
includeUser: include_user ?? false,
|
|
126
128
|
introspect: !(no_introspect ?? false),
|
|
127
|
-
timeout: 1e4
|
|
129
|
+
timeout: timeout ?? 1e4
|
|
128
130
|
});
|
|
129
131
|
const html = generateHtml(result);
|
|
130
132
|
const outputPath = resolve(output ?? "ai-context-report.html");
|
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.2",
|
|
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": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"typecheck": "tsc --noEmit",
|
|
22
22
|
"prepare": "npm run build",
|
|
23
23
|
"inspector": "npx @modelcontextprotocol/inspector node dist/index.js -- --mcp",
|
|
24
|
-
"serve:report": "node serve-report.
|
|
24
|
+
"serve:report": "node serve-report.cjs"
|
|
25
25
|
},
|
|
26
26
|
"engines": {
|
|
27
27
|
"node": ">=20.0.0"
|