@tyvm/knowhow 0.0.46 → 0.0.48

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 (461) hide show
  1. package/benchmarks/results/27b0a06/2025-09-27/xai/xai-grok-code-fast-1.json +2909 -0
  2. package/benchmarks/results/4057aed/2025-08-14/anthropic/anthropic-claude-sonnet-4-20250514.json +1671 -0
  3. package/jest.config.js +2 -2
  4. package/package.json +8 -3
  5. package/src/agents/base/base.ts +30 -24
  6. package/src/agents/patcher/patcher.ts +26 -5
  7. package/src/agents/tools/agentCall.ts +4 -2
  8. package/src/agents/tools/aiClient.ts +3 -11
  9. package/src/agents/tools/ast/astAppendNode.ts +90 -0
  10. package/src/agents/tools/ast/astDeleteNode.ts +88 -0
  11. package/src/agents/tools/ast/astEditNode.ts +95 -0
  12. package/src/agents/tools/ast/astGetPathForLine.ts +73 -0
  13. package/src/agents/tools/ast/astListPaths.ts +66 -0
  14. package/src/agents/tools/ast/index.ts +7 -0
  15. package/src/agents/tools/callPlugin.ts +8 -2
  16. package/src/agents/tools/embeddingSearch.ts +2 -1
  17. package/src/agents/tools/execCommand.ts +239 -94
  18. package/src/agents/tools/fileSearch.ts +15 -17
  19. package/src/agents/tools/index.ts +1 -0
  20. package/src/agents/tools/language/definitions.ts +10 -2
  21. package/src/agents/tools/language/index.ts +3 -2
  22. package/src/agents/tools/lintFile.ts +4 -2
  23. package/src/agents/tools/list.ts +203 -62
  24. package/src/agents/tools/patch.ts +48 -14
  25. package/src/agents/tools/readBlocks.ts +34 -0
  26. package/src/agents/tools/readFile.ts +23 -0
  27. package/src/agents/tools/stringReplace.ts +33 -9
  28. package/src/agents/tools/writeFile.ts +55 -0
  29. package/src/agents/tools/ycmd/server.ts +14 -4
  30. package/src/chat/CliChatService.ts +6 -1
  31. package/src/chat/modules/AgentModule.ts +107 -64
  32. package/src/chat/modules/AskModule.ts +0 -1
  33. package/src/chat/modules/SetupModule.ts +4 -4
  34. package/src/chat/modules/SystemModule.ts +28 -5
  35. package/src/chat/types.ts +2 -0
  36. package/src/chat-old.ts +2 -2
  37. package/src/clients/anthropic.ts +22 -1
  38. package/src/clients/openai.ts +1 -1
  39. package/src/clients/types.ts +1 -1
  40. package/src/clients/xai.ts +15 -5
  41. package/src/config.ts +17 -5
  42. package/src/dataset/diffs/generate.ts +2 -2
  43. package/src/dataset/diffs/jsonl.ts +0 -1
  44. package/src/embeddings.ts +6 -4
  45. package/src/index.ts +11 -5
  46. package/src/plugins/GitPlugin.ts +530 -0
  47. package/src/plugins/LinterPlugin.ts +89 -0
  48. package/src/plugins/PluginBase.ts +4 -2
  49. package/src/plugins/asana.ts +4 -2
  50. package/src/plugins/downloader/plugin.ts +5 -2
  51. package/src/plugins/embedding.ts +24 -4
  52. package/src/plugins/figma.ts +7 -3
  53. package/src/plugins/github.ts +4 -2
  54. package/src/plugins/jira.ts +4 -2
  55. package/src/plugins/language.ts +134 -27
  56. package/src/plugins/linear.ts +4 -2
  57. package/src/plugins/notion.ts +4 -2
  58. package/src/plugins/plugins.ts +27 -16
  59. package/src/plugins/tree-sitter/editor.ts +369 -0
  60. package/src/plugins/tree-sitter/lang-packs/index.ts +23 -0
  61. package/src/plugins/tree-sitter/lang-packs/java.ts +59 -0
  62. package/src/plugins/tree-sitter/lang-packs/javascript.ts +57 -0
  63. package/src/plugins/tree-sitter/lang-packs/python.ts +45 -0
  64. package/src/plugins/tree-sitter/lang-packs/types.ts +79 -0
  65. package/src/plugins/tree-sitter/lang-packs/typescript.ts +49 -0
  66. package/src/plugins/tree-sitter/parser.ts +444 -0
  67. package/src/plugins/tree-sitter/simple-paths.ts +467 -0
  68. package/src/plugins/types.ts +11 -0
  69. package/src/plugins/url.ts +5 -3
  70. package/src/plugins/vim.ts +8 -5
  71. package/src/processors/CustomVariables.ts +19 -7
  72. package/src/processors/TokenCompressor.ts +13 -13
  73. package/src/processors/ToolResponseCache.ts +15 -6
  74. package/src/services/EmbeddingService.ts +18 -9
  75. package/src/services/EventService.ts +80 -0
  76. package/src/services/Mcp.ts +5 -0
  77. package/src/services/S3.ts +4 -3
  78. package/src/services/Tools.ts +125 -53
  79. package/src/services/index.ts +16 -11
  80. package/src/services/types.ts +3 -3
  81. package/src/types.ts +7 -2
  82. package/src/worker.ts +14 -1
  83. package/test-comprehensive.ts +31 -0
  84. package/tests/clients/AIClient.test.ts +490 -0
  85. package/tests/manual/agent-events/run-test.ts +203 -0
  86. package/tests/{integration → manual/file-edits}/figma.test.ts +1 -1
  87. package/tests/{integration → manual/file-edits}/fileblocks/readwrite.test.ts +7 -3
  88. package/tests/{integration → manual/file-edits}/patching.test.ts +11 -8
  89. package/tests/plugins/language/languagePlugin-content-triggers.test.ts +332 -0
  90. package/tests/plugins/language/languagePlugin-integration.test.ts +456 -0
  91. package/tests/plugins/language/languagePlugin.test.ts +363 -0
  92. package/tests/processors/Base64ImageDetector.test.ts +403 -0
  93. package/tests/processors/CustomVariables.test.ts +430 -0
  94. package/tests/processors/HarmonyToolProcessor.test.ts +490 -0
  95. package/tests/processors/TokenCompressor.test.ts +391 -0
  96. package/tests/processors/ToolResponseCache.test.ts +688 -0
  97. package/tests/services/Tools.test.ts +1339 -0
  98. package/tests/test.spec.ts +162 -117
  99. package/tests/tree-sitter/editor.test.ts +113 -0
  100. package/tests/tree-sitter/invalid.test.ts +299 -0
  101. package/tests/tree-sitter/paths/common-edits.test.ts +564 -0
  102. package/tests/tree-sitter/paths/debug-exact-position.test.ts +44 -0
  103. package/tests/tree-sitter/paths/debug-line-indexing.test.ts +49 -0
  104. package/tests/tree-sitter/paths/debug-paths.test.ts +90 -0
  105. package/tests/tree-sitter/paths/paths.test.ts +170 -0
  106. package/tests/tree-sitter/paths/simple-paths.test.ts +367 -0
  107. package/tests/tree-sitter/sample-after.ts +48 -0
  108. package/tests/tree-sitter/sample-before.ts +25 -0
  109. package/tests/tree-sitter/test-files/completely-broken.ts +7 -0
  110. package/tests/tree-sitter/test-files/duplicate-braces.ts +39 -0
  111. package/tests/tree-sitter/test-files/invalid-nesting.ts +39 -0
  112. package/tests/tree-sitter/test-files/malformed-signature.ts +39 -0
  113. package/tests/tree-sitter/test-files/mismatched-parens.ts +39 -0
  114. package/tests/tree-sitter/test-files/missing-semicolon.ts +39 -0
  115. package/tests/tree-sitter/test-files/partially-broken.ts +20 -0
  116. package/tests/tree-sitter/test-files/specific-errors.ts +14 -0
  117. package/tests/tree-sitter/test-files/unclosed-string.ts +39 -0
  118. package/tests/tree-sitter/tree-sitter.test.ts +251 -0
  119. package/ts_build/package.json +8 -3
  120. package/ts_build/src/agents/base/base.d.ts +2 -2
  121. package/ts_build/src/agents/base/base.js +24 -20
  122. package/ts_build/src/agents/base/base.js.map +1 -1
  123. package/ts_build/src/agents/patcher/patcher.js +26 -5
  124. package/ts_build/src/agents/patcher/patcher.js.map +1 -1
  125. package/ts_build/src/agents/tools/agentCall.js +2 -1
  126. package/ts_build/src/agents/tools/agentCall.js.map +1 -1
  127. package/ts_build/src/agents/tools/aiClient.d.ts +7 -8
  128. package/ts_build/src/agents/tools/aiClient.js.map +1 -1
  129. package/ts_build/src/agents/tools/ast/astAppendNode.d.ts +1 -0
  130. package/ts_build/src/agents/tools/ast/astAppendNode.js +96 -0
  131. package/ts_build/src/agents/tools/ast/astAppendNode.js.map +1 -0
  132. package/ts_build/src/agents/tools/ast/astDeleteNode.d.ts +1 -0
  133. package/ts_build/src/agents/tools/ast/astDeleteNode.js +94 -0
  134. package/ts_build/src/agents/tools/ast/astDeleteNode.js.map +1 -0
  135. package/ts_build/src/agents/tools/ast/astEditNode.d.ts +1 -0
  136. package/ts_build/src/agents/tools/ast/astEditNode.js +96 -0
  137. package/ts_build/src/agents/tools/ast/astEditNode.js.map +1 -0
  138. package/ts_build/src/agents/tools/ast/astGetPathForLine.d.ts +1 -0
  139. package/ts_build/src/agents/tools/ast/astGetPathForLine.js +78 -0
  140. package/ts_build/src/agents/tools/ast/astGetPathForLine.js.map +1 -0
  141. package/ts_build/src/agents/tools/ast/astListPaths.d.ts +1 -0
  142. package/ts_build/src/agents/tools/ast/astListPaths.js +78 -0
  143. package/ts_build/src/agents/tools/ast/astListPaths.js.map +1 -0
  144. package/ts_build/src/agents/tools/ast/index.d.ts +5 -0
  145. package/ts_build/src/agents/tools/ast/index.js +14 -0
  146. package/ts_build/src/agents/tools/ast/index.js.map +1 -0
  147. package/ts_build/src/agents/tools/astAppendNode.d.ts +1 -0
  148. package/ts_build/src/agents/tools/astAppendNode.js +98 -0
  149. package/ts_build/src/agents/tools/astAppendNode.js.map +1 -0
  150. package/ts_build/src/agents/tools/astDeleteNode.d.ts +1 -0
  151. package/ts_build/src/agents/tools/astDeleteNode.js +95 -0
  152. package/ts_build/src/agents/tools/astDeleteNode.js.map +1 -0
  153. package/ts_build/src/agents/tools/astEditNode.d.ts +1 -0
  154. package/ts_build/src/agents/tools/astEditNode.js +98 -0
  155. package/ts_build/src/agents/tools/astEditNode.js.map +1 -0
  156. package/ts_build/src/agents/tools/astGetPathForLine.d.ts +1 -0
  157. package/ts_build/src/agents/tools/astGetPathForLine.js +89 -0
  158. package/ts_build/src/agents/tools/astGetPathForLine.js.map +1 -0
  159. package/ts_build/src/agents/tools/astListPaths.d.ts +1 -0
  160. package/ts_build/src/agents/tools/astListPaths.js +82 -0
  161. package/ts_build/src/agents/tools/astListPaths.js.map +1 -0
  162. package/ts_build/src/agents/tools/callPlugin.js +4 -2
  163. package/ts_build/src/agents/tools/callPlugin.js.map +1 -1
  164. package/ts_build/src/agents/tools/embeddingSearch.js +3 -2
  165. package/ts_build/src/agents/tools/embeddingSearch.js.map +1 -1
  166. package/ts_build/src/agents/tools/execCommand.d.ts +2 -2
  167. package/ts_build/src/agents/tools/execCommand.js +201 -67
  168. package/ts_build/src/agents/tools/execCommand.js.map +1 -1
  169. package/ts_build/src/agents/tools/fileSearch.d.ts +1 -1
  170. package/ts_build/src/agents/tools/fileSearch.js +11 -15
  171. package/ts_build/src/agents/tools/fileSearch.js.map +1 -1
  172. package/ts_build/src/agents/tools/github/index.d.ts +1 -1
  173. package/ts_build/src/agents/tools/index.d.ts +1 -0
  174. package/ts_build/src/agents/tools/index.js +1 -0
  175. package/ts_build/src/agents/tools/index.js.map +1 -1
  176. package/ts_build/src/agents/tools/language/definitions.js +11 -2
  177. package/ts_build/src/agents/tools/language/definitions.js.map +1 -1
  178. package/ts_build/src/agents/tools/language/index.js +4 -3
  179. package/ts_build/src/agents/tools/language/index.js.map +1 -1
  180. package/ts_build/src/agents/tools/lintFile.js +4 -2
  181. package/ts_build/src/agents/tools/lintFile.js.map +1 -1
  182. package/ts_build/src/agents/tools/list.js +185 -49
  183. package/ts_build/src/agents/tools/list.js.map +1 -1
  184. package/ts_build/src/agents/tools/patch.js +33 -10
  185. package/ts_build/src/agents/tools/patch.js.map +1 -1
  186. package/ts_build/src/agents/tools/readBlocks.js +23 -0
  187. package/ts_build/src/agents/tools/readBlocks.js.map +1 -1
  188. package/ts_build/src/agents/tools/readFile.js +14 -0
  189. package/ts_build/src/agents/tools/readFile.js.map +1 -1
  190. package/ts_build/src/agents/tools/stringReplace.js +19 -2
  191. package/ts_build/src/agents/tools/stringReplace.js.map +1 -1
  192. package/ts_build/src/agents/tools/writeFile.js +40 -0
  193. package/ts_build/src/agents/tools/writeFile.js.map +1 -1
  194. package/ts_build/src/agents/tools/ycmd/server.js +5 -0
  195. package/ts_build/src/agents/tools/ycmd/server.js.map +1 -1
  196. package/ts_build/src/chat/CliChatService.d.ts +1 -0
  197. package/ts_build/src/chat/CliChatService.js +6 -2
  198. package/ts_build/src/chat/CliChatService.js.map +1 -1
  199. package/ts_build/src/chat/modules/AgentModule.d.ts +5 -1
  200. package/ts_build/src/chat/modules/AgentModule.js +53 -31
  201. package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
  202. package/ts_build/src/chat/modules/AskModule.js.map +1 -1
  203. package/ts_build/src/chat/modules/SetupModule.js +4 -3
  204. package/ts_build/src/chat/modules/SetupModule.js.map +1 -1
  205. package/ts_build/src/chat/modules/SystemModule.js +19 -4
  206. package/ts_build/src/chat/modules/SystemModule.js.map +1 -1
  207. package/ts_build/src/chat/modules/index.d.ts +5 -0
  208. package/ts_build/src/chat/modules/index.js +14 -0
  209. package/ts_build/src/chat/modules/index.js.map +1 -0
  210. package/ts_build/src/chat/types.d.ts +2 -0
  211. package/ts_build/src/chat-old.js +3 -3
  212. package/ts_build/src/chat-old.js.map +1 -1
  213. package/ts_build/src/clients/anthropic.d.ts +1 -0
  214. package/ts_build/src/clients/anthropic.js +22 -1
  215. package/ts_build/src/clients/anthropic.js.map +1 -1
  216. package/ts_build/src/clients/openai.js +1 -1
  217. package/ts_build/src/clients/openai.js.map +1 -1
  218. package/ts_build/src/clients/types.d.ts +1 -1
  219. package/ts_build/src/clients/xai.d.ts +7 -0
  220. package/ts_build/src/clients/xai.js +13 -4
  221. package/ts_build/src/clients/xai.js.map +1 -1
  222. package/ts_build/src/config.js +14 -3
  223. package/ts_build/src/config.js.map +1 -1
  224. package/ts_build/src/dataset/diffs/generate.js +2 -2
  225. package/ts_build/src/dataset/diffs/generate.js.map +1 -1
  226. package/ts_build/src/dataset/diffs/jsonl.js.map +1 -1
  227. package/ts_build/src/embeddings.js +7 -9
  228. package/ts_build/src/embeddings.js.map +1 -1
  229. package/ts_build/src/index.js +10 -10
  230. package/ts_build/src/index.js.map +1 -1
  231. package/ts_build/src/plugins/GitPlugin.d.ts +39 -0
  232. package/ts_build/src/plugins/GitPlugin.js +439 -0
  233. package/ts_build/src/plugins/GitPlugin.js.map +1 -0
  234. package/ts_build/src/plugins/LinterPlugin.d.ts +15 -0
  235. package/ts_build/src/plugins/LinterPlugin.js +65 -0
  236. package/ts_build/src/plugins/LinterPlugin.js.map +1 -0
  237. package/ts_build/src/plugins/PluginBase.d.ts +4 -3
  238. package/ts_build/src/plugins/PluginBase.js +3 -3
  239. package/ts_build/src/plugins/PluginBase.js.map +1 -1
  240. package/ts_build/src/plugins/asana.d.ts +3 -1
  241. package/ts_build/src/plugins/asana.js +3 -2
  242. package/ts_build/src/plugins/asana.js.map +1 -1
  243. package/ts_build/src/plugins/downloader/plugin.d.ts +3 -1
  244. package/ts_build/src/plugins/downloader/plugin.js +3 -2
  245. package/ts_build/src/plugins/downloader/plugin.js.map +1 -1
  246. package/ts_build/src/plugins/embedding.d.ts +5 -1
  247. package/ts_build/src/plugins/embedding.js +15 -3
  248. package/ts_build/src/plugins/embedding.js.map +1 -1
  249. package/ts_build/src/plugins/figma.d.ts +3 -1
  250. package/ts_build/src/plugins/figma.js +28 -4
  251. package/ts_build/src/plugins/figma.js.map +1 -1
  252. package/ts_build/src/plugins/github.d.ts +3 -1
  253. package/ts_build/src/plugins/github.js +3 -2
  254. package/ts_build/src/plugins/github.js.map +1 -1
  255. package/ts_build/src/plugins/jira.d.ts +3 -1
  256. package/ts_build/src/plugins/jira.js +3 -2
  257. package/ts_build/src/plugins/jira.js.map +1 -1
  258. package/ts_build/src/plugins/language.d.ts +7 -4
  259. package/ts_build/src/plugins/language.js +85 -20
  260. package/ts_build/src/plugins/language.js.map +1 -1
  261. package/ts_build/src/plugins/linear.d.ts +3 -1
  262. package/ts_build/src/plugins/linear.js +3 -2
  263. package/ts_build/src/plugins/linear.js.map +1 -1
  264. package/ts_build/src/plugins/notion.d.ts +3 -1
  265. package/ts_build/src/plugins/notion.js +3 -2
  266. package/ts_build/src/plugins/notion.js.map +1 -1
  267. package/ts_build/src/plugins/plugins.d.ts +4 -3
  268. package/ts_build/src/plugins/plugins.js +24 -14
  269. package/ts_build/src/plugins/plugins.js.map +1 -1
  270. package/ts_build/src/plugins/tree-sitter/editor.d.ts +34 -0
  271. package/ts_build/src/plugins/tree-sitter/editor.js +218 -0
  272. package/ts_build/src/plugins/tree-sitter/editor.js.map +1 -0
  273. package/ts_build/src/plugins/tree-sitter/human-readable-paths-new.d.ts +29 -0
  274. package/ts_build/src/plugins/tree-sitter/human-readable-paths-new.js +538 -0
  275. package/ts_build/src/plugins/tree-sitter/human-readable-paths-new.js.map +1 -0
  276. package/ts_build/src/plugins/tree-sitter/human-readable-paths.d.ts +22 -0
  277. package/ts_build/src/plugins/tree-sitter/human-readable-paths.js +332 -0
  278. package/ts_build/src/plugins/tree-sitter/human-readable-paths.js.map +1 -0
  279. package/ts_build/src/plugins/tree-sitter/lang-packs/index.d.ts +8 -0
  280. package/ts_build/src/plugins/tree-sitter/lang-packs/index.js +26 -0
  281. package/ts_build/src/plugins/tree-sitter/lang-packs/index.js.map +1 -0
  282. package/ts_build/src/plugins/tree-sitter/lang-packs/java.d.ts +2 -0
  283. package/ts_build/src/plugins/tree-sitter/lang-packs/java.js +61 -0
  284. package/ts_build/src/plugins/tree-sitter/lang-packs/java.js.map +1 -0
  285. package/ts_build/src/plugins/tree-sitter/lang-packs/javascript.d.ts +2 -0
  286. package/ts_build/src/plugins/tree-sitter/lang-packs/javascript.js +59 -0
  287. package/ts_build/src/plugins/tree-sitter/lang-packs/javascript.js.map +1 -0
  288. package/ts_build/src/plugins/tree-sitter/lang-packs/python.d.ts +2 -0
  289. package/ts_build/src/plugins/tree-sitter/lang-packs/python.js +47 -0
  290. package/ts_build/src/plugins/tree-sitter/lang-packs/python.js.map +1 -0
  291. package/ts_build/src/plugins/tree-sitter/lang-packs/types.d.ts +43 -0
  292. package/ts_build/src/plugins/tree-sitter/lang-packs/types.js +3 -0
  293. package/ts_build/src/plugins/tree-sitter/lang-packs/types.js.map +1 -0
  294. package/ts_build/src/plugins/tree-sitter/lang-packs/typescript.d.ts +2 -0
  295. package/ts_build/src/plugins/tree-sitter/lang-packs/typescript.js +50 -0
  296. package/ts_build/src/plugins/tree-sitter/lang-packs/typescript.js.map +1 -0
  297. package/ts_build/src/plugins/tree-sitter/parser.d.ts +75 -0
  298. package/ts_build/src/plugins/tree-sitter/parser.js +306 -0
  299. package/ts_build/src/plugins/tree-sitter/parser.js.map +1 -0
  300. package/ts_build/src/plugins/tree-sitter/simple-paths.d.ts +22 -0
  301. package/ts_build/src/plugins/tree-sitter/simple-paths.js +332 -0
  302. package/ts_build/src/plugins/tree-sitter/simple-paths.js.map +1 -0
  303. package/ts_build/src/plugins/types.d.ts +10 -0
  304. package/ts_build/src/plugins/url.d.ts +3 -2
  305. package/ts_build/src/plugins/url.js +3 -2
  306. package/ts_build/src/plugins/url.js.map +1 -1
  307. package/ts_build/src/plugins/vim.d.ts +4 -2
  308. package/ts_build/src/plugins/vim.js +6 -8
  309. package/ts_build/src/plugins/vim.js.map +1 -1
  310. package/ts_build/src/processors/CustomVariables.js +12 -3
  311. package/ts_build/src/processors/CustomVariables.js.map +1 -1
  312. package/ts_build/src/processors/TokenCompressor.js +8 -11
  313. package/ts_build/src/processors/TokenCompressor.js.map +1 -1
  314. package/ts_build/src/processors/ToolResponseCache.d.ts +2 -2
  315. package/ts_build/src/processors/ToolResponseCache.js +12 -2
  316. package/ts_build/src/processors/ToolResponseCache.js.map +1 -1
  317. package/ts_build/src/services/EmbeddingService.d.ts +10 -1
  318. package/ts_build/src/services/EmbeddingService.js +12 -12
  319. package/ts_build/src/services/EmbeddingService.js.map +1 -1
  320. package/ts_build/src/services/EventService.d.ts +7 -0
  321. package/ts_build/src/services/EventService.js +49 -0
  322. package/ts_build/src/services/EventService.js.map +1 -1
  323. package/ts_build/src/services/Mcp.js +8 -0
  324. package/ts_build/src/services/Mcp.js.map +1 -1
  325. package/ts_build/src/services/S3.js +4 -3
  326. package/ts_build/src/services/S3.js.map +1 -1
  327. package/ts_build/src/services/Tools.d.ts +1 -0
  328. package/ts_build/src/services/Tools.js +97 -35
  329. package/ts_build/src/services/Tools.js.map +1 -1
  330. package/ts_build/src/services/index.d.ts +4 -5
  331. package/ts_build/src/services/index.js +14 -9
  332. package/ts_build/src/services/index.js.map +1 -1
  333. package/ts_build/src/services/types.js +3 -3
  334. package/ts_build/src/services/types.js.map +1 -1
  335. package/ts_build/src/types.d.ts +7 -1
  336. package/ts_build/src/types.js +4 -0
  337. package/ts_build/src/types.js.map +1 -1
  338. package/ts_build/src/worker.js +12 -1
  339. package/ts_build/src/worker.js.map +1 -1
  340. package/ts_build/tests/clients/AIClient.test.d.ts +1 -0
  341. package/ts_build/tests/clients/AIClient.test.js +377 -0
  342. package/ts_build/tests/clients/AIClient.test.js.map +1 -0
  343. package/ts_build/tests/languagePlugin.test.js +217 -11
  344. package/ts_build/tests/languagePlugin.test.js.map +1 -1
  345. package/ts_build/tests/manual/agent-events/event-handler-reliability.test.d.ts +1 -0
  346. package/ts_build/tests/manual/agent-events/event-handler-reliability.test.js +315 -0
  347. package/ts_build/tests/manual/agent-events/event-handler-reliability.test.js.map +1 -0
  348. package/ts_build/tests/manual/agent-events/run-test.d.ts +2 -0
  349. package/ts_build/tests/manual/agent-events/run-test.js +148 -0
  350. package/ts_build/tests/manual/agent-events/run-test.js.map +1 -0
  351. package/ts_build/tests/manual/file-edits/figma.test.d.ts +1 -0
  352. package/ts_build/tests/manual/file-edits/figma.test.js +47 -0
  353. package/ts_build/tests/manual/file-edits/figma.test.js.map +1 -0
  354. package/ts_build/tests/manual/file-edits/fileblocks/readwrite.test.d.ts +1 -0
  355. package/ts_build/tests/manual/file-edits/fileblocks/readwrite.test.js +100 -0
  356. package/ts_build/tests/manual/file-edits/fileblocks/readwrite.test.js.map +1 -0
  357. package/ts_build/tests/manual/file-edits/patching.test.d.ts +1 -0
  358. package/ts_build/tests/manual/file-edits/patching.test.js +119 -0
  359. package/ts_build/tests/manual/file-edits/patching.test.js.map +1 -0
  360. package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.d.ts +1 -0
  361. package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js +277 -0
  362. package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js.map +1 -0
  363. package/ts_build/tests/plugins/language/languagePlugin-integration.test.d.ts +1 -0
  364. package/ts_build/tests/plugins/language/languagePlugin-integration.test.js +331 -0
  365. package/ts_build/tests/plugins/language/languagePlugin-integration.test.js.map +1 -0
  366. package/ts_build/tests/plugins/language/languagePlugin.test.d.ts +1 -0
  367. package/ts_build/tests/plugins/language/languagePlugin.test.js +286 -0
  368. package/ts_build/tests/plugins/language/languagePlugin.test.js.map +1 -0
  369. package/ts_build/tests/processors/Base64ImageDetector.test.d.ts +1 -0
  370. package/ts_build/tests/processors/Base64ImageDetector.test.js +351 -0
  371. package/ts_build/tests/processors/Base64ImageDetector.test.js.map +1 -0
  372. package/ts_build/tests/processors/CustomVariables.test.d.ts +1 -0
  373. package/ts_build/tests/processors/CustomVariables.test.js +351 -0
  374. package/ts_build/tests/processors/CustomVariables.test.js.map +1 -0
  375. package/ts_build/tests/processors/HarmonyToolProcessor.test.d.ts +1 -0
  376. package/ts_build/tests/processors/HarmonyToolProcessor.test.js +382 -0
  377. package/ts_build/tests/processors/HarmonyToolProcessor.test.js.map +1 -0
  378. package/ts_build/tests/processors/TokenCompressor.test.d.ts +1 -0
  379. package/ts_build/tests/processors/TokenCompressor.test.js +300 -0
  380. package/ts_build/tests/processors/TokenCompressor.test.js.map +1 -0
  381. package/ts_build/tests/processors/ToolResponseCache.test.d.ts +1 -0
  382. package/ts_build/tests/processors/ToolResponseCache.test.js +539 -0
  383. package/ts_build/tests/processors/ToolResponseCache.test.js.map +1 -0
  384. package/ts_build/tests/services/Plugins/plugin-event-integration.test.d.ts +1 -0
  385. package/ts_build/tests/services/Plugins/plugin-event-integration.test.js +232 -0
  386. package/ts_build/tests/services/Plugins/plugin-event-integration.test.js.map +1 -0
  387. package/ts_build/tests/services/Tools.test.d.ts +1 -0
  388. package/ts_build/tests/services/Tools.test.js +1059 -0
  389. package/ts_build/tests/services/Tools.test.js.map +1 -0
  390. package/ts_build/tests/test.spec.js +110 -68
  391. package/ts_build/tests/test.spec.js.map +1 -1
  392. package/ts_build/tests/tree-sitter/editor.test.d.ts +1 -0
  393. package/ts_build/tests/tree-sitter/editor.test.js +85 -0
  394. package/ts_build/tests/tree-sitter/editor.test.js.map +1 -0
  395. package/ts_build/tests/tree-sitter/invalid.test.d.ts +1 -0
  396. package/ts_build/tests/tree-sitter/invalid.test.js +198 -0
  397. package/ts_build/tests/tree-sitter/invalid.test.js.map +1 -0
  398. package/ts_build/tests/tree-sitter/paths/common-edits.test.d.ts +1 -0
  399. package/ts_build/tests/tree-sitter/paths/common-edits.test.js +347 -0
  400. package/ts_build/tests/tree-sitter/paths/common-edits.test.js.map +1 -0
  401. package/ts_build/tests/tree-sitter/paths/debug-exact-position.test.d.ts +1 -0
  402. package/ts_build/tests/tree-sitter/paths/debug-exact-position.test.js +35 -0
  403. package/ts_build/tests/tree-sitter/paths/debug-exact-position.test.js.map +1 -0
  404. package/ts_build/tests/tree-sitter/paths/debug-line-indexing.test.d.ts +1 -0
  405. package/ts_build/tests/tree-sitter/paths/debug-line-indexing.test.js +38 -0
  406. package/ts_build/tests/tree-sitter/paths/debug-line-indexing.test.js.map +1 -0
  407. package/ts_build/tests/tree-sitter/paths/debug-paths.test.d.ts +1 -0
  408. package/ts_build/tests/tree-sitter/paths/debug-paths.test.js +74 -0
  409. package/ts_build/tests/tree-sitter/paths/debug-paths.test.js.map +1 -0
  410. package/ts_build/tests/tree-sitter/paths/human-readable-paths.test.d.ts +1 -0
  411. package/ts_build/tests/tree-sitter/paths/human-readable-paths.test.js +302 -0
  412. package/ts_build/tests/tree-sitter/paths/human-readable-paths.test.js.map +1 -0
  413. package/ts_build/tests/tree-sitter/paths/paths.test.d.ts +1 -0
  414. package/ts_build/tests/tree-sitter/paths/paths.test.js +116 -0
  415. package/ts_build/tests/tree-sitter/paths/paths.test.js.map +1 -0
  416. package/ts_build/tests/tree-sitter/paths/simple-paths.test.d.ts +1 -0
  417. package/ts_build/tests/tree-sitter/paths/simple-paths.test.js +302 -0
  418. package/ts_build/tests/tree-sitter/paths/simple-paths.test.js.map +1 -0
  419. package/ts_build/tests/tree-sitter/sample-after.d.ts +11 -0
  420. package/ts_build/tests/tree-sitter/sample-after.js +44 -0
  421. package/ts_build/tests/tree-sitter/sample-after.js.map +1 -0
  422. package/ts_build/tests/tree-sitter/sample-before.d.ts +9 -0
  423. package/ts_build/tests/tree-sitter/sample-before.js +28 -0
  424. package/ts_build/tests/tree-sitter/sample-before.js.map +1 -0
  425. package/ts_build/tests/tree-sitter/test-files/completely-broken.d.ts +2 -0
  426. package/ts_build/tests/tree-sitter/test-files/completely-broken.js +17 -0
  427. package/ts_build/tests/tree-sitter/test-files/completely-broken.js.map +1 -0
  428. package/ts_build/tests/tree-sitter/test-files/duplicate-braces.d.ts +8 -0
  429. package/ts_build/tests/tree-sitter/test-files/duplicate-braces.js +38 -0
  430. package/ts_build/tests/tree-sitter/test-files/duplicate-braces.js.map +1 -0
  431. package/ts_build/tests/tree-sitter/test-files/invalid-nesting.d.ts +8 -0
  432. package/ts_build/tests/tree-sitter/test-files/invalid-nesting.js +38 -0
  433. package/ts_build/tests/tree-sitter/test-files/invalid-nesting.js.map +1 -0
  434. package/ts_build/tests/tree-sitter/test-files/malformed-signature.d.ts +8 -0
  435. package/ts_build/tests/tree-sitter/test-files/malformed-signature.js +38 -0
  436. package/ts_build/tests/tree-sitter/test-files/malformed-signature.js.map +1 -0
  437. package/ts_build/tests/tree-sitter/test-files/mismatched-parens.d.ts +10 -0
  438. package/ts_build/tests/tree-sitter/test-files/mismatched-parens.js +38 -0
  439. package/ts_build/tests/tree-sitter/test-files/mismatched-parens.js.map +1 -0
  440. package/ts_build/tests/tree-sitter/test-files/missing-semicolon.d.ts +8 -0
  441. package/ts_build/tests/tree-sitter/test-files/missing-semicolon.js +38 -0
  442. package/ts_build/tests/tree-sitter/test-files/missing-semicolon.js.map +1 -0
  443. package/ts_build/tests/tree-sitter/test-files/partially-broken.d.ts +6 -0
  444. package/ts_build/tests/tree-sitter/test-files/partially-broken.js +20 -0
  445. package/ts_build/tests/tree-sitter/test-files/partially-broken.js.map +1 -0
  446. package/ts_build/tests/tree-sitter/test-files/specific-errors.d.ts +7 -0
  447. package/ts_build/tests/tree-sitter/test-files/specific-errors.js +14 -0
  448. package/ts_build/tests/tree-sitter/test-files/specific-errors.js.map +1 -0
  449. package/ts_build/tests/tree-sitter/test-files/unclosed-string.d.ts +8 -0
  450. package/ts_build/tests/tree-sitter/test-files/unclosed-string.js +38 -0
  451. package/ts_build/tests/tree-sitter/test-files/unclosed-string.js.map +1 -0
  452. package/ts_build/tests/tree-sitter/tree-sitter.test.d.ts +1 -0
  453. package/ts_build/tests/tree-sitter/tree-sitter.test.js +185 -0
  454. package/ts_build/tests/tree-sitter/tree-sitter.test.js.map +1 -0
  455. package/tsconfig.json +2 -1
  456. package/tests/languagePlugin.test.ts +0 -74
  457. /package/src/chat/modules/{index.js → index.ts} +0 -0
  458. /package/tests/{integration → manual/file-edits}/patching/input.txt +0 -0
  459. /package/tests/{integration → manual/file-edits}/patching/output.txt +0 -0
  460. /package/tests/{integration → manual/file-edits}/patching/patch.txt +0 -0
  461. /package/tests/{integration → manual/file-edits}/patching/unseen.txt +0 -0
@@ -0,0 +1,564 @@
1
+ import { LanguageAgnosticParser } from "../../../src/plugins/tree-sitter/parser";
2
+ import { TreeEditor } from "../../../src/plugins/tree-sitter/editor";
3
+
4
+ describe("Common Code Editing Operations with Tree Editor", () => {
5
+ let parser: LanguageAgnosticParser;
6
+ let editor: TreeEditor;
7
+
8
+ // Initial code with a simple class structure
9
+ const initialCode = `export class Calculator {
10
+ private history: number[] = [];
11
+ private operationCount: number = 0;
12
+
13
+ constructor(private precision: number = 2) {}
14
+
15
+ add(a: number, b: number): number {
16
+ const result = a + b;
17
+ this.history.push(result);
18
+ this.operationCount++;
19
+ return result;
20
+ }
21
+
22
+ multiply(a: number, b: number): number {
23
+ const result = a * b;
24
+ this.history.push(result);
25
+ this.operationCount++;
26
+ return result;
27
+ }
28
+
29
+ getHistory(): number[] {
30
+ return [...this.history];
31
+ }
32
+
33
+ getOperationCount(): number {
34
+ return this.operationCount;
35
+ }
36
+ }`;
37
+
38
+ beforeEach(() => {
39
+ parser = LanguageAgnosticParser.createTypeScriptParser();
40
+ editor = new TreeEditor(parser, initialCode);
41
+ });
42
+
43
+ describe("Class Method Operations", () => {
44
+ test("should create new method on a class using addMethodToClass", () => {
45
+ console.log("=== Creating new method on Calculator class ===");
46
+
47
+ const newMethodContent = ` subtract(a: number, b: number): number {
48
+ const result = a - b;
49
+ this.history.push(result);
50
+ this.operationCount++;
51
+ return result;
52
+ }`;
53
+
54
+ // Use the new simplified method instead of manual line counting
55
+ const modifiedEditor = editor.addMethodToClass(
56
+ "Calculator",
57
+ newMethodContent
58
+ );
59
+ const modifiedText = modifiedEditor.getCurrentText();
60
+
61
+ expect(modifiedText).toContain("subtract(a: number, b: number): number");
62
+ expect(modifiedText).toContain("const result = a - b;");
63
+
64
+ console.log("✓ Successfully added subtract method to Calculator class");
65
+ console.log("New method content:", newMethodContent.trim());
66
+ });
67
+
68
+ test("should automatically match 4-space indentation when adding methods", () => {
69
+ console.log("=== Testing 4-space indentation matching ===" );
70
+
71
+ // Create a class with 4-space indented methods
72
+ const fourSpaceIndentedCode = `export class FourSpaceCalculator {
73
+ private history: number[] = [];
74
+ private operationCount: number = 0;
75
+
76
+ constructor(private precision: number = 2) {}
77
+
78
+ add(a: number, b: number): number {
79
+ const result = a + b;
80
+ this.history.push(result);
81
+ this.operationCount++;
82
+ return result;
83
+ }
84
+
85
+ multiply(a: number, b: number): number {
86
+ const result = a * b;
87
+ this.history.push(result);
88
+ this.operationCount++;
89
+ return result;
90
+ }
91
+ }`;
92
+
93
+ // Create a new editor with the 4-space indented code
94
+ const fourSpaceEditor = new TreeEditor(parser, fourSpaceIndentedCode);
95
+
96
+ // Add a new method with 4-space indentation to match existing methods
97
+ const newMethodContent = ` subtract(a: number, b: number): number {
98
+ const result = a - b;
99
+ this.history.push(result);
100
+ this.operationCount++;
101
+ return result;
102
+ }`;
103
+
104
+ const modifiedEditor = fourSpaceEditor.addMethodToClass(
105
+ "FourSpaceCalculator",
106
+ newMethodContent
107
+ );
108
+ const modifiedText = modifiedEditor.getCurrentText();
109
+
110
+ // Verify the method was added
111
+ expect(modifiedText).toContain("subtract(a: number, b: number): number");
112
+ expect(modifiedText).toContain("const result = a - b;");
113
+
114
+ // Check that the indentation is preserved correctly (4 spaces for method, 8 spaces for body)
115
+ const lines = modifiedText.split('\n');
116
+ const subtractMethodLine = lines.find(line => line.includes('subtract(a: number, b: number)'));
117
+ const resultLine = lines.find(line => line.includes('const result = a - b;'));
118
+
119
+ expect(subtractMethodLine).toMatch(/^ subtract/); // 4 spaces before method name
120
+ expect(resultLine).toMatch(/^ const result = a - b;/); // 8 spaces before method body
121
+
122
+ console.log("✓ Successfully preserved 4-space indentation when adding method");
123
+ console.log("Method line indentation:", subtractMethodLine?.match(/^ */)?.[0].length, "spaces");
124
+ console.log("Body line indentation:", resultLine?.match(/^ */)?.[0].length, "spaces");
125
+ });
126
+
127
+ test("should rename a method on a class", () => {
128
+ console.log("=== Renaming multiply method to times ===");
129
+
130
+ // Find the multiply method using human-readable path
131
+ const matches = editor.findNodesBySimplePath("Calculator.multiply");
132
+ expect(matches.length).toBe(1);
133
+
134
+ const methodNode = matches[0].node;
135
+ console.log(`Found multiply method at path: ${matches[0].path}`);
136
+
137
+ // Get the method name node specifically
138
+ const methodNameNode = methodNode.children.find(
139
+ (child) =>
140
+ child.type === "property_identifier" && child.text === "multiply"
141
+ );
142
+ expect(methodNameNode).toBeDefined();
143
+
144
+ // Replace just the method name
145
+ const methodNamePath = parser.getNodePath(
146
+ editor.getTree().rootNode,
147
+ methodNameNode!
148
+ );
149
+ const modifiedEditor = editor.updateNodeByPath(methodNamePath, "times");
150
+ const modifiedText = modifiedEditor.getCurrentText();
151
+
152
+ expect(modifiedText).not.toContain("multiply(a: number, b: number)");
153
+ expect(modifiedText).toContain("times(a: number, b: number)");
154
+ expect(modifiedText).toContain("const result = a * b;"); // Body should remain the same
155
+
156
+ console.log("✓ Successfully renamed multiply method to times");
157
+ });
158
+
159
+ test("should move a method from one class to another using appendChild", () => {
160
+ console.log("=== Moving getHistory method to a new MathUtils class ===");
161
+
162
+ // First, define a new MathUtils class using appendChild
163
+ const newClassDefinition = `export class MathUtils {
164
+ static formatNumber(num: number, precision: number = 2): string {
165
+ return num.toFixed(precision);
166
+ }
167
+ }`;
168
+
169
+ // Add the new class at the end using appendChild
170
+ const editorWithNewClass = editor.appendChild("", newClassDefinition);
171
+
172
+ // Find the getHistory method to move
173
+ const historyMatches = editorWithNewClass.findNodesBySimplePath(
174
+ "Calculator.getHistory"
175
+ );
176
+ expect(historyMatches.length).toBe(1);
177
+
178
+ const historyMethodNode = historyMatches[0].node;
179
+ const historyMethodText = historyMethodNode.text;
180
+
181
+ console.log(`Found getHistory method: ${historyMethodText}`);
182
+
183
+ // Remove the method from Calculator class
184
+ const historyMethodPath = historyMatches[0].path;
185
+ const editorWithoutHistory = editorWithNewClass.updateNodeByPath(
186
+ historyMethodPath,
187
+ ""
188
+ );
189
+
190
+ // Now add the method to MathUtils class using appendChild
191
+ const modifiedHistoryMethod = ` static getHistoryForArray(history: number[]): number[] {
192
+ return [...history];
193
+ }`;
194
+
195
+ const finalEditor = editorWithoutHistory.appendChild(
196
+ "MathUtils",
197
+ modifiedHistoryMethod
198
+ );
199
+ const finalModifiedText = finalEditor.getCurrentText();
200
+
201
+ // Verify the method was moved
202
+ expect(finalModifiedText).toContain("export class MathUtils");
203
+ expect(finalModifiedText).toContain(
204
+ "getHistoryForArray(history: number[])"
205
+ );
206
+ expect(finalModifiedText).not.toContain("getHistory(): number[]"); // Original should be gone
207
+
208
+ console.log("✓ Successfully moved method from Calculator to MathUtils");
209
+ });
210
+ });
211
+
212
+ describe("Class Creation", () => {
213
+ test("should define a new class using appendChild", () => {
214
+ console.log("=== Defining a new Statistics class ===");
215
+
216
+ const newClassDefinition = `export class Statistics {
217
+ private data: number[] = [];
218
+
219
+ constructor(initialData: number[] = []) {
220
+ this.data = [...initialData];
221
+ }
222
+
223
+ addValue(value: number): void {
224
+ this.data.push(value);
225
+ }
226
+
227
+ getMean(): number {
228
+ if (this.data.length === 0) return 0;
229
+ return this.data.reduce((sum, val) => sum + val, 0) / this.data.length;
230
+ }
231
+
232
+ getMedian(): number {
233
+ if (this.data.length === 0) return 0;
234
+ const sorted = [...this.data].sort((a, b) => a - b);
235
+ const mid = Math.floor(sorted.length / 2);
236
+ return sorted.length % 2 === 0
237
+ ? (sorted[mid - 1] + sorted[mid]) / 2
238
+ : sorted[mid];
239
+ }
240
+ }`;
241
+
242
+ // Use appendChild to add the new class - much simpler than manual line counting!
243
+ const modifiedEditor = editor.appendChild("", newClassDefinition);
244
+ const modifiedText = modifiedEditor.getCurrentText();
245
+
246
+ // Verify the new class was added
247
+ expect(modifiedText).toContain("export class Statistics");
248
+ expect(modifiedText).toContain("getMean(): number");
249
+ expect(modifiedText).toContain("getMedian(): number");
250
+
251
+ // Verify we can find the new class using human-readable paths
252
+ const statsMatches = modifiedEditor.findNodesBySimplePath("Statistics");
253
+ expect(statsMatches.length).toBe(1);
254
+ expect(statsMatches[0].description).toContain(
255
+ "Class declaration: Statistics"
256
+ );
257
+
258
+ // Verify we can find methods in the new class
259
+ const meanMatches =
260
+ modifiedEditor.findNodesBySimplePath("Statistics.getMean");
261
+ expect(meanMatches.length).toBe(1);
262
+ expect(meanMatches[0].description).toContain(
263
+ "getMean method in class Statistics"
264
+ );
265
+
266
+ console.log("✓ Successfully defined Statistics class with methods");
267
+ console.log(
268
+ "Available human paths:",
269
+ modifiedEditor
270
+ .getAllSimplePaths()
271
+ .filter((p) => p.includes("Statistics"))
272
+ );
273
+ });
274
+ });
275
+
276
+ describe("Test Structure Operations", () => {
277
+ test("should define a describe block with a test using appendChild", () => {
278
+ console.log("=== Creating test structure with describe blocks ===");
279
+
280
+ const testCode = `describe("Calculator Basic Operations", () => {
281
+ test("should add two numbers correctly", () => {
282
+ const calc = new Calculator();
283
+ const result = calc.add(2, 3);
284
+ expect(result).toBe(5);
285
+ });
286
+ });`;
287
+
288
+ // Use appendChild instead of manual line counting
289
+ const modifiedEditor = editor.appendChild("", testCode);
290
+ const modifiedText = modifiedEditor.getCurrentText();
291
+
292
+ expect(modifiedText).toContain('describe("Calculator Basic Operations"');
293
+ expect(modifiedText).toContain('test("should add two numbers correctly"');
294
+ expect(modifiedText).toContain("expect(result).toBe(5)");
295
+
296
+ console.log("✓ Successfully created describe block with test");
297
+ });
298
+
299
+ test("should update logic of a specific test", () => {
300
+ console.log("=== Updating test assertion logic ===");
301
+
302
+ // First create a test structure using appendChild
303
+ const testCode = `describe("Calculator Operations", () => {
304
+ test("multiplication test", () => {
305
+ const calc = new Calculator();
306
+ const result = calc.multiply(3, 4);
307
+ expect(result).toBe(11); // This is wrong, should be 12
308
+ });
309
+ });`;
310
+
311
+ const modifiedEditor = editor.appendChild("", testCode);
312
+
313
+ // Now find and update the wrong assertion
314
+ const currentText = modifiedEditor.getCurrentText();
315
+ const wrongAssertion = "expect(result).toBe(11);";
316
+ const correctAssertion = "expect(result).toBe(12);";
317
+
318
+ // Update the assertion using string replacement approach
319
+ const updatedText = currentText.replace(wrongAssertion, correctAssertion);
320
+
321
+ // Create new editor with corrected text
322
+ const finalEditor = new TreeEditor(parser, updatedText);
323
+ const finalText = finalEditor.getCurrentText();
324
+
325
+ expect(finalText).toContain("expect(result).toBe(12);");
326
+ expect(finalText).not.toContain("expect(result).toBe(11);");
327
+
328
+ console.log("✓ Successfully updated test assertion from 11 to 12");
329
+ });
330
+
331
+ test("should add new test to existing describe block using appendToBlock", () => {
332
+ console.log("=== Adding new test to existing describe block ===");
333
+
334
+ // First create a describe block with one test using appendChild
335
+ const initialTestCode = `describe("Calculator Advanced Operations", () => {
336
+ test("should add numbers", () => {
337
+ const calc = new Calculator();
338
+ expect(calc.add(1, 2)).toBe(3);
339
+ });
340
+ });`;
341
+
342
+ const modifiedEditor = editor.appendChild("", initialTestCode);
343
+
344
+ // Use the new simplified method to add a test to the describe block
345
+ const newTest = ` test("should multiply numbers", () => {
346
+ const calc = new Calculator();
347
+ expect(calc.multiply(2, 3)).toBe(6);
348
+ });`;
349
+
350
+ const finalEditor = modifiedEditor.appendToBlock(
351
+ "describe(\"Calculator Advanced Operations\")",
352
+ newTest
353
+ );
354
+ const finalText = finalEditor.getCurrentText();
355
+
356
+ expect(finalText).toContain('test("should add numbers"');
357
+ expect(finalText).toContain('test("should multiply numbers"');
358
+ expect(finalText).toContain("expect(calc.multiply(2, 3)).toBe(6)");
359
+
360
+ console.log("✓ Successfully added new test to existing describe block");
361
+ });
362
+ });
363
+
364
+ describe("Path Resolution and Validation", () => {
365
+ test("should validate human-readable paths work correctly", () => {
366
+ console.log("=== Validating path resolution functionality ===");
367
+
368
+ // Test finding class
369
+ const classMatches = editor.findNodesBySimplePath("Calculator");
370
+ expect(classMatches.length).toBe(1);
371
+ expect(classMatches[0].description).toContain(
372
+ "Class declaration: Calculator"
373
+ );
374
+
375
+ // Test finding methods
376
+ const addMatches = editor.findNodesBySimplePath("Calculator.add");
377
+ expect(addMatches.length).toBe(1);
378
+ expect(addMatches[0].description).toContain(
379
+ "add method in class Calculator"
380
+ );
381
+
382
+ const multiplyMatches = editor.findNodesBySimplePath(
383
+ "Calculator.multiply"
384
+ );
385
+ expect(multiplyMatches.length).toBe(1);
386
+
387
+ // Test path-to-node and node-to-path round-trip
388
+ const node = addMatches[0].node;
389
+ const path = addMatches[0].path;
390
+
391
+ // Get node by path
392
+ const retrievedNode = (editor as any).findNodeByPath(path);
393
+ expect(retrievedNode).not.toBeNull();
394
+ expect(retrievedNode!.text).toBe(node.text);
395
+
396
+ console.log("✓ Path resolution validation successful");
397
+ console.log(
398
+ "Available human paths:",
399
+ editor.getAllSimplePaths().slice(0, 5)
400
+ );
401
+ });
402
+
403
+ test("should maintain syntax validation after edits", () => {
404
+ console.log("=== Validating syntax after modifications ===");
405
+
406
+ // Perform several edits using our new utility methods
407
+ const newMethod = ` divide(a: number, b: number): number {
408
+ if (b === 0) throw new Error('Division by zero');
409
+ const result = a / b;
410
+ this.history.push(result);
411
+ this.operationCount++;
412
+ return result;
413
+ }`;
414
+
415
+ // Use addMethodToClass instead of manual insertion logic
416
+ const currentEditor = editor.addMethodToClass("Calculator", newMethod);
417
+
418
+ // Verify the tree can still be parsed
419
+ const generatedCode = currentEditor.getCurrentText();
420
+ console.log("Generated code after adding divide method:");
421
+ console.log(generatedCode);
422
+ const tree = currentEditor.getTree();
423
+ expect(tree.rootNode.hasError).toBe(false);
424
+
425
+ // Verify we can still find elements
426
+ const divideMatches =
427
+ currentEditor.findNodesBySimplePath("Calculator.divide");
428
+ expect(divideMatches.length).toBe(1);
429
+
430
+ console.log("✓ Syntax remains valid after edits");
431
+ });
432
+
433
+ test("should demonstrate complex workflow with simplified utility methods", () => {
434
+ console.log("=== Complex workflow demonstration ===");
435
+
436
+ // Step 1: Add a new property using addPropertyToClass
437
+ const newProperty = ` private lastOperation: string = '';`;
438
+
439
+ let currentEditor = editor.addPropertyToClass("Calculator", newProperty);
440
+
441
+ // Step 2: Add a getter method using addMethodToClass
442
+ const getterMethod = ` getLastOperation(): string {
443
+ return this.lastOperation;
444
+ }`;
445
+
446
+ currentEditor = currentEditor.addMethodToClass(
447
+ "Calculator",
448
+ getterMethod
449
+ );
450
+
451
+ // Step 3: Add a new class using appendChild
452
+ const newClass = `export class OperationLogger {
453
+ private logs: string[] = [];
454
+
455
+ log(operation: string): void {
456
+ this.logs.push(\`\${new Date().toISOString()}: \${operation}\`);
457
+ }
458
+
459
+ getLogs(): string[] {
460
+ return [...this.logs];
461
+ }
462
+ }`;
463
+
464
+ currentEditor = currentEditor.appendChild("", newClass);
465
+
466
+ const finalText = currentEditor.getCurrentText();
467
+ console.log("Generated code in complex workflow:");
468
+ console.log(finalText);
469
+
470
+ expect(finalText).toContain("lastOperation: string");
471
+ expect(finalText).toContain("getLastOperation(): string");
472
+ expect(finalText).toContain("export class OperationLogger");
473
+
474
+ // Verify tree structure is still valid
475
+ expect(currentEditor.getTree().rootNode.hasError).toBe(false);
476
+
477
+ // Verify we can still navigate with paths
478
+ const allPaths = currentEditor.getAllSimplePaths();
479
+ expect(allPaths.some((path) => path.includes("getLastOperation"))).toBe(
480
+ true
481
+ );
482
+ expect(allPaths.some((path) => path.includes("OperationLogger"))).toBe(
483
+ true
484
+ );
485
+
486
+ console.log(
487
+ "✓ Complex workflow completed successfully with utility methods"
488
+ );
489
+ console.log(`Final code has ${finalText.split("\n").length} lines`);
490
+ });
491
+
492
+ test("should demonstrate the power of utility methods vs manual approach", () => {
493
+ console.log("=== Comparing utility methods vs manual approach ===");
494
+
495
+ // OLD WAY (commented out to show the complexity we've eliminated):
496
+ /*
497
+ // Manual approach would require:
498
+ // 1. Find the Calculator class manually
499
+ // 2. Find the class body node
500
+ // 3. Split text into lines
501
+ // 4. Loop through lines to find closing brace
502
+ // 5. Handle brace counting for nested structures
503
+ // 6. Calculate insertion point
504
+ // 7. Manually reconstruct the text
505
+ // This could be 20-30 lines of complex logic
506
+ */
507
+
508
+ // NEW WAY - Simple and clean:
509
+ const newMethod = ` modulo(a: number, b: number): number {
510
+ const result = a % b;
511
+ this.history.push(result);
512
+ this.operationCount++;
513
+ return result;
514
+ }`;
515
+
516
+ // Just one line!
517
+ const modifiedEditor = editor.addMethodToClass("Calculator", newMethod);
518
+
519
+ expect(modifiedEditor.getCurrentText()).toContain(
520
+ "modulo(a: number, b: number)"
521
+ );
522
+
523
+ // Add a property - also just one line!
524
+ const newProperty = ` private operationTimestamps: Date[] = [];`;
525
+ const editorWithProperty = modifiedEditor.addPropertyToClass(
526
+ "Calculator",
527
+ newProperty
528
+ );
529
+
530
+ expect(editorWithProperty.getCurrentText()).toContain(
531
+ "operationTimestamps: Date[]"
532
+ );
533
+
534
+ // Add a test to a describe block - one line!
535
+ const testBlock = `describe("Calculator Modulo Tests", () => {
536
+ test("should handle basic modulo", () => {
537
+ const calc = new Calculator();
538
+ expect(calc.modulo(10, 3)).toBe(1);
539
+ });
540
+ });`;
541
+
542
+ const editorWithTest = editorWithProperty.appendChild("", testBlock);
543
+
544
+ const newTest = ` test("should handle zero modulo", () => {
545
+ const calc = new Calculator();
546
+ expect(calc.modulo(0, 5)).toBe(0);
547
+ });`;
548
+
549
+ const finalEditor = editorWithTest.appendToBlock(
550
+ `describe("Calculator Modulo Tests")`,
551
+ newTest
552
+ );
553
+
554
+ const finalText = finalEditor.getCurrentText();
555
+ expect(finalText).toContain('test("should handle basic modulo"');
556
+ expect(finalText).toContain('test("should handle zero modulo"');
557
+
558
+ console.log("✓ Utility methods demonstrate massive code simplification");
559
+ console.log(
560
+ "Complex manual insertion logic replaced with simple method calls!"
561
+ );
562
+ });
563
+ });
564
+ });
@@ -0,0 +1,44 @@
1
+ import { LanguageAgnosticParser } from "../../../src/plugins/tree-sitter/parser";
2
+ import { TreeEditor } from "../../../src/plugins/tree-sitter/editor";
3
+
4
+ describe("Debug Exact Position Finding", () => {
5
+ test("should debug findPathsForLine position calculation", () => {
6
+ const parser = LanguageAgnosticParser.createTypeScriptParser();
7
+
8
+ const sampleCode = `
9
+ export class Calculator {
10
+ add(a: number, b: number): number {
11
+ const result = a + b;
12
+ return result;
13
+ }
14
+ }`;
15
+
16
+ const tree = parser.parseString(sampleCode);
17
+ console.log("=== Full source code ===");
18
+ console.log(tree.rootNode.text);
19
+ console.log("=== Lines breakdown ===");
20
+
21
+ const lines = tree.rootNode.text.split("\n");
22
+ lines.forEach((line, index) => {
23
+ console.log(`Line ${index}: "${line}"`);
24
+ const resultIndex = line.indexOf("result");
25
+ if (resultIndex !== -1) {
26
+ console.log(` Found "result" at column ${resultIndex}`);
27
+
28
+ // Find the node at this exact position
29
+ const node = tree.rootNode.descendantForPosition(
30
+ { row: index, column: resultIndex },
31
+ { row: index, column: resultIndex + "result".length }
32
+ );
33
+
34
+ console.log(` Node at position: type="${node?.type}", text="${node?.text}"`);
35
+ console.log(` Node position: start=${JSON.stringify(node?.startPosition)}, end=${JSON.stringify(node?.endPosition)}`);
36
+
37
+ if (node) {
38
+ const path = parser.getNodePath(tree.rootNode, node);
39
+ console.log(` Generated path: ${path}`);
40
+ }
41
+ }
42
+ });
43
+ });
44
+ });
@@ -0,0 +1,49 @@
1
+ import { LanguageAgnosticParser } from "../../../src/plugins/tree-sitter/parser";
2
+
3
+ describe("Debug Line Indexing", () => {
4
+ test("should debug line indexing in tree-sitter", () => {
5
+ const parser = LanguageAgnosticParser.createTypeScriptParser();
6
+
7
+ const sampleCode = `export class Calculator {
8
+ add(a: number, b: number): number {
9
+ const result = a + b;
10
+ return result;
11
+ }
12
+ }`;
13
+
14
+ console.log("=== Source without leading newline ===");
15
+ console.log(`"${sampleCode}"`);
16
+
17
+ const tree = parser.parseString(sampleCode);
18
+
19
+ const lines = sampleCode.split("\n");
20
+ lines.forEach((line, index) => {
21
+ console.log(`Line ${index}: "${line}"`);
22
+ });
23
+
24
+ console.log("\n=== Finding formal_parameters node manually ===");
25
+
26
+ function traverseNode(node: any, depth = 0) {
27
+ const indent = " ".repeat(depth);
28
+ console.log(`${indent}${node.type} [${node.startPosition.row}:${node.startPosition.column}-${node.endPosition.row}:${node.endPosition.column}] "${node.text.substring(0, 50)}${node.text.length > 50 ? '...' : ''}"`);
29
+
30
+ if (node.type === 'formal_parameters') {
31
+ console.log(`${indent}*** FOUND formal_parameters at row ${node.startPosition.row} ***`);
32
+ }
33
+
34
+ for (let i = 0; i < node.childCount; i++) {
35
+ traverseNode(node.child(i), depth + 1);
36
+ }
37
+ }
38
+
39
+ traverseNode(tree.rootNode);
40
+
41
+ console.log("\n=== Testing descendantForPosition for line 2, col 10 ===");
42
+ const testNode = tree.rootNode.descendantForPosition(
43
+ { row: 2, column: 10 },
44
+ { row: 2, column: 16 }
45
+ );
46
+ console.log(`Found node: type="${testNode?.type}", text="${testNode?.text}"`);
47
+ console.log(`Node position: ${JSON.stringify(testNode?.startPosition)} to ${JSON.stringify(testNode?.endPosition)}`);
48
+ });
49
+ });