@tyvm/knowhow 0.0.90 → 0.0.91

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 (262) hide show
  1. package/.depcheckrc +31 -0
  2. package/bin/knowhow.js +1 -1
  3. package/package.json +4 -32
  4. package/src/agents/tools/executeScript/index.ts +5 -0
  5. package/src/agents/tools/googleSearch.ts +2 -2
  6. package/src/agents/tools/index.ts +0 -3
  7. package/src/agents/tools/list.ts +0 -147
  8. package/src/agents/tools/loadWebpage.ts +3 -113
  9. package/src/auth/browserLogin.ts +10 -13
  10. package/src/cli.ts +63 -3
  11. package/src/clients/gemini.ts +96 -25
  12. package/src/clients/http.ts +7 -11
  13. package/src/clients/pricing/google.ts +122 -26
  14. package/src/conversion.ts +24 -54
  15. package/src/index.ts +8 -1
  16. package/src/login.ts +5 -6
  17. package/src/plugins/language.ts +0 -4
  18. package/src/plugins/plugins.ts +0 -14
  19. package/src/plugins/url.ts +31 -12
  20. package/src/services/GitHub.ts +2 -2
  21. package/src/services/KnowhowClient.ts +34 -34
  22. package/src/{plugins/downloader/downloader.ts → services/MediaProcessorService.ts} +109 -267
  23. package/src/services/S3.ts +16 -16
  24. package/src/services/index.ts +4 -4
  25. package/src/services/modules/index.ts +10 -2
  26. package/src/services/modules/types.ts +5 -2
  27. package/src/services/script-execution/ScriptExecutor.ts +29 -10
  28. package/src/services/script-execution/ScriptPolicy.ts +6 -2
  29. package/src/types.ts +1 -0
  30. package/src/utils/http.ts +127 -0
  31. package/src/workers/auth/PasskeySetup.ts +7 -11
  32. package/tests/clients/AIClient.test.ts +24 -21
  33. package/tests/manual/file-edits/figma.test.ts +3 -70
  34. package/tests/plugins/language/languagePlugin-content-triggers.test.ts +2 -0
  35. package/tests/plugins/language/languagePlugin.test.ts +2 -0
  36. package/tests/processors/ToolResponseCache.test.ts +2 -2
  37. package/tests/test.spec.ts +0 -14
  38. package/tests/unit/modules/moduleLoading.test.ts +7 -4
  39. package/tests/unit/plugins/pluginLoading.test.ts +6 -6
  40. package/ts_build/package.json +4 -32
  41. package/ts_build/src/agents/tools/ast/astAppendNode.d.ts +1 -1
  42. package/ts_build/src/agents/tools/ast/astAppendNode.js +2 -90
  43. package/ts_build/src/agents/tools/ast/astAppendNode.js.map +1 -1
  44. package/ts_build/src/agents/tools/ast/astDeleteNode.d.ts +1 -1
  45. package/ts_build/src/agents/tools/ast/astDeleteNode.js +2 -88
  46. package/ts_build/src/agents/tools/ast/astDeleteNode.js.map +1 -1
  47. package/ts_build/src/agents/tools/ast/astEditNode.d.ts +1 -1
  48. package/ts_build/src/agents/tools/ast/astEditNode.js +2 -90
  49. package/ts_build/src/agents/tools/ast/astEditNode.js.map +1 -1
  50. package/ts_build/src/agents/tools/ast/astGetPathForLine.d.ts +1 -1
  51. package/ts_build/src/agents/tools/ast/astGetPathForLine.js +2 -72
  52. package/ts_build/src/agents/tools/ast/astGetPathForLine.js.map +1 -1
  53. package/ts_build/src/agents/tools/ast/astListPaths.d.ts +1 -1
  54. package/ts_build/src/agents/tools/ast/astListPaths.js +2 -72
  55. package/ts_build/src/agents/tools/ast/astListPaths.js.map +1 -1
  56. package/ts_build/src/agents/tools/executeScript/index.d.ts +3 -2
  57. package/ts_build/src/agents/tools/executeScript/index.js +4 -1
  58. package/ts_build/src/agents/tools/executeScript/index.js.map +1 -1
  59. package/ts_build/src/agents/tools/googleSearch.js +2 -2
  60. package/ts_build/src/agents/tools/googleSearch.js.map +1 -1
  61. package/ts_build/src/agents/tools/index.d.ts +0 -3
  62. package/ts_build/src/agents/tools/index.js +0 -3
  63. package/ts_build/src/agents/tools/index.js.map +1 -1
  64. package/ts_build/src/agents/tools/list.js +0 -138
  65. package/ts_build/src/agents/tools/list.js.map +1 -1
  66. package/ts_build/src/agents/tools/loadWebpage.js +1 -89
  67. package/ts_build/src/agents/tools/loadWebpage.js.map +1 -1
  68. package/ts_build/src/agents/tools/textSearch.d.ts +1 -1
  69. package/ts_build/src/auth/browserLogin.js +7 -7
  70. package/ts_build/src/auth/browserLogin.js.map +1 -1
  71. package/ts_build/src/cli.d.ts +1 -1
  72. package/ts_build/src/cli.js +47 -1
  73. package/ts_build/src/cli.js.map +1 -1
  74. package/ts_build/src/clients/gemini.d.ts +1 -73
  75. package/ts_build/src/clients/gemini.js +57 -19
  76. package/ts_build/src/clients/gemini.js.map +1 -1
  77. package/ts_build/src/clients/http.js +5 -9
  78. package/ts_build/src/clients/http.js.map +1 -1
  79. package/ts_build/src/clients/pricing/google.d.ts +17 -73
  80. package/ts_build/src/clients/pricing/google.js +47 -10
  81. package/ts_build/src/clients/pricing/google.js.map +1 -1
  82. package/ts_build/src/conversion.d.ts +1 -4
  83. package/ts_build/src/conversion.js +12 -27
  84. package/ts_build/src/conversion.js.map +1 -1
  85. package/ts_build/src/index.d.ts +4 -0
  86. package/ts_build/src/index.js +7 -1
  87. package/ts_build/src/index.js.map +1 -1
  88. package/ts_build/src/login.js +5 -4
  89. package/ts_build/src/login.js.map +1 -1
  90. package/ts_build/src/plugins/downloader/downloader.js +3 -3
  91. package/ts_build/src/plugins/downloader/downloader.js.map +1 -1
  92. package/ts_build/src/plugins/language.js.map +1 -1
  93. package/ts_build/src/plugins/plugins.js +0 -14
  94. package/ts_build/src/plugins/plugins.js.map +1 -1
  95. package/ts_build/src/plugins/tree-sitter/editor.d.ts +3 -32
  96. package/ts_build/src/plugins/tree-sitter/editor.js +6 -208
  97. package/ts_build/src/plugins/tree-sitter/editor.js.map +1 -1
  98. package/ts_build/src/plugins/tree-sitter/parser.d.ts +19 -54
  99. package/ts_build/src/plugins/tree-sitter/parser.js +19 -293
  100. package/ts_build/src/plugins/tree-sitter/parser.js.map +1 -1
  101. package/ts_build/src/plugins/tree-sitter/simple-paths.d.ts +2 -15
  102. package/ts_build/src/plugins/tree-sitter/simple-paths.js +2 -324
  103. package/ts_build/src/plugins/tree-sitter/simple-paths.js.map +1 -1
  104. package/ts_build/src/plugins/url.js +27 -8
  105. package/ts_build/src/plugins/url.js.map +1 -1
  106. package/ts_build/src/services/GitHub.js +2 -2
  107. package/ts_build/src/services/GitHub.js.map +1 -1
  108. package/ts_build/src/services/KnowhowClient.d.ts +29 -29
  109. package/ts_build/src/services/KnowhowClient.js +33 -33
  110. package/ts_build/src/services/KnowhowClient.js.map +1 -1
  111. package/ts_build/src/services/MediaProcessorService.d.ts +22 -0
  112. package/ts_build/src/services/MediaProcessorService.js +215 -0
  113. package/ts_build/src/services/MediaProcessorService.js.map +1 -0
  114. package/ts_build/src/services/S3.js +12 -18
  115. package/ts_build/src/services/S3.js.map +1 -1
  116. package/ts_build/src/services/index.d.ts +3 -2
  117. package/ts_build/src/services/index.js +3 -3
  118. package/ts_build/src/services/index.js.map +1 -1
  119. package/ts_build/src/services/modules/index.js +10 -2
  120. package/ts_build/src/services/modules/index.js.map +1 -1
  121. package/ts_build/src/services/modules/types.d.ts +5 -2
  122. package/ts_build/src/services/script-execution/ScriptExecutor.js +22 -7
  123. package/ts_build/src/services/script-execution/ScriptExecutor.js.map +1 -1
  124. package/ts_build/src/services/script-execution/ScriptPolicy.d.ts +1 -1
  125. package/ts_build/src/services/script-execution/ScriptPolicy.js +4 -2
  126. package/ts_build/src/services/script-execution/ScriptPolicy.js.map +1 -1
  127. package/ts_build/src/types.d.ts +1 -0
  128. package/ts_build/src/types.js +1 -0
  129. package/ts_build/src/types.js.map +1 -1
  130. package/ts_build/src/utils/http.d.ts +27 -0
  131. package/ts_build/src/utils/http.js +98 -0
  132. package/ts_build/src/utils/http.js.map +1 -0
  133. package/ts_build/src/workers/auth/PasskeySetup.js +6 -7
  134. package/ts_build/src/workers/auth/PasskeySetup.js.map +1 -1
  135. package/ts_build/tests/clients/AIClient.test.js +11 -14
  136. package/ts_build/tests/clients/AIClient.test.js.map +1 -1
  137. package/ts_build/tests/manual/file-edits/figma.test.d.ts +0 -1
  138. package/ts_build/tests/manual/file-edits/figma.test.js +1 -46
  139. package/ts_build/tests/manual/file-edits/figma.test.js.map +1 -1
  140. package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js +2 -0
  141. package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js.map +1 -1
  142. package/ts_build/tests/plugins/language/languagePlugin.test.js +2 -0
  143. package/ts_build/tests/plugins/language/languagePlugin.test.js.map +1 -1
  144. package/ts_build/tests/processors/ToolResponseCache.test.js +2 -2
  145. package/ts_build/tests/processors/ToolResponseCache.test.js.map +1 -1
  146. package/ts_build/tests/test.spec.js +0 -14
  147. package/ts_build/tests/test.spec.js.map +1 -1
  148. package/ts_build/tests/tree-sitter/tree-sitter.test.d.ts +0 -1
  149. package/ts_build/tests/tree-sitter/tree-sitter.test.js +2 -183
  150. package/ts_build/tests/tree-sitter/tree-sitter.test.js.map +1 -1
  151. package/ts_build/tests/unit/modules/moduleLoading.test.js +6 -4
  152. package/ts_build/tests/unit/modules/moduleLoading.test.js.map +1 -1
  153. package/ts_build/tests/unit/plugins/pluginLoading.test.js +4 -4
  154. package/ts_build/tests/unit/plugins/pluginLoading.test.js.map +1 -1
  155. package/benchmarks/.dockerignore +0 -7
  156. package/benchmarks/README.md +0 -166
  157. package/benchmarks/docker/Dockerfile +0 -68
  158. package/benchmarks/example-config.yml +0 -27
  159. package/benchmarks/jest.config.js +0 -13
  160. package/benchmarks/package-lock.json +0 -4297
  161. package/benchmarks/package.json +0 -39
  162. package/benchmarks/results/27b0a06/2025-09-27/xai/xai-grok-code-fast-1.json +0 -2909
  163. package/benchmarks/results/4057aed/2025-08-14/anthropic/anthropic-claude-sonnet-4-20250514.json +0 -1671
  164. package/benchmarks/results/4542435/2025-08-05/lms/lms-openai-gpt-oss-20b.json +0 -2814
  165. package/benchmarks/results/4542435/2025-08-05/lms/lms-qwen-qwen3-30b-a3b-2507.json +0 -2014
  166. package/benchmarks/results/4fb9125/2025-08-07/anthropic/anthropic-claude-sonnet-4-20250514.json +0 -3121
  167. package/benchmarks/results/5766aee/2025-08-02/lms-qwen/qwen3-coder-30b.json +0 -98
  168. package/benchmarks/results/6d73808/2025-08-07/openai/openai-gpt-5.json +0 -3256
  169. package/benchmarks/results/77bf0a6/2025-08-02/lms-qwen/qwen3-30b-a3b-2507.json +0 -4298
  170. package/benchmarks/results/8c0d445/2025-08-03/anthropic/anthropic-claude-sonnet-4-20250514.json +0 -3031
  171. package/benchmarks/results/8c0d445/2025-08-03/openai/openai-gpt-4.1-2025-04-14.json +0 -2990
  172. package/benchmarks/results/ac6b2ab/2025-08-03/anthropic/anthropic-claude-sonnet-4-20250514.json +0 -3256
  173. package/benchmarks/results/ac6b2ab/2025-08-03/lms/lms-qwen-qwen3-coder-30b.json +0 -3007
  174. package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-2025-04-14.json +0 -3256
  175. package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-mini-2025-04-14.json +0 -3036
  176. package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-nano-2025-04-14.json +0 -3280
  177. package/benchmarks/results/adff675/2025-08-04/lms/lms-qwen-qwen3-30b-a3b-2507.json +0 -1920
  178. package/benchmarks/results/adff675/2025-08-04/lms/lms-qwen-qwen3-coder-30b.json +0 -3281
  179. package/benchmarks/results/b502ed9/2025-08-03/lms-qwen/qwen3-coder-30b.json +0 -2896
  180. package/benchmarks/results/d1a8129/2025-08-03/lms/lms-qwen-qwen3-coder-30b.json +0 -3011
  181. package/benchmarks/results/e60471c/2025-08-03/lms/qwen3-30b-a3b-2507.json +0 -3003
  182. package/benchmarks/scripts/build-and-run.sh +0 -47
  183. package/benchmarks/scripts/clone-exercism.sh +0 -92
  184. package/benchmarks/scripts/validate.sh +0 -48
  185. package/benchmarks/src/__tests__/runner.test.ts +0 -27
  186. package/benchmarks/src/cli.ts +0 -90
  187. package/benchmarks/src/evaluators/EvaluatorRegistry.ts +0 -64
  188. package/benchmarks/src/evaluators/JavaScriptEvaluator.ts +0 -183
  189. package/benchmarks/src/evaluators/index.ts +0 -3
  190. package/benchmarks/src/evaluators/types.ts +0 -22
  191. package/benchmarks/src/index.ts +0 -3
  192. package/benchmarks/src/providers.ts +0 -13
  193. package/benchmarks/src/runner.ts +0 -824
  194. package/benchmarks/src/types.ts +0 -63
  195. package/benchmarks/tsconfig.json +0 -19
  196. package/leaderboard/README.md +0 -148
  197. package/leaderboard/app/api/benchmark-data/route.ts +0 -131
  198. package/leaderboard/app/api/benchmark-detail/route.ts +0 -172
  199. package/leaderboard/app/details/[model]/[provider]/[language]/page.tsx +0 -501
  200. package/leaderboard/app/exercise/[model]/[provider]/[language]/[exercise]/page.tsx +0 -375
  201. package/leaderboard/app/globals.css +0 -27
  202. package/leaderboard/app/layout.tsx +0 -21
  203. package/leaderboard/app/page.tsx +0 -170
  204. package/leaderboard/components/LeaderboardTable.tsx +0 -168
  205. package/leaderboard/components/PerformanceChart.tsx +0 -109
  206. package/leaderboard/next-env.d.ts +0 -5
  207. package/leaderboard/next.config.js +0 -4
  208. package/leaderboard/package-lock.json +0 -6363
  209. package/leaderboard/package.json +0 -28
  210. package/leaderboard/postcss.config.js +0 -6
  211. package/leaderboard/tailwind.config.js +0 -17
  212. package/leaderboard/tsconfig.json +0 -28
  213. package/leaderboard/types/benchmark.ts +0 -67
  214. package/leaderboard/utils/dataProcessor.ts +0 -33
  215. package/src/agents/tools/asana/definitions.ts +0 -199
  216. package/src/agents/tools/asana/index.ts +0 -108
  217. package/src/agents/tools/ast/astAppendNode.ts +0 -90
  218. package/src/agents/tools/ast/astDeleteNode.ts +0 -88
  219. package/src/agents/tools/ast/astEditNode.ts +0 -95
  220. package/src/agents/tools/ast/astGetPathForLine.ts +0 -73
  221. package/src/agents/tools/ast/astListPaths.ts +0 -66
  222. package/src/agents/tools/ast/index.ts +0 -7
  223. package/src/agents/tools/github/definitions.ts +0 -89
  224. package/src/agents/tools/github/index.ts +0 -67
  225. package/src/chat-old.ts +0 -446
  226. package/src/plugins/asana.ts +0 -146
  227. package/src/plugins/downloader/plugin.ts +0 -103
  228. package/src/plugins/downloader/types.ts +0 -92
  229. package/src/plugins/figma.ts +0 -158
  230. package/src/plugins/github.ts +0 -219
  231. package/src/plugins/jira.ts +0 -115
  232. package/src/plugins/linear.ts +0 -230
  233. package/src/plugins/notion.ts +0 -179
  234. package/src/plugins/tree-sitter/editor.ts +0 -369
  235. package/src/plugins/tree-sitter/lang-packs/index.ts +0 -23
  236. package/src/plugins/tree-sitter/lang-packs/java.ts +0 -59
  237. package/src/plugins/tree-sitter/lang-packs/javascript.ts +0 -57
  238. package/src/plugins/tree-sitter/lang-packs/python.ts +0 -45
  239. package/src/plugins/tree-sitter/lang-packs/types.ts +0 -79
  240. package/src/plugins/tree-sitter/lang-packs/typescript.ts +0 -49
  241. package/src/plugins/tree-sitter/parser.ts +0 -470
  242. package/src/plugins/tree-sitter/simple-paths.ts +0 -467
  243. package/tests/tree-sitter/editor.test.ts +0 -113
  244. package/tests/tree-sitter/invalid.test.ts +0 -299
  245. package/tests/tree-sitter/paths/common-edits.test.ts +0 -564
  246. package/tests/tree-sitter/paths/debug-exact-position.test.ts +0 -44
  247. package/tests/tree-sitter/paths/debug-line-indexing.test.ts +0 -49
  248. package/tests/tree-sitter/paths/debug-paths.test.ts +0 -90
  249. package/tests/tree-sitter/paths/paths.test.ts +0 -170
  250. package/tests/tree-sitter/paths/simple-paths.test.ts +0 -367
  251. package/tests/tree-sitter/sample-after.ts +0 -48
  252. package/tests/tree-sitter/sample-before.ts +0 -25
  253. package/tests/tree-sitter/test-files/completely-broken.ts +0 -7
  254. package/tests/tree-sitter/test-files/duplicate-braces.ts +0 -39
  255. package/tests/tree-sitter/test-files/invalid-nesting.ts +0 -39
  256. package/tests/tree-sitter/test-files/malformed-signature.ts +0 -39
  257. package/tests/tree-sitter/test-files/mismatched-parens.ts +0 -39
  258. package/tests/tree-sitter/test-files/missing-semicolon.ts +0 -39
  259. package/tests/tree-sitter/test-files/partially-broken.ts +0 -20
  260. package/tests/tree-sitter/test-files/specific-errors.ts +0 -14
  261. package/tests/tree-sitter/test-files/unclosed-string.ts +0 -39
  262. 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
- }