@thoughtflow/codebase 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/dist/contexts/context-decomposer.d.ts +13 -0
  2. package/dist/contexts/context-decomposer.d.ts.map +1 -0
  3. package/dist/contexts/context-decomposer.js +97 -0
  4. package/dist/contexts/context-decomposer.js.map +1 -0
  5. package/dist/contexts/context-document-manager.d.ts +21 -0
  6. package/dist/contexts/context-document-manager.d.ts.map +1 -0
  7. package/dist/contexts/context-document-manager.js +69 -0
  8. package/dist/contexts/context-document-manager.js.map +1 -0
  9. package/dist/contexts/context-router.d.ts +13 -0
  10. package/dist/contexts/context-router.d.ts.map +1 -0
  11. package/dist/contexts/context-router.js +94 -0
  12. package/dist/contexts/context-router.js.map +1 -0
  13. package/dist/index.d.ts +53 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +76 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/libs/codebase/deep-analyzer.d.ts +58 -0
  18. package/dist/libs/codebase/deep-analyzer.d.ts.map +1 -0
  19. package/dist/libs/codebase/deep-analyzer.js +239 -0
  20. package/dist/libs/codebase/deep-analyzer.js.map +1 -0
  21. package/dist/libs/codebase/graph/dependency-extractor.d.ts +20 -0
  22. package/dist/libs/codebase/graph/dependency-extractor.d.ts.map +1 -0
  23. package/dist/libs/codebase/graph/dependency-extractor.js +174 -0
  24. package/dist/libs/codebase/graph/dependency-extractor.js.map +1 -0
  25. package/dist/libs/codebase/graph/graph-analysis.d.ts +42 -0
  26. package/dist/libs/codebase/graph/graph-analysis.d.ts.map +1 -0
  27. package/dist/libs/codebase/graph/graph-analysis.js +222 -0
  28. package/dist/libs/codebase/graph/graph-analysis.js.map +1 -0
  29. package/dist/libs/codebase/graph/graph-visualizer.d.ts +12 -0
  30. package/dist/libs/codebase/graph/graph-visualizer.d.ts.map +1 -0
  31. package/dist/libs/codebase/graph/graph-visualizer.js +99 -0
  32. package/dist/libs/codebase/graph/graph-visualizer.js.map +1 -0
  33. package/dist/libs/codebase/indexer/batch-processor.d.ts +18 -0
  34. package/dist/libs/codebase/indexer/batch-processor.d.ts.map +1 -0
  35. package/dist/libs/codebase/indexer/batch-processor.js +39 -0
  36. package/dist/libs/codebase/indexer/batch-processor.js.map +1 -0
  37. package/dist/libs/codebase/indexer/chunker-markdown.d.ts +19 -0
  38. package/dist/libs/codebase/indexer/chunker-markdown.d.ts.map +1 -0
  39. package/dist/libs/codebase/indexer/chunker-markdown.js +138 -0
  40. package/dist/libs/codebase/indexer/chunker-markdown.js.map +1 -0
  41. package/dist/libs/codebase/indexer/chunker.d.ts +21 -0
  42. package/dist/libs/codebase/indexer/chunker.d.ts.map +1 -0
  43. package/dist/libs/codebase/indexer/chunker.js +133 -0
  44. package/dist/libs/codebase/indexer/chunker.js.map +1 -0
  45. package/dist/libs/codebase/indexer/explorer.d.ts +29 -0
  46. package/dist/libs/codebase/indexer/explorer.d.ts.map +1 -0
  47. package/dist/libs/codebase/indexer/explorer.js +278 -0
  48. package/dist/libs/codebase/indexer/explorer.js.map +1 -0
  49. package/dist/libs/codebase/indexer/indexer.d.ts +35 -0
  50. package/dist/libs/codebase/indexer/indexer.d.ts.map +1 -0
  51. package/dist/libs/codebase/indexer/indexer.js +172 -0
  52. package/dist/libs/codebase/indexer/indexer.js.map +1 -0
  53. package/dist/libs/codebase/knowledge/cross-referencer.d.ts +32 -0
  54. package/dist/libs/codebase/knowledge/cross-referencer.d.ts.map +1 -0
  55. package/dist/libs/codebase/knowledge/cross-referencer.js +132 -0
  56. package/dist/libs/codebase/knowledge/cross-referencer.js.map +1 -0
  57. package/dist/libs/codebase/knowledge/markdown-extractor.d.ts +34 -0
  58. package/dist/libs/codebase/knowledge/markdown-extractor.d.ts.map +1 -0
  59. package/dist/libs/codebase/knowledge/markdown-extractor.js +273 -0
  60. package/dist/libs/codebase/knowledge/markdown-extractor.js.map +1 -0
  61. package/dist/libs/codebase/knowledge/summarizer.d.ts +25 -0
  62. package/dist/libs/codebase/knowledge/summarizer.d.ts.map +1 -0
  63. package/dist/libs/codebase/knowledge/summarizer.js +61 -0
  64. package/dist/libs/codebase/knowledge/summarizer.js.map +1 -0
  65. package/dist/libs/codebase/search/bm25.d.ts +23 -0
  66. package/dist/libs/codebase/search/bm25.d.ts.map +1 -0
  67. package/dist/libs/codebase/search/bm25.js +93 -0
  68. package/dist/libs/codebase/search/bm25.js.map +1 -0
  69. package/dist/libs/codebase/search/hybrid-search.d.ts +22 -0
  70. package/dist/libs/codebase/search/hybrid-search.d.ts.map +1 -0
  71. package/dist/libs/codebase/search/hybrid-search.js +80 -0
  72. package/dist/libs/codebase/search/hybrid-search.js.map +1 -0
  73. package/dist/libs/codebase-index.class.d.ts +66 -0
  74. package/dist/libs/codebase-index.class.d.ts.map +1 -0
  75. package/dist/libs/codebase-index.class.js +595 -0
  76. package/dist/libs/codebase-index.class.js.map +1 -0
  77. package/dist/tools/codebase/codebase-analyze.tool.d.ts +8 -0
  78. package/dist/tools/codebase/codebase-analyze.tool.d.ts.map +1 -0
  79. package/dist/tools/codebase/codebase-analyze.tool.js +20 -0
  80. package/dist/tools/codebase/codebase-analyze.tool.js.map +1 -0
  81. package/dist/tools/codebase/codebase-crossref.tool.d.ts +8 -0
  82. package/dist/tools/codebase/codebase-crossref.tool.d.ts.map +1 -0
  83. package/dist/tools/codebase/codebase-crossref.tool.js +20 -0
  84. package/dist/tools/codebase/codebase-crossref.tool.js.map +1 -0
  85. package/dist/tools/codebase/codebase-flow.tool.d.ts +8 -0
  86. package/dist/tools/codebase/codebase-flow.tool.d.ts.map +1 -0
  87. package/dist/tools/codebase/codebase-flow.tool.js +20 -0
  88. package/dist/tools/codebase/codebase-flow.tool.js.map +1 -0
  89. package/dist/tools/codebase/codebase-graph-circular.tool.d.ts +8 -0
  90. package/dist/tools/codebase/codebase-graph-circular.tool.d.ts.map +1 -0
  91. package/dist/tools/codebase/codebase-graph-circular.tool.js +17 -0
  92. package/dist/tools/codebase/codebase-graph-circular.tool.js.map +1 -0
  93. package/dist/tools/codebase/codebase-graph-query.tool.d.ts +8 -0
  94. package/dist/tools/codebase/codebase-graph-query.tool.d.ts.map +1 -0
  95. package/dist/tools/codebase/codebase-graph-query.tool.js +21 -0
  96. package/dist/tools/codebase/codebase-graph-query.tool.js.map +1 -0
  97. package/dist/tools/codebase/codebase-graph-stats.tool.d.ts +8 -0
  98. package/dist/tools/codebase/codebase-graph-stats.tool.d.ts.map +1 -0
  99. package/dist/tools/codebase/codebase-graph-stats.tool.js +17 -0
  100. package/dist/tools/codebase/codebase-graph-stats.tool.js.map +1 -0
  101. package/dist/tools/codebase/codebase-graph-visualize.tool.d.ts +8 -0
  102. package/dist/tools/codebase/codebase-graph-visualize.tool.d.ts.map +1 -0
  103. package/dist/tools/codebase/codebase-graph-visualize.tool.js +21 -0
  104. package/dist/tools/codebase/codebase-graph-visualize.tool.js.map +1 -0
  105. package/dist/tools/codebase/codebase-impact.tool.d.ts +8 -0
  106. package/dist/tools/codebase/codebase-impact.tool.d.ts.map +1 -0
  107. package/dist/tools/codebase/codebase-impact.tool.js +21 -0
  108. package/dist/tools/codebase/codebase-impact.tool.js.map +1 -0
  109. package/dist/tools/codebase/codebase-index.tool.d.ts +8 -0
  110. package/dist/tools/codebase/codebase-index.tool.d.ts.map +1 -0
  111. package/dist/tools/codebase/codebase-index.tool.js +21 -0
  112. package/dist/tools/codebase/codebase-index.tool.js.map +1 -0
  113. package/dist/tools/codebase/codebase-knowledge.tool.d.ts +8 -0
  114. package/dist/tools/codebase/codebase-knowledge.tool.d.ts.map +1 -0
  115. package/dist/tools/codebase/codebase-knowledge.tool.js +22 -0
  116. package/dist/tools/codebase/codebase-knowledge.tool.js.map +1 -0
  117. package/dist/tools/codebase/codebase-search.tool.d.ts +8 -0
  118. package/dist/tools/codebase/codebase-search.tool.d.ts.map +1 -0
  119. package/dist/tools/codebase/codebase-search.tool.js +24 -0
  120. package/dist/tools/codebase/codebase-search.tool.js.map +1 -0
  121. package/dist/tools/codebase/codebase-status.tool.d.ts +8 -0
  122. package/dist/tools/codebase/codebase-status.tool.d.ts.map +1 -0
  123. package/dist/tools/codebase/codebase-status.tool.js +19 -0
  124. package/dist/tools/codebase/codebase-status.tool.js.map +1 -0
  125. package/dist/tools/neural/comparative-analysis.tool.d.ts +37 -0
  126. package/dist/tools/neural/comparative-analysis.tool.d.ts.map +1 -0
  127. package/dist/tools/neural/comparative-analysis.tool.js +241 -0
  128. package/dist/tools/neural/comparative-analysis.tool.js.map +1 -0
  129. package/dist/tools/neural/index.d.ts +12 -0
  130. package/dist/tools/neural/index.d.ts.map +1 -0
  131. package/dist/tools/neural/index.js +28 -0
  132. package/dist/tools/neural/index.js.map +1 -0
  133. package/dist/tools/neural/neural-deadcode.tool.d.ts +10 -0
  134. package/dist/tools/neural/neural-deadcode.tool.d.ts.map +1 -0
  135. package/dist/tools/neural/neural-deadcode.tool.js +133 -0
  136. package/dist/tools/neural/neural-deadcode.tool.js.map +1 -0
  137. package/dist/tools/neural/neural-debug.tool.d.ts +11 -0
  138. package/dist/tools/neural/neural-debug.tool.d.ts.map +1 -0
  139. package/dist/tools/neural/neural-debug.tool.js +205 -0
  140. package/dist/tools/neural/neural-debug.tool.js.map +1 -0
  141. package/dist/tools/neural/neural-explain.tool.d.ts +9 -0
  142. package/dist/tools/neural/neural-explain.tool.d.ts.map +1 -0
  143. package/dist/tools/neural/neural-explain.tool.js +100 -0
  144. package/dist/tools/neural/neural-explain.tool.js.map +1 -0
  145. package/dist/tools/neural/neural-optimize.tool.d.ts +9 -0
  146. package/dist/tools/neural/neural-optimize.tool.d.ts.map +1 -0
  147. package/dist/tools/neural/neural-optimize.tool.js +117 -0
  148. package/dist/tools/neural/neural-optimize.tool.js.map +1 -0
  149. package/dist/tools/neural/neural-pattern.tool.d.ts +10 -0
  150. package/dist/tools/neural/neural-pattern.tool.d.ts.map +1 -0
  151. package/dist/tools/neural/neural-pattern.tool.js +169 -0
  152. package/dist/tools/neural/neural-pattern.tool.js.map +1 -0
  153. package/dist/tools/neural/neural-review.tool.d.ts +11 -0
  154. package/dist/tools/neural/neural-review.tool.d.ts.map +1 -0
  155. package/dist/tools/neural/neural-review.tool.js +152 -0
  156. package/dist/tools/neural/neural-review.tool.js.map +1 -0
  157. package/dist/tools/neural/neural-security.tool.d.ts +16 -0
  158. package/dist/tools/neural/neural-security.tool.d.ts.map +1 -0
  159. package/dist/tools/neural/neural-security.tool.js +256 -0
  160. package/dist/tools/neural/neural-security.tool.js.map +1 -0
  161. package/dist/tools/neural/neural-similar.tool.d.ts +9 -0
  162. package/dist/tools/neural/neural-similar.tool.d.ts.map +1 -0
  163. package/dist/tools/neural/neural-similar.tool.js +139 -0
  164. package/dist/tools/neural/neural-similar.tool.js.map +1 -0
  165. package/dist/tools/neural/neural-smells.tool.d.ts +9 -0
  166. package/dist/tools/neural/neural-smells.tool.d.ts.map +1 -0
  167. package/dist/tools/neural/neural-smells.tool.js +123 -0
  168. package/dist/tools/neural/neural-smells.tool.js.map +1 -0
  169. package/dist/tools/neural/neural-suggest.tool.d.ts +9 -0
  170. package/dist/tools/neural/neural-suggest.tool.d.ts.map +1 -0
  171. package/dist/tools/neural/neural-suggest.tool.js +64 -0
  172. package/dist/tools/neural/neural-suggest.tool.js.map +1 -0
  173. package/dist/tools/quality/index.d.ts +8 -0
  174. package/dist/tools/quality/index.d.ts.map +1 -0
  175. package/dist/tools/quality/index.js +24 -0
  176. package/dist/tools/quality/index.js.map +1 -0
  177. package/dist/tools/quality/quality-complexity.tool.d.ts +11 -0
  178. package/dist/tools/quality/quality-complexity.tool.d.ts.map +1 -0
  179. package/dist/tools/quality/quality-complexity.tool.js +152 -0
  180. package/dist/tools/quality/quality-complexity.tool.js.map +1 -0
  181. package/dist/tools/quality/quality-coupling.tool.d.ts +9 -0
  182. package/dist/tools/quality/quality-coupling.tool.d.ts.map +1 -0
  183. package/dist/tools/quality/quality-coupling.tool.js +51 -0
  184. package/dist/tools/quality/quality-coupling.tool.js.map +1 -0
  185. package/dist/tools/quality/quality-coverage.tool.d.ts +9 -0
  186. package/dist/tools/quality/quality-coverage.tool.d.ts.map +1 -0
  187. package/dist/tools/quality/quality-coverage.tool.js +104 -0
  188. package/dist/tools/quality/quality-coverage.tool.js.map +1 -0
  189. package/dist/tools/quality/quality-deps.tool.d.ts +11 -0
  190. package/dist/tools/quality/quality-deps.tool.d.ts.map +1 -0
  191. package/dist/tools/quality/quality-deps.tool.js +119 -0
  192. package/dist/tools/quality/quality-deps.tool.js.map +1 -0
  193. package/dist/tools/quality/quality-duplication.tool.d.ts +9 -0
  194. package/dist/tools/quality/quality-duplication.tool.d.ts.map +1 -0
  195. package/dist/tools/quality/quality-duplication.tool.js +100 -0
  196. package/dist/tools/quality/quality-duplication.tool.js.map +1 -0
  197. package/dist/tools/quality/quality-size.tool.d.ts +9 -0
  198. package/dist/tools/quality/quality-size.tool.d.ts.map +1 -0
  199. package/dist/tools/quality/quality-size.tool.js +94 -0
  200. package/dist/tools/quality/quality-size.tool.js.map +1 -0
  201. package/dist/tools/quality/quality-types.tool.d.ts +9 -0
  202. package/dist/tools/quality/quality-types.tool.d.ts.map +1 -0
  203. package/dist/tools/quality/quality-types.tool.js +95 -0
  204. package/dist/tools/quality/quality-types.tool.js.map +1 -0
  205. package/dist/tools/workspace/analyze-project.tool.d.ts +36 -0
  206. package/dist/tools/workspace/analyze-project.tool.d.ts.map +1 -0
  207. package/dist/tools/workspace/analyze-project.tool.js +454 -0
  208. package/dist/tools/workspace/analyze-project.tool.js.map +1 -0
  209. package/dist/tools/workspace/codebase-research.tool.d.ts +10 -0
  210. package/dist/tools/workspace/codebase-research.tool.d.ts.map +1 -0
  211. package/dist/tools/workspace/codebase-research.tool.js +89 -0
  212. package/dist/tools/workspace/codebase-research.tool.js.map +1 -0
  213. package/dist/tools/workspace/project-scanner.tool.d.ts +55 -0
  214. package/dist/tools/workspace/project-scanner.tool.d.ts.map +1 -0
  215. package/dist/tools/workspace/project-scanner.tool.js +978 -0
  216. package/dist/tools/workspace/project-scanner.tool.js.map +1 -0
  217. package/dist/tools/workspace/search-code.tool.d.ts +14 -0
  218. package/dist/tools/workspace/search-code.tool.d.ts.map +1 -0
  219. package/dist/tools/workspace/search-code.tool.js +286 -0
  220. package/dist/tools/workspace/search-code.tool.js.map +1 -0
  221. package/package.json +17 -0
  222. package/src/contexts/context-decomposer.ts +113 -0
  223. package/src/contexts/context-document-manager.ts +70 -0
  224. package/src/contexts/context-router.ts +121 -0
  225. package/src/index.ts +65 -0
  226. package/src/libs/codebase/deep-analyzer.ts +287 -0
  227. package/src/libs/codebase/graph/dependency-extractor.ts +165 -0
  228. package/src/libs/codebase/graph/graph-analysis.ts +231 -0
  229. package/src/libs/codebase/graph/graph-visualizer.ts +124 -0
  230. package/src/libs/codebase/indexer/batch-processor.ts +47 -0
  231. package/src/libs/codebase/indexer/chunker-markdown.ts +175 -0
  232. package/src/libs/codebase/indexer/chunker.ts +126 -0
  233. package/src/libs/codebase/indexer/explorer.ts +269 -0
  234. package/src/libs/codebase/indexer/indexer.ts +174 -0
  235. package/src/libs/codebase/knowledge/cross-referencer.ts +182 -0
  236. package/src/libs/codebase/knowledge/markdown-extractor.ts +270 -0
  237. package/src/libs/codebase/knowledge/summarizer.ts +85 -0
  238. package/src/libs/codebase/search/bm25.ts +109 -0
  239. package/src/libs/codebase/search/hybrid-search.ts +109 -0
  240. package/src/libs/codebase-index.class.ts +715 -0
  241. package/src/tools/codebase/codebase-analyze.tool.ts +18 -0
  242. package/src/tools/codebase/codebase-crossref.tool.ts +18 -0
  243. package/src/tools/codebase/codebase-flow.tool.ts +18 -0
  244. package/src/tools/codebase/codebase-graph-circular.tool.ts +15 -0
  245. package/src/tools/codebase/codebase-graph-query.tool.ts +19 -0
  246. package/src/tools/codebase/codebase-graph-stats.tool.ts +15 -0
  247. package/src/tools/codebase/codebase-graph-visualize.tool.ts +19 -0
  248. package/src/tools/codebase/codebase-impact.tool.ts +19 -0
  249. package/src/tools/codebase/codebase-index.tool.ts +19 -0
  250. package/src/tools/codebase/codebase-knowledge.tool.ts +20 -0
  251. package/src/tools/codebase/codebase-search.tool.ts +22 -0
  252. package/src/tools/codebase/codebase-status.tool.ts +17 -0
  253. package/src/tools/neural/comparative-analysis.tool.ts +309 -0
  254. package/src/tools/neural/index.ts +11 -0
  255. package/src/tools/neural/neural-deadcode.tool.ts +105 -0
  256. package/src/tools/neural/neural-debug.tool.ts +199 -0
  257. package/src/tools/neural/neural-explain.tool.ts +67 -0
  258. package/src/tools/neural/neural-optimize.tool.ts +93 -0
  259. package/src/tools/neural/neural-pattern.tool.ts +141 -0
  260. package/src/tools/neural/neural-review.tool.ts +145 -0
  261. package/src/tools/neural/neural-security.tool.ts +226 -0
  262. package/src/tools/neural/neural-similar.tool.ts +113 -0
  263. package/src/tools/neural/neural-smells.tool.ts +98 -0
  264. package/src/tools/neural/neural-suggest.tool.ts +65 -0
  265. package/src/tools/quality/index.ts +7 -0
  266. package/src/tools/quality/quality-complexity.tool.ts +132 -0
  267. package/src/tools/quality/quality-coupling.tool.ts +57 -0
  268. package/src/tools/quality/quality-coverage.tool.ts +78 -0
  269. package/src/tools/quality/quality-deps.tool.ts +89 -0
  270. package/src/tools/quality/quality-duplication.tool.ts +71 -0
  271. package/src/tools/quality/quality-size.tool.ts +66 -0
  272. package/src/tools/quality/quality-types.tool.ts +66 -0
  273. package/src/tools/workspace/analyze-project.tool.ts +429 -0
  274. package/src/tools/workspace/codebase-research.tool.ts +100 -0
  275. package/src/tools/workspace/project-scanner.tool.ts +1058 -0
  276. package/src/tools/workspace/search-code.tool.ts +344 -0
  277. package/tsconfig.build.json +12 -0
  278. package/tsconfig.json +9 -0
@@ -0,0 +1,121 @@
1
+ import type { ContextRoutingConfig, ContextDocumentCache, LlmAdapter } from "@thoughtflow/core"
2
+ import { callStructured } from "@thoughtflow/core"
3
+ import { z } from 'zod'
4
+
5
+ const STOP_WORDS = new Set([
6
+ 'a', 'an', 'the', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
7
+ 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'shall',
8
+ 'should', 'may', 'might', 'must', 'can', 'could', 'i', 'me', 'my',
9
+ 'we', 'our', 'you', 'your', 'he', 'she', 'it', 'they', 'them', 'this',
10
+ 'that', 'these', 'those', 'in', 'on', 'at', 'to', 'for', 'of', 'with',
11
+ 'by', 'from', 'and', 'or', 'not', 'but', 'if', 'so', 'no', 'yes',
12
+ 'what', 'which', 'who', 'whom', 'when', 'where', 'why', 'how'
13
+ ])
14
+
15
+ function tokenize(text: string): Set<string> {
16
+ return new Set(
17
+ text.toLowerCase()
18
+ .split(/[^a-zA-Z0-9]+/)
19
+ .filter(w => w.length > 0 && !STOP_WORDS.has(w))
20
+ )
21
+ }
22
+
23
+ function computeScore(
24
+ promptTokens: Set<string>,
25
+ doc: ContextDocumentCache
26
+ ): number {
27
+ if (doc.keywords.length === 0) return 0
28
+
29
+ let matches = 0
30
+ for (const kw of doc.keywords) {
31
+ let hasMatch = false
32
+ for (const t of tokenize(kw)) {
33
+ if (promptTokens.has(t)) {
34
+ hasMatch = true
35
+ break
36
+ }
37
+ }
38
+ if (hasMatch) matches++
39
+ }
40
+
41
+ let categoryBonus = 0
42
+ if (doc.category && promptTokens.has(doc.category)) {
43
+ categoryBonus = 0.3
44
+ }
45
+
46
+ return (matches / doc.keywords.length) + categoryBonus
47
+ }
48
+
49
+ const routingSchema = z.object({
50
+ relevant: z.array(z.string())
51
+ })
52
+
53
+ export class ContextRouter {
54
+ constructor(
55
+ private readonly config: ContextRoutingConfig,
56
+ private readonly adapter: LlmAdapter,
57
+ private readonly model: string
58
+ ) {}
59
+
60
+ /**
61
+ * Route the given prompt against cached document metadata.
62
+ * Returns the list of document names that are relevant.
63
+ */
64
+ async route(
65
+ prompt: string,
66
+ documents: ContextDocumentCache[]
67
+ ): Promise<string[]> {
68
+ const promptTokens = tokenize(prompt)
69
+ const strategy = this.config.strategy ?? 'hybrid'
70
+ const threshold = this.config.relevanceThreshold ?? 0.5
71
+
72
+ // ── Step 1: keyword matching ────────────────────────────────────
73
+
74
+ const scored = documents.map(doc => ({
75
+ name: doc.name,
76
+ score: computeScore(promptTokens, doc)
77
+ }))
78
+
79
+ const maxScore = Math.max(...scored.map(s => s.score), 0)
80
+ const normalized = scored.map(s => ({
81
+ ...s,
82
+ score: maxScore > 0 ? s.score / maxScore : 0
83
+ }))
84
+
85
+ const keywordHits = normalized
86
+ .filter(s => s.score >= threshold)
87
+ .map(s => s.name)
88
+
89
+ if (strategy === 'keyword') {
90
+ return keywordHits
91
+ }
92
+
93
+ if (strategy === 'hybrid' && keywordHits.length > 0) {
94
+ return keywordHits
95
+ }
96
+
97
+ // ── Step 2: LLM routing ────────────────────────────────────────
98
+
99
+ if (documents.length === 0) {
100
+ return []
101
+ }
102
+
103
+ const routingModel = this.config.model?.model ?? this.model
104
+
105
+ const docLines = documents
106
+ .map(d => `- ${d.name}: ${d.summary}`)
107
+ .join('\n')
108
+
109
+ const userPrompt = `Given the user query: "${prompt}"\n\nSelect which of the following documents are relevant:\n${docLines}`
110
+
111
+ const result = await callStructured(
112
+ this.adapter,
113
+ routingModel,
114
+ 'You are a document routing assistant. Select relevant documents based on the user query.',
115
+ userPrompt,
116
+ routingSchema
117
+ )
118
+
119
+ return result.result.relevant
120
+ }
121
+ }
package/src/index.ts ADDED
@@ -0,0 +1,65 @@
1
+ // Codebase index
2
+ export * from "./libs/codebase-index.class";
3
+
4
+ // Codebase libs — deep analyzer, graph, indexer, knowledge, search
5
+ export * from "./libs/codebase/deep-analyzer";
6
+ export * from "./libs/codebase/graph/dependency-extractor";
7
+ export * from "./libs/codebase/graph/graph-analysis";
8
+ export * from "./libs/codebase/graph/graph-visualizer";
9
+ export * from "./libs/codebase/indexer/batch-processor";
10
+ export * from "./libs/codebase/indexer/chunker-markdown";
11
+ export * from "./libs/codebase/indexer/chunker";
12
+ export * from "./libs/codebase/indexer/explorer";
13
+ export * from "./libs/codebase/indexer/indexer";
14
+ export * from "./libs/codebase/knowledge/cross-referencer";
15
+ export * from "./libs/codebase/knowledge/markdown-extractor";
16
+ export * from "./libs/codebase/knowledge/summarizer";
17
+ export * from "./libs/codebase/search/bm25";
18
+ export * from "./libs/codebase/search/hybrid-search";
19
+
20
+ // Tools — codebase
21
+ export * from "./tools/codebase/codebase-analyze.tool";
22
+ export * from "./tools/codebase/codebase-crossref.tool";
23
+ export * from "./tools/codebase/codebase-flow.tool";
24
+ export * from "./tools/codebase/codebase-graph-circular.tool";
25
+ export * from "./tools/codebase/codebase-graph-query.tool";
26
+ export * from "./tools/codebase/codebase-graph-stats.tool";
27
+ export * from "./tools/codebase/codebase-graph-visualize.tool";
28
+ export * from "./tools/codebase/codebase-impact.tool";
29
+ export * from "./tools/codebase/codebase-index.tool";
30
+ export * from "./tools/codebase/codebase-knowledge.tool";
31
+ export * from "./tools/codebase/codebase-search.tool";
32
+ export * from "./tools/codebase/codebase-status.tool";
33
+
34
+ // Tools — quality
35
+ export * from "./tools/quality/quality-complexity.tool";
36
+ export * from "./tools/quality/quality-coupling.tool";
37
+ export * from "./tools/quality/quality-coverage.tool";
38
+ export * from "./tools/quality/quality-deps.tool";
39
+ export * from "./tools/quality/quality-duplication.tool";
40
+ export * from "./tools/quality/quality-size.tool";
41
+ export * from "./tools/quality/quality-types.tool";
42
+
43
+ // Tools — neural
44
+ export * from "./tools/neural/comparative-analysis.tool";
45
+ export * from "./tools/neural/neural-deadcode.tool";
46
+ export * from "./tools/neural/neural-debug.tool";
47
+ export * from "./tools/neural/neural-explain.tool";
48
+ export * from "./tools/neural/neural-optimize.tool";
49
+ export * from "./tools/neural/neural-pattern.tool";
50
+ export * from "./tools/neural/neural-review.tool";
51
+ export * from "./tools/neural/neural-security.tool";
52
+ export * from "./tools/neural/neural-similar.tool";
53
+ export * from "./tools/neural/neural-smells.tool";
54
+ export * from "./tools/neural/neural-suggest.tool";
55
+
56
+ // Tools — workspace (codebase-related)
57
+ export * from "./tools/workspace/search-code.tool";
58
+ export * from "./tools/workspace/codebase-research.tool";
59
+ export * from "./tools/workspace/project-scanner.tool";
60
+ export * from "./tools/workspace/analyze-project.tool";
61
+
62
+ // Contexts
63
+ export * from "./contexts/context-decomposer";
64
+ export * from "./contexts/context-document-manager";
65
+ export * from "./contexts/context-router";
@@ -0,0 +1,287 @@
1
+ import type { IVectorStore, IEmbeddingProvider } from "@thoughtflow/core";
2
+ import { CodebaseExplorer, DiscoveredFile } from "./indexer/explorer";
3
+ import { CodebaseIndexer, IndexerOptions } from "./indexer/indexer";
4
+ import { DependencyExtractor, DependencyGraph } from "./graph/dependency-extractor";
5
+ import { CircularDetector, ImpactAnalyzer } from "./graph/graph-analysis";
6
+ import { GraphVisualizer } from "./graph/graph-visualizer";
7
+ import { MarkdownExtractor, ExtractedDocument } from "./knowledge/markdown-extractor";
8
+ import { CrossReferencer, CrossReferenceGraph } from "./knowledge/cross-referencer";
9
+ import * as path from "node:path";
10
+
11
+ export type AnalysisPhase =
12
+ | 'discover'
13
+ | 'index'
14
+ | 'graph'
15
+ | 'extract-knowledge'
16
+ | 'summarize'
17
+ | 'cross-reference'
18
+ | 'complete';
19
+
20
+ export interface DeepAnalysisConfig {
21
+ repoPath: string;
22
+ vectorStore: IVectorStore;
23
+ embeddingProvider: IEmbeddingProvider;
24
+ phases?: AnalysisPhase[];
25
+ onProgress?: (phase: AnalysisPhase, message: string, percent: number) => void;
26
+ }
27
+
28
+ export interface DeepAnalysisReport {
29
+ repoName: string;
30
+ repoPath: string;
31
+ analyzedAt: string;
32
+ durationMs: number;
33
+ stats: {
34
+ totalFiles: number;
35
+ codeFiles: number;
36
+ docFiles: number;
37
+ configFiles: number;
38
+ testFiles: number;
39
+ totalChunks: number;
40
+ };
41
+ architecture: {
42
+ techStack: string[];
43
+ topModules: string[];
44
+ entryPoints: string[];
45
+ circularDependencies: string[][];
46
+ };
47
+ knowledge: {
48
+ documentsExtracted: number;
49
+ usefulDocuments: number;
50
+ noiseDocuments: number;
51
+ decisions: number;
52
+ qualityScore: number;
53
+ };
54
+ traceability: {
55
+ totalReferences: number;
56
+ featuresWithCode: number;
57
+ featuresWithoutCode: number;
58
+ orphanDocuments: string[];
59
+ undocumentedModules: string[];
60
+ };
61
+ summary: string;
62
+ recommendations: string[];
63
+ mermaidDiagram: string;
64
+ }
65
+
66
+ export class DeepAnalyzer {
67
+ private config: DeepAnalysisConfig;
68
+ private startTime = 0;
69
+
70
+ constructor(config: DeepAnalysisConfig) {
71
+ this.config = {
72
+ phases: ['discover', 'index', 'graph', 'extract-knowledge', 'summarize', 'cross-reference', 'complete'],
73
+ ...config,
74
+ };
75
+ }
76
+
77
+ async analyze(): Promise<DeepAnalysisReport> {
78
+ this.startTime = Date.now();
79
+ const phases = this.config.phases!;
80
+ let files: DiscoveredFile[] = [];
81
+ let graph: DependencyGraph = { nodes: new Map(), edges: [] };
82
+ let documents: ExtractedDocument[] = [];
83
+ let crossRefGraph: CrossReferenceGraph = { nodes: new Map(), edges: [] };
84
+ let mermaidDiagram = "";
85
+
86
+ if (phases.includes('discover')) {
87
+ this.emit('discover', 'Discovering files...', 0);
88
+ const explorer = new CodebaseExplorer();
89
+ files = explorer.explore({ rootPath: this.config.repoPath });
90
+ this.emit('discover', `Found ${files.length} files`, 100);
91
+ }
92
+
93
+ if (phases.includes('index')) {
94
+ this.emit('index', 'Indexing codebase...', 0);
95
+ const indexer = new CodebaseIndexer(
96
+ this.config.vectorStore,
97
+ this.config.embeddingProvider,
98
+ { projectPath: this.config.repoPath, onProgress: (p) => {
99
+ this.emit('index', `${p.phase}: ${p.chunksEmbedded}/${p.chunksCreated} chunks`,
100
+ p.chunksCreated > 0 ? (p.chunksEmbedded / p.chunksCreated) * 100 : 50);
101
+ }}
102
+ );
103
+ await indexer.index();
104
+ this.emit('index', 'Indexing complete', 100);
105
+ }
106
+
107
+ if (phases.includes('graph')) {
108
+ this.emit('graph', 'Building dependency graph...', 0);
109
+ if (files.length === 0) {
110
+ const explorer = new CodebaseExplorer();
111
+ files = explorer.explore({ rootPath: this.config.repoPath });
112
+ }
113
+
114
+ const codeFiles = files.filter(
115
+ (f) => f.classification === 'source-code' || f.classification === 'test'
116
+ ).map((f) => ({ relativePath: f.relativePath, absolutePath: f.absolutePath }));
117
+
118
+ const depExtractor = new DependencyExtractor();
119
+ graph = await depExtractor.buildGraph(codeFiles, this.config.repoPath);
120
+ this.emit('graph', `Built graph: ${graph.nodes.size} nodes, ${graph.edges.length} edges`, 100);
121
+
122
+ const visualizer = new GraphVisualizer();
123
+ mermaidDiagram = visualizer.toMermaid(graph, { maxNodes: 100 });
124
+ }
125
+
126
+ if (phases.includes('extract-knowledge')) {
127
+ this.emit('extract-knowledge', 'Extracting knowledge from documentation...', 0);
128
+ if (files.length === 0) {
129
+ const explorer = new CodebaseExplorer();
130
+ files = explorer.explore({ rootPath: this.config.repoPath });
131
+ }
132
+
133
+ const docFiles = files.filter((f) => f.classification === 'documentation');
134
+ const extractor = new MarkdownExtractor();
135
+ documents = docFiles.map((f) => extractor.extract(f.absolutePath));
136
+ this.emit('extract-knowledge', `Extracted ${documents.length} documents`, 100);
137
+ }
138
+
139
+ if (phases.includes('cross-reference')) {
140
+ this.emit('cross-reference', 'Building cross-references...', 0);
141
+ const crossRef = new CrossReferencer();
142
+ const codeFiles = files.filter(
143
+ (f) => f.classification === 'source-code'
144
+ ).map((f) => ({ relativePath: f.relativePath }));
145
+
146
+ crossRefGraph = crossRef.buildReferences(documents, codeFiles, graph.edges as any);
147
+ this.emit('cross-reference', `Built ${crossRefGraph.edges.length} references`, 100);
148
+ }
149
+
150
+ // Build report
151
+ this.emit('complete', 'Generating report...', 90);
152
+
153
+ const cycles = new CircularDetector().findCycles(graph);
154
+ const usefulDocs = documents.filter((d) => d.qualityScore >= 0.3);
155
+ const noiseDocs = documents.filter((d) => d.qualityScore < 0.3);
156
+ const decisions = documents.filter((d) => d.docType === 'decision');
157
+
158
+ const techStack = this.detectTechStack(files, graph);
159
+
160
+ const report: DeepAnalysisReport = {
161
+ repoName: path.basename(this.config.repoPath),
162
+ repoPath: this.config.repoPath,
163
+ analyzedAt: new Date().toISOString(),
164
+ durationMs: Date.now() - this.startTime,
165
+ stats: {
166
+ totalFiles: files.length,
167
+ codeFiles: files.filter((f) => f.classification === 'source-code').length,
168
+ docFiles: files.filter((f) => f.classification === 'documentation').length,
169
+ configFiles: files.filter((f) => f.classification === 'config').length,
170
+ testFiles: files.filter((f) => f.classification === 'test').length,
171
+ totalChunks: 0,
172
+ },
173
+ architecture: {
174
+ techStack,
175
+ topModules: this.findTopModules(graph, 10),
176
+ entryPoints: this.findEntryPoints(graph),
177
+ circularDependencies: cycles,
178
+ },
179
+ knowledge: {
180
+ documentsExtracted: documents.length,
181
+ usefulDocuments: usefulDocs.length,
182
+ noiseDocuments: noiseDocs.length,
183
+ decisions: decisions.length,
184
+ qualityScore: documents.length > 0
185
+ ? usefulDocs.reduce((sum, d) => sum + d.qualityScore, 0) / usefulDocs.length
186
+ : 0,
187
+ },
188
+ traceability: {
189
+ totalReferences: crossRefGraph.edges.length,
190
+ featuresWithCode: 0,
191
+ featuresWithoutCode: 0,
192
+ orphanDocuments: crossRefGraph ? (new CrossReferencer() as any).findOrphanDocuments?.(crossRefGraph) ?? [] : [],
193
+ undocumentedModules: crossRefGraph ? (new CrossReferencer() as any).findUndocumentedCode?.(crossRefGraph) ?? [] : [],
194
+ },
195
+ summary: `This repository contains ${files.length} files across ${techStack.join(", ")} technologies.`,
196
+ recommendations: this.generateRecommendations(graph, cycles, usefulDocs, noiseDocs),
197
+ mermaidDiagram,
198
+ };
199
+
200
+ this.emit('complete', 'Analysis complete', 100);
201
+ return report;
202
+ }
203
+
204
+ private emit(phase: AnalysisPhase, message: string, percent: number): void {
205
+ this.config.onProgress?.(phase, message, percent);
206
+ }
207
+
208
+ private detectTechStack(files: DiscoveredFile[], graph: DependencyGraph): string[] {
209
+ const tech: string[] = [];
210
+ const langs = new Set<string>();
211
+ const configPaths = new Set<string>();
212
+
213
+ for (const file of files) {
214
+ if (file.language) langs.add(file.language);
215
+ configPaths.add(file.relativePath.toLowerCase());
216
+ }
217
+
218
+ if (langs.has("typescript") || langs.has("javascript")) tech.push("TypeScript");
219
+ if (langs.has("python")) tech.push("Python");
220
+ if (langs.has("go")) tech.push("Go");
221
+ if (langs.has("rust")) tech.push("Rust");
222
+ if (langs.has("java")) tech.push("Java");
223
+
224
+ const pathStr = Array.from(configPaths).join(" ");
225
+ if (pathStr.includes("package.json")) tech.push("Node.js");
226
+ if (pathStr.includes("docker")) tech.push("Docker");
227
+ if (pathStr.includes("kubernetes") || pathStr.includes("k8s")) tech.push("Kubernetes");
228
+ if (pathStr.includes("prisma")) tech.push("Prisma");
229
+ if (pathStr.includes(".github/workflows")) tech.push("GitHub Actions");
230
+ if (pathStr.includes("angular.json")) tech.push("Angular");
231
+ if (pathStr.includes("nest-cli.json") || pathStr.includes("@nestjs")) tech.push("NestJS");
232
+ if (pathStr.includes("next.config")) tech.push("Next.js");
233
+ if (pathStr.includes("react")) tech.push("React");
234
+
235
+ return tech;
236
+ }
237
+
238
+ private findTopModules(graph: DependencyGraph, limit: number): string[] {
239
+ const dependencyCount = new Map<string, number>();
240
+ for (const edge of graph.edges) {
241
+ if (!edge.to.startsWith(".")) continue;
242
+ dependencyCount.set(edge.to, (dependencyCount.get(edge.to) ?? 0) + 1);
243
+ }
244
+ return Array.from(dependencyCount.entries())
245
+ .sort((a, b) => b[1] - a[1])
246
+ .slice(0, limit)
247
+ .map(([mod]) => mod);
248
+ }
249
+
250
+ private findEntryPoints(graph: DependencyGraph): string[] {
251
+ const hasIncomingEdge = new Set<string>();
252
+ for (const edge of graph.edges) {
253
+ hasIncomingEdge.add(edge.to);
254
+ }
255
+ return Array.from(graph.nodes.keys()).filter((n) => !hasIncomingEdge.has(n)).slice(0, 20);
256
+ }
257
+
258
+ private generateRecommendations(
259
+ graph: DependencyGraph,
260
+ cycles: string[][],
261
+ usefulDocs: ExtractedDocument[],
262
+ noiseDocs: ExtractedDocument[]
263
+ ): string[] {
264
+ const recs: string[] = [];
265
+
266
+ if (cycles.length > 0) {
267
+ recs.push(`Found ${cycles.length} circular dependency group(s) — review and break cycles`);
268
+ }
269
+
270
+ if (noiseDocs.length > usefulDocs.length) {
271
+ recs.push(`High documentation noise ratio (${noiseDocs.length} low-quality vs ${usefulDocs.length} useful docs) — consider cleanup`);
272
+ }
273
+
274
+ const entryPoints = this.findEntryPoints(graph);
275
+ if (entryPoints.length === 0 && graph.nodes.size > 10) {
276
+ recs.push("No clear entry points detected — consider documenting the application entry");
277
+ }
278
+
279
+ const totalEdges = graph.edges.length;
280
+ const externalEdges = graph.edges.filter((e) => !e.to.startsWith(".")).length;
281
+ if (externalEdges > totalEdges * 0.5) {
282
+ recs.push("High external dependency ratio — review for potential vendor lock-in");
283
+ }
284
+
285
+ return recs;
286
+ }
287
+ }
@@ -0,0 +1,165 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+
4
+ export interface DependencyEdge {
5
+ from: string;
6
+ to: string;
7
+ type: 'import' | 'require' | 'dynamic-import';
8
+ symbols?: string[];
9
+ lineNumber: number;
10
+ }
11
+
12
+ export interface DependencyGraph {
13
+ nodes: Map<string, string[]>;
14
+ edges: DependencyEdge[];
15
+ }
16
+
17
+ const LANG_MAP: Record<string, string> = {
18
+ ".ts": "TypeScript", ".tsx": "Tsx", ".mts": "TypeScript", ".cts": "TypeScript",
19
+ ".js": "JavaScript", ".jsx": "JavaScript", ".mjs": "JavaScript", ".cjs": "JavaScript",
20
+ ".html": "Html",
21
+ };
22
+
23
+ async function parseWithAstGrep(lang: string, content: string) {
24
+ const { Lang, parse } = await import("@ast-grep/napi");
25
+ return parse(Lang[lang as keyof typeof Lang], content);
26
+ }
27
+
28
+ export class DependencyExtractor {
29
+ async extractImports(filePath: string, content: string): Promise<DependencyEdge[]> {
30
+ const ext = path.extname(filePath).toLowerCase();
31
+ const lang = LANG_MAP[ext];
32
+ if (!lang) return [];
33
+
34
+ try {
35
+ const root = (await parseWithAstGrep(lang, content)).root();
36
+ const edges: DependencyEdge[] = [];
37
+
38
+ const namedPatterns = [
39
+ 'import { $NAME } from "$SOURCE"',
40
+ "import { $NAME } from '$SOURCE'",
41
+ ];
42
+
43
+ const defaultPatterns = [
44
+ 'import $NAME from "$SOURCE"',
45
+ "import $NAME from '$SOURCE'",
46
+ ];
47
+
48
+ for (const pattern of namedPatterns) {
49
+ for (const node of root.findAll(pattern)) {
50
+ const source = node.getMatch('SOURCE')?.text();
51
+ if (!source) continue;
52
+
53
+ const cleanSource = source.replace(/^["']|["']$/g, "");
54
+ if (!cleanSource) continue;
55
+
56
+ const fullText = node.text();
57
+ const braceMatch = fullText.match(/\{([^}]+)\}/);
58
+ const symbols: string[] = [];
59
+ if (braceMatch) {
60
+ const names = braceMatch[1].match(/[A-Za-z_$][\w$]*/g) ?? [];
61
+ symbols.push(...names);
62
+ }
63
+
64
+ if (symbols.length === 0) {
65
+ const name = node.getMatch('NAME')?.text();
66
+ if (name) symbols.push(name);
67
+ }
68
+
69
+ edges.push({
70
+ from: filePath,
71
+ to: cleanSource,
72
+ type: 'import',
73
+ symbols: symbols.length > 0 ? symbols : undefined,
74
+ lineNumber: node.range().start.line + 1,
75
+ });
76
+ }
77
+ }
78
+
79
+ for (const pattern of defaultPatterns) {
80
+ for (const node of root.findAll(pattern)) {
81
+ const source = node.getMatch('SOURCE')?.text();
82
+ if (!source) continue;
83
+
84
+ const cleanSource = source.replace(/^["']|["']$/g, "");
85
+ if (!cleanSource) continue;
86
+
87
+ const name = node.getMatch('NAME')?.text();
88
+ edges.push({
89
+ from: filePath,
90
+ to: cleanSource,
91
+ type: 'import',
92
+ symbols: name ? [name] : undefined,
93
+ lineNumber: node.range().start.line + 1,
94
+ });
95
+ }
96
+ }
97
+
98
+ for (const pattern of ["const $NAME = require(\"$SOURCE\")", "const $NAME = require('$SOURCE')"]) {
99
+ for (const node of root.findAll(pattern)) {
100
+ const source = node.getMatch('SOURCE')?.text();
101
+ if (!source) continue;
102
+
103
+ const cleanSource = source.replace(/^["']|["']$/g, "");
104
+ if (!cleanSource) continue;
105
+
106
+ edges.push({
107
+ from: filePath,
108
+ to: cleanSource,
109
+ type: 'require',
110
+ lineNumber: node.range().start.line + 1,
111
+ });
112
+ }
113
+ }
114
+
115
+ return edges;
116
+ } catch {
117
+ return [];
118
+ }
119
+ }
120
+
121
+ async buildGraph(files: Array<{ relativePath: string; absolutePath: string }>, rootPath: string): Promise<DependencyGraph> {
122
+ const nodes = new Map<string, string[]>();
123
+ const edges: DependencyEdge[] = [];
124
+
125
+ for (const file of files) {
126
+ let content: string;
127
+ try {
128
+ content = fs.readFileSync(file.absolutePath, "utf8");
129
+ } catch {
130
+ continue;
131
+ }
132
+
133
+ const fileEdges = await this.extractImports(file.relativePath, content);
134
+ for (const edge of fileEdges) {
135
+ const resolved = this.resolvePath(edge.to, file.relativePath, rootPath);
136
+ edge.to = resolved;
137
+ edges.push(edge);
138
+
139
+ if (!nodes.has(edge.from)) {
140
+ nodes.set(edge.from, []);
141
+ }
142
+ nodes.get(edge.from)!.push(resolved);
143
+ }
144
+ }
145
+
146
+ return { nodes, edges };
147
+ }
148
+
149
+ private resolvePath(importPath: string, fromFile: string, rootPath: string): string {
150
+ if (!importPath.startsWith(".")) return importPath;
151
+
152
+ const fromDir = path.dirname(fromFile);
153
+ const resolved = path.join(fromDir, importPath).replace(/\\/g, "/");
154
+
155
+ const extensions = [".ts", ".tsx", ".js", ".jsx", ".mts", ".mjs", "/index.ts", "/index.js"];
156
+ for (const ext of extensions) {
157
+ const fullPath = path.join(rootPath, resolved + ext);
158
+ if (fs.existsSync(fullPath)) {
159
+ return resolved + ext;
160
+ }
161
+ }
162
+
163
+ return resolved;
164
+ }
165
+ }