bluera-knowledge 0.35.0 → 0.37.0
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.
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +32 -0
- package/README.md +8 -20
- package/bun.lock +27 -0
- package/dist/{chunk-L2SC6J4K.js → chunk-724FNI27.js} +466 -171
- package/dist/chunk-724FNI27.js.map +1 -0
- package/dist/{chunk-DNGE7FZ4.js → chunk-AO45YFHO.js} +1386 -42
- package/dist/chunk-AO45YFHO.js.map +1 -0
- package/dist/{chunk-MQQ46BST.js → chunk-F6DGSS2N.js} +2 -2
- package/dist/index.js +72 -5
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +37 -3
- package/dist/mcp/server.js +2 -2
- package/dist/workers/background-worker-cli.js +2 -2
- package/hooks/check-ready.sh +17 -7
- package/hooks/hooks.json +17 -1
- package/hooks/lib/store_summary.py +111 -0
- package/hooks/posttooluse-bk-reminder.py +33 -6
- package/hooks/stop-bk-check.py +86 -0
- package/hooks/userpromptsubmit-bk-nudge.py +156 -0
- package/package.json +3 -1
- package/scripts/auto-setup.sh +11 -3
- package/scripts/eval-candidates.sh +235 -0
- package/skills/advanced-workflows/references/combining-workflows.md +17 -0
- package/skills/advanced-workflows/references/error-recovery.md +44 -0
- package/skills/advanced-workflows/references/handling-large-results.md +48 -0
- package/skills/advanced-workflows/references/multi-store-search.md +42 -0
- package/skills/knowledge-search/SKILL.md +1 -1
- package/skills/search/statusline.md +75 -0
- package/skills/store-lifecycle/references/failure-recovery.md +80 -0
- package/skills/store-lifecycle/references/indexing-strategies.md +67 -0
- package/skills/store-lifecycle/references/job-monitoring.md +72 -0
- package/skills/store-lifecycle/references/lifecycle-checklist.md +20 -0
- package/skills/store-lifecycle/references/storage-management.md +43 -0
- package/skills/suggest/SKILL.md +13 -6
- package/dist/chunk-DNGE7FZ4.js.map +0 -1
- package/dist/chunk-L2SC6J4K.js.map +0 -1
- /package/dist/{chunk-MQQ46BST.js.map → chunk-F6DGSS2N.js.map} +0 -0
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
AdapterRegistry,
|
|
3
3
|
JobService,
|
|
4
4
|
StoreDefinitionService,
|
|
5
|
-
TEXT_EXTENSIONS,
|
|
6
5
|
createLazyServices,
|
|
7
6
|
createLogger,
|
|
8
7
|
destroyServices,
|
|
@@ -12,7 +11,7 @@ import {
|
|
|
12
11
|
isWebStoreDefinition,
|
|
13
12
|
ok,
|
|
14
13
|
summarizePayload
|
|
15
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-724FNI27.js";
|
|
16
15
|
import {
|
|
17
16
|
DEFAULT_IGNORE_DIRS,
|
|
18
17
|
checkStoreModelCompatibility
|
|
@@ -1049,6 +1048,119 @@ import { execFile } from "child_process";
|
|
|
1049
1048
|
import { readdir, stat } from "fs/promises";
|
|
1050
1049
|
import { extname, join } from "path";
|
|
1051
1050
|
import { promisify } from "util";
|
|
1051
|
+
|
|
1052
|
+
// src/utils/text-extensions.ts
|
|
1053
|
+
var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
1054
|
+
// Text/docs
|
|
1055
|
+
".txt",
|
|
1056
|
+
".md",
|
|
1057
|
+
".rst",
|
|
1058
|
+
".adoc",
|
|
1059
|
+
// JavaScript/TypeScript
|
|
1060
|
+
".js",
|
|
1061
|
+
".ts",
|
|
1062
|
+
".jsx",
|
|
1063
|
+
".tsx",
|
|
1064
|
+
".mjs",
|
|
1065
|
+
".cjs",
|
|
1066
|
+
".mts",
|
|
1067
|
+
".cts",
|
|
1068
|
+
// Config/data
|
|
1069
|
+
".json",
|
|
1070
|
+
".yaml",
|
|
1071
|
+
".yml",
|
|
1072
|
+
".toml",
|
|
1073
|
+
".ini",
|
|
1074
|
+
".env",
|
|
1075
|
+
// Web
|
|
1076
|
+
".html",
|
|
1077
|
+
".htm",
|
|
1078
|
+
".css",
|
|
1079
|
+
".scss",
|
|
1080
|
+
".sass",
|
|
1081
|
+
".less",
|
|
1082
|
+
".vue",
|
|
1083
|
+
".svelte",
|
|
1084
|
+
// Python
|
|
1085
|
+
".py",
|
|
1086
|
+
".pyi",
|
|
1087
|
+
".pyx",
|
|
1088
|
+
// Ruby
|
|
1089
|
+
".rb",
|
|
1090
|
+
".erb",
|
|
1091
|
+
".rake",
|
|
1092
|
+
// Go
|
|
1093
|
+
".go",
|
|
1094
|
+
// Rust
|
|
1095
|
+
".rs",
|
|
1096
|
+
// Java/JVM
|
|
1097
|
+
".java",
|
|
1098
|
+
".kt",
|
|
1099
|
+
".kts",
|
|
1100
|
+
".scala",
|
|
1101
|
+
".groovy",
|
|
1102
|
+
".gradle",
|
|
1103
|
+
// C/C++
|
|
1104
|
+
".c",
|
|
1105
|
+
".cpp",
|
|
1106
|
+
".cc",
|
|
1107
|
+
".cxx",
|
|
1108
|
+
".h",
|
|
1109
|
+
".hpp",
|
|
1110
|
+
".hxx",
|
|
1111
|
+
// C#/.NET
|
|
1112
|
+
".cs",
|
|
1113
|
+
".fs",
|
|
1114
|
+
".vb",
|
|
1115
|
+
// Swift/Objective-C
|
|
1116
|
+
".swift",
|
|
1117
|
+
".m",
|
|
1118
|
+
".mm",
|
|
1119
|
+
// PHP
|
|
1120
|
+
".php",
|
|
1121
|
+
// Shell
|
|
1122
|
+
".sh",
|
|
1123
|
+
".bash",
|
|
1124
|
+
".zsh",
|
|
1125
|
+
".fish",
|
|
1126
|
+
".ps1",
|
|
1127
|
+
".psm1",
|
|
1128
|
+
// SQL
|
|
1129
|
+
".sql",
|
|
1130
|
+
// Other
|
|
1131
|
+
".xml",
|
|
1132
|
+
".graphql",
|
|
1133
|
+
".gql",
|
|
1134
|
+
".proto",
|
|
1135
|
+
".lua",
|
|
1136
|
+
".r",
|
|
1137
|
+
".R",
|
|
1138
|
+
".jl",
|
|
1139
|
+
".ex",
|
|
1140
|
+
".exs",
|
|
1141
|
+
".erl",
|
|
1142
|
+
".hrl",
|
|
1143
|
+
".clj",
|
|
1144
|
+
".cljs",
|
|
1145
|
+
".cljc",
|
|
1146
|
+
".hs",
|
|
1147
|
+
".elm",
|
|
1148
|
+
".dart",
|
|
1149
|
+
".pl",
|
|
1150
|
+
".pm",
|
|
1151
|
+
".tcl",
|
|
1152
|
+
".vim",
|
|
1153
|
+
".zig",
|
|
1154
|
+
".nim",
|
|
1155
|
+
".v",
|
|
1156
|
+
".tf",
|
|
1157
|
+
".hcl",
|
|
1158
|
+
".dockerfile",
|
|
1159
|
+
".makefile",
|
|
1160
|
+
".cmake"
|
|
1161
|
+
]);
|
|
1162
|
+
|
|
1163
|
+
// src/utils/file-count.ts
|
|
1052
1164
|
var execFileAsync = promisify(execFile);
|
|
1053
1165
|
var TIMEOUT_MS = 5e3;
|
|
1054
1166
|
var IGNORE_DIRS = new Set(DEFAULT_IGNORE_DIRS);
|
|
@@ -1262,6 +1374,616 @@ var handleStoresPull = async (args, context) => {
|
|
|
1262
1374
|
// src/mcp/handlers/store.handler.ts
|
|
1263
1375
|
import { rm, access } from "fs/promises";
|
|
1264
1376
|
import { join as join2 } from "path";
|
|
1377
|
+
import { createUIResource } from "@mcp-ui/server";
|
|
1378
|
+
|
|
1379
|
+
// src/mcp/ui/styles.ts
|
|
1380
|
+
var BASE_STYLES = `
|
|
1381
|
+
:root {
|
|
1382
|
+
/* Surface colors */
|
|
1383
|
+
--bg-primary: #0d1117;
|
|
1384
|
+
--bg-secondary: #161b22;
|
|
1385
|
+
--bg-tertiary: #1c2129;
|
|
1386
|
+
--bg-card: #161b22;
|
|
1387
|
+
--bg-card-hover: #1c2129;
|
|
1388
|
+
--bg-inset: #0d1117;
|
|
1389
|
+
|
|
1390
|
+
/* Border colors */
|
|
1391
|
+
--border-primary: #30363d;
|
|
1392
|
+
--border-secondary: #21262d;
|
|
1393
|
+
--border-subtle: rgba(240, 246, 252, 0.06);
|
|
1394
|
+
|
|
1395
|
+
/* Text colors */
|
|
1396
|
+
--text-primary: #e6edf3;
|
|
1397
|
+
--text-secondary: #8b949e;
|
|
1398
|
+
--text-tertiary: #6e7681;
|
|
1399
|
+
--text-link: #58a6ff;
|
|
1400
|
+
--text-inverse: #0d1117;
|
|
1401
|
+
|
|
1402
|
+
/* Accent colors */
|
|
1403
|
+
--accent-blue: #58a6ff;
|
|
1404
|
+
--accent-green: #3fb950;
|
|
1405
|
+
--accent-orange: #d29922;
|
|
1406
|
+
--accent-red: #f85149;
|
|
1407
|
+
--accent-purple: #bc8cff;
|
|
1408
|
+
--accent-cyan: #39d2c0;
|
|
1409
|
+
--accent-pink: #f778ba;
|
|
1410
|
+
|
|
1411
|
+
/* Badge colors */
|
|
1412
|
+
--badge-repo-bg: rgba(88, 166, 255, 0.15);
|
|
1413
|
+
--badge-repo-text: #58a6ff;
|
|
1414
|
+
--badge-repo-border: rgba(88, 166, 255, 0.3);
|
|
1415
|
+
--badge-file-bg: rgba(188, 140, 255, 0.15);
|
|
1416
|
+
--badge-file-text: #bc8cff;
|
|
1417
|
+
--badge-file-border: rgba(188, 140, 255, 0.3);
|
|
1418
|
+
--badge-web-bg: rgba(57, 210, 192, 0.15);
|
|
1419
|
+
--badge-web-text: #39d2c0;
|
|
1420
|
+
--badge-web-border: rgba(57, 210, 192, 0.3);
|
|
1421
|
+
|
|
1422
|
+
/* Status colors */
|
|
1423
|
+
--status-ready: #3fb950;
|
|
1424
|
+
--status-indexing: #d29922;
|
|
1425
|
+
--status-error: #f85149;
|
|
1426
|
+
--status-unknown: #6e7681;
|
|
1427
|
+
|
|
1428
|
+
/* Score colors */
|
|
1429
|
+
--score-high: #3fb950;
|
|
1430
|
+
--score-medium: #d29922;
|
|
1431
|
+
--score-low: #f85149;
|
|
1432
|
+
|
|
1433
|
+
/* Confidence colors */
|
|
1434
|
+
--confidence-high-bg: rgba(63, 185, 80, 0.15);
|
|
1435
|
+
--confidence-high-text: #3fb950;
|
|
1436
|
+
--confidence-medium-bg: rgba(210, 153, 34, 0.15);
|
|
1437
|
+
--confidence-medium-text: #d29922;
|
|
1438
|
+
--confidence-low-bg: rgba(248, 81, 73, 0.15);
|
|
1439
|
+
--confidence-low-text: #f85149;
|
|
1440
|
+
|
|
1441
|
+
/* Spacing */
|
|
1442
|
+
--space-xs: 4px;
|
|
1443
|
+
--space-sm: 8px;
|
|
1444
|
+
--space-md: 12px;
|
|
1445
|
+
--space-lg: 16px;
|
|
1446
|
+
--space-xl: 24px;
|
|
1447
|
+
--space-2xl: 32px;
|
|
1448
|
+
|
|
1449
|
+
/* Typography */
|
|
1450
|
+
--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
|
|
1451
|
+
--font-mono: "SF Mono", "Cascadia Code", "Fira Code", "JetBrains Mono", ui-monospace, SFMono-Regular, "Liberation Mono", Menlo, Monaco, Consolas, monospace;
|
|
1452
|
+
--font-size-xs: 11px;
|
|
1453
|
+
--font-size-sm: 12px;
|
|
1454
|
+
--font-size-md: 14px;
|
|
1455
|
+
--font-size-lg: 16px;
|
|
1456
|
+
--font-size-xl: 20px;
|
|
1457
|
+
--font-size-2xl: 24px;
|
|
1458
|
+
|
|
1459
|
+
/* Radius */
|
|
1460
|
+
--radius-sm: 4px;
|
|
1461
|
+
--radius-md: 6px;
|
|
1462
|
+
--radius-lg: 8px;
|
|
1463
|
+
--radius-xl: 12px;
|
|
1464
|
+
|
|
1465
|
+
/* Shadows */
|
|
1466
|
+
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
|
|
1467
|
+
--shadow-md: 0 2px 8px rgba(0, 0, 0, 0.3);
|
|
1468
|
+
--shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.4);
|
|
1469
|
+
|
|
1470
|
+
/* Transitions */
|
|
1471
|
+
--transition-fast: 120ms ease;
|
|
1472
|
+
--transition-normal: 200ms ease;
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
*, *::before, *::after {
|
|
1476
|
+
box-sizing: border-box;
|
|
1477
|
+
margin: 0;
|
|
1478
|
+
padding: 0;
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
body {
|
|
1482
|
+
font-family: var(--font-sans);
|
|
1483
|
+
font-size: var(--font-size-md);
|
|
1484
|
+
color: var(--text-primary);
|
|
1485
|
+
background: var(--bg-primary);
|
|
1486
|
+
line-height: 1.5;
|
|
1487
|
+
-webkit-font-smoothing: antialiased;
|
|
1488
|
+
-moz-osx-font-smoothing: grayscale;
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
/* Container */
|
|
1492
|
+
.container {
|
|
1493
|
+
max-width: 1200px;
|
|
1494
|
+
margin: 0 auto;
|
|
1495
|
+
padding: var(--space-lg);
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
/* Header */
|
|
1499
|
+
.header {
|
|
1500
|
+
margin-bottom: var(--space-xl);
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
.header-title {
|
|
1504
|
+
font-size: var(--font-size-xl);
|
|
1505
|
+
font-weight: 600;
|
|
1506
|
+
color: var(--text-primary);
|
|
1507
|
+
margin-bottom: var(--space-xs);
|
|
1508
|
+
display: flex;
|
|
1509
|
+
align-items: center;
|
|
1510
|
+
gap: var(--space-sm);
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
.header-subtitle {
|
|
1514
|
+
font-size: var(--font-size-sm);
|
|
1515
|
+
color: var(--text-secondary);
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
/* Badges */
|
|
1519
|
+
.badge {
|
|
1520
|
+
display: inline-flex;
|
|
1521
|
+
align-items: center;
|
|
1522
|
+
padding: 2px 8px;
|
|
1523
|
+
border-radius: 9999px;
|
|
1524
|
+
font-size: var(--font-size-xs);
|
|
1525
|
+
font-weight: 500;
|
|
1526
|
+
letter-spacing: 0.02em;
|
|
1527
|
+
text-transform: uppercase;
|
|
1528
|
+
border: 1px solid;
|
|
1529
|
+
white-space: nowrap;
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
.badge-repo {
|
|
1533
|
+
background: var(--badge-repo-bg);
|
|
1534
|
+
color: var(--badge-repo-text);
|
|
1535
|
+
border-color: var(--badge-repo-border);
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
.badge-file {
|
|
1539
|
+
background: var(--badge-file-bg);
|
|
1540
|
+
color: var(--badge-file-text);
|
|
1541
|
+
border-color: var(--badge-file-border);
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
.badge-web {
|
|
1545
|
+
background: var(--badge-web-bg);
|
|
1546
|
+
color: var(--badge-web-text);
|
|
1547
|
+
border-color: var(--badge-web-border);
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
/* Status dot */
|
|
1551
|
+
.status-dot {
|
|
1552
|
+
display: inline-block;
|
|
1553
|
+
width: 8px;
|
|
1554
|
+
height: 8px;
|
|
1555
|
+
border-radius: 50%;
|
|
1556
|
+
flex-shrink: 0;
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1559
|
+
.status-ready { background: var(--status-ready); box-shadow: 0 0 6px var(--status-ready); }
|
|
1560
|
+
.status-indexing { background: var(--status-indexing); box-shadow: 0 0 6px var(--status-indexing); animation: pulse 2s infinite; }
|
|
1561
|
+
.status-error { background: var(--status-error); box-shadow: 0 0 6px var(--status-error); }
|
|
1562
|
+
.status-unknown { background: var(--status-unknown); }
|
|
1563
|
+
|
|
1564
|
+
@keyframes pulse {
|
|
1565
|
+
0%, 100% { opacity: 1; }
|
|
1566
|
+
50% { opacity: 0.4; }
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
/* Tags */
|
|
1570
|
+
.tag {
|
|
1571
|
+
display: inline-flex;
|
|
1572
|
+
align-items: center;
|
|
1573
|
+
padding: 1px 6px;
|
|
1574
|
+
border-radius: var(--radius-sm);
|
|
1575
|
+
font-size: var(--font-size-xs);
|
|
1576
|
+
color: var(--text-secondary);
|
|
1577
|
+
background: var(--bg-tertiary);
|
|
1578
|
+
border: 1px solid var(--border-secondary);
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
/* Metadata row */
|
|
1582
|
+
.meta-row {
|
|
1583
|
+
display: flex;
|
|
1584
|
+
align-items: center;
|
|
1585
|
+
gap: var(--space-sm);
|
|
1586
|
+
font-size: var(--font-size-sm);
|
|
1587
|
+
color: var(--text-secondary);
|
|
1588
|
+
flex-wrap: wrap;
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
.meta-separator {
|
|
1592
|
+
width: 1px;
|
|
1593
|
+
height: 12px;
|
|
1594
|
+
background: var(--border-primary);
|
|
1595
|
+
flex-shrink: 0;
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
/* Monospace text */
|
|
1599
|
+
.mono {
|
|
1600
|
+
font-family: var(--font-mono);
|
|
1601
|
+
font-size: var(--font-size-sm);
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1604
|
+
/* Code block */
|
|
1605
|
+
.code-block {
|
|
1606
|
+
background: var(--bg-inset);
|
|
1607
|
+
border: 1px solid var(--border-secondary);
|
|
1608
|
+
border-radius: var(--radius-md);
|
|
1609
|
+
padding: var(--space-md);
|
|
1610
|
+
overflow-x: auto;
|
|
1611
|
+
font-family: var(--font-mono);
|
|
1612
|
+
font-size: var(--font-size-sm);
|
|
1613
|
+
line-height: 1.6;
|
|
1614
|
+
color: var(--text-primary);
|
|
1615
|
+
white-space: pre;
|
|
1616
|
+
tab-size: 2;
|
|
1617
|
+
}
|
|
1618
|
+
|
|
1619
|
+
/* Details/Summary (expand/collapse) */
|
|
1620
|
+
details {
|
|
1621
|
+
border-top: 1px solid var(--border-secondary);
|
|
1622
|
+
margin-top: var(--space-md);
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
details summary {
|
|
1626
|
+
cursor: pointer;
|
|
1627
|
+
padding: var(--space-sm) 0;
|
|
1628
|
+
font-size: var(--font-size-sm);
|
|
1629
|
+
color: var(--text-secondary);
|
|
1630
|
+
user-select: none;
|
|
1631
|
+
list-style: none;
|
|
1632
|
+
display: flex;
|
|
1633
|
+
align-items: center;
|
|
1634
|
+
gap: var(--space-sm);
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1637
|
+
details summary::-webkit-details-marker {
|
|
1638
|
+
display: none;
|
|
1639
|
+
}
|
|
1640
|
+
|
|
1641
|
+
details summary::before {
|
|
1642
|
+
content: "\\25B6";
|
|
1643
|
+
font-size: 10px;
|
|
1644
|
+
color: var(--text-tertiary);
|
|
1645
|
+
transition: transform var(--transition-fast);
|
|
1646
|
+
display: inline-block;
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1649
|
+
details[open] summary::before {
|
|
1650
|
+
transform: rotate(90deg);
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
details summary:hover {
|
|
1654
|
+
color: var(--text-primary);
|
|
1655
|
+
}
|
|
1656
|
+
|
|
1657
|
+
details .details-content {
|
|
1658
|
+
padding: var(--space-md) 0;
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
/* Truncate text */
|
|
1662
|
+
.truncate {
|
|
1663
|
+
overflow: hidden;
|
|
1664
|
+
text-overflow: ellipsis;
|
|
1665
|
+
white-space: nowrap;
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
/* Empty state */
|
|
1669
|
+
.empty-state {
|
|
1670
|
+
text-align: center;
|
|
1671
|
+
padding: var(--space-2xl) var(--space-lg);
|
|
1672
|
+
color: var(--text-secondary);
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
.empty-state-title {
|
|
1676
|
+
font-size: var(--font-size-lg);
|
|
1677
|
+
font-weight: 500;
|
|
1678
|
+
color: var(--text-primary);
|
|
1679
|
+
margin-bottom: var(--space-sm);
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1682
|
+
/* Score bar */
|
|
1683
|
+
.score-bar-container {
|
|
1684
|
+
display: flex;
|
|
1685
|
+
align-items: center;
|
|
1686
|
+
gap: var(--space-sm);
|
|
1687
|
+
min-width: 120px;
|
|
1688
|
+
}
|
|
1689
|
+
|
|
1690
|
+
.score-bar-track {
|
|
1691
|
+
flex: 1;
|
|
1692
|
+
height: 4px;
|
|
1693
|
+
background: var(--bg-inset);
|
|
1694
|
+
border-radius: 2px;
|
|
1695
|
+
overflow: hidden;
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
.score-bar-fill {
|
|
1699
|
+
height: 100%;
|
|
1700
|
+
border-radius: 2px;
|
|
1701
|
+
transition: width var(--transition-normal);
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
.score-label {
|
|
1705
|
+
font-size: var(--font-size-xs);
|
|
1706
|
+
font-family: var(--font-mono);
|
|
1707
|
+
min-width: 36px;
|
|
1708
|
+
text-align: right;
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
/* Pill list */
|
|
1712
|
+
.pill-list {
|
|
1713
|
+
display: flex;
|
|
1714
|
+
flex-wrap: wrap;
|
|
1715
|
+
gap: var(--space-xs);
|
|
1716
|
+
list-style: none;
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
.pill {
|
|
1720
|
+
display: inline-flex;
|
|
1721
|
+
align-items: center;
|
|
1722
|
+
padding: 2px 8px;
|
|
1723
|
+
border-radius: var(--radius-sm);
|
|
1724
|
+
font-size: var(--font-size-xs);
|
|
1725
|
+
font-family: var(--font-mono);
|
|
1726
|
+
color: var(--text-secondary);
|
|
1727
|
+
background: var(--bg-tertiary);
|
|
1728
|
+
border: 1px solid var(--border-secondary);
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
/* Section heading inside cards */
|
|
1732
|
+
.section-label {
|
|
1733
|
+
font-size: var(--font-size-xs);
|
|
1734
|
+
font-weight: 600;
|
|
1735
|
+
text-transform: uppercase;
|
|
1736
|
+
letter-spacing: 0.05em;
|
|
1737
|
+
color: var(--text-tertiary);
|
|
1738
|
+
margin-bottom: var(--space-xs);
|
|
1739
|
+
}
|
|
1740
|
+
`;
|
|
1741
|
+
|
|
1742
|
+
// src/mcp/ui/stores-dashboard.ts
|
|
1743
|
+
function escapeHtml(text) {
|
|
1744
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1745
|
+
}
|
|
1746
|
+
function formatDate(isoDate) {
|
|
1747
|
+
const date = new Date(isoDate);
|
|
1748
|
+
const now = /* @__PURE__ */ new Date();
|
|
1749
|
+
const diffMs = now.getTime() - date.getTime();
|
|
1750
|
+
const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
|
|
1751
|
+
if (diffDays === 0) return "Today";
|
|
1752
|
+
if (diffDays === 1) return "Yesterday";
|
|
1753
|
+
if (diffDays < 7) return `${String(diffDays)}d ago`;
|
|
1754
|
+
if (diffDays < 30) return `${String(Math.floor(diffDays / 7))}w ago`;
|
|
1755
|
+
if (diffDays < 365) return `${String(Math.floor(diffDays / 30))}mo ago`;
|
|
1756
|
+
return `${String(Math.floor(diffDays / 365))}y ago`;
|
|
1757
|
+
}
|
|
1758
|
+
function getTypeIcon(type) {
|
|
1759
|
+
switch (type) {
|
|
1760
|
+
case "repo":
|
|
1761
|
+
return `<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1h-8a1 1 0 00-1 1v6.708A2.486 2.486 0 014.5 9h8V1.5zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"/></svg>`;
|
|
1762
|
+
case "file":
|
|
1763
|
+
return `<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M3.75 1.5a.25.25 0 00-.25.25v11.5c0 .138.112.25.25.25h8.5a.25.25 0 00.25-.25V6H9.75A1.75 1.75 0 018 4.25V1.5H3.75zm5.75.56v2.19c0 .138.112.25.25.25h2.19L9.5 2.06zM2 1.75C2 .784 2.784 0 3.75 0h5.086c.464 0 .909.184 1.237.513l3.414 3.414c.329.328.513.773.513 1.237v8.086A1.75 1.75 0 0112.25 15h-8.5A1.75 1.75 0 012 13.25V1.75z"/></svg>`;
|
|
1764
|
+
case "web":
|
|
1765
|
+
return `<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0zM8 0a8 8 0 100 16A8 8 0 008 0zM6.379 5.227A31.17 31.17 0 006 7.5h4a31.17 31.17 0 00-.379-2.273c-.27.096-.56.17-.862.22a4.463 4.463 0 00-.518.06 4.463 4.463 0 00-.518-.06c-.303-.05-.592-.124-.862-.22zM5.43 7.5a32.81 32.81 0 01.42-2.667 8.202 8.202 0 01-.987-.652A6.537 6.537 0 003.538 7.5H5.43zm-1.893 1.5h1.893c.05.898.155 1.787.42 2.667a8.202 8.202 0 01-.987.652A6.537 6.537 0 013.538 9zm6.963 0a32.81 32.81 0 01-.42 2.667c.326.217.668.41.987.652A6.537 6.537 0 0012.462 9h-1.893zm1.893-1.5h-1.893a32.81 32.81 0 00-.42-2.667c.326-.217.668-.41.987-.652A6.537 6.537 0 0112.462 7.5zM6 9h4a31.17 31.17 0 01-.379 2.273 4.708 4.708 0 01-.862-.22 4.463 4.463 0 01-.518-.06 4.463 4.463 0 01-.518.06c-.303.05-.592.124-.862.22A31.17 31.17 0 016 9zm2-6.97a3.26 3.26 0 01.762.292c.243.12.474.263.69.427A31.682 31.682 0 009.131 1.5 6.524 6.524 0 008 2.03zm0 11.94c.372-.06.753-.244 1.131-.53a31.682 31.682 0 00-.32-1.248 3.26 3.26 0 01-.762.292 4.463 4.463 0 01-.05.007v1.48zm0-11.94V2.03a3.26 3.26 0 00-.762.292c-.243.12-.474.263-.69.427.107.397.21.812.32 1.248A6.524 6.524 0 008 2.03zm0 11.94v-1.48a4.463 4.463 0 00.05.007 3.26 3.26 0 00.762.292c.107-.397.21-.812.32-1.248-.216.164-.447.307-.69.427A3.26 3.26 0 008 13.97z"/></svg>`;
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
function renderStoreCard(store) {
|
|
1769
|
+
const statusClass = store.modelId !== void 0 ? "ready" : "unknown";
|
|
1770
|
+
const statusLabel = store.modelId !== void 0 ? "Ready" : "Not indexed";
|
|
1771
|
+
const location = store.path ?? store.url ?? "";
|
|
1772
|
+
const truncatedLocation = location.length > 60 ? `...${location.slice(location.length - 57)}` : location;
|
|
1773
|
+
const tagsHtml = store.tags !== void 0 && store.tags.length > 0 ? `<div class="card-tags">
|
|
1774
|
+
${store.tags.map((t) => `<span class="tag">${escapeHtml(t)}</span>`).join("")}
|
|
1775
|
+
</div>` : "";
|
|
1776
|
+
const descriptionHtml = store.description !== void 0 ? `<p class="card-description">${escapeHtml(store.description)}</p>` : "";
|
|
1777
|
+
const branchHtml = store.branch !== void 0 ? `<span class="meta-separator"></span>
|
|
1778
|
+
<span class="mono">${escapeHtml(store.branch)}</span>` : "";
|
|
1779
|
+
const modelHtml = store.modelId !== void 0 ? `<span class="meta-separator"></span>
|
|
1780
|
+
<span class="mono" title="Embedding model">${escapeHtml(store.modelId)}</span>` : "";
|
|
1781
|
+
return `
|
|
1782
|
+
<div class="store-card">
|
|
1783
|
+
<div class="card-header">
|
|
1784
|
+
<div class="card-title-row">
|
|
1785
|
+
<div class="card-status">
|
|
1786
|
+
<span class="status-dot status-${statusClass}" title="${statusLabel}"></span>
|
|
1787
|
+
</div>
|
|
1788
|
+
<h3 class="card-title">${escapeHtml(store.name)}</h3>
|
|
1789
|
+
<span class="badge badge-${store.type}">
|
|
1790
|
+
${getTypeIcon(store.type)}
|
|
1791
|
+
<span style="margin-left: 4px">${store.type}</span>
|
|
1792
|
+
</span>
|
|
1793
|
+
</div>
|
|
1794
|
+
${descriptionHtml}
|
|
1795
|
+
</div>
|
|
1796
|
+
<div class="card-body">
|
|
1797
|
+
${location.length > 0 ? `<div class="card-location mono truncate" title="${escapeHtml(location)}">${escapeHtml(truncatedLocation)}</div>` : ""}
|
|
1798
|
+
${tagsHtml}
|
|
1799
|
+
</div>
|
|
1800
|
+
<div class="card-footer">
|
|
1801
|
+
<div class="meta-row">
|
|
1802
|
+
<span title="${escapeHtml(store.createdAt)}">${formatDate(store.createdAt)}</span>
|
|
1803
|
+
${branchHtml}
|
|
1804
|
+
${modelHtml}
|
|
1805
|
+
</div>
|
|
1806
|
+
</div>
|
|
1807
|
+
</div>
|
|
1808
|
+
`;
|
|
1809
|
+
}
|
|
1810
|
+
function renderStoresDashboard(stores) {
|
|
1811
|
+
const storesByType = {
|
|
1812
|
+
repo: stores.filter((s) => s.type === "repo").length,
|
|
1813
|
+
file: stores.filter((s) => s.type === "file").length,
|
|
1814
|
+
web: stores.filter((s) => s.type === "web").length
|
|
1815
|
+
};
|
|
1816
|
+
const indexed = stores.filter((s) => s.modelId !== void 0).length;
|
|
1817
|
+
const summaryParts = [];
|
|
1818
|
+
if (storesByType.repo > 0) summaryParts.push(`${String(storesByType.repo)} repo`);
|
|
1819
|
+
if (storesByType.file > 0) summaryParts.push(`${String(storesByType.file)} file`);
|
|
1820
|
+
if (storesByType.web > 0) summaryParts.push(`${String(storesByType.web)} web`);
|
|
1821
|
+
const contentHtml = stores.length === 0 ? `<div class="empty-state">
|
|
1822
|
+
<div class="empty-state-title">No knowledge stores</div>
|
|
1823
|
+
<p>Create a store to start indexing code and documentation.</p>
|
|
1824
|
+
</div>` : `<div class="store-grid">
|
|
1825
|
+
${stores.map((store) => renderStoreCard(store)).join("")}
|
|
1826
|
+
</div>`;
|
|
1827
|
+
return `<!DOCTYPE html>
|
|
1828
|
+
<html lang="en">
|
|
1829
|
+
<head>
|
|
1830
|
+
<meta charset="UTF-8">
|
|
1831
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1832
|
+
<title>Knowledge Stores</title>
|
|
1833
|
+
<style>
|
|
1834
|
+
${BASE_STYLES}
|
|
1835
|
+
|
|
1836
|
+
/* Dashboard-specific styles */
|
|
1837
|
+
.dashboard-stats {
|
|
1838
|
+
display: flex;
|
|
1839
|
+
gap: var(--space-lg);
|
|
1840
|
+
margin-bottom: var(--space-xl);
|
|
1841
|
+
flex-wrap: wrap;
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
.stat-card {
|
|
1845
|
+
background: var(--bg-secondary);
|
|
1846
|
+
border: 1px solid var(--border-primary);
|
|
1847
|
+
border-radius: var(--radius-lg);
|
|
1848
|
+
padding: var(--space-md) var(--space-lg);
|
|
1849
|
+
display: flex;
|
|
1850
|
+
flex-direction: column;
|
|
1851
|
+
min-width: 100px;
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
.stat-value {
|
|
1855
|
+
font-size: var(--font-size-2xl);
|
|
1856
|
+
font-weight: 700;
|
|
1857
|
+
color: var(--text-primary);
|
|
1858
|
+
line-height: 1.2;
|
|
1859
|
+
}
|
|
1860
|
+
|
|
1861
|
+
.stat-label {
|
|
1862
|
+
font-size: var(--font-size-xs);
|
|
1863
|
+
color: var(--text-tertiary);
|
|
1864
|
+
text-transform: uppercase;
|
|
1865
|
+
letter-spacing: 0.05em;
|
|
1866
|
+
margin-top: 2px;
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1869
|
+
/* Store card grid */
|
|
1870
|
+
.store-grid {
|
|
1871
|
+
display: grid;
|
|
1872
|
+
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
|
|
1873
|
+
gap: var(--space-lg);
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
@media (max-width: 768px) {
|
|
1877
|
+
.store-grid {
|
|
1878
|
+
grid-template-columns: 1fr;
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
.store-card {
|
|
1883
|
+
background: var(--bg-card);
|
|
1884
|
+
border: 1px solid var(--border-primary);
|
|
1885
|
+
border-radius: var(--radius-lg);
|
|
1886
|
+
overflow: hidden;
|
|
1887
|
+
transition: border-color var(--transition-normal), box-shadow var(--transition-normal);
|
|
1888
|
+
display: flex;
|
|
1889
|
+
flex-direction: column;
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
.store-card:hover {
|
|
1893
|
+
border-color: var(--border-primary);
|
|
1894
|
+
box-shadow: var(--shadow-md);
|
|
1895
|
+
background: var(--bg-card-hover);
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1898
|
+
.card-header {
|
|
1899
|
+
padding: var(--space-lg) var(--space-lg) var(--space-sm);
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1902
|
+
.card-title-row {
|
|
1903
|
+
display: flex;
|
|
1904
|
+
align-items: center;
|
|
1905
|
+
gap: var(--space-sm);
|
|
1906
|
+
}
|
|
1907
|
+
|
|
1908
|
+
.card-status {
|
|
1909
|
+
display: flex;
|
|
1910
|
+
align-items: center;
|
|
1911
|
+
flex-shrink: 0;
|
|
1912
|
+
}
|
|
1913
|
+
|
|
1914
|
+
.card-title {
|
|
1915
|
+
font-size: var(--font-size-md);
|
|
1916
|
+
font-weight: 600;
|
|
1917
|
+
color: var(--text-primary);
|
|
1918
|
+
flex: 1;
|
|
1919
|
+
min-width: 0;
|
|
1920
|
+
overflow: hidden;
|
|
1921
|
+
text-overflow: ellipsis;
|
|
1922
|
+
white-space: nowrap;
|
|
1923
|
+
}
|
|
1924
|
+
|
|
1925
|
+
.card-description {
|
|
1926
|
+
font-size: var(--font-size-sm);
|
|
1927
|
+
color: var(--text-secondary);
|
|
1928
|
+
margin-top: var(--space-sm);
|
|
1929
|
+
line-height: 1.5;
|
|
1930
|
+
display: -webkit-box;
|
|
1931
|
+
-webkit-line-clamp: 2;
|
|
1932
|
+
-webkit-box-orient: vertical;
|
|
1933
|
+
overflow: hidden;
|
|
1934
|
+
}
|
|
1935
|
+
|
|
1936
|
+
.card-body {
|
|
1937
|
+
padding: var(--space-sm) var(--space-lg);
|
|
1938
|
+
flex: 1;
|
|
1939
|
+
}
|
|
1940
|
+
|
|
1941
|
+
.card-location {
|
|
1942
|
+
color: var(--text-tertiary);
|
|
1943
|
+
font-size: var(--font-size-sm);
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
.card-tags {
|
|
1947
|
+
display: flex;
|
|
1948
|
+
flex-wrap: wrap;
|
|
1949
|
+
gap: var(--space-xs);
|
|
1950
|
+
margin-top: var(--space-sm);
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
.card-footer {
|
|
1954
|
+
padding: var(--space-sm) var(--space-lg) var(--space-lg);
|
|
1955
|
+
border-top: 1px solid var(--border-secondary);
|
|
1956
|
+
margin-top: auto;
|
|
1957
|
+
}
|
|
1958
|
+
</style>
|
|
1959
|
+
</head>
|
|
1960
|
+
<body>
|
|
1961
|
+
<div class="container">
|
|
1962
|
+
<div class="header">
|
|
1963
|
+
<h1 class="header-title">Knowledge Stores</h1>
|
|
1964
|
+
<p class="header-subtitle">${String(stores.length)} store${stores.length !== 1 ? "s" : ""}${summaryParts.length > 0 ? ` \u2014 ${summaryParts.join(", ")}` : ""}</p>
|
|
1965
|
+
</div>
|
|
1966
|
+
<div class="dashboard-stats">
|
|
1967
|
+
<div class="stat-card">
|
|
1968
|
+
<span class="stat-value">${String(stores.length)}</span>
|
|
1969
|
+
<span class="stat-label">Total Stores</span>
|
|
1970
|
+
</div>
|
|
1971
|
+
<div class="stat-card">
|
|
1972
|
+
<span class="stat-value">${String(indexed)}</span>
|
|
1973
|
+
<span class="stat-label">Indexed</span>
|
|
1974
|
+
</div>
|
|
1975
|
+
<div class="stat-card">
|
|
1976
|
+
<span class="stat-value">${String(stores.length - indexed)}</span>
|
|
1977
|
+
<span class="stat-label">Pending</span>
|
|
1978
|
+
</div>
|
|
1979
|
+
</div>
|
|
1980
|
+
${contentHtml}
|
|
1981
|
+
</div>
|
|
1982
|
+
</body>
|
|
1983
|
+
</html>`;
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
// src/mcp/handlers/store.handler.ts
|
|
1265
1987
|
var logger6 = createLogger("mcp-store");
|
|
1266
1988
|
var handleListStores = async (args, context) => {
|
|
1267
1989
|
const validated = ListStoresArgsSchema.parse(args);
|
|
@@ -1270,33 +1992,30 @@ var handleListStores = async (args, context) => {
|
|
|
1270
1992
|
const stores = await services.store.list();
|
|
1271
1993
|
const filtered = validated.type !== void 0 ? stores.filter((s) => s.type === validated.type) : stores;
|
|
1272
1994
|
logger6.info({ count: filtered.length, type: validated.type }, "List stores completed");
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
}
|
|
1298
|
-
]
|
|
1299
|
-
};
|
|
1995
|
+
const storeData = filtered.map((s) => ({
|
|
1996
|
+
id: s.id,
|
|
1997
|
+
name: s.name,
|
|
1998
|
+
type: s.type,
|
|
1999
|
+
path: "path" in s ? s.path : void 0,
|
|
2000
|
+
url: "url" in s && s.url !== void 0 ? s.url : void 0,
|
|
2001
|
+
branch: "branch" in s ? s.branch : void 0,
|
|
2002
|
+
depth: "depth" in s ? s.depth : void 0,
|
|
2003
|
+
maxPages: "maxPages" in s ? s.maxPages : void 0,
|
|
2004
|
+
tags: "tags" in s ? s.tags : void 0,
|
|
2005
|
+
description: s.description,
|
|
2006
|
+
modelId: s.modelId,
|
|
2007
|
+
createdAt: s.createdAt.toISOString()
|
|
2008
|
+
}));
|
|
2009
|
+
const uiResource = createUIResource({
|
|
2010
|
+
uri: "ui://bk/stores",
|
|
2011
|
+
content: { type: "rawHtml", htmlString: renderStoresDashboard(storeData) },
|
|
2012
|
+
encoding: "text"
|
|
2013
|
+
});
|
|
2014
|
+
const content = [
|
|
2015
|
+
{ type: "text", text: JSON.stringify({ stores: storeData }, null, 2) },
|
|
2016
|
+
uiResource
|
|
2017
|
+
];
|
|
2018
|
+
return { content };
|
|
1300
2019
|
};
|
|
1301
2020
|
var handleGetStoreInfo = async (args, context) => {
|
|
1302
2021
|
const validated = GetStoreInfoArgsSchema.parse(args);
|
|
@@ -2200,6 +2919,9 @@ var handleExecute = async (args, context) => {
|
|
|
2200
2919
|
}
|
|
2201
2920
|
};
|
|
2202
2921
|
|
|
2922
|
+
// src/mcp/handlers/search.handler.ts
|
|
2923
|
+
import { createUIResource as createUIResource2 } from "@mcp-ui/server";
|
|
2924
|
+
|
|
2203
2925
|
// src/services/token.service.ts
|
|
2204
2926
|
var CHARS_PER_TOKEN = 3.5;
|
|
2205
2927
|
function estimateTokens(text) {
|
|
@@ -2294,6 +3016,609 @@ var LRUCache = class {
|
|
|
2294
3016
|
}
|
|
2295
3017
|
};
|
|
2296
3018
|
|
|
3019
|
+
// src/mcp/ui/search-results.ts
|
|
3020
|
+
function escapeHtml2(text) {
|
|
3021
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
3022
|
+
}
|
|
3023
|
+
function getScoreColor(score) {
|
|
3024
|
+
if (score >= 0.7) return "var(--score-high)";
|
|
3025
|
+
if (score >= 0.4) return "var(--score-medium)";
|
|
3026
|
+
return "var(--score-low)";
|
|
3027
|
+
}
|
|
3028
|
+
function getScoreClass(score) {
|
|
3029
|
+
if (score >= 0.7) return "high";
|
|
3030
|
+
if (score >= 0.4) return "medium";
|
|
3031
|
+
return "low";
|
|
3032
|
+
}
|
|
3033
|
+
function getConfidenceClass(confidence) {
|
|
3034
|
+
switch (confidence) {
|
|
3035
|
+
case "high":
|
|
3036
|
+
return "confidence-high";
|
|
3037
|
+
case "medium":
|
|
3038
|
+
return "confidence-medium";
|
|
3039
|
+
case "low":
|
|
3040
|
+
return "confidence-low";
|
|
3041
|
+
default:
|
|
3042
|
+
return "confidence-medium";
|
|
3043
|
+
}
|
|
3044
|
+
}
|
|
3045
|
+
function getTypeIcon2(type) {
|
|
3046
|
+
switch (type) {
|
|
3047
|
+
case "function":
|
|
3048
|
+
return '<span class="type-icon type-fn">fn</span>';
|
|
3049
|
+
case "class":
|
|
3050
|
+
return '<span class="type-icon type-class">C</span>';
|
|
3051
|
+
case "interface":
|
|
3052
|
+
return '<span class="type-icon type-iface">I</span>';
|
|
3053
|
+
case "type":
|
|
3054
|
+
return '<span class="type-icon type-type">T</span>';
|
|
3055
|
+
case "const":
|
|
3056
|
+
return '<span class="type-icon type-const">K</span>';
|
|
3057
|
+
case "documentation":
|
|
3058
|
+
return '<span class="type-icon type-doc">D</span>';
|
|
3059
|
+
case "example":
|
|
3060
|
+
return '<span class="type-icon type-example">E</span>';
|
|
3061
|
+
default:
|
|
3062
|
+
return '<span class="type-icon type-default">?</span>';
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
3065
|
+
function renderContextSection(context) {
|
|
3066
|
+
const sections = [];
|
|
3067
|
+
if (context.interfaces !== void 0 && context.interfaces.length > 0) {
|
|
3068
|
+
sections.push(`
|
|
3069
|
+
<div class="context-group">
|
|
3070
|
+
<div class="section-label">Interfaces</div>
|
|
3071
|
+
<ul class="pill-list">
|
|
3072
|
+
${context.interfaces.map((i) => `<li class="pill">${escapeHtml2(i)}</li>`).join("")}
|
|
3073
|
+
</ul>
|
|
3074
|
+
</div>
|
|
3075
|
+
`);
|
|
3076
|
+
}
|
|
3077
|
+
if (context.keyImports !== void 0 && context.keyImports.length > 0) {
|
|
3078
|
+
sections.push(`
|
|
3079
|
+
<div class="context-group">
|
|
3080
|
+
<div class="section-label">Key Imports</div>
|
|
3081
|
+
<ul class="pill-list">
|
|
3082
|
+
${context.keyImports.map((i) => `<li class="pill">${escapeHtml2(i)}</li>`).join("")}
|
|
3083
|
+
</ul>
|
|
3084
|
+
</div>
|
|
3085
|
+
`);
|
|
3086
|
+
}
|
|
3087
|
+
if (context.relatedConcepts !== void 0 && context.relatedConcepts.length > 0) {
|
|
3088
|
+
sections.push(`
|
|
3089
|
+
<div class="context-group">
|
|
3090
|
+
<div class="section-label">Related Concepts</div>
|
|
3091
|
+
<ul class="pill-list">
|
|
3092
|
+
${context.relatedConcepts.map((c) => `<li class="pill">${escapeHtml2(c)}</li>`).join("")}
|
|
3093
|
+
</ul>
|
|
3094
|
+
</div>
|
|
3095
|
+
`);
|
|
3096
|
+
}
|
|
3097
|
+
if (context.usage !== void 0) {
|
|
3098
|
+
sections.push(`
|
|
3099
|
+
<div class="context-group">
|
|
3100
|
+
<div class="section-label">Usage</div>
|
|
3101
|
+
<div class="usage-stats">
|
|
3102
|
+
<span class="usage-stat">
|
|
3103
|
+
<span class="usage-value">${String(context.usage.calledBy)}</span>
|
|
3104
|
+
<span class="usage-label">called by</span>
|
|
3105
|
+
</span>
|
|
3106
|
+
<span class="usage-stat">
|
|
3107
|
+
<span class="usage-value">${String(context.usage.calls)}</span>
|
|
3108
|
+
<span class="usage-label">calls</span>
|
|
3109
|
+
</span>
|
|
3110
|
+
</div>
|
|
3111
|
+
</div>
|
|
3112
|
+
`);
|
|
3113
|
+
}
|
|
3114
|
+
return sections.join("");
|
|
3115
|
+
}
|
|
3116
|
+
function renderFullSection(full) {
|
|
3117
|
+
const sections = [];
|
|
3118
|
+
if (full.documentation !== void 0 && full.documentation.length > 0) {
|
|
3119
|
+
sections.push(`
|
|
3120
|
+
<div class="full-group">
|
|
3121
|
+
<div class="section-label">Documentation</div>
|
|
3122
|
+
<div class="documentation-text">${escapeHtml2(full.documentation)}</div>
|
|
3123
|
+
</div>
|
|
3124
|
+
`);
|
|
3125
|
+
}
|
|
3126
|
+
if (full.completeCode !== void 0 && full.completeCode.length > 0) {
|
|
3127
|
+
sections.push(`
|
|
3128
|
+
<div class="full-group">
|
|
3129
|
+
<div class="section-label">Source Code</div>
|
|
3130
|
+
<pre class="code-block"><code>${escapeHtml2(full.completeCode)}</code></pre>
|
|
3131
|
+
</div>
|
|
3132
|
+
`);
|
|
3133
|
+
}
|
|
3134
|
+
if (full.relatedCode !== void 0 && full.relatedCode.length > 0) {
|
|
3135
|
+
sections.push(`
|
|
3136
|
+
<div class="full-group">
|
|
3137
|
+
<div class="section-label">Related Code</div>
|
|
3138
|
+
<div class="related-code-list">
|
|
3139
|
+
${full.relatedCode.map(
|
|
3140
|
+
(rc) => `
|
|
3141
|
+
<div class="related-code-item">
|
|
3142
|
+
<div class="related-code-file mono">${escapeHtml2(rc.file)}</div>
|
|
3143
|
+
<div class="related-code-summary">${escapeHtml2(rc.summary)}</div>
|
|
3144
|
+
<div class="related-code-relationship">${escapeHtml2(rc.relationship)}</div>
|
|
3145
|
+
</div>
|
|
3146
|
+
`
|
|
3147
|
+
).join("")}
|
|
3148
|
+
</div>
|
|
3149
|
+
</div>
|
|
3150
|
+
`);
|
|
3151
|
+
}
|
|
3152
|
+
return sections.join("");
|
|
3153
|
+
}
|
|
3154
|
+
function renderResultCard(result, index) {
|
|
3155
|
+
const { summary, context, full } = result;
|
|
3156
|
+
const scorePercent = Math.round(result.score * 100);
|
|
3157
|
+
const scoreColor = getScoreColor(result.score);
|
|
3158
|
+
const scoreClass = getScoreClass(result.score);
|
|
3159
|
+
const hasContext = context !== void 0 && (context.interfaces !== void 0 && context.interfaces.length > 0 || context.keyImports !== void 0 && context.keyImports.length > 0 || context.relatedConcepts !== void 0 && context.relatedConcepts.length > 0 || context.usage !== void 0);
|
|
3160
|
+
const hasFull = full !== void 0 && (full.completeCode !== void 0 && full.completeCode.length > 0 || full.relatedCode !== void 0 && full.relatedCode.length > 0 || full.documentation !== void 0 && full.documentation.length > 0);
|
|
3161
|
+
const locationParts = summary.location?.split(":") ?? [];
|
|
3162
|
+
const fileName = locationParts[0] ?? "";
|
|
3163
|
+
const lineNum = locationParts[1] ?? "";
|
|
3164
|
+
return `
|
|
3165
|
+
<div class="result-card">
|
|
3166
|
+
<div class="result-header">
|
|
3167
|
+
<div class="result-rank">${String(index + 1)}</div>
|
|
3168
|
+
<div class="result-main">
|
|
3169
|
+
<div class="result-title-row">
|
|
3170
|
+
${summary.type !== void 0 ? getTypeIcon2(summary.type) : ""}
|
|
3171
|
+
<span class="result-name">${escapeHtml2(summary.name ?? "Unknown")}</span>
|
|
3172
|
+
<div class="score-bar-container">
|
|
3173
|
+
<div class="score-bar-track">
|
|
3174
|
+
<div class="score-bar-fill" style="width: ${String(scorePercent)}%; background: ${scoreColor}"></div>
|
|
3175
|
+
</div>
|
|
3176
|
+
<span class="score-label score-${scoreClass}">${String(scorePercent)}%</span>
|
|
3177
|
+
</div>
|
|
3178
|
+
</div>
|
|
3179
|
+
${summary.signature !== void 0 ? `<div class="result-signature mono">${escapeHtml2(summary.signature)}</div>` : ""}
|
|
3180
|
+
${summary.purpose !== void 0 ? `<p class="result-purpose">${escapeHtml2(summary.purpose)}</p>` : ""}
|
|
3181
|
+
<div class="result-meta meta-row">
|
|
3182
|
+
${fileName.length > 0 ? `<span class="result-location mono" title="${escapeHtml2(summary.location ?? "")}">
|
|
3183
|
+
${escapeHtml2(fileName)}${lineNum.length > 0 ? `<span class="line-number">:${escapeHtml2(lineNum)}</span>` : ""}
|
|
3184
|
+
</span>` : ""}
|
|
3185
|
+
${summary.storeName !== void 0 ? `<span class="meta-separator"></span>
|
|
3186
|
+
<span class="result-store">${escapeHtml2(summary.storeName)}</span>` : ""}
|
|
3187
|
+
</div>
|
|
3188
|
+
${summary.relevanceReason !== void 0 ? `<div class="result-relevance">${escapeHtml2(summary.relevanceReason)}</div>` : ""}
|
|
3189
|
+
</div>
|
|
3190
|
+
</div>
|
|
3191
|
+
${hasContext || hasFull ? `<details>
|
|
3192
|
+
<summary>${hasContext && hasFull ? "Context & Source Code" : hasContext ? "Context" : "Source Code"}</summary>
|
|
3193
|
+
<div class="details-content">
|
|
3194
|
+
${hasContext ? renderContextSection(context) : ""}
|
|
3195
|
+
${hasFull ? renderFullSection(full) : ""}
|
|
3196
|
+
</div>
|
|
3197
|
+
</details>` : ""}
|
|
3198
|
+
</div>
|
|
3199
|
+
`;
|
|
3200
|
+
}
|
|
3201
|
+
function renderStoresList(stores) {
|
|
3202
|
+
const entries = Object.entries(stores);
|
|
3203
|
+
if (entries.length === 0) return "";
|
|
3204
|
+
return entries.map(([name, info]) => {
|
|
3205
|
+
const badgeClass = info.type === "repo" ? "badge-repo" : info.type === "file" ? "badge-file" : "badge-web";
|
|
3206
|
+
const location = info.path ?? info.url ?? "";
|
|
3207
|
+
return `
|
|
3208
|
+
<span class="store-chip">
|
|
3209
|
+
<span class="badge ${badgeClass}" style="font-size: 10px; padding: 1px 6px;">${escapeHtml2(info.type)}</span>
|
|
3210
|
+
<span class="store-chip-name">${escapeHtml2(name)}</span>
|
|
3211
|
+
${location.length > 0 ? `<span class="store-chip-location mono truncate" title="${escapeHtml2(location)}">${escapeHtml2(location)}</span>` : ""}
|
|
3212
|
+
</span>
|
|
3213
|
+
`;
|
|
3214
|
+
}).join("");
|
|
3215
|
+
}
|
|
3216
|
+
function renderSearchResults(query, results, metadata) {
|
|
3217
|
+
const confidenceHtml = metadata.confidence !== void 0 ? `<span class="confidence-badge ${getConfidenceClass(metadata.confidence)}">${escapeHtml2(metadata.confidence)} confidence</span>` : "";
|
|
3218
|
+
const storesHtml = renderStoresList(metadata.stores);
|
|
3219
|
+
const contentHtml = results.length === 0 ? `<div class="empty-state">
|
|
3220
|
+
<div class="empty-state-title">No results found</div>
|
|
3221
|
+
<p>Try broadening your search query or checking different stores.</p>
|
|
3222
|
+
</div>` : `<div class="results-list">
|
|
3223
|
+
${results.map((result, index) => renderResultCard(result, index)).join("")}
|
|
3224
|
+
</div>`;
|
|
3225
|
+
return `<!DOCTYPE html>
|
|
3226
|
+
<html lang="en">
|
|
3227
|
+
<head>
|
|
3228
|
+
<meta charset="UTF-8">
|
|
3229
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3230
|
+
<title>Search Results</title>
|
|
3231
|
+
<style>
|
|
3232
|
+
${BASE_STYLES}
|
|
3233
|
+
|
|
3234
|
+
/* Search-specific styles */
|
|
3235
|
+
.search-header {
|
|
3236
|
+
background: var(--bg-secondary);
|
|
3237
|
+
border: 1px solid var(--border-primary);
|
|
3238
|
+
border-radius: var(--radius-lg);
|
|
3239
|
+
padding: var(--space-lg);
|
|
3240
|
+
margin-bottom: var(--space-xl);
|
|
3241
|
+
}
|
|
3242
|
+
|
|
3243
|
+
.search-query {
|
|
3244
|
+
font-size: var(--font-size-lg);
|
|
3245
|
+
font-weight: 600;
|
|
3246
|
+
color: var(--text-primary);
|
|
3247
|
+
margin-bottom: var(--space-md);
|
|
3248
|
+
display: flex;
|
|
3249
|
+
align-items: flex-start;
|
|
3250
|
+
gap: var(--space-sm);
|
|
3251
|
+
}
|
|
3252
|
+
|
|
3253
|
+
.search-query-icon {
|
|
3254
|
+
color: var(--text-tertiary);
|
|
3255
|
+
flex-shrink: 0;
|
|
3256
|
+
margin-top: 2px;
|
|
3257
|
+
}
|
|
3258
|
+
|
|
3259
|
+
.search-query-text {
|
|
3260
|
+
color: var(--accent-blue);
|
|
3261
|
+
word-break: break-word;
|
|
3262
|
+
}
|
|
3263
|
+
|
|
3264
|
+
.search-meta {
|
|
3265
|
+
display: flex;
|
|
3266
|
+
align-items: center;
|
|
3267
|
+
gap: var(--space-md);
|
|
3268
|
+
flex-wrap: wrap;
|
|
3269
|
+
font-size: var(--font-size-sm);
|
|
3270
|
+
color: var(--text-secondary);
|
|
3271
|
+
}
|
|
3272
|
+
|
|
3273
|
+
.search-meta-item {
|
|
3274
|
+
display: flex;
|
|
3275
|
+
align-items: center;
|
|
3276
|
+
gap: var(--space-xs);
|
|
3277
|
+
}
|
|
3278
|
+
|
|
3279
|
+
.confidence-badge {
|
|
3280
|
+
display: inline-flex;
|
|
3281
|
+
align-items: center;
|
|
3282
|
+
padding: 2px 8px;
|
|
3283
|
+
border-radius: 9999px;
|
|
3284
|
+
font-size: var(--font-size-xs);
|
|
3285
|
+
font-weight: 500;
|
|
3286
|
+
text-transform: capitalize;
|
|
3287
|
+
}
|
|
3288
|
+
|
|
3289
|
+
.confidence-high {
|
|
3290
|
+
background: var(--confidence-high-bg);
|
|
3291
|
+
color: var(--confidence-high-text);
|
|
3292
|
+
}
|
|
3293
|
+
|
|
3294
|
+
.confidence-medium {
|
|
3295
|
+
background: var(--confidence-medium-bg);
|
|
3296
|
+
color: var(--confidence-medium-text);
|
|
3297
|
+
}
|
|
3298
|
+
|
|
3299
|
+
.confidence-low {
|
|
3300
|
+
background: var(--confidence-low-bg);
|
|
3301
|
+
color: var(--confidence-low-text);
|
|
3302
|
+
}
|
|
3303
|
+
|
|
3304
|
+
.stores-searched {
|
|
3305
|
+
display: flex;
|
|
3306
|
+
flex-wrap: wrap;
|
|
3307
|
+
gap: var(--space-sm);
|
|
3308
|
+
margin-top: var(--space-md);
|
|
3309
|
+
padding-top: var(--space-md);
|
|
3310
|
+
border-top: 1px solid var(--border-secondary);
|
|
3311
|
+
}
|
|
3312
|
+
|
|
3313
|
+
.stores-searched-label {
|
|
3314
|
+
font-size: var(--font-size-xs);
|
|
3315
|
+
color: var(--text-tertiary);
|
|
3316
|
+
text-transform: uppercase;
|
|
3317
|
+
letter-spacing: 0.05em;
|
|
3318
|
+
width: 100%;
|
|
3319
|
+
margin-bottom: var(--space-xs);
|
|
3320
|
+
}
|
|
3321
|
+
|
|
3322
|
+
.store-chip {
|
|
3323
|
+
display: inline-flex;
|
|
3324
|
+
align-items: center;
|
|
3325
|
+
gap: var(--space-xs);
|
|
3326
|
+
padding: var(--space-xs) var(--space-sm);
|
|
3327
|
+
background: var(--bg-tertiary);
|
|
3328
|
+
border: 1px solid var(--border-secondary);
|
|
3329
|
+
border-radius: var(--radius-md);
|
|
3330
|
+
font-size: var(--font-size-sm);
|
|
3331
|
+
}
|
|
3332
|
+
|
|
3333
|
+
.store-chip-name {
|
|
3334
|
+
color: var(--text-primary);
|
|
3335
|
+
font-weight: 500;
|
|
3336
|
+
}
|
|
3337
|
+
|
|
3338
|
+
.store-chip-location {
|
|
3339
|
+
color: var(--text-tertiary);
|
|
3340
|
+
font-size: var(--font-size-xs);
|
|
3341
|
+
max-width: 200px;
|
|
3342
|
+
}
|
|
3343
|
+
|
|
3344
|
+
/* Results list */
|
|
3345
|
+
.results-list {
|
|
3346
|
+
display: flex;
|
|
3347
|
+
flex-direction: column;
|
|
3348
|
+
gap: var(--space-md);
|
|
3349
|
+
}
|
|
3350
|
+
|
|
3351
|
+
.result-card {
|
|
3352
|
+
background: var(--bg-card);
|
|
3353
|
+
border: 1px solid var(--border-primary);
|
|
3354
|
+
border-radius: var(--radius-lg);
|
|
3355
|
+
overflow: hidden;
|
|
3356
|
+
transition: border-color var(--transition-normal);
|
|
3357
|
+
}
|
|
3358
|
+
|
|
3359
|
+
.result-card:hover {
|
|
3360
|
+
border-color: rgba(88, 166, 255, 0.3);
|
|
3361
|
+
}
|
|
3362
|
+
|
|
3363
|
+
.result-header {
|
|
3364
|
+
display: flex;
|
|
3365
|
+
gap: var(--space-md);
|
|
3366
|
+
padding: var(--space-lg);
|
|
3367
|
+
}
|
|
3368
|
+
|
|
3369
|
+
.result-rank {
|
|
3370
|
+
flex-shrink: 0;
|
|
3371
|
+
width: 28px;
|
|
3372
|
+
height: 28px;
|
|
3373
|
+
display: flex;
|
|
3374
|
+
align-items: center;
|
|
3375
|
+
justify-content: center;
|
|
3376
|
+
background: var(--bg-tertiary);
|
|
3377
|
+
border: 1px solid var(--border-secondary);
|
|
3378
|
+
border-radius: var(--radius-sm);
|
|
3379
|
+
font-size: var(--font-size-sm);
|
|
3380
|
+
font-weight: 600;
|
|
3381
|
+
color: var(--text-tertiary);
|
|
3382
|
+
font-family: var(--font-mono);
|
|
3383
|
+
}
|
|
3384
|
+
|
|
3385
|
+
.result-main {
|
|
3386
|
+
flex: 1;
|
|
3387
|
+
min-width: 0;
|
|
3388
|
+
}
|
|
3389
|
+
|
|
3390
|
+
.result-title-row {
|
|
3391
|
+
display: flex;
|
|
3392
|
+
align-items: center;
|
|
3393
|
+
gap: var(--space-sm);
|
|
3394
|
+
margin-bottom: var(--space-xs);
|
|
3395
|
+
}
|
|
3396
|
+
|
|
3397
|
+
.type-icon {
|
|
3398
|
+
display: inline-flex;
|
|
3399
|
+
align-items: center;
|
|
3400
|
+
justify-content: center;
|
|
3401
|
+
width: 22px;
|
|
3402
|
+
height: 22px;
|
|
3403
|
+
border-radius: var(--radius-sm);
|
|
3404
|
+
font-size: 11px;
|
|
3405
|
+
font-weight: 700;
|
|
3406
|
+
font-family: var(--font-mono);
|
|
3407
|
+
flex-shrink: 0;
|
|
3408
|
+
}
|
|
3409
|
+
|
|
3410
|
+
.type-fn { background: rgba(88, 166, 255, 0.15); color: var(--accent-blue); }
|
|
3411
|
+
.type-class { background: rgba(210, 153, 34, 0.15); color: var(--accent-orange); }
|
|
3412
|
+
.type-iface { background: rgba(57, 210, 192, 0.15); color: var(--accent-cyan); }
|
|
3413
|
+
.type-type { background: rgba(188, 140, 255, 0.15); color: var(--accent-purple); }
|
|
3414
|
+
.type-const { background: rgba(63, 185, 80, 0.15); color: var(--accent-green); }
|
|
3415
|
+
.type-doc { background: rgba(139, 148, 158, 0.15); color: var(--text-secondary); }
|
|
3416
|
+
.type-example { background: rgba(247, 120, 186, 0.15); color: var(--accent-pink); }
|
|
3417
|
+
.type-default { background: rgba(139, 148, 158, 0.1); color: var(--text-tertiary); }
|
|
3418
|
+
|
|
3419
|
+
.result-name {
|
|
3420
|
+
font-size: var(--font-size-md);
|
|
3421
|
+
font-weight: 600;
|
|
3422
|
+
color: var(--text-primary);
|
|
3423
|
+
font-family: var(--font-mono);
|
|
3424
|
+
flex: 1;
|
|
3425
|
+
min-width: 0;
|
|
3426
|
+
overflow: hidden;
|
|
3427
|
+
text-overflow: ellipsis;
|
|
3428
|
+
white-space: nowrap;
|
|
3429
|
+
}
|
|
3430
|
+
|
|
3431
|
+
.result-signature {
|
|
3432
|
+
color: var(--text-secondary);
|
|
3433
|
+
margin-bottom: var(--space-sm);
|
|
3434
|
+
font-size: var(--font-size-sm);
|
|
3435
|
+
line-height: 1.4;
|
|
3436
|
+
overflow-x: auto;
|
|
3437
|
+
white-space: pre-wrap;
|
|
3438
|
+
word-break: break-all;
|
|
3439
|
+
}
|
|
3440
|
+
|
|
3441
|
+
.result-purpose {
|
|
3442
|
+
color: var(--text-secondary);
|
|
3443
|
+
font-size: var(--font-size-sm);
|
|
3444
|
+
margin-bottom: var(--space-sm);
|
|
3445
|
+
line-height: 1.5;
|
|
3446
|
+
}
|
|
3447
|
+
|
|
3448
|
+
.result-meta {
|
|
3449
|
+
margin-bottom: var(--space-xs);
|
|
3450
|
+
}
|
|
3451
|
+
|
|
3452
|
+
.result-location {
|
|
3453
|
+
color: var(--text-tertiary);
|
|
3454
|
+
font-size: var(--font-size-sm);
|
|
3455
|
+
}
|
|
3456
|
+
|
|
3457
|
+
.line-number {
|
|
3458
|
+
color: var(--accent-blue);
|
|
3459
|
+
}
|
|
3460
|
+
|
|
3461
|
+
.result-store {
|
|
3462
|
+
font-size: var(--font-size-sm);
|
|
3463
|
+
color: var(--text-tertiary);
|
|
3464
|
+
}
|
|
3465
|
+
|
|
3466
|
+
.result-relevance {
|
|
3467
|
+
font-size: var(--font-size-sm);
|
|
3468
|
+
color: var(--text-secondary);
|
|
3469
|
+
font-style: italic;
|
|
3470
|
+
margin-top: var(--space-xs);
|
|
3471
|
+
padding-left: var(--space-md);
|
|
3472
|
+
border-left: 2px solid var(--border-secondary);
|
|
3473
|
+
}
|
|
3474
|
+
|
|
3475
|
+
.score-high { color: var(--score-high); }
|
|
3476
|
+
.score-medium { color: var(--score-medium); }
|
|
3477
|
+
.score-low { color: var(--score-low); }
|
|
3478
|
+
|
|
3479
|
+
/* Context & Full sections inside details */
|
|
3480
|
+
.result-card details {
|
|
3481
|
+
margin: 0;
|
|
3482
|
+
border-top: 1px solid var(--border-secondary);
|
|
3483
|
+
}
|
|
3484
|
+
|
|
3485
|
+
.result-card details summary {
|
|
3486
|
+
padding: var(--space-sm) var(--space-lg);
|
|
3487
|
+
font-weight: 500;
|
|
3488
|
+
}
|
|
3489
|
+
|
|
3490
|
+
.result-card .details-content {
|
|
3491
|
+
padding: 0 var(--space-lg) var(--space-lg);
|
|
3492
|
+
}
|
|
3493
|
+
|
|
3494
|
+
.context-group,
|
|
3495
|
+
.full-group {
|
|
3496
|
+
margin-bottom: var(--space-md);
|
|
3497
|
+
}
|
|
3498
|
+
|
|
3499
|
+
.context-group:last-child,
|
|
3500
|
+
.full-group:last-child {
|
|
3501
|
+
margin-bottom: 0;
|
|
3502
|
+
}
|
|
3503
|
+
|
|
3504
|
+
.usage-stats {
|
|
3505
|
+
display: flex;
|
|
3506
|
+
gap: var(--space-lg);
|
|
3507
|
+
}
|
|
3508
|
+
|
|
3509
|
+
.usage-stat {
|
|
3510
|
+
display: flex;
|
|
3511
|
+
align-items: baseline;
|
|
3512
|
+
gap: var(--space-xs);
|
|
3513
|
+
}
|
|
3514
|
+
|
|
3515
|
+
.usage-value {
|
|
3516
|
+
font-size: var(--font-size-lg);
|
|
3517
|
+
font-weight: 700;
|
|
3518
|
+
font-family: var(--font-mono);
|
|
3519
|
+
color: var(--text-primary);
|
|
3520
|
+
}
|
|
3521
|
+
|
|
3522
|
+
.usage-label {
|
|
3523
|
+
font-size: var(--font-size-xs);
|
|
3524
|
+
color: var(--text-tertiary);
|
|
3525
|
+
}
|
|
3526
|
+
|
|
3527
|
+
.documentation-text {
|
|
3528
|
+
font-size: var(--font-size-sm);
|
|
3529
|
+
color: var(--text-secondary);
|
|
3530
|
+
line-height: 1.6;
|
|
3531
|
+
white-space: pre-wrap;
|
|
3532
|
+
}
|
|
3533
|
+
|
|
3534
|
+
.related-code-list {
|
|
3535
|
+
display: flex;
|
|
3536
|
+
flex-direction: column;
|
|
3537
|
+
gap: var(--space-sm);
|
|
3538
|
+
}
|
|
3539
|
+
|
|
3540
|
+
.related-code-item {
|
|
3541
|
+
padding: var(--space-sm) var(--space-md);
|
|
3542
|
+
background: var(--bg-inset);
|
|
3543
|
+
border: 1px solid var(--border-secondary);
|
|
3544
|
+
border-radius: var(--radius-md);
|
|
3545
|
+
}
|
|
3546
|
+
|
|
3547
|
+
.related-code-file {
|
|
3548
|
+
font-size: var(--font-size-sm);
|
|
3549
|
+
color: var(--accent-blue);
|
|
3550
|
+
margin-bottom: 2px;
|
|
3551
|
+
}
|
|
3552
|
+
|
|
3553
|
+
.related-code-summary {
|
|
3554
|
+
font-size: var(--font-size-sm);
|
|
3555
|
+
color: var(--text-primary);
|
|
3556
|
+
}
|
|
3557
|
+
|
|
3558
|
+
.related-code-relationship {
|
|
3559
|
+
font-size: var(--font-size-xs);
|
|
3560
|
+
color: var(--text-tertiary);
|
|
3561
|
+
font-style: italic;
|
|
3562
|
+
margin-top: 2px;
|
|
3563
|
+
}
|
|
3564
|
+
|
|
3565
|
+
/* Code block inside result cards \u2014 tighter fit */
|
|
3566
|
+
.result-card .code-block {
|
|
3567
|
+
max-height: 400px;
|
|
3568
|
+
overflow-y: auto;
|
|
3569
|
+
font-size: var(--font-size-sm);
|
|
3570
|
+
}
|
|
3571
|
+
|
|
3572
|
+
/* Scrollbar styling for code blocks */
|
|
3573
|
+
.code-block::-webkit-scrollbar {
|
|
3574
|
+
width: 6px;
|
|
3575
|
+
height: 6px;
|
|
3576
|
+
}
|
|
3577
|
+
|
|
3578
|
+
.code-block::-webkit-scrollbar-track {
|
|
3579
|
+
background: transparent;
|
|
3580
|
+
}
|
|
3581
|
+
|
|
3582
|
+
.code-block::-webkit-scrollbar-thumb {
|
|
3583
|
+
background: var(--border-primary);
|
|
3584
|
+
border-radius: 3px;
|
|
3585
|
+
}
|
|
3586
|
+
|
|
3587
|
+
.code-block::-webkit-scrollbar-thumb:hover {
|
|
3588
|
+
background: var(--text-tertiary);
|
|
3589
|
+
}
|
|
3590
|
+
</style>
|
|
3591
|
+
</head>
|
|
3592
|
+
<body>
|
|
3593
|
+
<div class="container">
|
|
3594
|
+
<div class="search-header">
|
|
3595
|
+
<div class="search-query">
|
|
3596
|
+
<span class="search-query-icon">
|
|
3597
|
+
<svg width="18" height="18" viewBox="0 0 16 16" fill="currentColor"><path d="M10.68 11.74a6 6 0 01-7.922-8.982 6 6 0 018.982 7.922l3.04 3.04a.749.749 0 01-.326 1.275.749.749 0 01-.734-.215l-3.04-3.04zM11.5 7a4.499 4.499 0 10-8.997 0A4.499 4.499 0 0011.5 7z"/></svg>
|
|
3598
|
+
</span>
|
|
3599
|
+
<span class="search-query-text">${escapeHtml2(query)}</span>
|
|
3600
|
+
</div>
|
|
3601
|
+
<div class="search-meta">
|
|
3602
|
+
<span class="search-meta-item">
|
|
3603
|
+
<strong>${String(results.length)}</strong> result${results.length !== 1 ? "s" : ""}
|
|
3604
|
+
</span>
|
|
3605
|
+
<span class="meta-separator"></span>
|
|
3606
|
+
<span class="search-meta-item">${String(metadata.timeMs)}ms</span>
|
|
3607
|
+
<span class="meta-separator"></span>
|
|
3608
|
+
<span class="search-meta-item">${escapeHtml2(metadata.mode)} mode</span>
|
|
3609
|
+
${confidenceHtml.length > 0 ? `<span class="meta-separator"></span>${confidenceHtml}` : ""}
|
|
3610
|
+
</div>
|
|
3611
|
+
${storesHtml.length > 0 ? `<div class="stores-searched">
|
|
3612
|
+
<span class="stores-searched-label">Stores Searched</span>
|
|
3613
|
+
${storesHtml}
|
|
3614
|
+
</div>` : ""}
|
|
3615
|
+
</div>
|
|
3616
|
+
${contentHtml}
|
|
3617
|
+
</div>
|
|
3618
|
+
</body>
|
|
3619
|
+
</html>`;
|
|
3620
|
+
}
|
|
3621
|
+
|
|
2297
3622
|
// src/mcp/handlers/search.handler.ts
|
|
2298
3623
|
var logger10 = createLogger("mcp-search");
|
|
2299
3624
|
var resultCache = new LRUCache(1e3);
|
|
@@ -2471,14 +3796,22 @@ var handleSearch = async (args, context) => {
|
|
|
2471
3796
|
},
|
|
2472
3797
|
"Search complete - context sent to Claude Code"
|
|
2473
3798
|
);
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
3799
|
+
const textContent = { type: "text", text: header + responseJson };
|
|
3800
|
+
const uiResource = createUIResource2({
|
|
3801
|
+
uri: `ui://bk/search/${encodeURIComponent(validated.query)}`,
|
|
3802
|
+
content: {
|
|
3803
|
+
type: "rawHtml",
|
|
3804
|
+
htmlString: renderSearchResults(validated.query, enhancedResults, {
|
|
3805
|
+
timeMs: results.timeMs,
|
|
3806
|
+
confidence: results.confidence,
|
|
3807
|
+
mode: results.mode,
|
|
3808
|
+
stores: storeMap
|
|
3809
|
+
})
|
|
3810
|
+
},
|
|
3811
|
+
encoding: "text"
|
|
3812
|
+
});
|
|
3813
|
+
const content = [textContent, uiResource];
|
|
3814
|
+
return { content };
|
|
2482
3815
|
};
|
|
2483
3816
|
var handleGetFullContext = async (args, context) => {
|
|
2484
3817
|
const validated = GetFullContextArgsSchema.parse(args);
|
|
@@ -2683,13 +4016,24 @@ function createMCPServer(options, services) {
|
|
|
2683
4016
|
}
|
|
2684
4017
|
}
|
|
2685
4018
|
);
|
|
2686
|
-
server.setRequestHandler(ListToolsRequestSchema, () => {
|
|
2687
|
-
|
|
4019
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
4020
|
+
let storeHint = "";
|
|
4021
|
+
try {
|
|
4022
|
+
const stores = await services.store.list();
|
|
4023
|
+
if (stores.length > 0) {
|
|
4024
|
+
const cap = 3;
|
|
4025
|
+
const names = stores.slice(0, cap).map((s) => s.name).join(", ");
|
|
4026
|
+
const overflow = stores.length > cap ? ` (+${String(stores.length - cap)} more)` : "";
|
|
4027
|
+
storeHint = ` Currently indexed: ${names}${overflow}.`;
|
|
4028
|
+
}
|
|
4029
|
+
} catch {
|
|
4030
|
+
}
|
|
4031
|
+
return {
|
|
2688
4032
|
tools: [
|
|
2689
4033
|
// Native search tool with full schema (most used, benefits from detailed params)
|
|
2690
4034
|
{
|
|
2691
4035
|
name: "search",
|
|
2692
|
-
description:
|
|
4036
|
+
description: `Search indexed library source code, documentation, and API references.${storeHint} You MUST use this tool to look up library/dependency details BEFORE relying on training data or grepping node_modules/vendor directories. Use whenever a question involves a third-party library, framework, or dependency. Returns structured code units with progressive context layers.`,
|
|
2693
4037
|
inputSchema: {
|
|
2694
4038
|
type: "object",
|
|
2695
4039
|
properties: {
|
|
@@ -2785,7 +4129,7 @@ function createMCPServer(options, services) {
|
|
|
2785
4129
|
}
|
|
2786
4130
|
}
|
|
2787
4131
|
]
|
|
2788
|
-
}
|
|
4132
|
+
};
|
|
2789
4133
|
});
|
|
2790
4134
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
2791
4135
|
const { name, arguments: args } = request.params;
|
|
@@ -2881,4 +4225,4 @@ export {
|
|
|
2881
4225
|
createMCPServer,
|
|
2882
4226
|
runMCPServer
|
|
2883
4227
|
};
|
|
2884
|
-
//# sourceMappingURL=chunk-
|
|
4228
|
+
//# sourceMappingURL=chunk-AO45YFHO.js.map
|