@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.
Files changed (275) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1140 -0
  3. package/bin/kb.mjs +10 -0
  4. package/package.json +67 -0
  5. package/packages/analyzers/dist/blast-radius-analyzer.d.ts +23 -0
  6. package/packages/analyzers/dist/blast-radius-analyzer.js +114 -0
  7. package/packages/analyzers/dist/dependency-analyzer.d.ts +29 -0
  8. package/packages/analyzers/dist/dependency-analyzer.js +425 -0
  9. package/packages/analyzers/dist/diagram-generator.d.ts +13 -0
  10. package/packages/analyzers/dist/diagram-generator.js +86 -0
  11. package/packages/analyzers/dist/entry-point-analyzer.d.ts +19 -0
  12. package/packages/analyzers/dist/entry-point-analyzer.js +239 -0
  13. package/packages/analyzers/dist/index.d.ts +14 -0
  14. package/packages/analyzers/dist/index.js +23 -0
  15. package/packages/analyzers/dist/knowledge-producer.d.ts +32 -0
  16. package/packages/analyzers/dist/knowledge-producer.js +113 -0
  17. package/packages/analyzers/dist/pattern-analyzer.d.ts +12 -0
  18. package/packages/analyzers/dist/pattern-analyzer.js +359 -0
  19. package/packages/analyzers/dist/regex-call-graph.d.ts +17 -0
  20. package/packages/analyzers/dist/regex-call-graph.js +428 -0
  21. package/packages/analyzers/dist/structure-analyzer.d.ts +11 -0
  22. package/packages/analyzers/dist/structure-analyzer.js +258 -0
  23. package/packages/analyzers/dist/symbol-analyzer.d.ts +10 -0
  24. package/packages/analyzers/dist/symbol-analyzer.js +442 -0
  25. package/packages/analyzers/dist/ts-call-graph.d.ts +27 -0
  26. package/packages/analyzers/dist/ts-call-graph.js +160 -0
  27. package/packages/analyzers/dist/types.d.ts +98 -0
  28. package/packages/analyzers/dist/types.js +1 -0
  29. package/packages/chunker/dist/call-graph-extractor.d.ts +22 -0
  30. package/packages/chunker/dist/call-graph-extractor.js +90 -0
  31. package/packages/chunker/dist/chunker-factory.d.ts +7 -0
  32. package/packages/chunker/dist/chunker-factory.js +36 -0
  33. package/packages/chunker/dist/chunker.interface.d.ts +10 -0
  34. package/packages/chunker/dist/chunker.interface.js +1 -0
  35. package/packages/chunker/dist/code-chunker.d.ts +14 -0
  36. package/packages/chunker/dist/code-chunker.js +134 -0
  37. package/packages/chunker/dist/generic-chunker.d.ts +12 -0
  38. package/packages/chunker/dist/generic-chunker.js +72 -0
  39. package/packages/chunker/dist/index.d.ts +8 -0
  40. package/packages/chunker/dist/index.js +21 -0
  41. package/packages/chunker/dist/markdown-chunker.d.ts +14 -0
  42. package/packages/chunker/dist/markdown-chunker.js +122 -0
  43. package/packages/chunker/dist/treesitter-chunker.d.ts +47 -0
  44. package/packages/chunker/dist/treesitter-chunker.js +234 -0
  45. package/packages/cli/dist/commands/analyze.d.ts +3 -0
  46. package/packages/cli/dist/commands/analyze.js +112 -0
  47. package/packages/cli/dist/commands/context-cmds.d.ts +3 -0
  48. package/packages/cli/dist/commands/context-cmds.js +155 -0
  49. package/packages/cli/dist/commands/environment.d.ts +3 -0
  50. package/packages/cli/dist/commands/environment.js +204 -0
  51. package/packages/cli/dist/commands/execution.d.ts +3 -0
  52. package/packages/cli/dist/commands/execution.js +137 -0
  53. package/packages/cli/dist/commands/graph.d.ts +3 -0
  54. package/packages/cli/dist/commands/graph.js +81 -0
  55. package/packages/cli/dist/commands/init.d.ts +8 -0
  56. package/packages/cli/dist/commands/init.js +87 -0
  57. package/packages/cli/dist/commands/knowledge.d.ts +3 -0
  58. package/packages/cli/dist/commands/knowledge.js +139 -0
  59. package/packages/cli/dist/commands/search.d.ts +3 -0
  60. package/packages/cli/dist/commands/search.js +267 -0
  61. package/packages/cli/dist/commands/system.d.ts +3 -0
  62. package/packages/cli/dist/commands/system.js +241 -0
  63. package/packages/cli/dist/commands/workspace.d.ts +3 -0
  64. package/packages/cli/dist/commands/workspace.js +388 -0
  65. package/packages/cli/dist/context.d.ts +5 -0
  66. package/packages/cli/dist/context.js +14 -0
  67. package/packages/cli/dist/helpers.d.ts +52 -0
  68. package/packages/cli/dist/helpers.js +458 -0
  69. package/packages/cli/dist/index.d.ts +8 -0
  70. package/packages/cli/dist/index.js +69 -0
  71. package/packages/cli/dist/kb-init.d.ts +57 -0
  72. package/packages/cli/dist/kb-init.js +82 -0
  73. package/packages/cli/dist/types.d.ts +7 -0
  74. package/packages/cli/dist/types.js +1 -0
  75. package/packages/core/dist/constants.d.ts +49 -0
  76. package/packages/core/dist/constants.js +43 -0
  77. package/packages/core/dist/content-detector.d.ts +9 -0
  78. package/packages/core/dist/content-detector.js +79 -0
  79. package/packages/core/dist/errors.d.ts +18 -0
  80. package/packages/core/dist/errors.js +40 -0
  81. package/packages/core/dist/index.d.ts +6 -0
  82. package/packages/core/dist/index.js +9 -0
  83. package/packages/core/dist/logger.d.ts +9 -0
  84. package/packages/core/dist/logger.js +34 -0
  85. package/packages/core/dist/types.d.ts +108 -0
  86. package/packages/core/dist/types.js +1 -0
  87. package/packages/embeddings/dist/embedder.interface.d.ts +24 -0
  88. package/packages/embeddings/dist/embedder.interface.js +1 -0
  89. package/packages/embeddings/dist/index.d.ts +3 -0
  90. package/packages/embeddings/dist/index.js +5 -0
  91. package/packages/embeddings/dist/onnx-embedder.d.ts +24 -0
  92. package/packages/embeddings/dist/onnx-embedder.js +82 -0
  93. package/packages/indexer/dist/file-hasher.d.ts +11 -0
  94. package/packages/indexer/dist/file-hasher.js +13 -0
  95. package/packages/indexer/dist/filesystem-crawler.d.ts +27 -0
  96. package/packages/indexer/dist/filesystem-crawler.js +125 -0
  97. package/packages/indexer/dist/graph-extractor.d.ts +22 -0
  98. package/packages/indexer/dist/graph-extractor.js +111 -0
  99. package/packages/indexer/dist/incremental-indexer.d.ts +47 -0
  100. package/packages/indexer/dist/incremental-indexer.js +278 -0
  101. package/packages/indexer/dist/index.d.ts +5 -0
  102. package/packages/indexer/dist/index.js +14 -0
  103. package/packages/server/dist/api.d.ts +8 -0
  104. package/packages/server/dist/api.js +9 -0
  105. package/packages/server/dist/config.d.ts +3 -0
  106. package/packages/server/dist/config.js +75 -0
  107. package/packages/server/dist/curated-manager.d.ts +86 -0
  108. package/packages/server/dist/curated-manager.js +357 -0
  109. package/packages/server/dist/index.d.ts +2 -0
  110. package/packages/server/dist/index.js +134 -0
  111. package/packages/server/dist/replay-interceptor.d.ts +11 -0
  112. package/packages/server/dist/replay-interceptor.js +38 -0
  113. package/packages/server/dist/resources/resources.d.ts +4 -0
  114. package/packages/server/dist/resources/resources.js +40 -0
  115. package/packages/server/dist/server.d.ts +21 -0
  116. package/packages/server/dist/server.js +247 -0
  117. package/packages/server/dist/tools/analyze.tools.d.ts +11 -0
  118. package/packages/server/dist/tools/analyze.tools.js +288 -0
  119. package/packages/server/dist/tools/forge.tools.d.ts +12 -0
  120. package/packages/server/dist/tools/forge.tools.js +501 -0
  121. package/packages/server/dist/tools/forget.tool.d.ts +4 -0
  122. package/packages/server/dist/tools/forget.tool.js +43 -0
  123. package/packages/server/dist/tools/graph.tool.d.ts +4 -0
  124. package/packages/server/dist/tools/graph.tool.js +110 -0
  125. package/packages/server/dist/tools/list.tool.d.ts +4 -0
  126. package/packages/server/dist/tools/list.tool.js +56 -0
  127. package/packages/server/dist/tools/lookup.tool.d.ts +4 -0
  128. package/packages/server/dist/tools/lookup.tool.js +53 -0
  129. package/packages/server/dist/tools/onboard.tool.d.ts +5 -0
  130. package/packages/server/dist/tools/onboard.tool.js +112 -0
  131. package/packages/server/dist/tools/produce.tool.d.ts +3 -0
  132. package/packages/server/dist/tools/produce.tool.js +74 -0
  133. package/packages/server/dist/tools/read.tool.d.ts +4 -0
  134. package/packages/server/dist/tools/read.tool.js +49 -0
  135. package/packages/server/dist/tools/reindex.tool.d.ts +7 -0
  136. package/packages/server/dist/tools/reindex.tool.js +70 -0
  137. package/packages/server/dist/tools/remember.tool.d.ts +4 -0
  138. package/packages/server/dist/tools/remember.tool.js +45 -0
  139. package/packages/server/dist/tools/replay.tool.d.ts +3 -0
  140. package/packages/server/dist/tools/replay.tool.js +89 -0
  141. package/packages/server/dist/tools/search.tool.d.ts +5 -0
  142. package/packages/server/dist/tools/search.tool.js +331 -0
  143. package/packages/server/dist/tools/status.tool.d.ts +4 -0
  144. package/packages/server/dist/tools/status.tool.js +68 -0
  145. package/packages/server/dist/tools/toolkit.tools.d.ts +35 -0
  146. package/packages/server/dist/tools/toolkit.tools.js +1674 -0
  147. package/packages/server/dist/tools/update.tool.d.ts +4 -0
  148. package/packages/server/dist/tools/update.tool.js +42 -0
  149. package/packages/server/dist/tools/utility.tools.d.ts +15 -0
  150. package/packages/server/dist/tools/utility.tools.js +461 -0
  151. package/packages/store/dist/graph-store.interface.d.ts +104 -0
  152. package/packages/store/dist/graph-store.interface.js +1 -0
  153. package/packages/store/dist/index.d.ts +6 -0
  154. package/packages/store/dist/index.js +9 -0
  155. package/packages/store/dist/lance-store.d.ts +32 -0
  156. package/packages/store/dist/lance-store.js +258 -0
  157. package/packages/store/dist/sqlite-graph-store.d.ts +43 -0
  158. package/packages/store/dist/sqlite-graph-store.js +374 -0
  159. package/packages/store/dist/store-factory.d.ts +9 -0
  160. package/packages/store/dist/store-factory.js +14 -0
  161. package/packages/store/dist/store.interface.d.ts +48 -0
  162. package/packages/store/dist/store.interface.js +1 -0
  163. package/packages/tools/dist/batch.d.ts +21 -0
  164. package/packages/tools/dist/batch.js +45 -0
  165. package/packages/tools/dist/changelog.d.ts +34 -0
  166. package/packages/tools/dist/changelog.js +112 -0
  167. package/packages/tools/dist/check.d.ts +26 -0
  168. package/packages/tools/dist/check.js +59 -0
  169. package/packages/tools/dist/checkpoint.d.ts +17 -0
  170. package/packages/tools/dist/checkpoint.js +43 -0
  171. package/packages/tools/dist/codemod.d.ts +37 -0
  172. package/packages/tools/dist/codemod.js +69 -0
  173. package/packages/tools/dist/compact.d.ts +41 -0
  174. package/packages/tools/dist/compact.js +60 -0
  175. package/packages/tools/dist/data-transform.d.ts +10 -0
  176. package/packages/tools/dist/data-transform.js +124 -0
  177. package/packages/tools/dist/dead-symbols.d.ts +21 -0
  178. package/packages/tools/dist/dead-symbols.js +71 -0
  179. package/packages/tools/dist/delegate.d.ts +34 -0
  180. package/packages/tools/dist/delegate.js +130 -0
  181. package/packages/tools/dist/diff-parse.d.ts +26 -0
  182. package/packages/tools/dist/diff-parse.js +153 -0
  183. package/packages/tools/dist/digest.d.ts +53 -0
  184. package/packages/tools/dist/digest.js +242 -0
  185. package/packages/tools/dist/encode.d.ts +14 -0
  186. package/packages/tools/dist/encode.js +46 -0
  187. package/packages/tools/dist/env-info.d.ts +28 -0
  188. package/packages/tools/dist/env-info.js +58 -0
  189. package/packages/tools/dist/eval.d.ts +13 -0
  190. package/packages/tools/dist/eval.js +79 -0
  191. package/packages/tools/dist/evidence-map.d.ts +79 -0
  192. package/packages/tools/dist/evidence-map.js +203 -0
  193. package/packages/tools/dist/file-summary.d.ts +32 -0
  194. package/packages/tools/dist/file-summary.js +106 -0
  195. package/packages/tools/dist/file-walk.d.ts +4 -0
  196. package/packages/tools/dist/file-walk.js +75 -0
  197. package/packages/tools/dist/find-examples.d.ts +25 -0
  198. package/packages/tools/dist/find-examples.js +48 -0
  199. package/packages/tools/dist/find.d.ts +47 -0
  200. package/packages/tools/dist/find.js +120 -0
  201. package/packages/tools/dist/forge-classify.d.ts +44 -0
  202. package/packages/tools/dist/forge-classify.js +319 -0
  203. package/packages/tools/dist/forge-ground.d.ts +64 -0
  204. package/packages/tools/dist/forge-ground.js +184 -0
  205. package/packages/tools/dist/git-context.d.ts +22 -0
  206. package/packages/tools/dist/git-context.js +46 -0
  207. package/packages/tools/dist/graph-query.d.ts +89 -0
  208. package/packages/tools/dist/graph-query.js +194 -0
  209. package/packages/tools/dist/health.d.ts +14 -0
  210. package/packages/tools/dist/health.js +118 -0
  211. package/packages/tools/dist/http-request.d.ts +23 -0
  212. package/packages/tools/dist/http-request.js +58 -0
  213. package/packages/tools/dist/index.d.ts +49 -0
  214. package/packages/tools/dist/index.js +273 -0
  215. package/packages/tools/dist/lane.d.ts +39 -0
  216. package/packages/tools/dist/lane.js +227 -0
  217. package/packages/tools/dist/measure.d.ts +38 -0
  218. package/packages/tools/dist/measure.js +119 -0
  219. package/packages/tools/dist/onboard.d.ts +41 -0
  220. package/packages/tools/dist/onboard.js +1139 -0
  221. package/packages/tools/dist/parse-output.d.ts +80 -0
  222. package/packages/tools/dist/parse-output.js +158 -0
  223. package/packages/tools/dist/process-manager.d.ts +18 -0
  224. package/packages/tools/dist/process-manager.js +69 -0
  225. package/packages/tools/dist/queue.d.ts +38 -0
  226. package/packages/tools/dist/queue.js +126 -0
  227. package/packages/tools/dist/regex-test.d.ts +31 -0
  228. package/packages/tools/dist/regex-test.js +39 -0
  229. package/packages/tools/dist/rename.d.ts +29 -0
  230. package/packages/tools/dist/rename.js +70 -0
  231. package/packages/tools/dist/replay.d.ts +56 -0
  232. package/packages/tools/dist/replay.js +108 -0
  233. package/packages/tools/dist/schema-validate.d.ts +23 -0
  234. package/packages/tools/dist/schema-validate.js +141 -0
  235. package/packages/tools/dist/scope-map.d.ts +52 -0
  236. package/packages/tools/dist/scope-map.js +72 -0
  237. package/packages/tools/dist/snippet.d.ts +34 -0
  238. package/packages/tools/dist/snippet.js +80 -0
  239. package/packages/tools/dist/stash.d.ts +12 -0
  240. package/packages/tools/dist/stash.js +60 -0
  241. package/packages/tools/dist/stratum-card.d.ts +31 -0
  242. package/packages/tools/dist/stratum-card.js +239 -0
  243. package/packages/tools/dist/symbol.d.ts +28 -0
  244. package/packages/tools/dist/symbol.js +87 -0
  245. package/packages/tools/dist/test-run.d.ts +23 -0
  246. package/packages/tools/dist/test-run.js +55 -0
  247. package/packages/tools/dist/text-utils.d.ts +16 -0
  248. package/packages/tools/dist/text-utils.js +31 -0
  249. package/packages/tools/dist/time-utils.d.ts +18 -0
  250. package/packages/tools/dist/time-utils.js +135 -0
  251. package/packages/tools/dist/trace.d.ts +24 -0
  252. package/packages/tools/dist/trace.js +114 -0
  253. package/packages/tools/dist/truncation.d.ts +22 -0
  254. package/packages/tools/dist/truncation.js +45 -0
  255. package/packages/tools/dist/watch.d.ts +30 -0
  256. package/packages/tools/dist/watch.js +61 -0
  257. package/packages/tools/dist/web-fetch.d.ts +45 -0
  258. package/packages/tools/dist/web-fetch.js +249 -0
  259. package/packages/tools/dist/web-search.d.ts +23 -0
  260. package/packages/tools/dist/web-search.js +46 -0
  261. package/packages/tools/dist/workset.d.ts +45 -0
  262. package/packages/tools/dist/workset.js +77 -0
  263. package/packages/tui/dist/App.d.ts +8 -0
  264. package/packages/tui/dist/App.js +52659 -0
  265. package/packages/tui/dist/index.d.ts +19 -0
  266. package/packages/tui/dist/index.js +54742 -0
  267. package/packages/tui/dist/panels/CuratedPanel.d.ts +8 -0
  268. package/packages/tui/dist/panels/CuratedPanel.js +34452 -0
  269. package/packages/tui/dist/panels/LogPanel.d.ts +3 -0
  270. package/packages/tui/dist/panels/LogPanel.js +51894 -0
  271. package/packages/tui/dist/panels/SearchPanel.d.ts +10 -0
  272. package/packages/tui/dist/panels/SearchPanel.js +34985 -0
  273. package/packages/tui/dist/panels/StatusPanel.d.ts +8 -0
  274. package/packages/tui/dist/panels/StatusPanel.js +34465 -0
  275. package/skills/knowledge-base/SKILL.md +316 -0
@@ -0,0 +1,125 @@
1
+ import { lstat, readdir, readFile, stat } from "node:fs/promises";
2
+ import { extname, join, relative } from "node:path";
3
+ import { FILE_LIMITS } from "@kb/core";
4
+ import { minimatch } from "minimatch";
5
+ class FilesystemCrawler {
6
+ /** Binary file extensions that should always be skipped */
7
+ static BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
8
+ ".node",
9
+ ".so",
10
+ ".dylib",
11
+ ".dll",
12
+ ".wasm",
13
+ ".bin",
14
+ ".exe",
15
+ ".png",
16
+ ".jpg",
17
+ ".jpeg",
18
+ ".gif",
19
+ ".bmp",
20
+ ".ico",
21
+ ".webp",
22
+ ".svg",
23
+ ".mp3",
24
+ ".mp4",
25
+ ".wav",
26
+ ".avi",
27
+ ".mov",
28
+ ".flac",
29
+ ".zip",
30
+ ".gz",
31
+ ".tar",
32
+ ".bz2",
33
+ ".7z",
34
+ ".rar",
35
+ ".pdf",
36
+ ".doc",
37
+ ".docx",
38
+ ".xls",
39
+ ".xlsx",
40
+ ".ppt",
41
+ ".pptx",
42
+ ".ttf",
43
+ ".otf",
44
+ ".woff",
45
+ ".woff2",
46
+ ".eot",
47
+ ".pyc",
48
+ ".class",
49
+ ".o",
50
+ ".obj",
51
+ ".a",
52
+ ".lib"
53
+ ]);
54
+ async crawl(options) {
55
+ const results = [];
56
+ const visited = /* @__PURE__ */ new Set();
57
+ await this.walkDir(options.rootDir, options.rootDir, options.excludePatterns, results, visited);
58
+ return results;
59
+ }
60
+ async walkDir(dir, rootDir, excludePatterns, results, visited) {
61
+ let entries;
62
+ try {
63
+ entries = await readdir(dir, { withFileTypes: true });
64
+ } catch (err) {
65
+ const code = err.code;
66
+ if (code === "EACCES" || code === "EPERM") {
67
+ console.error(`[KB] Permission denied, skipping directory: ${dir}`);
68
+ }
69
+ return;
70
+ }
71
+ for (const entry of entries) {
72
+ const fullPath = join(dir, entry.name);
73
+ const relPath = relative(rootDir, fullPath).replace(/\\/g, "/");
74
+ if (this.isExcluded(relPath, excludePatterns)) {
75
+ continue;
76
+ }
77
+ if (entry.isDirectory()) {
78
+ if (entry.name.startsWith(".")) {
79
+ continue;
80
+ }
81
+ try {
82
+ const linkStat = await lstat(fullPath);
83
+ if (linkStat.isSymbolicLink()) {
84
+ continue;
85
+ }
86
+ } catch {
87
+ continue;
88
+ }
89
+ const realPath = fullPath;
90
+ if (visited.has(realPath)) continue;
91
+ visited.add(realPath);
92
+ await this.walkDir(fullPath, rootDir, excludePatterns, results, visited);
93
+ } else if (entry.isFile()) {
94
+ const ext = extname(entry.name).toLowerCase();
95
+ if (FilesystemCrawler.BINARY_EXTENSIONS.has(ext)) {
96
+ continue;
97
+ }
98
+ try {
99
+ const fileStat = await stat(fullPath);
100
+ if (fileStat.size > FILE_LIMITS.maxFileSizeBytes) {
101
+ continue;
102
+ }
103
+ const content = await readFile(fullPath, "utf-8");
104
+ if (content.includes("\0")) {
105
+ continue;
106
+ }
107
+ results.push({
108
+ relativePath: relPath,
109
+ absolutePath: fullPath,
110
+ content,
111
+ extension: ext
112
+ });
113
+ } catch {
114
+ }
115
+ }
116
+ }
117
+ }
118
+ isExcluded(relativePath, patterns) {
119
+ return patterns.some((pattern) => minimatch(relativePath, pattern, { dot: true }));
120
+ }
121
+ }
122
+ export {
123
+ FilesystemCrawler
124
+ };
125
+ //# sourceMappingURL=filesystem-crawler.js.map
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Lightweight graph extraction for automatic population during indexing.
3
+ * Extracts symbols (functions, classes, interfaces, etc.) and import relationships
4
+ * from source code, producing GraphNode[] and GraphEdge[] for the graph store.
5
+ *
6
+ * Focuses on TS/JS — the primary use case. Non-code files return empty graphs.
7
+ */
8
+ import type { GraphEdge, GraphNode } from '@kb/store';
9
+ export interface ExtractedGraph {
10
+ nodes: GraphNode[];
11
+ edges: GraphEdge[];
12
+ }
13
+ /**
14
+ * Extract graph nodes and edges from a single file's content.
15
+ * Produces:
16
+ * - One "module" node per file
17
+ * - Symbol nodes (function, class, interface, type, const, enum)
18
+ * - "defines" edges from module → symbol
19
+ * - "imports" edges from module → imported module
20
+ */
21
+ export declare function extractGraph(content: string, sourcePath: string): ExtractedGraph;
22
+ //# sourceMappingURL=graph-extractor.d.ts.map
@@ -0,0 +1,111 @@
1
+ import { createHash } from "node:crypto";
2
+ import { dirname, extname, join } from "node:path";
3
+ const CODE_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
4
+ const SYMBOL_PATTERNS = [
5
+ // Exported
6
+ { pattern: /^export\s+(?:async\s+)?function\s+(\w+)/gm, kind: "function", exported: true },
7
+ { pattern: /^export\s+(?:default\s+)?class\s+(\w+)/gm, kind: "class", exported: true },
8
+ { pattern: /^export\s+interface\s+(\w+)/gm, kind: "interface", exported: true },
9
+ { pattern: /^export\s+type\s+(\w+)/gm, kind: "type", exported: true },
10
+ { pattern: /^export\s+(?:const|let)\s+(\w+)/gm, kind: "const", exported: true },
11
+ { pattern: /^export\s+enum\s+(\w+)/gm, kind: "enum", exported: true },
12
+ // Non-exported (top-level only)
13
+ { pattern: /^(?:async\s+)?function\s+(\w+)/gm, kind: "function", exported: false },
14
+ { pattern: /^class\s+(\w+)/gm, kind: "class", exported: false },
15
+ { pattern: /^interface\s+(\w+)/gm, kind: "interface", exported: false },
16
+ { pattern: /^type\s+(\w+)/gm, kind: "type", exported: false },
17
+ { pattern: /^enum\s+(\w+)/gm, kind: "enum", exported: false }
18
+ ];
19
+ const IMPORT_PATTERNS = [
20
+ // ES import: import { x } from 'module' / import x from 'module' / import type { x } from '...'
21
+ /import\s+(?:(?:type\s+)?(?:(?:\{[^}]*\}|[\w*]+)\s+from\s+)?)['"]([^'"]+)['"]/g,
22
+ // Dynamic import: import('module')
23
+ /import\(\s*['"]([^'"]+)['"]\s*\)/g,
24
+ // CommonJS require: require('module')
25
+ /require\(\s*['"]([^'"]+)['"]\s*\)/g
26
+ ];
27
+ function nodeId(type, name, sourcePath) {
28
+ return createHash("sha256").update(`${type}:${name}:${sourcePath}`).digest("hex").slice(0, 16);
29
+ }
30
+ function edgeId(fromId, toId, type) {
31
+ return createHash("sha256").update(`${fromId}-${type}-${toId}`).digest("hex").slice(0, 16);
32
+ }
33
+ function resolveImportPath(importSource, fromPath) {
34
+ const dir = dirname(fromPath);
35
+ const resolved = join(dir, importSource).replace(/\\/g, "/");
36
+ return resolved.replace(/\.(js|jsx|ts|tsx|mjs|cjs)$/, "");
37
+ }
38
+ function moduleKey(sourcePath) {
39
+ return sourcePath.replace(/\.(js|jsx|ts|tsx|mjs|cjs)$/, "");
40
+ }
41
+ function extractGraph(content, sourcePath) {
42
+ const ext = extname(sourcePath).toLowerCase();
43
+ if (!CODE_EXTENSIONS.has(ext)) {
44
+ return { nodes: [], edges: [] };
45
+ }
46
+ const nodes = [];
47
+ const edges = [];
48
+ const now = (/* @__PURE__ */ new Date()).toISOString();
49
+ const seenSymbols = /* @__PURE__ */ new Set();
50
+ const mk = moduleKey(sourcePath);
51
+ const modId = nodeId("module", mk, mk);
52
+ nodes.push({
53
+ id: modId,
54
+ type: "module",
55
+ name: sourcePath,
56
+ properties: { ext },
57
+ sourcePath,
58
+ createdAt: now
59
+ });
60
+ for (const { pattern, kind, exported } of SYMBOL_PATTERNS) {
61
+ const regex = new RegExp(pattern.source, pattern.flags);
62
+ let match;
63
+ while ((match = regex.exec(content)) !== null) {
64
+ const name = match[1];
65
+ const key = `${kind}:${name}`;
66
+ if (seenSymbols.has(key)) continue;
67
+ seenSymbols.add(key);
68
+ const symId = nodeId(kind, name, sourcePath);
69
+ nodes.push({
70
+ id: symId,
71
+ type: kind,
72
+ name,
73
+ properties: { exported },
74
+ sourcePath,
75
+ createdAt: now
76
+ });
77
+ edges.push({
78
+ id: edgeId(modId, symId, "defines"),
79
+ fromId: modId,
80
+ toId: symId,
81
+ type: "defines",
82
+ weight: exported ? 1 : 0.5
83
+ });
84
+ }
85
+ }
86
+ const seenImports = /* @__PURE__ */ new Set();
87
+ for (const pattern of IMPORT_PATTERNS) {
88
+ const regex = new RegExp(pattern.source, pattern.flags);
89
+ let match;
90
+ while ((match = regex.exec(content)) !== null) {
91
+ const source = match[1];
92
+ if (!source.startsWith(".")) continue;
93
+ if (seenImports.has(source)) continue;
94
+ seenImports.add(source);
95
+ const targetKey = resolveImportPath(source, sourcePath);
96
+ const targetModId = nodeId("module", targetKey, targetKey);
97
+ edges.push({
98
+ id: edgeId(modId, targetModId, "imports"),
99
+ fromId: modId,
100
+ toId: targetModId,
101
+ type: "imports",
102
+ properties: { source }
103
+ });
104
+ }
105
+ }
106
+ return { nodes, edges };
107
+ }
108
+ export {
109
+ extractGraph
110
+ };
111
+ //# sourceMappingURL=graph-extractor.js.map
@@ -0,0 +1,47 @@
1
+ import type { IndexStats, KBConfig } from '@kb/core';
2
+ import type { IEmbedder } from '@kb/embeddings';
3
+ import type { IGraphStore, IKnowledgeStore } from '@kb/store';
4
+ export interface IndexProgress {
5
+ phase: 'crawling' | 'chunking' | 'embedding' | 'storing' | 'cleanup' | 'done';
6
+ filesTotal: number;
7
+ filesProcessed: number;
8
+ chunksTotal: number;
9
+ chunksProcessed: number;
10
+ /** The file currently being processed */
11
+ currentFile?: string;
12
+ }
13
+ export type ProgressCallback = (progress: IndexProgress) => void;
14
+ export interface IndexResult {
15
+ filesProcessed: number;
16
+ filesSkipped: number;
17
+ chunksCreated: number;
18
+ filesRemoved: number;
19
+ durationMs: number;
20
+ }
21
+ export declare class IncrementalIndexer {
22
+ private readonly embedder;
23
+ private readonly store;
24
+ private readonly crawler;
25
+ private indexing;
26
+ private graphStore?;
27
+ constructor(embedder: IEmbedder, store: IKnowledgeStore);
28
+ /** Set the graph store for auto-population during indexing and cleanup on re-index. */
29
+ setGraphStore(graphStore: IGraphStore): void;
30
+ /**
31
+ * Index all configured sources. Only re-indexes files that have changed.
32
+ * Sources are crawled in parallel, and file processing runs concurrently
33
+ * up to `config.indexing.concurrency` (default: half of CPU cores).
34
+ */
35
+ index(config: KBConfig, onProgress?: ProgressCallback): Promise<IndexResult>;
36
+ private doIndex;
37
+ /**
38
+ * Force re-index all files (ignoring hashes).
39
+ */
40
+ reindexAll(config: KBConfig, onProgress?: ProgressCallback): Promise<IndexResult>;
41
+ private doReindex;
42
+ /**
43
+ * Get current index statistics.
44
+ */
45
+ getStats(): Promise<IndexStats>;
46
+ }
47
+ //# sourceMappingURL=incremental-indexer.d.ts.map
@@ -0,0 +1,278 @@
1
+ import { availableParallelism } from "node:os";
2
+ import { createChunker } from "@kb/chunker";
3
+ import { detectContentType } from "@kb/core";
4
+ import { generateRecordId, hashContent } from "./file-hasher.js";
5
+ import { FilesystemCrawler } from "./filesystem-crawler.js";
6
+ import { extractGraph } from "./graph-extractor.js";
7
+ async function runConcurrent(items, fn, concurrency, onError) {
8
+ let nextIndex = 0;
9
+ async function worker() {
10
+ while (nextIndex < items.length) {
11
+ const i = nextIndex++;
12
+ try {
13
+ await fn(items[i]);
14
+ } catch (err) {
15
+ onError?.(items[i], err);
16
+ }
17
+ }
18
+ }
19
+ await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
20
+ }
21
+ const DEFAULT_CONCURRENCY = Math.max(1, Math.floor(availableParallelism() / 2));
22
+ class IncrementalIndexer {
23
+ constructor(embedder, store) {
24
+ this.embedder = embedder;
25
+ this.store = store;
26
+ this.crawler = new FilesystemCrawler();
27
+ }
28
+ crawler;
29
+ indexing = false;
30
+ graphStore;
31
+ /** Set the graph store for auto-population during indexing and cleanup on re-index. */
32
+ setGraphStore(graphStore) {
33
+ this.graphStore = graphStore;
34
+ }
35
+ /**
36
+ * Index all configured sources. Only re-indexes files that have changed.
37
+ * Sources are crawled in parallel, and file processing runs concurrently
38
+ * up to `config.indexing.concurrency` (default: half of CPU cores).
39
+ */
40
+ async index(config, onProgress) {
41
+ if (this.indexing) {
42
+ throw new Error("Indexing is already in progress");
43
+ }
44
+ this.indexing = true;
45
+ try {
46
+ return await this.doIndex(config, onProgress, {});
47
+ } finally {
48
+ this.indexing = false;
49
+ }
50
+ }
51
+ async doIndex(config, onProgress, opts = {}) {
52
+ const startTime = Date.now();
53
+ let filesProcessed = 0;
54
+ let filesSkipped = 0;
55
+ let chunksCreated = 0;
56
+ let filesRemoved = 0;
57
+ const concurrency = config.indexing.concurrency ?? DEFAULT_CONCURRENCY;
58
+ onProgress?.({
59
+ phase: "crawling",
60
+ filesTotal: 0,
61
+ filesProcessed: 0,
62
+ chunksTotal: 0,
63
+ chunksProcessed: 0
64
+ });
65
+ const crawlResults = await Promise.all(
66
+ config.sources.map(
67
+ (source) => this.crawler.crawl({
68
+ rootDir: source.path,
69
+ excludePatterns: source.excludePatterns
70
+ })
71
+ )
72
+ );
73
+ const allFiles = crawlResults.flat();
74
+ let filesToProcess;
75
+ let pathsToRemove;
76
+ if (opts.skipHashCheck) {
77
+ filesToProcess = allFiles;
78
+ pathsToRemove = [];
79
+ } else {
80
+ const existingPaths = await this.store.listSourcePaths();
81
+ const currentPathSet = new Set(allFiles.map((f) => f.relativePath));
82
+ pathsToRemove = existingPaths.filter(
83
+ (p) => !currentPathSet.has(p) && !p.startsWith("curated/")
84
+ );
85
+ filesToProcess = [];
86
+ await runConcurrent(
87
+ allFiles,
88
+ async (file) => {
89
+ const contentHash = hashContent(file.content);
90
+ const existingRecords = await this.store.getBySourcePath(file.relativePath);
91
+ if (existingRecords.length > 0 && existingRecords[0].fileHash === contentHash) {
92
+ filesSkipped++;
93
+ return;
94
+ }
95
+ filesToProcess.push(file);
96
+ },
97
+ concurrency,
98
+ (file, err) => console.error(`[indexer] hash check failed for ${file.relativePath}:`, err)
99
+ );
100
+ }
101
+ const totalFiles = filesToProcess.length;
102
+ const GRAPH_FLUSH_INTERVAL = 50;
103
+ let pendingNodes = [];
104
+ let pendingEdges = [];
105
+ let graphFilesAccumulated = 0;
106
+ const flushGraph = async () => {
107
+ if (!this.graphStore) return;
108
+ try {
109
+ if (pendingNodes.length > 0) {
110
+ await this.graphStore.upsertNodes(pendingNodes);
111
+ }
112
+ if (pendingEdges.length > 0) {
113
+ await this.graphStore.upsertEdges(pendingEdges);
114
+ }
115
+ } catch (err) {
116
+ console.error("[indexer] graph batch flush failed:", err);
117
+ }
118
+ pendingNodes = [];
119
+ pendingEdges = [];
120
+ graphFilesAccumulated = 0;
121
+ };
122
+ await runConcurrent(
123
+ filesToProcess,
124
+ async (file) => {
125
+ onProgress?.({
126
+ phase: "chunking",
127
+ filesTotal: totalFiles,
128
+ filesProcessed,
129
+ chunksTotal: chunksCreated,
130
+ chunksProcessed: chunksCreated,
131
+ currentFile: file.relativePath
132
+ });
133
+ const contentType = detectContentType(file.relativePath);
134
+ const chunker = createChunker(file.extension);
135
+ const chunks = chunker.chunk(file.content, {
136
+ sourcePath: file.relativePath,
137
+ contentType
138
+ });
139
+ if (chunks.length === 0) return;
140
+ onProgress?.({
141
+ phase: "embedding",
142
+ filesTotal: totalFiles,
143
+ filesProcessed,
144
+ chunksTotal: chunksCreated + chunks.length,
145
+ chunksProcessed: chunksCreated,
146
+ currentFile: file.relativePath
147
+ });
148
+ const vectors = await this.embedder.embedBatch(chunks.map((c) => c.text));
149
+ const fileHash = hashContent(file.content);
150
+ const records = chunks.map((chunk, i) => ({
151
+ id: generateRecordId(file.relativePath, i),
152
+ content: chunk.text,
153
+ sourcePath: chunk.sourcePath,
154
+ contentType: chunk.contentType,
155
+ headingPath: chunk.headingPath,
156
+ chunkIndex: chunk.chunkIndex,
157
+ totalChunks: chunk.totalChunks,
158
+ startLine: chunk.startLine,
159
+ endLine: chunk.endLine,
160
+ fileHash,
161
+ indexedAt: (/* @__PURE__ */ new Date()).toISOString(),
162
+ origin: "indexed",
163
+ tags: [],
164
+ version: 1
165
+ }));
166
+ onProgress?.({
167
+ phase: "storing",
168
+ filesTotal: totalFiles,
169
+ filesProcessed,
170
+ chunksTotal: chunksCreated + chunks.length,
171
+ chunksProcessed: chunksCreated,
172
+ currentFile: file.relativePath
173
+ });
174
+ await this.store.upsert(records, vectors);
175
+ if (this.graphStore) {
176
+ try {
177
+ if (!opts.graphCleared) {
178
+ await this.graphStore.deleteBySourcePath(file.relativePath);
179
+ }
180
+ const graph = extractGraph(file.content, file.relativePath);
181
+ if (graph.nodes.length > 0) pendingNodes.push(...graph.nodes);
182
+ if (graph.edges.length > 0) pendingEdges.push(...graph.edges);
183
+ graphFilesAccumulated++;
184
+ if (graphFilesAccumulated >= GRAPH_FLUSH_INTERVAL) {
185
+ await flushGraph();
186
+ }
187
+ } catch (err) {
188
+ console.error(`[indexer] graph extraction failed for ${file.relativePath}:`, err);
189
+ }
190
+ }
191
+ filesProcessed++;
192
+ chunksCreated += chunks.length;
193
+ },
194
+ concurrency,
195
+ (file, err) => console.error(`[indexer] processing failed for ${file.relativePath}:`, err)
196
+ );
197
+ await flushGraph();
198
+ if (pathsToRemove.length > 0) {
199
+ onProgress?.({
200
+ phase: "cleanup",
201
+ filesTotal: totalFiles,
202
+ filesProcessed,
203
+ chunksTotal: chunksCreated,
204
+ chunksProcessed: chunksCreated
205
+ });
206
+ await runConcurrent(
207
+ pathsToRemove,
208
+ async (path) => {
209
+ await this.store.deleteBySourcePath(path);
210
+ if (this.graphStore) {
211
+ await this.graphStore.deleteBySourcePath(path).catch((err) => console.error(`[indexer] graph cleanup failed for ${path}:`, err));
212
+ }
213
+ filesRemoved++;
214
+ },
215
+ concurrency,
216
+ (path, err) => console.error(`[indexer] cleanup failed for ${path}:`, err)
217
+ );
218
+ }
219
+ onProgress?.({
220
+ phase: "done",
221
+ filesTotal: totalFiles,
222
+ filesProcessed,
223
+ chunksTotal: chunksCreated,
224
+ chunksProcessed: chunksCreated
225
+ });
226
+ return {
227
+ filesProcessed,
228
+ filesSkipped,
229
+ chunksCreated,
230
+ filesRemoved,
231
+ durationMs: Date.now() - startTime
232
+ };
233
+ }
234
+ /**
235
+ * Force re-index all files (ignoring hashes).
236
+ */
237
+ async reindexAll(config, onProgress) {
238
+ await this.store.dropTable();
239
+ if (this.graphStore) {
240
+ try {
241
+ const stats = await this.graphStore.getStats();
242
+ if (stats.nodeCount > 0) {
243
+ await this.graphStore.clear();
244
+ console.error(
245
+ `[indexer] Graph store cleared (was ${stats.nodeCount} nodes, ${stats.edgeCount} edges)`
246
+ );
247
+ }
248
+ } catch (err) {
249
+ console.error("[indexer] Graph store clear failed:", err);
250
+ }
251
+ }
252
+ return this.doReindex(config, onProgress);
253
+ }
254
+ async doReindex(config, onProgress) {
255
+ if (this.indexing) {
256
+ throw new Error("Indexing is already in progress");
257
+ }
258
+ this.indexing = true;
259
+ try {
260
+ return await this.doIndex(config, onProgress, {
261
+ skipHashCheck: true,
262
+ graphCleared: true
263
+ });
264
+ } finally {
265
+ this.indexing = false;
266
+ }
267
+ }
268
+ /**
269
+ * Get current index statistics.
270
+ */
271
+ async getStats() {
272
+ return this.store.getStats();
273
+ }
274
+ }
275
+ export {
276
+ IncrementalIndexer
277
+ };
278
+ //# sourceMappingURL=incremental-indexer.js.map
@@ -0,0 +1,5 @@
1
+ export { generateRecordId, hashContent } from './file-hasher.js';
2
+ export { type CrawlOptions, type CrawlResult, FilesystemCrawler } from './filesystem-crawler.js';
3
+ export { type ExtractedGraph, extractGraph } from './graph-extractor.js';
4
+ export { IncrementalIndexer, type IndexProgress, type IndexResult, type ProgressCallback, } from './incremental-indexer.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,14 @@
1
+ import { generateRecordId, hashContent } from "./file-hasher.js";
2
+ import { FilesystemCrawler } from "./filesystem-crawler.js";
3
+ import { extractGraph } from "./graph-extractor.js";
4
+ import {
5
+ IncrementalIndexer
6
+ } from "./incremental-indexer.js";
7
+ export {
8
+ FilesystemCrawler,
9
+ IncrementalIndexer,
10
+ extractGraph,
11
+ generateRecordId,
12
+ hashContent
13
+ };
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Public API for @kb/server — imported by CLI and other consumers.
3
+ * Does NOT start the server (unlike index.ts which auto-calls main()).
4
+ */
5
+ export { loadConfig } from './config.js';
6
+ export type { KnowledgeBaseComponents } from './server.js';
7
+ export { createMcpServer, createServer, initializeKnowledgeBase } from './server.js';
8
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1,9 @@
1
+ import { loadConfig } from "./config.js";
2
+ import { createMcpServer, createServer, initializeKnowledgeBase } from "./server.js";
3
+ export {
4
+ createMcpServer,
5
+ createServer,
6
+ initializeKnowledgeBase,
7
+ loadConfig
8
+ };
9
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1,3 @@
1
+ import type { KBConfig } from '@kb/core';
2
+ export declare function loadConfig(): KBConfig;
3
+ //# sourceMappingURL=config.d.ts.map