@tyvm/knowhow 0.0.90 → 0.0.92

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 (272) hide show
  1. package/.depcheckrc +30 -0
  2. package/bin/knowhow.js +1 -1
  3. package/package.json +8 -34
  4. package/src/agents/configurable/ConfigAgent.ts +2 -2
  5. package/src/agents/tools/executeScript/index.ts +5 -0
  6. package/src/agents/tools/googleSearch.ts +2 -2
  7. package/src/agents/tools/index.ts +0 -3
  8. package/src/agents/tools/list.ts +0 -147
  9. package/src/agents/tools/loadWebpage.ts +3 -113
  10. package/src/auth/browserLogin.ts +10 -13
  11. package/src/chat/modules/AgentModule.ts +0 -1
  12. package/src/chat/types.ts +1 -1
  13. package/src/cli.ts +63 -3
  14. package/src/clients/gemini.ts +96 -25
  15. package/src/clients/http.ts +7 -11
  16. package/src/clients/pricing/google.ts +122 -26
  17. package/src/conversion.ts +24 -54
  18. package/src/index.ts +15 -20
  19. package/src/login.ts +5 -6
  20. package/src/plugins/language.ts +0 -4
  21. package/src/plugins/plugins.ts +0 -14
  22. package/src/plugins/url.ts +31 -12
  23. package/src/services/EmbeddingsService.ts +70 -0
  24. package/src/services/KnowhowClient.ts +34 -34
  25. package/src/{plugins/downloader/downloader.ts → services/MediaProcessorService.ts} +109 -267
  26. package/src/services/S3.ts +19 -87
  27. package/src/services/index.ts +8 -8
  28. package/src/services/modules/index.ts +12 -3
  29. package/src/services/modules/types.ts +8 -2
  30. package/src/services/script-execution/ScriptExecutor.ts +29 -10
  31. package/src/services/script-execution/ScriptPolicy.ts +6 -2
  32. package/src/types.ts +1 -0
  33. package/src/utils/http.ts +127 -0
  34. package/src/workers/auth/PasskeySetup.ts +7 -11
  35. package/tests/clients/AIClient.test.ts +24 -21
  36. package/tests/manual/file-edits/figma.test.ts +3 -70
  37. package/tests/plugins/language/languagePlugin-content-triggers.test.ts +2 -0
  38. package/tests/plugins/language/languagePlugin.test.ts +2 -0
  39. package/tests/processors/ToolResponseCache.test.ts +2 -2
  40. package/tests/test.spec.ts +0 -14
  41. package/tests/unit/modules/moduleLoading.test.ts +12 -4
  42. package/tests/unit/plugins/pluginLoading.test.ts +6 -6
  43. package/ts_build/package.json +8 -34
  44. package/ts_build/src/agents/tools/ast/astAppendNode.d.ts +1 -1
  45. package/ts_build/src/agents/tools/ast/astAppendNode.js +2 -90
  46. package/ts_build/src/agents/tools/ast/astAppendNode.js.map +1 -1
  47. package/ts_build/src/agents/tools/ast/astDeleteNode.d.ts +1 -1
  48. package/ts_build/src/agents/tools/ast/astDeleteNode.js +2 -88
  49. package/ts_build/src/agents/tools/ast/astDeleteNode.js.map +1 -1
  50. package/ts_build/src/agents/tools/ast/astEditNode.d.ts +1 -1
  51. package/ts_build/src/agents/tools/ast/astEditNode.js +2 -90
  52. package/ts_build/src/agents/tools/ast/astEditNode.js.map +1 -1
  53. package/ts_build/src/agents/tools/ast/astGetPathForLine.d.ts +1 -1
  54. package/ts_build/src/agents/tools/ast/astGetPathForLine.js +2 -72
  55. package/ts_build/src/agents/tools/ast/astGetPathForLine.js.map +1 -1
  56. package/ts_build/src/agents/tools/ast/astListPaths.d.ts +1 -1
  57. package/ts_build/src/agents/tools/ast/astListPaths.js +2 -72
  58. package/ts_build/src/agents/tools/ast/astListPaths.js.map +1 -1
  59. package/ts_build/src/agents/tools/executeScript/index.d.ts +3 -2
  60. package/ts_build/src/agents/tools/executeScript/index.js +4 -1
  61. package/ts_build/src/agents/tools/executeScript/index.js.map +1 -1
  62. package/ts_build/src/agents/tools/googleSearch.js +2 -2
  63. package/ts_build/src/agents/tools/googleSearch.js.map +1 -1
  64. package/ts_build/src/agents/tools/index.d.ts +0 -3
  65. package/ts_build/src/agents/tools/index.js +0 -3
  66. package/ts_build/src/agents/tools/index.js.map +1 -1
  67. package/ts_build/src/agents/tools/list.js +0 -138
  68. package/ts_build/src/agents/tools/list.js.map +1 -1
  69. package/ts_build/src/agents/tools/loadWebpage.js +1 -89
  70. package/ts_build/src/agents/tools/loadWebpage.js.map +1 -1
  71. package/ts_build/src/agents/tools/textSearch.d.ts +1 -1
  72. package/ts_build/src/auth/browserLogin.js +7 -7
  73. package/ts_build/src/auth/browserLogin.js.map +1 -1
  74. package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
  75. package/ts_build/src/chat/types.d.ts +1 -1
  76. package/ts_build/src/cli.d.ts +1 -1
  77. package/ts_build/src/cli.js +47 -1
  78. package/ts_build/src/cli.js.map +1 -1
  79. package/ts_build/src/clients/gemini.d.ts +1 -73
  80. package/ts_build/src/clients/gemini.js +57 -19
  81. package/ts_build/src/clients/gemini.js.map +1 -1
  82. package/ts_build/src/clients/http.js +5 -9
  83. package/ts_build/src/clients/http.js.map +1 -1
  84. package/ts_build/src/clients/pricing/google.d.ts +17 -73
  85. package/ts_build/src/clients/pricing/google.js +47 -10
  86. package/ts_build/src/clients/pricing/google.js.map +1 -1
  87. package/ts_build/src/conversion.d.ts +1 -4
  88. package/ts_build/src/conversion.js +12 -27
  89. package/ts_build/src/conversion.js.map +1 -1
  90. package/ts_build/src/index.d.ts +4 -0
  91. package/ts_build/src/index.js +15 -14
  92. package/ts_build/src/index.js.map +1 -1
  93. package/ts_build/src/login.js +5 -4
  94. package/ts_build/src/login.js.map +1 -1
  95. package/ts_build/src/plugins/downloader/downloader.js +3 -3
  96. package/ts_build/src/plugins/downloader/downloader.js.map +1 -1
  97. package/ts_build/src/plugins/language.js.map +1 -1
  98. package/ts_build/src/plugins/plugins.js +0 -14
  99. package/ts_build/src/plugins/plugins.js.map +1 -1
  100. package/ts_build/src/plugins/tree-sitter/editor.d.ts +3 -32
  101. package/ts_build/src/plugins/tree-sitter/editor.js +6 -208
  102. package/ts_build/src/plugins/tree-sitter/editor.js.map +1 -1
  103. package/ts_build/src/plugins/tree-sitter/parser.d.ts +19 -54
  104. package/ts_build/src/plugins/tree-sitter/parser.js +19 -293
  105. package/ts_build/src/plugins/tree-sitter/parser.js.map +1 -1
  106. package/ts_build/src/plugins/tree-sitter/simple-paths.d.ts +2 -15
  107. package/ts_build/src/plugins/tree-sitter/simple-paths.js +2 -324
  108. package/ts_build/src/plugins/tree-sitter/simple-paths.js.map +1 -1
  109. package/ts_build/src/plugins/url.js +27 -8
  110. package/ts_build/src/plugins/url.js.map +1 -1
  111. package/ts_build/src/services/EmbeddingsService.d.ts +14 -0
  112. package/ts_build/src/services/EmbeddingsService.js +33 -0
  113. package/ts_build/src/services/EmbeddingsService.js.map +1 -0
  114. package/ts_build/src/services/GitHub.js +2 -2
  115. package/ts_build/src/services/GitHub.js.map +1 -1
  116. package/ts_build/src/services/KnowhowClient.d.ts +29 -29
  117. package/ts_build/src/services/KnowhowClient.js +33 -33
  118. package/ts_build/src/services/KnowhowClient.js.map +1 -1
  119. package/ts_build/src/services/MediaProcessorService.d.ts +22 -0
  120. package/ts_build/src/services/MediaProcessorService.js +215 -0
  121. package/ts_build/src/services/MediaProcessorService.js.map +1 -0
  122. package/ts_build/src/services/S3.d.ts +0 -4
  123. package/ts_build/src/services/S3.js +14 -60
  124. package/ts_build/src/services/S3.js.map +1 -1
  125. package/ts_build/src/services/index.d.ts +6 -5
  126. package/ts_build/src/services/index.js +6 -6
  127. package/ts_build/src/services/index.js.map +1 -1
  128. package/ts_build/src/services/modules/index.js +12 -3
  129. package/ts_build/src/services/modules/index.js.map +1 -1
  130. package/ts_build/src/services/modules/types.d.ts +8 -2
  131. package/ts_build/src/services/script-execution/ScriptExecutor.js +22 -7
  132. package/ts_build/src/services/script-execution/ScriptExecutor.js.map +1 -1
  133. package/ts_build/src/services/script-execution/ScriptPolicy.d.ts +1 -1
  134. package/ts_build/src/services/script-execution/ScriptPolicy.js +4 -2
  135. package/ts_build/src/services/script-execution/ScriptPolicy.js.map +1 -1
  136. package/ts_build/src/types.d.ts +1 -0
  137. package/ts_build/src/types.js +1 -0
  138. package/ts_build/src/types.js.map +1 -1
  139. package/ts_build/src/utils/http.d.ts +27 -0
  140. package/ts_build/src/utils/http.js +98 -0
  141. package/ts_build/src/utils/http.js.map +1 -0
  142. package/ts_build/src/workers/auth/PasskeySetup.js +6 -7
  143. package/ts_build/src/workers/auth/PasskeySetup.js.map +1 -1
  144. package/ts_build/tests/clients/AIClient.test.js +11 -14
  145. package/ts_build/tests/clients/AIClient.test.js.map +1 -1
  146. package/ts_build/tests/manual/file-edits/figma.test.d.ts +0 -1
  147. package/ts_build/tests/manual/file-edits/figma.test.js +1 -46
  148. package/ts_build/tests/manual/file-edits/figma.test.js.map +1 -1
  149. package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js +2 -0
  150. package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js.map +1 -1
  151. package/ts_build/tests/plugins/language/languagePlugin.test.js +2 -0
  152. package/ts_build/tests/plugins/language/languagePlugin.test.js.map +1 -1
  153. package/ts_build/tests/processors/ToolResponseCache.test.js +2 -2
  154. package/ts_build/tests/processors/ToolResponseCache.test.js.map +1 -1
  155. package/ts_build/tests/test.spec.js +0 -14
  156. package/ts_build/tests/test.spec.js.map +1 -1
  157. package/ts_build/tests/tree-sitter/tree-sitter.test.d.ts +0 -1
  158. package/ts_build/tests/tree-sitter/tree-sitter.test.js +2 -183
  159. package/ts_build/tests/tree-sitter/tree-sitter.test.js.map +1 -1
  160. package/ts_build/tests/unit/modules/moduleLoading.test.js +11 -4
  161. package/ts_build/tests/unit/modules/moduleLoading.test.js.map +1 -1
  162. package/ts_build/tests/unit/plugins/pluginLoading.test.js +4 -4
  163. package/ts_build/tests/unit/plugins/pluginLoading.test.js.map +1 -1
  164. package/benchmarks/.dockerignore +0 -7
  165. package/benchmarks/README.md +0 -166
  166. package/benchmarks/docker/Dockerfile +0 -68
  167. package/benchmarks/example-config.yml +0 -27
  168. package/benchmarks/jest.config.js +0 -13
  169. package/benchmarks/package-lock.json +0 -4297
  170. package/benchmarks/package.json +0 -39
  171. package/benchmarks/results/27b0a06/2025-09-27/xai/xai-grok-code-fast-1.json +0 -2909
  172. package/benchmarks/results/4057aed/2025-08-14/anthropic/anthropic-claude-sonnet-4-20250514.json +0 -1671
  173. package/benchmarks/results/4542435/2025-08-05/lms/lms-openai-gpt-oss-20b.json +0 -2814
  174. package/benchmarks/results/4542435/2025-08-05/lms/lms-qwen-qwen3-30b-a3b-2507.json +0 -2014
  175. package/benchmarks/results/4fb9125/2025-08-07/anthropic/anthropic-claude-sonnet-4-20250514.json +0 -3121
  176. package/benchmarks/results/5766aee/2025-08-02/lms-qwen/qwen3-coder-30b.json +0 -98
  177. package/benchmarks/results/6d73808/2025-08-07/openai/openai-gpt-5.json +0 -3256
  178. package/benchmarks/results/77bf0a6/2025-08-02/lms-qwen/qwen3-30b-a3b-2507.json +0 -4298
  179. package/benchmarks/results/8c0d445/2025-08-03/anthropic/anthropic-claude-sonnet-4-20250514.json +0 -3031
  180. package/benchmarks/results/8c0d445/2025-08-03/openai/openai-gpt-4.1-2025-04-14.json +0 -2990
  181. package/benchmarks/results/ac6b2ab/2025-08-03/anthropic/anthropic-claude-sonnet-4-20250514.json +0 -3256
  182. package/benchmarks/results/ac6b2ab/2025-08-03/lms/lms-qwen-qwen3-coder-30b.json +0 -3007
  183. package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-2025-04-14.json +0 -3256
  184. package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-mini-2025-04-14.json +0 -3036
  185. package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-nano-2025-04-14.json +0 -3280
  186. package/benchmarks/results/adff675/2025-08-04/lms/lms-qwen-qwen3-30b-a3b-2507.json +0 -1920
  187. package/benchmarks/results/adff675/2025-08-04/lms/lms-qwen-qwen3-coder-30b.json +0 -3281
  188. package/benchmarks/results/b502ed9/2025-08-03/lms-qwen/qwen3-coder-30b.json +0 -2896
  189. package/benchmarks/results/d1a8129/2025-08-03/lms/lms-qwen-qwen3-coder-30b.json +0 -3011
  190. package/benchmarks/results/e60471c/2025-08-03/lms/qwen3-30b-a3b-2507.json +0 -3003
  191. package/benchmarks/scripts/build-and-run.sh +0 -47
  192. package/benchmarks/scripts/clone-exercism.sh +0 -92
  193. package/benchmarks/scripts/validate.sh +0 -48
  194. package/benchmarks/src/__tests__/runner.test.ts +0 -27
  195. package/benchmarks/src/cli.ts +0 -90
  196. package/benchmarks/src/evaluators/EvaluatorRegistry.ts +0 -64
  197. package/benchmarks/src/evaluators/JavaScriptEvaluator.ts +0 -183
  198. package/benchmarks/src/evaluators/index.ts +0 -3
  199. package/benchmarks/src/evaluators/types.ts +0 -22
  200. package/benchmarks/src/index.ts +0 -3
  201. package/benchmarks/src/providers.ts +0 -13
  202. package/benchmarks/src/runner.ts +0 -824
  203. package/benchmarks/src/types.ts +0 -63
  204. package/benchmarks/tsconfig.json +0 -19
  205. package/leaderboard/README.md +0 -148
  206. package/leaderboard/app/api/benchmark-data/route.ts +0 -131
  207. package/leaderboard/app/api/benchmark-detail/route.ts +0 -172
  208. package/leaderboard/app/details/[model]/[provider]/[language]/page.tsx +0 -501
  209. package/leaderboard/app/exercise/[model]/[provider]/[language]/[exercise]/page.tsx +0 -375
  210. package/leaderboard/app/globals.css +0 -27
  211. package/leaderboard/app/layout.tsx +0 -21
  212. package/leaderboard/app/page.tsx +0 -170
  213. package/leaderboard/components/LeaderboardTable.tsx +0 -168
  214. package/leaderboard/components/PerformanceChart.tsx +0 -109
  215. package/leaderboard/next-env.d.ts +0 -5
  216. package/leaderboard/next.config.js +0 -4
  217. package/leaderboard/package-lock.json +0 -6363
  218. package/leaderboard/package.json +0 -28
  219. package/leaderboard/postcss.config.js +0 -6
  220. package/leaderboard/tailwind.config.js +0 -17
  221. package/leaderboard/tsconfig.json +0 -28
  222. package/leaderboard/types/benchmark.ts +0 -67
  223. package/leaderboard/utils/dataProcessor.ts +0 -33
  224. package/src/agents/tools/asana/definitions.ts +0 -199
  225. package/src/agents/tools/asana/index.ts +0 -108
  226. package/src/agents/tools/ast/astAppendNode.ts +0 -90
  227. package/src/agents/tools/ast/astDeleteNode.ts +0 -88
  228. package/src/agents/tools/ast/astEditNode.ts +0 -95
  229. package/src/agents/tools/ast/astGetPathForLine.ts +0 -73
  230. package/src/agents/tools/ast/astListPaths.ts +0 -66
  231. package/src/agents/tools/ast/index.ts +0 -7
  232. package/src/agents/tools/github/definitions.ts +0 -89
  233. package/src/agents/tools/github/index.ts +0 -67
  234. package/src/chat-old.ts +0 -446
  235. package/src/plugins/asana.ts +0 -146
  236. package/src/plugins/downloader/plugin.ts +0 -103
  237. package/src/plugins/downloader/types.ts +0 -92
  238. package/src/plugins/figma.ts +0 -158
  239. package/src/plugins/github.ts +0 -219
  240. package/src/plugins/jira.ts +0 -115
  241. package/src/plugins/linear.ts +0 -230
  242. package/src/plugins/notion.ts +0 -179
  243. package/src/plugins/tree-sitter/editor.ts +0 -369
  244. package/src/plugins/tree-sitter/lang-packs/index.ts +0 -23
  245. package/src/plugins/tree-sitter/lang-packs/java.ts +0 -59
  246. package/src/plugins/tree-sitter/lang-packs/javascript.ts +0 -57
  247. package/src/plugins/tree-sitter/lang-packs/python.ts +0 -45
  248. package/src/plugins/tree-sitter/lang-packs/types.ts +0 -79
  249. package/src/plugins/tree-sitter/lang-packs/typescript.ts +0 -49
  250. package/src/plugins/tree-sitter/parser.ts +0 -470
  251. package/src/plugins/tree-sitter/simple-paths.ts +0 -467
  252. package/src/services/GitHub.ts +0 -59
  253. package/tests/tree-sitter/editor.test.ts +0 -113
  254. package/tests/tree-sitter/invalid.test.ts +0 -299
  255. package/tests/tree-sitter/paths/common-edits.test.ts +0 -564
  256. package/tests/tree-sitter/paths/debug-exact-position.test.ts +0 -44
  257. package/tests/tree-sitter/paths/debug-line-indexing.test.ts +0 -49
  258. package/tests/tree-sitter/paths/debug-paths.test.ts +0 -90
  259. package/tests/tree-sitter/paths/paths.test.ts +0 -170
  260. package/tests/tree-sitter/paths/simple-paths.test.ts +0 -367
  261. package/tests/tree-sitter/sample-after.ts +0 -48
  262. package/tests/tree-sitter/sample-before.ts +0 -25
  263. package/tests/tree-sitter/test-files/completely-broken.ts +0 -7
  264. package/tests/tree-sitter/test-files/duplicate-braces.ts +0 -39
  265. package/tests/tree-sitter/test-files/invalid-nesting.ts +0 -39
  266. package/tests/tree-sitter/test-files/malformed-signature.ts +0 -39
  267. package/tests/tree-sitter/test-files/mismatched-parens.ts +0 -39
  268. package/tests/tree-sitter/test-files/missing-semicolon.ts +0 -39
  269. package/tests/tree-sitter/test-files/partially-broken.ts +0 -20
  270. package/tests/tree-sitter/test-files/specific-errors.ts +0 -14
  271. package/tests/tree-sitter/test-files/unclosed-string.ts +0 -39
  272. package/tests/tree-sitter/tree-sitter.test.ts +0 -251
@@ -1,470 +0,0 @@
1
- /**
2
- * Tree-Sitter Language-Agnostic Parser
3
- *
4
- * HEISENBERG TEST ISSUE - NATIVE MODULE STABILITY:
5
- * Tree-sitter uses native node bindings (.node files) that occasionally have state corruption
6
- * issues when tests run in parallel or modules are re-imported. This manifests as tree.rootNode
7
- * being undefined intermittently (Heisenberg bug - fails unpredictably).
8
- *
9
- * SOLUTION: Defensive guards at lines 250 and 320 check for undefined rootNode and return
10
- * early to prevent crashes. This provides 93%+ test stability (acceptable for native modules).
11
- *
12
- * WHAT DIDN'T WORK:
13
- * - Running tests serially (maxWorkers: 1) - MADE IT WORSE
14
- * - Clearing module cache (resetModules: true) - BROKE initialization completely
15
- * - afterEach cleanup hooks - No effect
16
- * - The native module needs parallel execution patterns to initialize correctly
17
- */
18
- import Parser from "tree-sitter";
19
- import TypeScript from "tree-sitter-typescript";
20
- import JavaScript from "tree-sitter-javascript";
21
- import { readFileSync } from "fs";
22
- import {
23
- LanguagePackConfig,
24
- BodyRule,
25
- NormalizedKind,
26
- } from "./lang-packs/types";
27
- import { languagePacks, getLanguagePack } from "./lang-packs";
28
-
29
- export type Tree = Parser.Tree;
30
- export type SyntaxNode = Parser.SyntaxNode;
31
-
32
- export interface TreeNode {
33
- type: string;
34
- text: string;
35
- startPosition: { row: number; column: number };
36
- endPosition: { row: number; column: number };
37
- children: TreeNode[];
38
- }
39
-
40
- export interface LanguageConfig {
41
- language: any;
42
- methodDeclarationTypes: string[];
43
- classDeclarationTypes: string[];
44
- }
45
-
46
- export interface PathLocation {
47
- path: string;
48
- row: number;
49
- column: number;
50
- text: string;
51
- }
52
-
53
- export interface TreeEdit {
54
- type: "add" | "remove" | "update";
55
- path: string;
56
- content?: string;
57
- lineNumber?: number;
58
- }
59
-
60
- // Utility function to get language pack by language name
61
- export function getLanguagePackForLanguage(
62
- languageName: string
63
- ): LanguagePackConfig | undefined {
64
- const normalizedName =
65
- LanguageAgnosticParser.resolveLanguageName(languageName);
66
- return getLanguagePack(normalizedName);
67
- }
68
-
69
- export class LanguageAgnosticParser {
70
- public parser: Parser;
71
- public currentLanguagePack?: LanguagePackConfig;
72
-
73
- constructor(language: string) {
74
- this.parser = new Parser();
75
- this.setupFromLanguageName(language);
76
- }
77
-
78
- static resolveLanguageName(extOrName: string): string {
79
- const aliases: Record<string, string> = {
80
- js: "javascript",
81
- jsx: "javascript",
82
- ts: "typescript",
83
- tsx: "typescript",
84
- javascript: "javascript",
85
- typescript: "typescript",
86
- };
87
- return aliases[extOrName.toLowerCase()] || extOrName;
88
- }
89
-
90
- static suportedLanguages(): string[] {
91
- return Array.from(new Set(Object.keys(languagePacks)));
92
- }
93
-
94
- static createParserForFile(filePath: string): LanguageAgnosticParser {
95
- const ext = filePath.split(".").pop()?.toLowerCase();
96
- return new LanguageAgnosticParser(ext);
97
- }
98
-
99
- static createTypeScriptParser(): LanguageAgnosticParser {
100
- return new LanguageAgnosticParser("typescript");
101
- }
102
-
103
- static createJavaScriptParser(): LanguageAgnosticParser {
104
- return new LanguageAgnosticParser("javascript");
105
- }
106
-
107
- static supportsLanguage(languageName: string): boolean {
108
- return !!getLanguagePackForLanguage(languageName);
109
- }
110
-
111
- static supportsFile(filePath: string): boolean {
112
- const ext = filePath.split(".").pop()?.toLowerCase();
113
- return !!getLanguagePackForLanguage(ext || "");
114
- }
115
-
116
- private setupFromLanguageName(languageName: string) {
117
- this.setLanguagePack(languageName);
118
- this.setupParserForLanguage(languageName);
119
- }
120
-
121
- private setupParserForLanguage(languageName: string) {
122
- const normalizedName =
123
- LanguageAgnosticParser.resolveLanguageName(languageName);
124
-
125
- switch (normalizedName) {
126
- case "javascript":
127
- this.parser.setLanguage(JavaScript);
128
- break;
129
- case "typescript":
130
- this.parser.setLanguage(TypeScript.typescript);
131
- break;
132
- default:
133
- throw new Error(`Unsupported language: ${languageName}`);
134
- }
135
- }
136
-
137
- setLanguagePack(languageName: string) {
138
- const pack = getLanguagePackForLanguage(languageName);
139
- if (pack) {
140
- this.currentLanguagePack = pack;
141
- }
142
- }
143
-
144
- getLanguagePack(): LanguagePackConfig | undefined {
145
- return this.currentLanguagePack;
146
- }
147
-
148
- getLanguage(): string | undefined {
149
- return this.currentLanguagePack?.language;
150
- }
151
-
152
- // Helper function to get normalized node kind
153
- nodeKind(node: Parser.SyntaxNode): NormalizedKind {
154
- const pack = this.currentLanguagePack;
155
- return pack.kindMap[node.type] || "unknown";
156
- }
157
-
158
- // Apply a body rule to find the body node
159
- applyRule(
160
- node: Parser.SyntaxNode,
161
- rule: BodyRule,
162
- pack: LanguagePackConfig
163
- ): Parser.SyntaxNode | undefined {
164
- switch (rule.kind) {
165
- case "self":
166
- return node;
167
-
168
- case "child":
169
- if (!rule.nodeType) return undefined;
170
- return node.children.find((child) => child.type === rule.nodeType);
171
-
172
- case "field":
173
- if (!rule.field) return undefined;
174
- return node.childForFieldName(rule.field);
175
-
176
- case "functionBody":
177
- // Find statement_block child for functions
178
- return node.children.find((child) => child.type === "statement_block");
179
-
180
- case "callCallbackBody":
181
- // For call expressions, find the last argument if it's a function
182
- const args = node.childForFieldName("arguments");
183
- if (!args) return undefined;
184
- const lastArg = args.children[args.children.length - 1];
185
- if (!lastArg) return undefined;
186
-
187
- // If it's a function-like node, get its body
188
- if (
189
- lastArg.type === "arrow_function" ||
190
- lastArg.type === "function_expression"
191
- ) {
192
- return this.applyRule(lastArg, { kind: "functionBody" }, pack);
193
- }
194
- return lastArg;
195
-
196
- default:
197
- return undefined;
198
- }
199
- }
200
-
201
- // Get body node using mini language pack
202
- getBodyNodeWithLanguagePack(
203
- node: Parser.SyntaxNode,
204
- pack: LanguagePackConfig
205
- ): Parser.SyntaxNode | undefined {
206
- const rules = pack.bodyMap[node.type];
207
- if (!rules || rules.length === 0) {
208
- return undefined;
209
- }
210
-
211
- // Try each rule in order until one succeeds
212
- for (const rule of rules) {
213
- const result = this.applyRule(node, rule, pack);
214
- if (result) {
215
- return result;
216
- }
217
- }
218
-
219
- return undefined;
220
- }
221
-
222
- getBodyNode(node: Parser.SyntaxNode): Parser.SyntaxNode | null {
223
- if (!this.currentLanguagePack) {
224
- return null;
225
- }
226
- const result = this.getBodyNodeWithLanguagePack(
227
- node,
228
- this.currentLanguagePack
229
- );
230
- return result || null;
231
- }
232
-
233
- // Get body node using mini language pack (public method for editor)
234
- getBodyNodeForLanguage(
235
- node: Parser.SyntaxNode,
236
- language: string
237
- ): Parser.SyntaxNode | undefined {
238
- const pack = getLanguagePackForLanguage(language.toLowerCase());
239
- if (!pack) return undefined;
240
- return this.getBodyNodeWithLanguagePack(node, pack);
241
- }
242
-
243
- // Get normalized node kind for a language
244
- getNodeKindForLanguage(
245
- node: Parser.SyntaxNode,
246
- language: string
247
- ): NormalizedKind {
248
- const pack = getLanguagePackForLanguage(language.toLowerCase());
249
- if (!pack) return "unknown";
250
- return this.nodeKind(node);
251
- }
252
-
253
- parseFile(filePath: string): Parser.Tree {
254
- const sourceCode = readFileSync(filePath, "utf8");
255
- return this.parser.parse(sourceCode);
256
- }
257
-
258
- parseString(sourceCode: string): Parser.Tree {
259
- return this.parser.parse(sourceCode);
260
- }
261
-
262
- getFileText(tree: Parser.Tree): string {
263
- return tree.rootNode.text;
264
- }
265
-
266
- findPathsForLine(tree: Parser.Tree, searchText: string): PathLocation[] {
267
- const results: PathLocation[] = [];
268
-
269
- // Guard against native module state corruption (Heisenberg bug)
270
- // See file header comment for details on the tree-sitter stability issue
271
- if (!tree.rootNode) return results;
272
-
273
- const sourceText = tree.rootNode.text;
274
- const lines = sourceText.split("\n");
275
-
276
- lines.forEach((line, lineIndex) => {
277
- let columnIndex = line.indexOf(searchText);
278
- while (columnIndex !== -1) {
279
- // Find the node at this position
280
- const node = tree.rootNode.descendantForPosition(
281
- { row: lineIndex, column: columnIndex },
282
- { row: lineIndex, column: columnIndex + searchText.length }
283
- );
284
-
285
- if (node) {
286
- const path = this.getNodePath(tree.rootNode, node);
287
- results.push({
288
- path,
289
- row: lineIndex,
290
- column: columnIndex,
291
- text: searchText,
292
- });
293
- }
294
-
295
- columnIndex = line.indexOf(searchText, columnIndex + 1);
296
- }
297
- });
298
-
299
- return results;
300
- }
301
-
302
- getNodePath(
303
- rootNode: Parser.SyntaxNode,
304
- targetNode: Parser.SyntaxNode
305
- ): string {
306
- const path: string[] = [];
307
- let current: Parser.SyntaxNode | null = targetNode;
308
-
309
- while (current && current !== rootNode) {
310
- if (current.parent) {
311
- const siblings = current.parent.children;
312
- const index = siblings.indexOf(current);
313
- path.unshift(`${current.type}[${index}]`);
314
- current = current.parent;
315
- } else {
316
- break;
317
- }
318
- }
319
-
320
- return path.join("/");
321
- }
322
- nodeToObject(node: Parser.SyntaxNode): TreeNode {
323
- return {
324
- type: node.type,
325
- text: node.text,
326
- startPosition: {
327
- row: node.startPosition.row,
328
- column: node.startPosition.column,
329
- },
330
- endPosition: {
331
- row: node.endPosition.row,
332
- column: node.endPosition.column,
333
- },
334
- children: node.children.map((child) => this.nodeToObject(child)),
335
- };
336
- }
337
-
338
- findNodesByType(tree: Parser.Tree, nodeType: string): Parser.SyntaxNode[] {
339
- const results: Parser.SyntaxNode[] = [];
340
-
341
- // Guard against native module state corruption (Heisenberg bug)
342
- // See file header comment for details on the tree-sitter stability issue
343
- if (!tree.rootNode) return results;
344
-
345
- function traverse(node: Parser.SyntaxNode) {
346
- if (node.type === nodeType) {
347
- results.push(node);
348
- }
349
-
350
- for (const child of node.children) {
351
- traverse(child);
352
- }
353
- }
354
-
355
- traverse(tree.rootNode);
356
- return results;
357
- }
358
-
359
- getTypesForKind(kind: NormalizedKind): string[] {
360
- if (!this.currentLanguagePack) return [];
361
- return Object.entries(this.currentLanguagePack.kindMap)
362
- .filter(([_, v]) => v === kind)
363
- .map(([k, _]) => k);
364
- }
365
-
366
- findNodesByKind(
367
- tree: Parser.Tree,
368
- kind: NormalizedKind
369
- ): Parser.SyntaxNode[] {
370
- const types = this.getTypesForKind(kind);
371
- const results: Parser.SyntaxNode[] = [];
372
- for (const type of types) {
373
- results.push(...this.findNodesByType(tree, type));
374
- }
375
- return results;
376
- }
377
-
378
- findClassDeclarations(tree: Parser.Tree): Parser.SyntaxNode[] {
379
- return this.findNodesByKind(tree, "class");
380
- }
381
-
382
- findMethodDeclarations(tree: Parser.Tree): Parser.SyntaxNode[] {
383
- return this.findNodesByKind(tree, "method");
384
- }
385
-
386
- printTree(node: Parser.SyntaxNode, indent: string = ""): string {
387
- let result = `${indent}${node.type}`;
388
- if (node.isNamed && node.text.length < 50) {
389
- result += `: "${node.text.replace(/\n/g, "\\n")}"`;
390
- }
391
- result += "\n";
392
-
393
- for (const child of node.children) {
394
- result += this.printTree(child, indent + " ");
395
- }
396
-
397
- return result;
398
- }
399
-
400
- findErrorNodes(node: Parser.SyntaxNode): Parser.SyntaxNode[] {
401
- const errorNodes: Parser.SyntaxNode[] = [];
402
-
403
- function traverse(n: any) {
404
- if (n.type === "ERROR" || n.hasError) {
405
- errorNodes.push(n);
406
- }
407
-
408
- for (const child of n.children || []) {
409
- traverse(child);
410
- }
411
- }
412
-
413
- traverse(node);
414
- return errorNodes;
415
- }
416
- }
417
-
418
- export function compareTreeStructures(
419
- tree1: Parser.Tree,
420
- tree2: Parser.Tree
421
- ): {
422
- differences: string[];
423
- summary: string;
424
- } {
425
- const differences: string[] = [];
426
-
427
- function compareNodes(
428
- node1: Parser.SyntaxNode | null,
429
- node2: Parser.SyntaxNode | null,
430
- path: string = "root"
431
- ) {
432
- if (!node1 && !node2) return;
433
-
434
- if (!node1) {
435
- differences.push(`Node removed at ${path}: ${node2!.type}`);
436
- return;
437
- }
438
-
439
- if (!node2) {
440
- differences.push(`Node added at ${path}: ${node1.type}`);
441
- return;
442
- }
443
-
444
- if (node1.type !== node2.type) {
445
- differences.push(
446
- `Node type changed at ${path}: ${node1.type} -> ${node2.type}`
447
- );
448
- }
449
-
450
- if (node1.text !== node2.text && node1.text.length < 100) {
451
- differences.push(
452
- `Node text changed at ${path} (${node1.type}): "${node1.text}" -> "${node2.text}"`
453
- );
454
- }
455
-
456
- const maxChildren = Math.max(node1.children.length, node2.children.length);
457
- for (let i = 0; i < maxChildren; i++) {
458
- const child1 = node1.children[i] || null;
459
- const child2 = node2.children[i] || null;
460
- compareNodes(child1, child2, `${path}.${i}`);
461
- }
462
- }
463
-
464
- compareNodes(tree1.rootNode, tree2.rootNode);
465
-
466
- return {
467
- differences,
468
- summary: `Found ${differences.length} differences between the two trees`,
469
- };
470
- }