bluera-knowledge 0.31.0 → 0.32.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 +24 -0
- package/.mcp.json +13 -0
- package/CHANGELOG.md +20 -0
- package/NOTICE +47 -0
- package/README.md +2 -2
- package/bun.lock +1978 -0
- package/commands/add-folder.md +48 -0
- package/commands/add-repo.md +50 -0
- package/commands/cancel.md +63 -0
- package/commands/check-status.md +130 -0
- package/commands/crawl.md +61 -0
- package/commands/doctor.md +27 -0
- package/commands/eval.md +222 -0
- package/commands/health.md +72 -0
- package/commands/index.md +48 -0
- package/commands/remove-store.md +52 -0
- package/commands/search.md +80 -0
- package/commands/search.sh +63 -0
- package/commands/skill-activation.md +131 -0
- package/commands/stores.md +54 -0
- package/commands/suggest.md +118 -0
- package/commands/sync.md +96 -0
- package/commands/test-plugin.md +547 -0
- package/commands/uninstall.md +65 -0
- package/dist/{chunk-B335UOU7.js → chunk-3TB7TDVF.js} +24 -3
- package/dist/chunk-3TB7TDVF.js.map +1 -0
- package/dist/{chunk-KCI4U6FH.js → chunk-KDZDLJUY.js} +2 -2
- package/dist/{chunk-AEXFPA57.js → chunk-YDTTD53Y.js} +158 -26
- package/dist/chunk-YDTTD53Y.js.map +1 -0
- package/dist/index.js +3 -3
- package/dist/mcp/bootstrap.js +10 -0
- package/dist/mcp/bootstrap.js.map +1 -1
- package/dist/mcp/server.d.ts +5 -3
- package/dist/mcp/server.js +2 -2
- package/dist/workers/background-worker-cli.js +2 -2
- package/hooks/check-ready.sh +109 -0
- package/hooks/hooks.json +87 -0
- package/hooks/job-status-hook.sh +51 -0
- package/hooks/posttooluse-bk-reminder.py +126 -0
- package/hooks/posttooluse-web-research.py +209 -0
- package/hooks/pretooluse-bk-suggest.py +296 -0
- package/hooks/skill-activation.py +221 -0
- package/hooks/skill-rules.json +131 -0
- package/package.json +10 -2
- package/scripts/CLAUDE.md +65 -0
- package/scripts/auto-setup.sh +65 -0
- package/scripts/bench-regression.sh +345 -0
- package/scripts/dev.sh +16 -0
- package/scripts/doctor.sh +103 -0
- package/scripts/download-models.ts +188 -0
- package/scripts/export-web-store.ts +142 -0
- package/scripts/lib/mock-server.sh +70 -0
- package/scripts/mcp-wrapper.sh +91 -0
- package/scripts/setup.sh +224 -0
- package/scripts/test-mcp-dev.js +260 -0
- package/scripts/validate-local.sh +412 -0
- package/scripts/validate-npm-release.sh +406 -0
- package/skills/advanced-workflows/SKILL.md +273 -0
- package/skills/knowledge-search/SKILL.md +110 -0
- package/skills/search-optimization/SKILL.md +199 -0
- package/skills/search-optimization/references/mistakes.md +21 -0
- package/skills/search-optimization/references/strategies.md +80 -0
- package/skills/store-lifecycle/SKILL.md +470 -0
- package/skills/when-to-query/SKILL.md +160 -0
- package/dist/chunk-AEXFPA57.js.map +0 -1
- package/dist/chunk-B335UOU7.js.map +0 -1
- /package/dist/{chunk-KCI4U6FH.js.map → chunk-KDZDLJUY.js.map} +0 -0
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
createLogger,
|
|
3
3
|
summarizePayload,
|
|
4
4
|
truncateForLog
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-3TB7TDVF.js";
|
|
6
6
|
|
|
7
7
|
// src/crawl/intelligent-crawler.ts
|
|
8
8
|
import { EventEmitter } from "events";
|
|
@@ -916,4 +916,4 @@ export {
|
|
|
916
916
|
getCrawlStrategy,
|
|
917
917
|
IntelligentCrawler
|
|
918
918
|
};
|
|
919
|
-
//# sourceMappingURL=chunk-
|
|
919
|
+
//# sourceMappingURL=chunk-KDZDLJUY.js.map
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
isWebStoreDefinition,
|
|
13
13
|
ok,
|
|
14
14
|
summarizePayload
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-3TB7TDVF.js";
|
|
16
16
|
import {
|
|
17
17
|
DEFAULT_IGNORE_DIRS,
|
|
18
18
|
checkStoreModelCompatibility
|
|
@@ -656,7 +656,8 @@ var SearchArgsSchema = z.object({
|
|
|
656
656
|
"find-implementation",
|
|
657
657
|
"find-usage",
|
|
658
658
|
"find-definition",
|
|
659
|
-
"find-documentation"
|
|
659
|
+
"find-documentation",
|
|
660
|
+
"find-files"
|
|
660
661
|
]).optional(),
|
|
661
662
|
mode: z.enum(["vector", "fts", "hybrid"]).default("hybrid"),
|
|
662
663
|
detail: z.enum(["minimal", "contextual", "full"]).default("minimal"),
|
|
@@ -666,7 +667,11 @@ var SearchArgsSchema = z.object({
|
|
|
666
667
|
minRelevance: z.number().min(0, "minRelevance must be between 0 and 1").max(1, "minRelevance must be between 0 and 1").optional()
|
|
667
668
|
});
|
|
668
669
|
var GetFullContextArgsSchema = z.object({
|
|
669
|
-
resultId: z.string().min(1, "Result ID must be a non-empty string")
|
|
670
|
+
resultId: z.string().min(1, "Result ID must be a non-empty string").optional(),
|
|
671
|
+
file: z.string().min(1, "File path must be a non-empty string").optional(),
|
|
672
|
+
store: z.string().min(1, "Store name or ID").optional()
|
|
673
|
+
}).refine((data) => data.resultId !== void 0 || data.file !== void 0, {
|
|
674
|
+
message: "Either resultId or file must be provided"
|
|
670
675
|
});
|
|
671
676
|
var ListStoresArgsSchema = z.object({
|
|
672
677
|
type: z.enum(["file", "repo", "web"]).optional()
|
|
@@ -2242,7 +2247,14 @@ var LRUCache = class {
|
|
|
2242
2247
|
var logger10 = createLogger("mcp-search");
|
|
2243
2248
|
var resultCache = new LRUCache(1e3);
|
|
2244
2249
|
var handleSearch = async (args, context) => {
|
|
2245
|
-
|
|
2250
|
+
let validated = SearchArgsSchema.parse(args);
|
|
2251
|
+
if (validated.intent === "find-files") {
|
|
2252
|
+
validated = {
|
|
2253
|
+
...validated,
|
|
2254
|
+
detail: "minimal",
|
|
2255
|
+
...validated.limit === 10 ? { limit: 20 } : {}
|
|
2256
|
+
};
|
|
2257
|
+
}
|
|
2246
2258
|
logger10.info(
|
|
2247
2259
|
{
|
|
2248
2260
|
query: validated.query,
|
|
@@ -2310,24 +2322,73 @@ var handleSearch = async (args, context) => {
|
|
|
2310
2322
|
for (const result of results.results) {
|
|
2311
2323
|
resultCache.set(result.id, result);
|
|
2312
2324
|
}
|
|
2313
|
-
const
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2325
|
+
const storeById = /* @__PURE__ */ new Map();
|
|
2326
|
+
const uniqueStoreIds = new Set(results.results.map((r) => r.metadata.storeId));
|
|
2327
|
+
for (const storeId of uniqueStoreIds) {
|
|
2328
|
+
const store = await services.store.getByIdOrName(storeId);
|
|
2329
|
+
if (store) storeById.set(storeId, store);
|
|
2330
|
+
}
|
|
2331
|
+
const storeMap = {};
|
|
2332
|
+
for (const store of storeById.values()) {
|
|
2333
|
+
storeMap[store.name] = {
|
|
2334
|
+
type: store.type,
|
|
2335
|
+
..."path" in store ? { path: store.path } : {},
|
|
2336
|
+
..."url" in store && store.url !== void 0 ? { url: store.url } : {}
|
|
2337
|
+
};
|
|
2338
|
+
}
|
|
2339
|
+
const enhancedResults = results.results.map((r) => {
|
|
2340
|
+
const store = storeById.get(r.metadata.storeId);
|
|
2341
|
+
return {
|
|
2342
|
+
id: r.id,
|
|
2343
|
+
score: r.score,
|
|
2344
|
+
summary: {
|
|
2345
|
+
...r.summary,
|
|
2346
|
+
storeName: store?.name,
|
|
2347
|
+
repoRoot: store?.type === "repo" ? store.path : void 0
|
|
2348
|
+
},
|
|
2349
|
+
context: r.context,
|
|
2350
|
+
full: r.full
|
|
2351
|
+
};
|
|
2352
|
+
});
|
|
2353
|
+
if (validated.intent === "find-files") {
|
|
2354
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2355
|
+
const files = enhancedResults.filter((r) => {
|
|
2356
|
+
const loc = r.summary.location?.split(":")[0] ?? "";
|
|
2357
|
+
if (seen.has(loc)) return false;
|
|
2358
|
+
seen.add(loc);
|
|
2359
|
+
return true;
|
|
2360
|
+
}).map((r) => ({
|
|
2361
|
+
location: r.summary.location,
|
|
2362
|
+
name: r.summary.name,
|
|
2363
|
+
type: r.summary.type,
|
|
2364
|
+
score: r.score
|
|
2365
|
+
}));
|
|
2366
|
+
const findFilesData = {
|
|
2367
|
+
files,
|
|
2368
|
+
stores: storeMap,
|
|
2369
|
+
totalResults: files.length,
|
|
2370
|
+
timeMs: results.timeMs
|
|
2371
|
+
};
|
|
2372
|
+
const findFilesJson = JSON.stringify(findFilesData, null, 2);
|
|
2373
|
+
const findFilesTokens = estimateTokens(findFilesJson);
|
|
2374
|
+
const findFilesHeader = `Find files: "${validated.query}" | Files: ${String(files.length)} | ${formatTokenCount(findFilesTokens)} tokens | ${String(results.timeMs)}ms
|
|
2375
|
+
|
|
2376
|
+
`;
|
|
2377
|
+
logger10.info(
|
|
2378
|
+
{
|
|
2379
|
+
query: validated.query,
|
|
2380
|
+
totalFiles: files.length,
|
|
2381
|
+
responseTokens: findFilesTokens,
|
|
2382
|
+
timeMs: results.timeMs
|
|
2383
|
+
},
|
|
2384
|
+
"Find-files search complete"
|
|
2385
|
+
);
|
|
2386
|
+
return {
|
|
2387
|
+
content: [{ type: "text", text: findFilesHeader + findFilesJson }]
|
|
2388
|
+
};
|
|
2389
|
+
}
|
|
2330
2390
|
const responseData = {
|
|
2391
|
+
stores: storeMap,
|
|
2331
2392
|
results: enhancedResults,
|
|
2332
2393
|
totalResults: results.totalResults,
|
|
2333
2394
|
mode: results.mode,
|
|
@@ -2370,6 +2431,70 @@ var handleSearch = async (args, context) => {
|
|
|
2370
2431
|
};
|
|
2371
2432
|
var handleGetFullContext = async (args, context) => {
|
|
2372
2433
|
const validated = GetFullContextArgsSchema.parse(args);
|
|
2434
|
+
const { services } = context;
|
|
2435
|
+
if (validated.file !== void 0) {
|
|
2436
|
+
const filePath = validated.file;
|
|
2437
|
+
logger10.info({ file: filePath, store: validated.store }, "Get full context by file path");
|
|
2438
|
+
let targetStores;
|
|
2439
|
+
if (validated.store !== void 0) {
|
|
2440
|
+
const store2 = await services.store.getByIdOrName(validated.store);
|
|
2441
|
+
if (!store2) throw new Error(`Store not found: ${validated.store}`);
|
|
2442
|
+
targetStores = [store2];
|
|
2443
|
+
} else {
|
|
2444
|
+
targetStores = await services.store.list();
|
|
2445
|
+
}
|
|
2446
|
+
const currentModelId = services.store.getCurrentModelId();
|
|
2447
|
+
const compatible = targetStores.filter(
|
|
2448
|
+
(s) => checkStoreModelCompatibility(s, { currentModelId }).compatible
|
|
2449
|
+
);
|
|
2450
|
+
if (compatible.length === 0) {
|
|
2451
|
+
throw new Error("No compatible stores found");
|
|
2452
|
+
}
|
|
2453
|
+
services.lance.setDimensions(await services.embeddings.ensureDimensions());
|
|
2454
|
+
for (const s of compatible) {
|
|
2455
|
+
await services.lance.initialize(s.id);
|
|
2456
|
+
}
|
|
2457
|
+
const fileResults = await services.search.search({
|
|
2458
|
+
query: filePath,
|
|
2459
|
+
stores: compatible.map((s) => s.id),
|
|
2460
|
+
mode: "fts",
|
|
2461
|
+
limit: 5,
|
|
2462
|
+
detail: "full"
|
|
2463
|
+
});
|
|
2464
|
+
const matching = fileResults.results.filter(
|
|
2465
|
+
(r) => r.metadata.path?.includes(filePath) === true
|
|
2466
|
+
);
|
|
2467
|
+
if (matching.length === 0) {
|
|
2468
|
+
throw new Error(`No indexed content found for file: ${filePath}`);
|
|
2469
|
+
}
|
|
2470
|
+
for (const r of matching) {
|
|
2471
|
+
resultCache.set(r.id, r);
|
|
2472
|
+
}
|
|
2473
|
+
const responseJson2 = JSON.stringify(
|
|
2474
|
+
{
|
|
2475
|
+
results: matching.map((r) => ({
|
|
2476
|
+
id: r.id,
|
|
2477
|
+
score: r.score,
|
|
2478
|
+
summary: r.summary,
|
|
2479
|
+
context: r.context,
|
|
2480
|
+
full: r.full
|
|
2481
|
+
}))
|
|
2482
|
+
},
|
|
2483
|
+
null,
|
|
2484
|
+
2
|
|
2485
|
+
);
|
|
2486
|
+
logger10.info(
|
|
2487
|
+
{
|
|
2488
|
+
file: filePath,
|
|
2489
|
+
resultCount: matching.length,
|
|
2490
|
+
...summarizePayload(responseJson2, "mcp-full-context-file", filePath)
|
|
2491
|
+
},
|
|
2492
|
+
"Full context retrieved by file path"
|
|
2493
|
+
);
|
|
2494
|
+
return {
|
|
2495
|
+
content: [{ type: "text", text: responseJson2 }]
|
|
2496
|
+
};
|
|
2497
|
+
}
|
|
2373
2498
|
logger10.info({ resultId: validated.resultId }, "Get full context requested");
|
|
2374
2499
|
const resultId = validated.resultId;
|
|
2375
2500
|
const cachedResult = resultCache.get(resultId);
|
|
@@ -2406,7 +2531,6 @@ var handleGetFullContext = async (args, context) => {
|
|
|
2406
2531
|
]
|
|
2407
2532
|
};
|
|
2408
2533
|
}
|
|
2409
|
-
const { services } = context;
|
|
2410
2534
|
const store = await services.store.getByIdOrName(cachedResult.metadata.storeId);
|
|
2411
2535
|
if (!store) {
|
|
2412
2536
|
throw new Error(`Store not found: ${cachedResult.metadata.storeId}`);
|
|
@@ -2529,7 +2653,8 @@ function createMCPServer(options, services) {
|
|
|
2529
2653
|
"find-implementation",
|
|
2530
2654
|
"find-usage",
|
|
2531
2655
|
"find-definition",
|
|
2532
|
-
"find-documentation"
|
|
2656
|
+
"find-documentation",
|
|
2657
|
+
"find-files"
|
|
2533
2658
|
],
|
|
2534
2659
|
description: "Search intent for better ranking"
|
|
2535
2660
|
},
|
|
@@ -2577,9 +2702,16 @@ function createMCPServer(options, services) {
|
|
|
2577
2702
|
resultId: {
|
|
2578
2703
|
type: "string",
|
|
2579
2704
|
description: "Result ID from previous search"
|
|
2705
|
+
},
|
|
2706
|
+
file: {
|
|
2707
|
+
type: "string",
|
|
2708
|
+
description: "File path to retrieve context for (alternative to resultId)"
|
|
2709
|
+
},
|
|
2710
|
+
store: {
|
|
2711
|
+
type: "string",
|
|
2712
|
+
description: "Store name to scope file lookup (optional, searches all if omitted)"
|
|
2580
2713
|
}
|
|
2581
|
-
}
|
|
2582
|
-
required: ["resultId"]
|
|
2714
|
+
}
|
|
2583
2715
|
}
|
|
2584
2716
|
},
|
|
2585
2717
|
// Meta-tool for store and job management (consolidates 8 tools into 1)
|
|
@@ -2694,4 +2826,4 @@ export {
|
|
|
2694
2826
|
createMCPServer,
|
|
2695
2827
|
runMCPServer
|
|
2696
2828
|
};
|
|
2697
|
-
//# sourceMappingURL=chunk-
|
|
2829
|
+
//# sourceMappingURL=chunk-YDTTD53Y.js.map
|