@vpxa/kb 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/package.json +1 -1
  2. package/packages/analyzers/dist/blast-radius-analyzer.js +13 -114
  3. package/packages/analyzers/dist/dependency-analyzer.js +11 -425
  4. package/packages/analyzers/dist/diagram-generator.js +4 -86
  5. package/packages/analyzers/dist/entry-point-analyzer.js +5 -239
  6. package/packages/analyzers/dist/index.js +1 -23
  7. package/packages/analyzers/dist/knowledge-producer.js +24 -113
  8. package/packages/analyzers/dist/pattern-analyzer.js +5 -359
  9. package/packages/analyzers/dist/regex-call-graph.js +1 -428
  10. package/packages/analyzers/dist/structure-analyzer.js +4 -258
  11. package/packages/analyzers/dist/symbol-analyzer.js +13 -442
  12. package/packages/analyzers/dist/ts-call-graph.js +1 -160
  13. package/packages/analyzers/dist/types.js +0 -1
  14. package/packages/chunker/dist/call-graph-extractor.js +1 -90
  15. package/packages/chunker/dist/chunker-factory.js +1 -36
  16. package/packages/chunker/dist/chunker.interface.js +0 -1
  17. package/packages/chunker/dist/code-chunker.js +14 -134
  18. package/packages/chunker/dist/generic-chunker.js +5 -72
  19. package/packages/chunker/dist/index.js +1 -21
  20. package/packages/chunker/dist/markdown-chunker.js +7 -119
  21. package/packages/chunker/dist/treesitter-chunker.js +8 -234
  22. package/packages/cli/dist/commands/analyze.js +3 -112
  23. package/packages/cli/dist/commands/context-cmds.js +1 -155
  24. package/packages/cli/dist/commands/environment.js +2 -204
  25. package/packages/cli/dist/commands/execution.js +1 -137
  26. package/packages/cli/dist/commands/graph.js +7 -81
  27. package/packages/cli/dist/commands/init.js +9 -87
  28. package/packages/cli/dist/commands/knowledge.js +1 -139
  29. package/packages/cli/dist/commands/search.js +8 -267
  30. package/packages/cli/dist/commands/system.js +4 -241
  31. package/packages/cli/dist/commands/workspace.js +2 -388
  32. package/packages/cli/dist/context.js +1 -14
  33. package/packages/cli/dist/helpers.js +3 -458
  34. package/packages/cli/dist/index.js +3 -69
  35. package/packages/cli/dist/kb-init.js +1 -82
  36. package/packages/cli/dist/types.js +0 -1
  37. package/packages/core/dist/constants.js +1 -43
  38. package/packages/core/dist/content-detector.js +1 -79
  39. package/packages/core/dist/errors.js +1 -40
  40. package/packages/core/dist/index.js +1 -9
  41. package/packages/core/dist/logger.js +1 -34
  42. package/packages/core/dist/types.js +0 -1
  43. package/packages/embeddings/dist/embedder.interface.js +0 -1
  44. package/packages/embeddings/dist/index.js +1 -5
  45. package/packages/embeddings/dist/onnx-embedder.js +1 -82
  46. package/packages/indexer/dist/file-hasher.js +1 -13
  47. package/packages/indexer/dist/filesystem-crawler.js +1 -125
  48. package/packages/indexer/dist/graph-extractor.js +1 -111
  49. package/packages/indexer/dist/incremental-indexer.js +1 -278
  50. package/packages/indexer/dist/index.js +1 -14
  51. package/packages/server/dist/api.js +1 -9
  52. package/packages/server/dist/config.js +1 -75
  53. package/packages/server/dist/curated-manager.js +9 -356
  54. package/packages/server/dist/index.js +1 -134
  55. package/packages/server/dist/replay-interceptor.js +1 -38
  56. package/packages/server/dist/resources/resources.js +2 -40
  57. package/packages/server/dist/server.js +1 -247
  58. package/packages/server/dist/tools/analyze.tools.js +1 -288
  59. package/packages/server/dist/tools/forge.tools.js +11 -499
  60. package/packages/server/dist/tools/forget.tool.js +3 -39
  61. package/packages/server/dist/tools/graph.tool.js +5 -110
  62. package/packages/server/dist/tools/list.tool.js +5 -53
  63. package/packages/server/dist/tools/lookup.tool.js +8 -51
  64. package/packages/server/dist/tools/onboard.tool.js +2 -112
  65. package/packages/server/dist/tools/produce.tool.js +4 -74
  66. package/packages/server/dist/tools/read.tool.js +4 -47
  67. package/packages/server/dist/tools/reindex.tool.js +2 -70
  68. package/packages/server/dist/tools/remember.tool.js +3 -42
  69. package/packages/server/dist/tools/replay.tool.js +6 -88
  70. package/packages/server/dist/tools/search.tool.js +17 -327
  71. package/packages/server/dist/tools/status.tool.js +3 -68
  72. package/packages/server/dist/tools/toolkit.tools.js +20 -1673
  73. package/packages/server/dist/tools/update.tool.js +3 -39
  74. package/packages/server/dist/tools/utility.tools.js +19 -456
  75. package/packages/store/dist/graph-store.interface.js +0 -1
  76. package/packages/store/dist/index.js +1 -9
  77. package/packages/store/dist/lance-store.js +1 -258
  78. package/packages/store/dist/sqlite-graph-store.js +8 -309
  79. package/packages/store/dist/store-factory.js +1 -14
  80. package/packages/store/dist/store.interface.js +0 -1
  81. package/packages/tools/dist/batch.js +1 -45
  82. package/packages/tools/dist/changelog.js +2 -112
  83. package/packages/tools/dist/check.js +2 -59
  84. package/packages/tools/dist/checkpoint.js +2 -43
  85. package/packages/tools/dist/codemod.js +2 -69
  86. package/packages/tools/dist/compact.js +3 -60
  87. package/packages/tools/dist/data-transform.js +1 -124
  88. package/packages/tools/dist/dead-symbols.js +2 -71
  89. package/packages/tools/dist/delegate.js +3 -128
  90. package/packages/tools/dist/diff-parse.js +3 -153
  91. package/packages/tools/dist/digest.js +7 -242
  92. package/packages/tools/dist/encode.js +1 -46
  93. package/packages/tools/dist/env-info.js +1 -58
  94. package/packages/tools/dist/eval.js +3 -79
  95. package/packages/tools/dist/evidence-map.js +3 -203
  96. package/packages/tools/dist/file-summary.js +2 -106
  97. package/packages/tools/dist/file-walk.js +1 -75
  98. package/packages/tools/dist/find-examples.js +3 -48
  99. package/packages/tools/dist/find.js +1 -120
  100. package/packages/tools/dist/forge-classify.js +2 -319
  101. package/packages/tools/dist/forge-ground.js +1 -184
  102. package/packages/tools/dist/git-context.js +3 -46
  103. package/packages/tools/dist/graph-query.js +1 -194
  104. package/packages/tools/dist/health.js +1 -118
  105. package/packages/tools/dist/http-request.js +1 -58
  106. package/packages/tools/dist/index.js +1 -273
  107. package/packages/tools/dist/lane.js +7 -227
  108. package/packages/tools/dist/measure.js +2 -119
  109. package/packages/tools/dist/onboard.js +42 -1136
  110. package/packages/tools/dist/parse-output.js +2 -158
  111. package/packages/tools/dist/process-manager.js +1 -69
  112. package/packages/tools/dist/queue.js +2 -126
  113. package/packages/tools/dist/regex-test.js +1 -39
  114. package/packages/tools/dist/rename.js +2 -70
  115. package/packages/tools/dist/replay.js +6 -108
  116. package/packages/tools/dist/schema-validate.js +1 -141
  117. package/packages/tools/dist/scope-map.js +1 -72
  118. package/packages/tools/dist/snippet.js +1 -80
  119. package/packages/tools/dist/stash.js +2 -60
  120. package/packages/tools/dist/stratum-card.js +5 -238
  121. package/packages/tools/dist/symbol.js +3 -87
  122. package/packages/tools/dist/test-run.js +2 -55
  123. package/packages/tools/dist/text-utils.js +2 -31
  124. package/packages/tools/dist/time-utils.js +1 -135
  125. package/packages/tools/dist/trace.js +2 -114
  126. package/packages/tools/dist/truncation.js +10 -41
  127. package/packages/tools/dist/watch.js +1 -61
  128. package/packages/tools/dist/web-fetch.js +9 -244
  129. package/packages/tools/dist/web-search.js +1 -46
  130. package/packages/tools/dist/workset.js +2 -77
  131. package/packages/tui/dist/App.js +260 -52468
  132. package/packages/tui/dist/index.js +286 -54551
  133. package/packages/tui/dist/panels/CuratedPanel.js +211 -34291
  134. package/packages/tui/dist/panels/LogPanel.js +259 -51703
  135. package/packages/tui/dist/panels/SearchPanel.js +212 -34824
  136. package/packages/tui/dist/panels/StatusPanel.js +211 -34304
@@ -1,139 +1 @@
1
- import { compact } from "@kb/tools";
2
- import { ctx } from "../context.js";
3
- import { extractNumFlag, extractStrFlag, readStdin, splitCsv } from "../helpers.js";
4
- const knowledgeCommands = [
5
- {
6
- name: "remember",
7
- description: "Store curated knowledge",
8
- usage: "kb remember <title> --category <cat> [--tags tag1,tag2]",
9
- run: async (args) => {
10
- const category = extractStrFlag(args, "--category", "").trim();
11
- const tags = splitCsv(extractStrFlag(args, "--tags", ""));
12
- const title = args.shift()?.trim() ?? "";
13
- const stdinContent = await readStdin();
14
- const content = stdinContent.trim().length > 0 ? stdinContent : args.join(" ").trim();
15
- if (!title || !category || !content.trim()) {
16
- console.error("Usage: kb remember <title> --category <cat> [--tags tag1,tag2]");
17
- process.exit(1);
18
- }
19
- const { curated } = await ctx();
20
- const result = await curated.remember(title, content, category, tags);
21
- console.log("Stored curated entry");
22
- console.log(` Path: ${result.path}`);
23
- console.log(` Category: ${category}`);
24
- if (tags.length > 0) console.log(` Tags: ${tags.join(", ")}`);
25
- }
26
- },
27
- {
28
- name: "forget",
29
- description: "Remove a curated entry",
30
- usage: "kb forget <path> --reason <reason>",
31
- run: async (args) => {
32
- const reason = extractStrFlag(args, "--reason", "").trim();
33
- const relativePath = args.shift()?.trim() ?? "";
34
- if (!relativePath || !reason) {
35
- console.error("Usage: kb forget <path> --reason <reason>");
36
- process.exit(1);
37
- }
38
- const { curated } = await ctx();
39
- const result = await curated.forget(relativePath, reason);
40
- console.log(`Removed curated entry: ${result.path}`);
41
- }
42
- },
43
- {
44
- name: "read",
45
- description: "Read a curated entry",
46
- usage: "kb read <path>",
47
- run: async (args) => {
48
- const relativePath = args.shift()?.trim() ?? "";
49
- if (!relativePath) {
50
- console.error("Usage: kb read <path>");
51
- process.exit(1);
52
- }
53
- const { curated } = await ctx();
54
- const entry = await curated.read(relativePath);
55
- console.log(entry.title);
56
- console.log("\u2500".repeat(60));
57
- console.log(`Path: ${entry.path}`);
58
- console.log(`Category: ${entry.category}`);
59
- console.log(`Version: ${entry.version}`);
60
- console.log(`Tags: ${entry.tags.length > 0 ? entry.tags.join(", ") : "None"}`);
61
- console.log("");
62
- console.log(entry.content);
63
- }
64
- },
65
- {
66
- name: "list",
67
- description: "List curated entries",
68
- usage: "kb list [--category <cat>] [--tag <tag>]",
69
- run: async (args) => {
70
- const category = extractStrFlag(args, "--category", "").trim() || void 0;
71
- const tag = extractStrFlag(args, "--tag", "").trim() || void 0;
72
- const { curated } = await ctx();
73
- const entries = await curated.list({ category, tag });
74
- if (entries.length === 0) {
75
- console.log("No curated entries found.");
76
- return;
77
- }
78
- console.log(`Curated entries (${entries.length})`);
79
- console.log("\u2500".repeat(60));
80
- for (const entry of entries) {
81
- console.log(entry.path);
82
- console.log(` ${entry.title}`);
83
- console.log(` Category: ${entry.category} | Version: ${entry.version}`);
84
- console.log(` Tags: ${entry.tags.length > 0 ? entry.tags.join(", ") : "None"}`);
85
- const preview = entry.contentPreview.replace(/\s+/g, " ").trim();
86
- if (preview) console.log(` Preview: ${preview}`);
87
- console.log("");
88
- }
89
- }
90
- },
91
- {
92
- name: "update",
93
- description: "Update a curated entry",
94
- usage: "kb update <path> --reason <reason>",
95
- run: async (args) => {
96
- const reason = extractStrFlag(args, "--reason", "").trim();
97
- const relativePath = args.shift()?.trim() ?? "";
98
- const content = await readStdin();
99
- if (!relativePath || !reason || !content.trim()) {
100
- console.error("Usage: kb update <path> --reason <reason>");
101
- process.exit(1);
102
- }
103
- const { curated } = await ctx();
104
- const result = await curated.update(relativePath, content, reason);
105
- console.log("Updated curated entry");
106
- console.log(` Path: ${result.path}`);
107
- console.log(` Version: ${result.version}`);
108
- }
109
- },
110
- {
111
- name: "compact",
112
- description: "Compress text for context",
113
- usage: "kb compact <query> [--max-chars N] [--segmentation paragraph|sentence|line]",
114
- run: async (args) => {
115
- const maxChars = extractNumFlag(args, "--max-chars", 3e3);
116
- const segmentation = extractStrFlag(args, "--segmentation", "paragraph");
117
- const query = args.join(" ").trim();
118
- const text = await readStdin();
119
- if (!query || !text.trim()) {
120
- console.error(
121
- "Usage: kb compact <query> [--max-chars N] [--segmentation paragraph|sentence|line]"
122
- );
123
- process.exit(1);
124
- }
125
- const { embedder } = await ctx();
126
- const result = await compact(embedder, { text, query, maxChars, segmentation });
127
- console.log(`Compressed ${result.originalChars} chars to ${result.compressedChars} chars`);
128
- console.log(
129
- `Ratio: ${(result.ratio * 100).toFixed(1)}% | Segments: ${result.segmentsKept}/${result.segmentsTotal}`
130
- );
131
- console.log("");
132
- console.log(result.text);
133
- }
134
- }
135
- ];
136
- export {
137
- knowledgeCommands
138
- };
139
- //# sourceMappingURL=knowledge.js.map
1
+ import{compact as m}from"@kb/tools";import{ctx as i}from"../context.js";import{extractNumFlag as p,extractStrFlag as c,readStdin as l,splitCsv as d}from"../helpers.js";const f=[{name:"remember",description:"Store curated knowledge",usage:"kb remember <title> --category <cat> [--tags tag1,tag2]",run:async t=>{const o=c(t,"--category","").trim(),a=d(c(t,"--tags","")),e=t.shift()?.trim()??"",r=await l(),n=r.trim().length>0?r:t.join(" ").trim();(!e||!o||!n.trim())&&(console.error("Usage: kb remember <title> --category <cat> [--tags tag1,tag2]"),process.exit(1));const{curated:s}=await i(),g=await s.remember(e,n,o,a);console.log("Stored curated entry"),console.log(` Path: ${g.path}`),console.log(` Category: ${o}`),a.length>0&&console.log(` Tags: ${a.join(", ")}`)}},{name:"forget",description:"Remove a curated entry",usage:"kb forget <path> --reason <reason>",run:async t=>{const o=c(t,"--reason","").trim(),a=t.shift()?.trim()??"";(!a||!o)&&(console.error("Usage: kb forget <path> --reason <reason>"),process.exit(1));const{curated:e}=await i(),r=await e.forget(a,o);console.log(`Removed curated entry: ${r.path}`)}},{name:"read",description:"Read a curated entry",usage:"kb read <path>",run:async t=>{const o=t.shift()?.trim()??"";o||(console.error("Usage: kb read <path>"),process.exit(1));const{curated:a}=await i(),e=await a.read(o);console.log(e.title),console.log("\u2500".repeat(60)),console.log(`Path: ${e.path}`),console.log(`Category: ${e.category}`),console.log(`Version: ${e.version}`),console.log(`Tags: ${e.tags.length>0?e.tags.join(", "):"None"}`),console.log(""),console.log(e.content)}},{name:"list",description:"List curated entries",usage:"kb list [--category <cat>] [--tag <tag>]",run:async t=>{const o=c(t,"--category","").trim()||void 0,a=c(t,"--tag","").trim()||void 0,{curated:e}=await i(),r=await e.list({category:o,tag:a});if(r.length===0){console.log("No curated entries found.");return}console.log(`Curated entries (${r.length})`),console.log("\u2500".repeat(60));for(const n of r){console.log(n.path),console.log(` ${n.title}`),console.log(` Category: ${n.category} | Version: ${n.version}`),console.log(` Tags: ${n.tags.length>0?n.tags.join(", "):"None"}`);const s=n.contentPreview.replace(/\s+/g," ").trim();s&&console.log(` Preview: ${s}`),console.log("")}}},{name:"update",description:"Update a curated entry",usage:"kb update <path> --reason <reason>",run:async t=>{const o=c(t,"--reason","").trim(),a=t.shift()?.trim()??"",e=await l();(!a||!o||!e.trim())&&(console.error("Usage: kb update <path> --reason <reason>"),process.exit(1));const{curated:r}=await i(),n=await r.update(a,e,o);console.log("Updated curated entry"),console.log(` Path: ${n.path}`),console.log(` Version: ${n.version}`)}},{name:"compact",description:"Compress text for context",usage:"kb compact <query> [--max-chars N] [--segmentation paragraph|sentence|line]",run:async t=>{const o=p(t,"--max-chars",3e3),a=c(t,"--segmentation","paragraph"),e=t.join(" ").trim(),r=await l();(!e||!r.trim())&&(console.error("Usage: kb compact <query> [--max-chars N] [--segmentation paragraph|sentence|line]"),process.exit(1));const{embedder:n}=await i(),s=await m(n,{text:r,query:e,maxChars:o,segmentation:a});console.log(`Compressed ${s.originalChars} chars to ${s.compressedChars} chars`),console.log(`Ratio: ${(s.ratio*100).toFixed(1)}% | Segments: ${s.segmentsKept}/${s.segmentsTotal}`),console.log(""),console.log(s.text)}}];export{f as knowledgeCommands};
@@ -1,267 +1,8 @@
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
1
+ import{find as $,findDeadSymbols as k,findExamples as x,scopeMap as w,symbol as N,trace as R}from"@kb/tools";import{ctx as g}from"../context.js";import{extractNumFlag as p,extractStrFlag as h,formatFocusRanges as T,printDeadSymbolsResult as C,printExamplesResult as F,printSymbolInfo as S,printTraceResult as j,rrf as I}from"../helpers.js";const v=[{name:"search",description:"Search the knowledge base",usage:"kb search <query> [--limit N] [--mode hybrid|semantic|keyword] [--graph-hops 0-3]",run:async o=>{const t=p(o,"--limit",5),r=h(o,"--mode","hybrid"),e=p(o,"--graph-hops",0),s=o.join(" ").trim();s||(console.error("Usage: kb search <query>"),process.exit(1));const{embedder:n,store:a,graphStore:c}=await g(),l=await n.embedQuery(s);let d;if(r==="keyword")d=await a.ftsSearch(s,{limit:t});else if(r==="semantic")d=await a.search(l,{limit:t});else{const[i,f]=await Promise.all([a.search(l,{limit:t*2}),a.ftsSearch(s,{limit:t*2}).catch(()=>[])]);d=I(i,f).slice(0,t)}if(d.length===0){console.log("No results found.");return}for(const{record:i,score:f}of d){console.log(`
2
+ ${"\u2500".repeat(60)}`),console.log(`[${(f*100).toFixed(1)}%] ${i.sourcePath}:${i.startLine}-${i.endLine}`),console.log(` Type: ${i.contentType} | Origin: ${i.origin}`),i.tags.length>0&&console.log(` Tags: ${i.tags.join(", ")}`),console.log("");const y=i.content.length>500?`${i.content.slice(0,500)}...`:i.content;console.log(y)}if(console.log(`
3
+ ${"\u2500".repeat(60)}`),console.log(`${d.length} result(s) found.`),e>0&&d.length>0)try{const{graphAugmentSearch:i}=await import("@kb/tools"),f=d.map(m=>({recordId:m.record.id,score:m.score,sourcePath:m.record.sourcePath})),b=(await i(c,f,{hops:e,maxPerHit:5})).filter(m=>m.graphContext.nodes.length>0);if(b.length>0){console.log(`
4
+ Graph context (${e} hop${e>1?"s":""}):
5
+ `);for(const m of b){console.log(` ${m.sourcePath}:`);for(const u of m.graphContext.nodes.slice(0,5))console.log(` \u2192 ${u.name} (${u.type})`);for(const u of m.graphContext.edges.slice(0,5))console.log(` \u2192 ${u.fromId} --[${u.type}]--> ${u.toId}`)}}}catch(i){console.error(`[graph] augmentation failed: ${i.message}`)}}},{name:"find",description:"Run federated search across indexed content and files",usage:"kb find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]",run:async o=>{const t=p(o,"--limit",10),r=h(o,"--glob","").trim()||void 0,e=h(o,"--pattern","").trim()||void 0,s=o.join(" ").trim()||void 0;!s&&!r&&!e&&(console.error("Usage: kb find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]"),process.exit(1));const{embedder:n,store:a}=await g(),c=await $(n,a,{query:s,glob:r,pattern:e,limit:t});if(c.results.length===0){console.log("No matches found.");return}console.log(`Strategies: ${c.strategies.join(", ")}`),console.log(`Results: ${c.results.length} shown (${c.totalFound} total)`);for(const l of c.results){const d=l.lineRange?`:${l.lineRange.start}-${l.lineRange.end}`:"";console.log(`
6
+ [${l.source}] ${l.path}${d}`),console.log(` Score: ${(l.score*100).toFixed(1)}%`),l.preview&&console.log(` ${l.preview.replace(/\s+/g," ").trim()}`)}}},{name:"scope-map",description:"Generate a reading plan for a task",usage:"kb scope-map <task> [--max-files N]",run:async o=>{const t=p(o,"--max-files",15),r=o.join(" ").trim();r||(console.error("Usage: kb scope-map <task> [--max-files N]"),process.exit(1));const{embedder:e,store:s}=await g(),n=await w(e,s,{task:r,maxFiles:t});console.log(`Task: ${n.task}`),console.log(`Files: ${n.files.length}`),console.log(`Estimated tokens: ${n.totalEstimatedTokens}`),console.log(""),console.log("Reading order:");for(const a of n.readingOrder)console.log(` ${a}`);for(const[a,c]of n.files.entries())console.log(`
7
+ ${a+1}. ${c.path}`),console.log(` Relevance: ${(c.relevance*100).toFixed(1)}% | Tokens: ${c.estimatedTokens}`),console.log(` Why: ${c.reason}`),c.focusRanges.length>0&&console.log(` Focus: ${T(c.focusRanges)}`)}},{name:"symbol",description:"Resolve a symbol definition, imports, and references",usage:"kb symbol <name> [--limit N]",run:async o=>{const t=p(o,"--limit",20),r=o.join(" ").trim();r||(console.error("Usage: kb symbol <name> [--limit N]"),process.exit(1));const{embedder:e,store:s}=await g(),n=await N(e,s,{name:r,limit:t});S(n)}},{name:"trace",description:"Trace forward/backward flow for a symbol or file location",usage:"kb trace <start> [--direction forward|backward|both] [--max-depth N]",run:async o=>{const t=h(o,"--direction","both").trim()||"both",r=p(o,"--max-depth",3),e=o.join(" ").trim();(!e||!["forward","backward","both"].includes(t))&&(console.error("Usage: kb trace <start> [--direction forward|backward|both] [--max-depth N]"),process.exit(1));const{embedder:s,store:n}=await g(),a=await R(s,n,{start:e,direction:t,maxDepth:r});j(a)}},{name:"examples",description:"Find real code examples of a symbol or pattern",usage:"kb examples <query> [--limit N] [--content-type type]",run:async o=>{const t=p(o,"--limit",5),r=h(o,"--content-type","").trim()||void 0,e=o.join(" ").trim();e||(console.error("Usage: kb examples <query> [--limit N] [--content-type type]"),process.exit(1));const{embedder:s,store:n}=await g(),a=await x(s,n,{query:e,limit:t,contentType:r});F(a)}},{name:"dead-symbols",description:"Find exported symbols that appear to be unused",usage:"kb dead-symbols [--limit N]",run:async o=>{const t=p(o,"--limit",100),{embedder:r,store:e}=await g(),s=await k(r,e,{limit:t});C(s)}},{name:"lookup",description:"Look up indexed content by record ID or source path",usage:"kb lookup <id>",run:async o=>{const t=o.join(" ").trim();t||(console.error("Usage: kb lookup <id>"),process.exit(1));const{store:r}=await g(),e=await r.getById(t);if(e){console.log(e.id),console.log("\u2500".repeat(60)),console.log(`Path: ${e.sourcePath}`),console.log(`Chunk: ${e.chunkIndex+1}/${e.totalChunks}`),console.log(`Lines: ${e.startLine}-${e.endLine}`),console.log(`Type: ${e.contentType} | Origin: ${e.origin}`),e.tags.length>0&&console.log(`Tags: ${e.tags.join(", ")}`),console.log(""),console.log(e.content);return}const s=await r.getBySourcePath(t);if(s.length===0){console.log(`No indexed content found for: ${t}`);return}s.sort((n,a)=>n.chunkIndex-a.chunkIndex),console.log(t),console.log("\u2500".repeat(60)),console.log(`Chunks: ${s.length} | Type: ${s[0].contentType}`);for(const n of s){const a=n.startLine?` (lines ${n.startLine}-${n.endLine})`:"";console.log(`
8
+ Chunk ${n.chunkIndex+1}/${n.totalChunks}${a}`),console.log(n.content)}}}];export{v as searchCommands};