@vpxa/kb 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1140 -0
- package/bin/kb.mjs +10 -0
- package/package.json +67 -0
- package/packages/analyzers/dist/blast-radius-analyzer.d.ts +23 -0
- package/packages/analyzers/dist/blast-radius-analyzer.js +114 -0
- package/packages/analyzers/dist/dependency-analyzer.d.ts +29 -0
- package/packages/analyzers/dist/dependency-analyzer.js +425 -0
- package/packages/analyzers/dist/diagram-generator.d.ts +13 -0
- package/packages/analyzers/dist/diagram-generator.js +86 -0
- package/packages/analyzers/dist/entry-point-analyzer.d.ts +19 -0
- package/packages/analyzers/dist/entry-point-analyzer.js +239 -0
- package/packages/analyzers/dist/index.d.ts +14 -0
- package/packages/analyzers/dist/index.js +23 -0
- package/packages/analyzers/dist/knowledge-producer.d.ts +32 -0
- package/packages/analyzers/dist/knowledge-producer.js +113 -0
- package/packages/analyzers/dist/pattern-analyzer.d.ts +12 -0
- package/packages/analyzers/dist/pattern-analyzer.js +359 -0
- package/packages/analyzers/dist/regex-call-graph.d.ts +17 -0
- package/packages/analyzers/dist/regex-call-graph.js +428 -0
- package/packages/analyzers/dist/structure-analyzer.d.ts +11 -0
- package/packages/analyzers/dist/structure-analyzer.js +258 -0
- package/packages/analyzers/dist/symbol-analyzer.d.ts +10 -0
- package/packages/analyzers/dist/symbol-analyzer.js +442 -0
- package/packages/analyzers/dist/ts-call-graph.d.ts +27 -0
- package/packages/analyzers/dist/ts-call-graph.js +160 -0
- package/packages/analyzers/dist/types.d.ts +98 -0
- package/packages/analyzers/dist/types.js +1 -0
- package/packages/chunker/dist/call-graph-extractor.d.ts +22 -0
- package/packages/chunker/dist/call-graph-extractor.js +90 -0
- package/packages/chunker/dist/chunker-factory.d.ts +7 -0
- package/packages/chunker/dist/chunker-factory.js +36 -0
- package/packages/chunker/dist/chunker.interface.d.ts +10 -0
- package/packages/chunker/dist/chunker.interface.js +1 -0
- package/packages/chunker/dist/code-chunker.d.ts +14 -0
- package/packages/chunker/dist/code-chunker.js +134 -0
- package/packages/chunker/dist/generic-chunker.d.ts +12 -0
- package/packages/chunker/dist/generic-chunker.js +72 -0
- package/packages/chunker/dist/index.d.ts +8 -0
- package/packages/chunker/dist/index.js +21 -0
- package/packages/chunker/dist/markdown-chunker.d.ts +14 -0
- package/packages/chunker/dist/markdown-chunker.js +122 -0
- package/packages/chunker/dist/treesitter-chunker.d.ts +47 -0
- package/packages/chunker/dist/treesitter-chunker.js +234 -0
- package/packages/cli/dist/commands/analyze.d.ts +3 -0
- package/packages/cli/dist/commands/analyze.js +112 -0
- package/packages/cli/dist/commands/context-cmds.d.ts +3 -0
- package/packages/cli/dist/commands/context-cmds.js +155 -0
- package/packages/cli/dist/commands/environment.d.ts +3 -0
- package/packages/cli/dist/commands/environment.js +204 -0
- package/packages/cli/dist/commands/execution.d.ts +3 -0
- package/packages/cli/dist/commands/execution.js +137 -0
- package/packages/cli/dist/commands/graph.d.ts +3 -0
- package/packages/cli/dist/commands/graph.js +81 -0
- package/packages/cli/dist/commands/init.d.ts +8 -0
- package/packages/cli/dist/commands/init.js +87 -0
- package/packages/cli/dist/commands/knowledge.d.ts +3 -0
- package/packages/cli/dist/commands/knowledge.js +139 -0
- package/packages/cli/dist/commands/search.d.ts +3 -0
- package/packages/cli/dist/commands/search.js +267 -0
- package/packages/cli/dist/commands/system.d.ts +3 -0
- package/packages/cli/dist/commands/system.js +241 -0
- package/packages/cli/dist/commands/workspace.d.ts +3 -0
- package/packages/cli/dist/commands/workspace.js +388 -0
- package/packages/cli/dist/context.d.ts +5 -0
- package/packages/cli/dist/context.js +14 -0
- package/packages/cli/dist/helpers.d.ts +52 -0
- package/packages/cli/dist/helpers.js +458 -0
- package/packages/cli/dist/index.d.ts +8 -0
- package/packages/cli/dist/index.js +69 -0
- package/packages/cli/dist/kb-init.d.ts +57 -0
- package/packages/cli/dist/kb-init.js +82 -0
- package/packages/cli/dist/types.d.ts +7 -0
- package/packages/cli/dist/types.js +1 -0
- package/packages/core/dist/constants.d.ts +49 -0
- package/packages/core/dist/constants.js +43 -0
- package/packages/core/dist/content-detector.d.ts +9 -0
- package/packages/core/dist/content-detector.js +79 -0
- package/packages/core/dist/errors.d.ts +18 -0
- package/packages/core/dist/errors.js +40 -0
- package/packages/core/dist/index.d.ts +6 -0
- package/packages/core/dist/index.js +9 -0
- package/packages/core/dist/logger.d.ts +9 -0
- package/packages/core/dist/logger.js +34 -0
- package/packages/core/dist/types.d.ts +108 -0
- package/packages/core/dist/types.js +1 -0
- package/packages/embeddings/dist/embedder.interface.d.ts +24 -0
- package/packages/embeddings/dist/embedder.interface.js +1 -0
- package/packages/embeddings/dist/index.d.ts +3 -0
- package/packages/embeddings/dist/index.js +5 -0
- package/packages/embeddings/dist/onnx-embedder.d.ts +24 -0
- package/packages/embeddings/dist/onnx-embedder.js +82 -0
- package/packages/indexer/dist/file-hasher.d.ts +11 -0
- package/packages/indexer/dist/file-hasher.js +13 -0
- package/packages/indexer/dist/filesystem-crawler.d.ts +27 -0
- package/packages/indexer/dist/filesystem-crawler.js +125 -0
- package/packages/indexer/dist/graph-extractor.d.ts +22 -0
- package/packages/indexer/dist/graph-extractor.js +111 -0
- package/packages/indexer/dist/incremental-indexer.d.ts +47 -0
- package/packages/indexer/dist/incremental-indexer.js +278 -0
- package/packages/indexer/dist/index.d.ts +5 -0
- package/packages/indexer/dist/index.js +14 -0
- package/packages/server/dist/api.d.ts +8 -0
- package/packages/server/dist/api.js +9 -0
- package/packages/server/dist/config.d.ts +3 -0
- package/packages/server/dist/config.js +75 -0
- package/packages/server/dist/curated-manager.d.ts +86 -0
- package/packages/server/dist/curated-manager.js +357 -0
- package/packages/server/dist/index.d.ts +2 -0
- package/packages/server/dist/index.js +134 -0
- package/packages/server/dist/replay-interceptor.d.ts +11 -0
- package/packages/server/dist/replay-interceptor.js +38 -0
- package/packages/server/dist/resources/resources.d.ts +4 -0
- package/packages/server/dist/resources/resources.js +40 -0
- package/packages/server/dist/server.d.ts +21 -0
- package/packages/server/dist/server.js +247 -0
- package/packages/server/dist/tools/analyze.tools.d.ts +11 -0
- package/packages/server/dist/tools/analyze.tools.js +288 -0
- package/packages/server/dist/tools/forge.tools.d.ts +12 -0
- package/packages/server/dist/tools/forge.tools.js +501 -0
- package/packages/server/dist/tools/forget.tool.d.ts +4 -0
- package/packages/server/dist/tools/forget.tool.js +43 -0
- package/packages/server/dist/tools/graph.tool.d.ts +4 -0
- package/packages/server/dist/tools/graph.tool.js +110 -0
- package/packages/server/dist/tools/list.tool.d.ts +4 -0
- package/packages/server/dist/tools/list.tool.js +56 -0
- package/packages/server/dist/tools/lookup.tool.d.ts +4 -0
- package/packages/server/dist/tools/lookup.tool.js +53 -0
- package/packages/server/dist/tools/onboard.tool.d.ts +5 -0
- package/packages/server/dist/tools/onboard.tool.js +112 -0
- package/packages/server/dist/tools/produce.tool.d.ts +3 -0
- package/packages/server/dist/tools/produce.tool.js +74 -0
- package/packages/server/dist/tools/read.tool.d.ts +4 -0
- package/packages/server/dist/tools/read.tool.js +49 -0
- package/packages/server/dist/tools/reindex.tool.d.ts +7 -0
- package/packages/server/dist/tools/reindex.tool.js +70 -0
- package/packages/server/dist/tools/remember.tool.d.ts +4 -0
- package/packages/server/dist/tools/remember.tool.js +45 -0
- package/packages/server/dist/tools/replay.tool.d.ts +3 -0
- package/packages/server/dist/tools/replay.tool.js +89 -0
- package/packages/server/dist/tools/search.tool.d.ts +5 -0
- package/packages/server/dist/tools/search.tool.js +331 -0
- package/packages/server/dist/tools/status.tool.d.ts +4 -0
- package/packages/server/dist/tools/status.tool.js +68 -0
- package/packages/server/dist/tools/toolkit.tools.d.ts +35 -0
- package/packages/server/dist/tools/toolkit.tools.js +1674 -0
- package/packages/server/dist/tools/update.tool.d.ts +4 -0
- package/packages/server/dist/tools/update.tool.js +42 -0
- package/packages/server/dist/tools/utility.tools.d.ts +15 -0
- package/packages/server/dist/tools/utility.tools.js +461 -0
- package/packages/store/dist/graph-store.interface.d.ts +104 -0
- package/packages/store/dist/graph-store.interface.js +1 -0
- package/packages/store/dist/index.d.ts +6 -0
- package/packages/store/dist/index.js +9 -0
- package/packages/store/dist/lance-store.d.ts +32 -0
- package/packages/store/dist/lance-store.js +258 -0
- package/packages/store/dist/sqlite-graph-store.d.ts +43 -0
- package/packages/store/dist/sqlite-graph-store.js +374 -0
- package/packages/store/dist/store-factory.d.ts +9 -0
- package/packages/store/dist/store-factory.js +14 -0
- package/packages/store/dist/store.interface.d.ts +48 -0
- package/packages/store/dist/store.interface.js +1 -0
- package/packages/tools/dist/batch.d.ts +21 -0
- package/packages/tools/dist/batch.js +45 -0
- package/packages/tools/dist/changelog.d.ts +34 -0
- package/packages/tools/dist/changelog.js +112 -0
- package/packages/tools/dist/check.d.ts +26 -0
- package/packages/tools/dist/check.js +59 -0
- package/packages/tools/dist/checkpoint.d.ts +17 -0
- package/packages/tools/dist/checkpoint.js +43 -0
- package/packages/tools/dist/codemod.d.ts +37 -0
- package/packages/tools/dist/codemod.js +69 -0
- package/packages/tools/dist/compact.d.ts +41 -0
- package/packages/tools/dist/compact.js +60 -0
- package/packages/tools/dist/data-transform.d.ts +10 -0
- package/packages/tools/dist/data-transform.js +124 -0
- package/packages/tools/dist/dead-symbols.d.ts +21 -0
- package/packages/tools/dist/dead-symbols.js +71 -0
- package/packages/tools/dist/delegate.d.ts +34 -0
- package/packages/tools/dist/delegate.js +130 -0
- package/packages/tools/dist/diff-parse.d.ts +26 -0
- package/packages/tools/dist/diff-parse.js +153 -0
- package/packages/tools/dist/digest.d.ts +53 -0
- package/packages/tools/dist/digest.js +242 -0
- package/packages/tools/dist/encode.d.ts +14 -0
- package/packages/tools/dist/encode.js +46 -0
- package/packages/tools/dist/env-info.d.ts +28 -0
- package/packages/tools/dist/env-info.js +58 -0
- package/packages/tools/dist/eval.d.ts +13 -0
- package/packages/tools/dist/eval.js +79 -0
- package/packages/tools/dist/evidence-map.d.ts +79 -0
- package/packages/tools/dist/evidence-map.js +203 -0
- package/packages/tools/dist/file-summary.d.ts +32 -0
- package/packages/tools/dist/file-summary.js +106 -0
- package/packages/tools/dist/file-walk.d.ts +4 -0
- package/packages/tools/dist/file-walk.js +75 -0
- package/packages/tools/dist/find-examples.d.ts +25 -0
- package/packages/tools/dist/find-examples.js +48 -0
- package/packages/tools/dist/find.d.ts +47 -0
- package/packages/tools/dist/find.js +120 -0
- package/packages/tools/dist/forge-classify.d.ts +44 -0
- package/packages/tools/dist/forge-classify.js +319 -0
- package/packages/tools/dist/forge-ground.d.ts +64 -0
- package/packages/tools/dist/forge-ground.js +184 -0
- package/packages/tools/dist/git-context.d.ts +22 -0
- package/packages/tools/dist/git-context.js +46 -0
- package/packages/tools/dist/graph-query.d.ts +89 -0
- package/packages/tools/dist/graph-query.js +194 -0
- package/packages/tools/dist/health.d.ts +14 -0
- package/packages/tools/dist/health.js +118 -0
- package/packages/tools/dist/http-request.d.ts +23 -0
- package/packages/tools/dist/http-request.js +58 -0
- package/packages/tools/dist/index.d.ts +49 -0
- package/packages/tools/dist/index.js +273 -0
- package/packages/tools/dist/lane.d.ts +39 -0
- package/packages/tools/dist/lane.js +227 -0
- package/packages/tools/dist/measure.d.ts +38 -0
- package/packages/tools/dist/measure.js +119 -0
- package/packages/tools/dist/onboard.d.ts +41 -0
- package/packages/tools/dist/onboard.js +1139 -0
- package/packages/tools/dist/parse-output.d.ts +80 -0
- package/packages/tools/dist/parse-output.js +158 -0
- package/packages/tools/dist/process-manager.d.ts +18 -0
- package/packages/tools/dist/process-manager.js +69 -0
- package/packages/tools/dist/queue.d.ts +38 -0
- package/packages/tools/dist/queue.js +126 -0
- package/packages/tools/dist/regex-test.d.ts +31 -0
- package/packages/tools/dist/regex-test.js +39 -0
- package/packages/tools/dist/rename.d.ts +29 -0
- package/packages/tools/dist/rename.js +70 -0
- package/packages/tools/dist/replay.d.ts +56 -0
- package/packages/tools/dist/replay.js +108 -0
- package/packages/tools/dist/schema-validate.d.ts +23 -0
- package/packages/tools/dist/schema-validate.js +141 -0
- package/packages/tools/dist/scope-map.d.ts +52 -0
- package/packages/tools/dist/scope-map.js +72 -0
- package/packages/tools/dist/snippet.d.ts +34 -0
- package/packages/tools/dist/snippet.js +80 -0
- package/packages/tools/dist/stash.d.ts +12 -0
- package/packages/tools/dist/stash.js +60 -0
- package/packages/tools/dist/stratum-card.d.ts +31 -0
- package/packages/tools/dist/stratum-card.js +239 -0
- package/packages/tools/dist/symbol.d.ts +28 -0
- package/packages/tools/dist/symbol.js +87 -0
- package/packages/tools/dist/test-run.d.ts +23 -0
- package/packages/tools/dist/test-run.js +55 -0
- package/packages/tools/dist/text-utils.d.ts +16 -0
- package/packages/tools/dist/text-utils.js +31 -0
- package/packages/tools/dist/time-utils.d.ts +18 -0
- package/packages/tools/dist/time-utils.js +135 -0
- package/packages/tools/dist/trace.d.ts +24 -0
- package/packages/tools/dist/trace.js +114 -0
- package/packages/tools/dist/truncation.d.ts +22 -0
- package/packages/tools/dist/truncation.js +45 -0
- package/packages/tools/dist/watch.d.ts +30 -0
- package/packages/tools/dist/watch.js +61 -0
- package/packages/tools/dist/web-fetch.d.ts +45 -0
- package/packages/tools/dist/web-fetch.js +249 -0
- package/packages/tools/dist/web-search.d.ts +23 -0
- package/packages/tools/dist/web-search.js +46 -0
- package/packages/tools/dist/workset.d.ts +45 -0
- package/packages/tools/dist/workset.js +77 -0
- package/packages/tui/dist/App.d.ts +8 -0
- package/packages/tui/dist/App.js +52659 -0
- package/packages/tui/dist/index.d.ts +19 -0
- package/packages/tui/dist/index.js +54742 -0
- package/packages/tui/dist/panels/CuratedPanel.d.ts +8 -0
- package/packages/tui/dist/panels/CuratedPanel.js +34452 -0
- package/packages/tui/dist/panels/LogPanel.d.ts +3 -0
- package/packages/tui/dist/panels/LogPanel.js +51894 -0
- package/packages/tui/dist/panels/SearchPanel.d.ts +10 -0
- package/packages/tui/dist/panels/SearchPanel.js +34985 -0
- package/packages/tui/dist/panels/StatusPanel.d.ts +8 -0
- package/packages/tui/dist/panels/StatusPanel.js +34465 -0
- package/skills/knowledge-base/SKILL.md +316 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { find, findDeadSymbols, findExamples, scopeMap, symbol, trace } from "@kb/tools";
|
|
2
|
+
import { ctx } from "../context.js";
|
|
3
|
+
import {
|
|
4
|
+
extractNumFlag,
|
|
5
|
+
extractStrFlag,
|
|
6
|
+
formatFocusRanges,
|
|
7
|
+
printDeadSymbolsResult,
|
|
8
|
+
printExamplesResult,
|
|
9
|
+
printSymbolInfo,
|
|
10
|
+
printTraceResult,
|
|
11
|
+
rrf
|
|
12
|
+
} from "../helpers.js";
|
|
13
|
+
const searchCommands = [
|
|
14
|
+
{
|
|
15
|
+
name: "search",
|
|
16
|
+
description: "Search the knowledge base",
|
|
17
|
+
usage: "kb search <query> [--limit N] [--mode hybrid|semantic|keyword] [--graph-hops 0-3]",
|
|
18
|
+
run: async (args) => {
|
|
19
|
+
const limit = extractNumFlag(args, "--limit", 5);
|
|
20
|
+
const mode = extractStrFlag(args, "--mode", "hybrid");
|
|
21
|
+
const graphHops = extractNumFlag(args, "--graph-hops", 0);
|
|
22
|
+
const query = args.join(" ").trim();
|
|
23
|
+
if (!query) {
|
|
24
|
+
console.error("Usage: kb search <query>");
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
const { embedder, store, graphStore } = await ctx();
|
|
28
|
+
const queryVector = await embedder.embedQuery(query);
|
|
29
|
+
let results;
|
|
30
|
+
if (mode === "keyword") {
|
|
31
|
+
results = await store.ftsSearch(query, { limit });
|
|
32
|
+
} else if (mode === "semantic") {
|
|
33
|
+
results = await store.search(queryVector, { limit });
|
|
34
|
+
} else {
|
|
35
|
+
const [vec, fts] = await Promise.all([
|
|
36
|
+
store.search(queryVector, { limit: limit * 2 }),
|
|
37
|
+
store.ftsSearch(query, { limit: limit * 2 }).catch(() => [])
|
|
38
|
+
]);
|
|
39
|
+
results = rrf(vec, fts).slice(0, limit);
|
|
40
|
+
}
|
|
41
|
+
if (results.length === 0) {
|
|
42
|
+
console.log("No results found.");
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
for (const { record, score } of results) {
|
|
46
|
+
console.log(`
|
|
47
|
+
${"\u2500".repeat(60)}`);
|
|
48
|
+
console.log(
|
|
49
|
+
`[${(score * 100).toFixed(1)}%] ${record.sourcePath}:${record.startLine}-${record.endLine}`
|
|
50
|
+
);
|
|
51
|
+
console.log(` Type: ${record.contentType} | Origin: ${record.origin}`);
|
|
52
|
+
if (record.tags.length > 0) console.log(` Tags: ${record.tags.join(", ")}`);
|
|
53
|
+
console.log("");
|
|
54
|
+
const preview = record.content.length > 500 ? `${record.content.slice(0, 500)}...` : record.content;
|
|
55
|
+
console.log(preview);
|
|
56
|
+
}
|
|
57
|
+
console.log(`
|
|
58
|
+
${"\u2500".repeat(60)}`);
|
|
59
|
+
console.log(`${results.length} result(s) found.`);
|
|
60
|
+
if (graphHops > 0 && results.length > 0) {
|
|
61
|
+
try {
|
|
62
|
+
const { graphAugmentSearch } = await import("@kb/tools");
|
|
63
|
+
const hits = results.map((r) => ({
|
|
64
|
+
recordId: r.record.id,
|
|
65
|
+
score: r.score,
|
|
66
|
+
sourcePath: r.record.sourcePath
|
|
67
|
+
}));
|
|
68
|
+
const augmented = await graphAugmentSearch(graphStore, hits, {
|
|
69
|
+
hops: graphHops,
|
|
70
|
+
maxPerHit: 5
|
|
71
|
+
});
|
|
72
|
+
const hasContext = augmented.filter((a) => a.graphContext.nodes.length > 0);
|
|
73
|
+
if (hasContext.length > 0) {
|
|
74
|
+
console.log(`
|
|
75
|
+
Graph context (${graphHops} hop${graphHops > 1 ? "s" : ""}):
|
|
76
|
+
`);
|
|
77
|
+
for (const aug of hasContext) {
|
|
78
|
+
console.log(` ${aug.sourcePath}:`);
|
|
79
|
+
for (const n of aug.graphContext.nodes.slice(0, 5)) {
|
|
80
|
+
console.log(` \u2192 ${n.name} (${n.type})`);
|
|
81
|
+
}
|
|
82
|
+
for (const e of aug.graphContext.edges.slice(0, 5)) {
|
|
83
|
+
console.log(` \u2192 ${e.fromId} --[${e.type}]--> ${e.toId}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
} catch (err) {
|
|
88
|
+
console.error(`[graph] augmentation failed: ${err.message}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: "find",
|
|
95
|
+
description: "Run federated search across indexed content and files",
|
|
96
|
+
usage: "kb find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]",
|
|
97
|
+
run: async (args) => {
|
|
98
|
+
const limit = extractNumFlag(args, "--limit", 10);
|
|
99
|
+
const glob = extractStrFlag(args, "--glob", "").trim() || void 0;
|
|
100
|
+
const pattern = extractStrFlag(args, "--pattern", "").trim() || void 0;
|
|
101
|
+
const query = args.join(" ").trim() || void 0;
|
|
102
|
+
if (!query && !glob && !pattern) {
|
|
103
|
+
console.error("Usage: kb find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]");
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
const { embedder, store } = await ctx();
|
|
107
|
+
const result = await find(embedder, store, { query, glob, pattern, limit });
|
|
108
|
+
if (result.results.length === 0) {
|
|
109
|
+
console.log("No matches found.");
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
console.log(`Strategies: ${result.strategies.join(", ")}`);
|
|
113
|
+
console.log(`Results: ${result.results.length} shown (${result.totalFound} total)`);
|
|
114
|
+
for (const match of result.results) {
|
|
115
|
+
const lineRange = match.lineRange ? `:${match.lineRange.start}-${match.lineRange.end}` : "";
|
|
116
|
+
console.log(`
|
|
117
|
+
[${match.source}] ${match.path}${lineRange}`);
|
|
118
|
+
console.log(` Score: ${(match.score * 100).toFixed(1)}%`);
|
|
119
|
+
if (match.preview) console.log(` ${match.preview.replace(/\s+/g, " ").trim()}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: "scope-map",
|
|
125
|
+
description: "Generate a reading plan for a task",
|
|
126
|
+
usage: "kb scope-map <task> [--max-files N]",
|
|
127
|
+
run: async (args) => {
|
|
128
|
+
const maxFiles = extractNumFlag(args, "--max-files", 15);
|
|
129
|
+
const task = args.join(" ").trim();
|
|
130
|
+
if (!task) {
|
|
131
|
+
console.error("Usage: kb scope-map <task> [--max-files N]");
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
const { embedder, store } = await ctx();
|
|
135
|
+
const result = await scopeMap(embedder, store, { task, maxFiles });
|
|
136
|
+
console.log(`Task: ${result.task}`);
|
|
137
|
+
console.log(`Files: ${result.files.length}`);
|
|
138
|
+
console.log(`Estimated tokens: ${result.totalEstimatedTokens}`);
|
|
139
|
+
console.log("");
|
|
140
|
+
console.log("Reading order:");
|
|
141
|
+
for (const path of result.readingOrder) console.log(` ${path}`);
|
|
142
|
+
for (const [index, file] of result.files.entries()) {
|
|
143
|
+
console.log(`
|
|
144
|
+
${index + 1}. ${file.path}`);
|
|
145
|
+
console.log(
|
|
146
|
+
` Relevance: ${(file.relevance * 100).toFixed(1)}% | Tokens: ${file.estimatedTokens}`
|
|
147
|
+
);
|
|
148
|
+
console.log(` Why: ${file.reason}`);
|
|
149
|
+
if (file.focusRanges.length > 0) {
|
|
150
|
+
console.log(` Focus: ${formatFocusRanges(file.focusRanges)}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: "symbol",
|
|
157
|
+
description: "Resolve a symbol definition, imports, and references",
|
|
158
|
+
usage: "kb symbol <name> [--limit N]",
|
|
159
|
+
run: async (args) => {
|
|
160
|
+
const limit = extractNumFlag(args, "--limit", 20);
|
|
161
|
+
const name = args.join(" ").trim();
|
|
162
|
+
if (!name) {
|
|
163
|
+
console.error("Usage: kb symbol <name> [--limit N]");
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
const { embedder, store } = await ctx();
|
|
167
|
+
const result = await symbol(embedder, store, { name, limit });
|
|
168
|
+
printSymbolInfo(result);
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
name: "trace",
|
|
173
|
+
description: "Trace forward/backward flow for a symbol or file location",
|
|
174
|
+
usage: "kb trace <start> [--direction forward|backward|both] [--max-depth N]",
|
|
175
|
+
run: async (args) => {
|
|
176
|
+
const directionValue = extractStrFlag(args, "--direction", "both").trim() || "both";
|
|
177
|
+
const maxDepth = extractNumFlag(args, "--max-depth", 3);
|
|
178
|
+
const start = args.join(" ").trim();
|
|
179
|
+
if (!start || !["forward", "backward", "both"].includes(directionValue)) {
|
|
180
|
+
console.error(
|
|
181
|
+
"Usage: kb trace <start> [--direction forward|backward|both] [--max-depth N]"
|
|
182
|
+
);
|
|
183
|
+
process.exit(1);
|
|
184
|
+
}
|
|
185
|
+
const { embedder, store } = await ctx();
|
|
186
|
+
const result = await trace(embedder, store, {
|
|
187
|
+
start,
|
|
188
|
+
direction: directionValue,
|
|
189
|
+
maxDepth
|
|
190
|
+
});
|
|
191
|
+
printTraceResult(result);
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
name: "examples",
|
|
196
|
+
description: "Find real code examples of a symbol or pattern",
|
|
197
|
+
usage: "kb examples <query> [--limit N] [--content-type type]",
|
|
198
|
+
run: async (args) => {
|
|
199
|
+
const limit = extractNumFlag(args, "--limit", 5);
|
|
200
|
+
const contentType = extractStrFlag(args, "--content-type", "").trim() || void 0;
|
|
201
|
+
const query = args.join(" ").trim();
|
|
202
|
+
if (!query) {
|
|
203
|
+
console.error("Usage: kb examples <query> [--limit N] [--content-type type]");
|
|
204
|
+
process.exit(1);
|
|
205
|
+
}
|
|
206
|
+
const { embedder, store } = await ctx();
|
|
207
|
+
const result = await findExamples(embedder, store, { query, limit, contentType });
|
|
208
|
+
printExamplesResult(result);
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
name: "dead-symbols",
|
|
213
|
+
description: "Find exported symbols that appear to be unused",
|
|
214
|
+
usage: "kb dead-symbols [--limit N]",
|
|
215
|
+
run: async (args) => {
|
|
216
|
+
const limit = extractNumFlag(args, "--limit", 100);
|
|
217
|
+
const { embedder, store } = await ctx();
|
|
218
|
+
const result = await findDeadSymbols(embedder, store, { limit });
|
|
219
|
+
printDeadSymbolsResult(result);
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
name: "lookup",
|
|
224
|
+
description: "Look up indexed content by record ID or source path",
|
|
225
|
+
usage: "kb lookup <id>",
|
|
226
|
+
run: async (args) => {
|
|
227
|
+
const key = args.join(" ").trim();
|
|
228
|
+
if (!key) {
|
|
229
|
+
console.error("Usage: kb lookup <id>");
|
|
230
|
+
process.exit(1);
|
|
231
|
+
}
|
|
232
|
+
const { store } = await ctx();
|
|
233
|
+
const record = await store.getById(key);
|
|
234
|
+
if (record) {
|
|
235
|
+
console.log(record.id);
|
|
236
|
+
console.log("\u2500".repeat(60));
|
|
237
|
+
console.log(`Path: ${record.sourcePath}`);
|
|
238
|
+
console.log(`Chunk: ${record.chunkIndex + 1}/${record.totalChunks}`);
|
|
239
|
+
console.log(`Lines: ${record.startLine}-${record.endLine}`);
|
|
240
|
+
console.log(`Type: ${record.contentType} | Origin: ${record.origin}`);
|
|
241
|
+
if (record.tags.length > 0) console.log(`Tags: ${record.tags.join(", ")}`);
|
|
242
|
+
console.log("");
|
|
243
|
+
console.log(record.content);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const records = await store.getBySourcePath(key);
|
|
247
|
+
if (records.length === 0) {
|
|
248
|
+
console.log(`No indexed content found for: ${key}`);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
records.sort((a, b) => a.chunkIndex - b.chunkIndex);
|
|
252
|
+
console.log(key);
|
|
253
|
+
console.log("\u2500".repeat(60));
|
|
254
|
+
console.log(`Chunks: ${records.length} | Type: ${records[0].contentType}`);
|
|
255
|
+
for (const chunk of records) {
|
|
256
|
+
const lineInfo = chunk.startLine ? ` (lines ${chunk.startLine}-${chunk.endLine})` : "";
|
|
257
|
+
console.log(`
|
|
258
|
+
Chunk ${chunk.chunkIndex + 1}/${chunk.totalChunks}${lineInfo}`);
|
|
259
|
+
console.log(chunk.content);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
];
|
|
264
|
+
export {
|
|
265
|
+
searchCommands
|
|
266
|
+
};
|
|
267
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { fork } from "node:child_process";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { batch, check, health, replayClear, replayList, replayTrim } from "@kb/tools";
|
|
5
|
+
import { ctx } from "../context.js";
|
|
6
|
+
import {
|
|
7
|
+
executeCliBatchOperation,
|
|
8
|
+
extractStrFlag,
|
|
9
|
+
parseBatchPayload,
|
|
10
|
+
printCheckResult,
|
|
11
|
+
readInput
|
|
12
|
+
} from "../helpers.js";
|
|
13
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
const systemCommands = [
|
|
15
|
+
{
|
|
16
|
+
name: "status",
|
|
17
|
+
description: "Show knowledge base index status and statistics",
|
|
18
|
+
run: async () => {
|
|
19
|
+
const { store } = await ctx();
|
|
20
|
+
const stats = await store.getStats();
|
|
21
|
+
const paths = await store.listSourcePaths();
|
|
22
|
+
console.log("Knowledge Base Status");
|
|
23
|
+
console.log("\u2500".repeat(40));
|
|
24
|
+
console.log(` Records: ${stats.totalRecords}`);
|
|
25
|
+
console.log(` Files: ${stats.totalFiles}`);
|
|
26
|
+
console.log(` Indexed: ${stats.lastIndexedAt ?? "Never"}`);
|
|
27
|
+
console.log(` Backend: ${stats.storeBackend}`);
|
|
28
|
+
console.log(` Model: ${stats.embeddingModel}`);
|
|
29
|
+
console.log("");
|
|
30
|
+
console.log("Content Types:");
|
|
31
|
+
for (const [type, count] of Object.entries(stats.contentTypeBreakdown)) {
|
|
32
|
+
console.log(` ${type}: ${count}`);
|
|
33
|
+
}
|
|
34
|
+
if (paths.length > 0) {
|
|
35
|
+
console.log("");
|
|
36
|
+
console.log(`Files (${paths.length} total):`);
|
|
37
|
+
for (const p of paths.slice(0, 20)) console.log(` ${p}`);
|
|
38
|
+
if (paths.length > 20) console.log(` ... and ${paths.length - 20} more`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "reindex",
|
|
44
|
+
description: "Re-index the knowledge base from configured sources",
|
|
45
|
+
usage: "kb reindex [--full]",
|
|
46
|
+
run: async (args) => {
|
|
47
|
+
const full = args.includes("--full");
|
|
48
|
+
const { store, indexer, curated, config } = await ctx();
|
|
49
|
+
console.log("Indexing sources...");
|
|
50
|
+
const progressCb = (p) => {
|
|
51
|
+
if (p.phase === "chunking" && p.currentFile) {
|
|
52
|
+
process.stdout.write(`\r [${p.filesProcessed + 1}/${p.filesTotal}] ${p.currentFile}`);
|
|
53
|
+
}
|
|
54
|
+
if (p.phase === "done") process.stdout.write("\n");
|
|
55
|
+
};
|
|
56
|
+
let result;
|
|
57
|
+
if (full) {
|
|
58
|
+
console.log("Dropping existing index for full reindex...");
|
|
59
|
+
result = await indexer.reindexAll(config, progressCb);
|
|
60
|
+
} else {
|
|
61
|
+
result = await indexer.index(config, progressCb);
|
|
62
|
+
}
|
|
63
|
+
console.log(
|
|
64
|
+
`Done: ${result.filesProcessed} files, ${result.chunksCreated} chunks in ${(result.durationMs / 1e3).toFixed(1)}s`
|
|
65
|
+
);
|
|
66
|
+
console.log("Building FTS index...");
|
|
67
|
+
await store.createFtsIndex();
|
|
68
|
+
console.log("Re-indexing curated entries...");
|
|
69
|
+
const curatedResult = await curated.reindexAll();
|
|
70
|
+
console.log(`Curated: ${curatedResult.indexed} entries restored`);
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: "serve",
|
|
75
|
+
description: "Start the MCP server (stdio or HTTP)",
|
|
76
|
+
usage: "kb serve [--transport stdio|http] [--port N]",
|
|
77
|
+
run: async (args) => {
|
|
78
|
+
const serverEntry = resolve(__dirname, "..", "..", "..", "server", "dist", "index.js");
|
|
79
|
+
const transport = extractStrFlag(args, "--transport", "stdio");
|
|
80
|
+
const port = extractStrFlag(args, "--port", "3210");
|
|
81
|
+
const child = fork(serverEntry, [], {
|
|
82
|
+
stdio: transport === "stdio" ? ["pipe", "pipe", "inherit", "ipc"] : "inherit",
|
|
83
|
+
env: {
|
|
84
|
+
...process.env,
|
|
85
|
+
KB_TRANSPORT: transport,
|
|
86
|
+
KB_PORT: port
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
if (transport === "stdio" && child.stdin && child.stdout) {
|
|
90
|
+
process.stdin.pipe(child.stdin);
|
|
91
|
+
child.stdout.pipe(process.stdout);
|
|
92
|
+
}
|
|
93
|
+
child.on("exit", (code) => process.exit(code ?? 0));
|
|
94
|
+
process.on("SIGINT", () => child.kill("SIGINT"));
|
|
95
|
+
process.on("SIGTERM", () => child.kill("SIGTERM"));
|
|
96
|
+
await new Promise(() => {
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: "init",
|
|
102
|
+
description: "Initialize a knowledge base in the current directory",
|
|
103
|
+
usage: "kb init [--force]",
|
|
104
|
+
run: async (args) => {
|
|
105
|
+
const force = args.includes("--force");
|
|
106
|
+
const { initProject } = await import("./init.js");
|
|
107
|
+
await initProject({ force });
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
name: "check",
|
|
112
|
+
description: "Run incremental typecheck and lint",
|
|
113
|
+
usage: "kb check [--cwd <dir>] [--files f1,f2] [--skip-types] [--skip-lint]",
|
|
114
|
+
run: async (args) => {
|
|
115
|
+
const cwd = extractStrFlag(args, "--cwd", "").trim() || void 0;
|
|
116
|
+
const filesValue = extractStrFlag(args, "--files", "");
|
|
117
|
+
const files = filesValue.split(",").map((item) => item.trim()).filter(Boolean);
|
|
118
|
+
let skipTypes = false;
|
|
119
|
+
if (args.includes("--skip-types")) {
|
|
120
|
+
args.splice(args.indexOf("--skip-types"), 1);
|
|
121
|
+
skipTypes = true;
|
|
122
|
+
}
|
|
123
|
+
let skipLint = false;
|
|
124
|
+
if (args.includes("--skip-lint")) {
|
|
125
|
+
args.splice(args.indexOf("--skip-lint"), 1);
|
|
126
|
+
skipLint = true;
|
|
127
|
+
}
|
|
128
|
+
const result = await check({
|
|
129
|
+
cwd,
|
|
130
|
+
files: files.length > 0 ? files : void 0,
|
|
131
|
+
skipTypes,
|
|
132
|
+
skipLint
|
|
133
|
+
});
|
|
134
|
+
printCheckResult(result);
|
|
135
|
+
if (!result.passed) process.exitCode = 1;
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: "batch",
|
|
140
|
+
description: "Execute built-in operations from JSON input",
|
|
141
|
+
usage: "kb batch [--file path] [--concurrency N]",
|
|
142
|
+
run: async (args) => {
|
|
143
|
+
const filePath = extractStrFlag(args, "--file", "").trim() || void 0;
|
|
144
|
+
const overrideConcurrency = (() => {
|
|
145
|
+
const idx = args.indexOf("--concurrency");
|
|
146
|
+
if (idx === -1 || idx + 1 >= args.length) return 0;
|
|
147
|
+
const val = Number.parseInt(args.splice(idx, 2)[1], 10);
|
|
148
|
+
return Number.isNaN(val) ? 0 : val;
|
|
149
|
+
})();
|
|
150
|
+
const input = await readInput(filePath);
|
|
151
|
+
if (!input.trim()) {
|
|
152
|
+
console.error("Usage: kb batch [--file path] [--concurrency N]");
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
const payload = parseBatchPayload(input);
|
|
156
|
+
const concurrency = overrideConcurrency > 0 ? overrideConcurrency : payload.concurrency;
|
|
157
|
+
const needsContext = payload.operations.some((operation) => operation.type !== "check");
|
|
158
|
+
const context = needsContext ? await ctx() : null;
|
|
159
|
+
const result = await batch(
|
|
160
|
+
payload.operations,
|
|
161
|
+
async (operation) => executeCliBatchOperation(operation, context),
|
|
162
|
+
{ concurrency }
|
|
163
|
+
);
|
|
164
|
+
console.log(JSON.stringify(result, null, 2));
|
|
165
|
+
if (result.some((item) => item.status === "error")) process.exitCode = 1;
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: "health",
|
|
170
|
+
description: "Run project health checks on the current directory",
|
|
171
|
+
usage: "kb health [path]",
|
|
172
|
+
run: async (args) => {
|
|
173
|
+
const targetPath = args.shift();
|
|
174
|
+
const result = health(targetPath);
|
|
175
|
+
console.log(`Project Health: ${result.path}`);
|
|
176
|
+
console.log("\u2500".repeat(50));
|
|
177
|
+
for (const check2 of result.checks) {
|
|
178
|
+
const icon = check2.status === "pass" ? "+" : check2.status === "warn" ? "~" : "X";
|
|
179
|
+
console.log(` [${icon}] ${check2.name}: ${check2.message}`);
|
|
180
|
+
}
|
|
181
|
+
console.log("\u2500".repeat(50));
|
|
182
|
+
console.log(`Score: ${result.score}% \u2014 ${result.summary}`);
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
name: "replay",
|
|
187
|
+
description: "Show recent tool invocation audit trail",
|
|
188
|
+
usage: "kb replay [--last N] [--tool <name>] [--source mcp|cli]",
|
|
189
|
+
run: async (args) => {
|
|
190
|
+
const last = Number.parseInt(args[args.indexOf("--last") + 1], 10) || 20;
|
|
191
|
+
const toolFilter = args.includes("--tool") ? args[args.indexOf("--tool") + 1] : void 0;
|
|
192
|
+
const sourceFilter = args.includes("--source") ? args[args.indexOf("--source") + 1] : void 0;
|
|
193
|
+
const entries = replayList({ last, tool: toolFilter, source: sourceFilter });
|
|
194
|
+
if (entries.length === 0) {
|
|
195
|
+
console.log("No replay entries. Activity is logged when tools are invoked.");
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
console.log(`Replay Log (${entries.length} entries)
|
|
199
|
+
`);
|
|
200
|
+
for (const e of entries) {
|
|
201
|
+
const time = e.ts.split("T")[1]?.split(".")[0] ?? e.ts;
|
|
202
|
+
const status = e.status === "ok" ? "\u2713" : "\u2717";
|
|
203
|
+
console.log(`${time} ${status} ${e.tool} (${e.durationMs}ms) [${e.source}]`);
|
|
204
|
+
console.log(` in: ${e.input}`);
|
|
205
|
+
console.log(` out: ${e.output}`);
|
|
206
|
+
}
|
|
207
|
+
replayTrim();
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: "replay-clear",
|
|
212
|
+
description: "Clear the replay audit trail",
|
|
213
|
+
run: async () => {
|
|
214
|
+
replayClear();
|
|
215
|
+
console.log("Replay log cleared.");
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
name: "tui",
|
|
220
|
+
description: "Launch interactive terminal dashboard (human monitoring)",
|
|
221
|
+
run: async () => {
|
|
222
|
+
try {
|
|
223
|
+
const { launch } = await import("@kb/tui");
|
|
224
|
+
const { store, embedder, config } = await ctx();
|
|
225
|
+
launch({ store, embedder, config });
|
|
226
|
+
} catch (err) {
|
|
227
|
+
if (err.code === "ERR_MODULE_NOT_FOUND") {
|
|
228
|
+
console.error(
|
|
229
|
+
"TUI requires ink and react. Install them with:\n pnpm add -D ink react @types/react"
|
|
230
|
+
);
|
|
231
|
+
process.exit(1);
|
|
232
|
+
}
|
|
233
|
+
throw err;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
];
|
|
238
|
+
export {
|
|
239
|
+
systemCommands
|
|
240
|
+
};
|
|
241
|
+
//# sourceMappingURL=system.js.map
|