@tyvm/knowhow 0.0.47 → 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 (459) 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/xai.ts +15 -5
  40. package/src/config.ts +17 -5
  41. package/src/dataset/diffs/generate.ts +2 -2
  42. package/src/dataset/diffs/jsonl.ts +0 -1
  43. package/src/embeddings.ts +6 -4
  44. package/src/index.ts +11 -5
  45. package/src/plugins/GitPlugin.ts +530 -0
  46. package/src/plugins/LinterPlugin.ts +89 -0
  47. package/src/plugins/PluginBase.ts +4 -2
  48. package/src/plugins/asana.ts +4 -2
  49. package/src/plugins/downloader/plugin.ts +5 -2
  50. package/src/plugins/embedding.ts +24 -4
  51. package/src/plugins/figma.ts +7 -3
  52. package/src/plugins/github.ts +4 -2
  53. package/src/plugins/jira.ts +4 -2
  54. package/src/plugins/language.ts +134 -27
  55. package/src/plugins/linear.ts +4 -2
  56. package/src/plugins/notion.ts +4 -2
  57. package/src/plugins/plugins.ts +27 -16
  58. package/src/plugins/tree-sitter/editor.ts +369 -0
  59. package/src/plugins/tree-sitter/lang-packs/index.ts +23 -0
  60. package/src/plugins/tree-sitter/lang-packs/java.ts +59 -0
  61. package/src/plugins/tree-sitter/lang-packs/javascript.ts +57 -0
  62. package/src/plugins/tree-sitter/lang-packs/python.ts +45 -0
  63. package/src/plugins/tree-sitter/lang-packs/types.ts +79 -0
  64. package/src/plugins/tree-sitter/lang-packs/typescript.ts +49 -0
  65. package/src/plugins/tree-sitter/parser.ts +444 -0
  66. package/src/plugins/tree-sitter/simple-paths.ts +467 -0
  67. package/src/plugins/types.ts +11 -0
  68. package/src/plugins/url.ts +5 -3
  69. package/src/plugins/vim.ts +8 -5
  70. package/src/processors/CustomVariables.ts +19 -7
  71. package/src/processors/TokenCompressor.ts +13 -13
  72. package/src/processors/ToolResponseCache.ts +15 -6
  73. package/src/services/EmbeddingService.ts +18 -9
  74. package/src/services/EventService.ts +80 -0
  75. package/src/services/Mcp.ts +5 -0
  76. package/src/services/S3.ts +4 -3
  77. package/src/services/Tools.ts +125 -53
  78. package/src/services/index.ts +16 -11
  79. package/src/services/types.ts +3 -3
  80. package/src/types.ts +7 -2
  81. package/src/worker.ts +14 -1
  82. package/test-comprehensive.ts +31 -0
  83. package/tests/clients/AIClient.test.ts +490 -0
  84. package/tests/manual/agent-events/run-test.ts +203 -0
  85. package/tests/{integration → manual/file-edits}/figma.test.ts +1 -1
  86. package/tests/{integration → manual/file-edits}/fileblocks/readwrite.test.ts +7 -3
  87. package/tests/{integration → manual/file-edits}/patching.test.ts +11 -8
  88. package/tests/plugins/language/languagePlugin-content-triggers.test.ts +332 -0
  89. package/tests/plugins/language/languagePlugin-integration.test.ts +456 -0
  90. package/tests/plugins/language/languagePlugin.test.ts +363 -0
  91. package/tests/processors/Base64ImageDetector.test.ts +403 -0
  92. package/tests/processors/CustomVariables.test.ts +430 -0
  93. package/tests/processors/HarmonyToolProcessor.test.ts +490 -0
  94. package/tests/processors/TokenCompressor.test.ts +391 -0
  95. package/tests/processors/ToolResponseCache.test.ts +688 -0
  96. package/tests/services/Tools.test.ts +1339 -0
  97. package/tests/test.spec.ts +162 -117
  98. package/tests/tree-sitter/editor.test.ts +113 -0
  99. package/tests/tree-sitter/invalid.test.ts +299 -0
  100. package/tests/tree-sitter/paths/common-edits.test.ts +564 -0
  101. package/tests/tree-sitter/paths/debug-exact-position.test.ts +44 -0
  102. package/tests/tree-sitter/paths/debug-line-indexing.test.ts +49 -0
  103. package/tests/tree-sitter/paths/debug-paths.test.ts +90 -0
  104. package/tests/tree-sitter/paths/paths.test.ts +170 -0
  105. package/tests/tree-sitter/paths/simple-paths.test.ts +367 -0
  106. package/tests/tree-sitter/sample-after.ts +48 -0
  107. package/tests/tree-sitter/sample-before.ts +25 -0
  108. package/tests/tree-sitter/test-files/completely-broken.ts +7 -0
  109. package/tests/tree-sitter/test-files/duplicate-braces.ts +39 -0
  110. package/tests/tree-sitter/test-files/invalid-nesting.ts +39 -0
  111. package/tests/tree-sitter/test-files/malformed-signature.ts +39 -0
  112. package/tests/tree-sitter/test-files/mismatched-parens.ts +39 -0
  113. package/tests/tree-sitter/test-files/missing-semicolon.ts +39 -0
  114. package/tests/tree-sitter/test-files/partially-broken.ts +20 -0
  115. package/tests/tree-sitter/test-files/specific-errors.ts +14 -0
  116. package/tests/tree-sitter/test-files/unclosed-string.ts +39 -0
  117. package/tests/tree-sitter/tree-sitter.test.ts +251 -0
  118. package/ts_build/package.json +8 -3
  119. package/ts_build/src/agents/base/base.d.ts +2 -2
  120. package/ts_build/src/agents/base/base.js +24 -20
  121. package/ts_build/src/agents/base/base.js.map +1 -1
  122. package/ts_build/src/agents/patcher/patcher.js +26 -5
  123. package/ts_build/src/agents/patcher/patcher.js.map +1 -1
  124. package/ts_build/src/agents/tools/agentCall.js +2 -1
  125. package/ts_build/src/agents/tools/agentCall.js.map +1 -1
  126. package/ts_build/src/agents/tools/aiClient.d.ts +7 -8
  127. package/ts_build/src/agents/tools/aiClient.js.map +1 -1
  128. package/ts_build/src/agents/tools/ast/astAppendNode.d.ts +1 -0
  129. package/ts_build/src/agents/tools/ast/astAppendNode.js +96 -0
  130. package/ts_build/src/agents/tools/ast/astAppendNode.js.map +1 -0
  131. package/ts_build/src/agents/tools/ast/astDeleteNode.d.ts +1 -0
  132. package/ts_build/src/agents/tools/ast/astDeleteNode.js +94 -0
  133. package/ts_build/src/agents/tools/ast/astDeleteNode.js.map +1 -0
  134. package/ts_build/src/agents/tools/ast/astEditNode.d.ts +1 -0
  135. package/ts_build/src/agents/tools/ast/astEditNode.js +96 -0
  136. package/ts_build/src/agents/tools/ast/astEditNode.js.map +1 -0
  137. package/ts_build/src/agents/tools/ast/astGetPathForLine.d.ts +1 -0
  138. package/ts_build/src/agents/tools/ast/astGetPathForLine.js +78 -0
  139. package/ts_build/src/agents/tools/ast/astGetPathForLine.js.map +1 -0
  140. package/ts_build/src/agents/tools/ast/astListPaths.d.ts +1 -0
  141. package/ts_build/src/agents/tools/ast/astListPaths.js +78 -0
  142. package/ts_build/src/agents/tools/ast/astListPaths.js.map +1 -0
  143. package/ts_build/src/agents/tools/ast/index.d.ts +5 -0
  144. package/ts_build/src/agents/tools/ast/index.js +14 -0
  145. package/ts_build/src/agents/tools/ast/index.js.map +1 -0
  146. package/ts_build/src/agents/tools/astAppendNode.d.ts +1 -0
  147. package/ts_build/src/agents/tools/astAppendNode.js +98 -0
  148. package/ts_build/src/agents/tools/astAppendNode.js.map +1 -0
  149. package/ts_build/src/agents/tools/astDeleteNode.d.ts +1 -0
  150. package/ts_build/src/agents/tools/astDeleteNode.js +95 -0
  151. package/ts_build/src/agents/tools/astDeleteNode.js.map +1 -0
  152. package/ts_build/src/agents/tools/astEditNode.d.ts +1 -0
  153. package/ts_build/src/agents/tools/astEditNode.js +98 -0
  154. package/ts_build/src/agents/tools/astEditNode.js.map +1 -0
  155. package/ts_build/src/agents/tools/astGetPathForLine.d.ts +1 -0
  156. package/ts_build/src/agents/tools/astGetPathForLine.js +89 -0
  157. package/ts_build/src/agents/tools/astGetPathForLine.js.map +1 -0
  158. package/ts_build/src/agents/tools/astListPaths.d.ts +1 -0
  159. package/ts_build/src/agents/tools/astListPaths.js +82 -0
  160. package/ts_build/src/agents/tools/astListPaths.js.map +1 -0
  161. package/ts_build/src/agents/tools/callPlugin.js +4 -2
  162. package/ts_build/src/agents/tools/callPlugin.js.map +1 -1
  163. package/ts_build/src/agents/tools/embeddingSearch.js +3 -2
  164. package/ts_build/src/agents/tools/embeddingSearch.js.map +1 -1
  165. package/ts_build/src/agents/tools/execCommand.d.ts +2 -2
  166. package/ts_build/src/agents/tools/execCommand.js +201 -67
  167. package/ts_build/src/agents/tools/execCommand.js.map +1 -1
  168. package/ts_build/src/agents/tools/fileSearch.d.ts +1 -1
  169. package/ts_build/src/agents/tools/fileSearch.js +11 -15
  170. package/ts_build/src/agents/tools/fileSearch.js.map +1 -1
  171. package/ts_build/src/agents/tools/github/index.d.ts +1 -1
  172. package/ts_build/src/agents/tools/index.d.ts +1 -0
  173. package/ts_build/src/agents/tools/index.js +1 -0
  174. package/ts_build/src/agents/tools/index.js.map +1 -1
  175. package/ts_build/src/agents/tools/language/definitions.js +11 -2
  176. package/ts_build/src/agents/tools/language/definitions.js.map +1 -1
  177. package/ts_build/src/agents/tools/language/index.js +4 -3
  178. package/ts_build/src/agents/tools/language/index.js.map +1 -1
  179. package/ts_build/src/agents/tools/lintFile.js +4 -2
  180. package/ts_build/src/agents/tools/lintFile.js.map +1 -1
  181. package/ts_build/src/agents/tools/list.js +185 -49
  182. package/ts_build/src/agents/tools/list.js.map +1 -1
  183. package/ts_build/src/agents/tools/patch.js +33 -10
  184. package/ts_build/src/agents/tools/patch.js.map +1 -1
  185. package/ts_build/src/agents/tools/readBlocks.js +23 -0
  186. package/ts_build/src/agents/tools/readBlocks.js.map +1 -1
  187. package/ts_build/src/agents/tools/readFile.js +14 -0
  188. package/ts_build/src/agents/tools/readFile.js.map +1 -1
  189. package/ts_build/src/agents/tools/stringReplace.js +19 -2
  190. package/ts_build/src/agents/tools/stringReplace.js.map +1 -1
  191. package/ts_build/src/agents/tools/writeFile.js +40 -0
  192. package/ts_build/src/agents/tools/writeFile.js.map +1 -1
  193. package/ts_build/src/agents/tools/ycmd/server.js +5 -0
  194. package/ts_build/src/agents/tools/ycmd/server.js.map +1 -1
  195. package/ts_build/src/chat/CliChatService.d.ts +1 -0
  196. package/ts_build/src/chat/CliChatService.js +6 -2
  197. package/ts_build/src/chat/CliChatService.js.map +1 -1
  198. package/ts_build/src/chat/modules/AgentModule.d.ts +5 -1
  199. package/ts_build/src/chat/modules/AgentModule.js +53 -31
  200. package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
  201. package/ts_build/src/chat/modules/AskModule.js.map +1 -1
  202. package/ts_build/src/chat/modules/SetupModule.js +4 -3
  203. package/ts_build/src/chat/modules/SetupModule.js.map +1 -1
  204. package/ts_build/src/chat/modules/SystemModule.js +19 -4
  205. package/ts_build/src/chat/modules/SystemModule.js.map +1 -1
  206. package/ts_build/src/chat/modules/index.d.ts +5 -0
  207. package/ts_build/src/chat/modules/index.js +14 -0
  208. package/ts_build/src/chat/modules/index.js.map +1 -0
  209. package/ts_build/src/chat/types.d.ts +2 -0
  210. package/ts_build/src/chat-old.js +3 -3
  211. package/ts_build/src/chat-old.js.map +1 -1
  212. package/ts_build/src/clients/anthropic.d.ts +1 -0
  213. package/ts_build/src/clients/anthropic.js +22 -1
  214. package/ts_build/src/clients/anthropic.js.map +1 -1
  215. package/ts_build/src/clients/openai.js +1 -1
  216. package/ts_build/src/clients/openai.js.map +1 -1
  217. package/ts_build/src/clients/xai.d.ts +7 -0
  218. package/ts_build/src/clients/xai.js +13 -4
  219. package/ts_build/src/clients/xai.js.map +1 -1
  220. package/ts_build/src/config.js +14 -3
  221. package/ts_build/src/config.js.map +1 -1
  222. package/ts_build/src/dataset/diffs/generate.js +2 -2
  223. package/ts_build/src/dataset/diffs/generate.js.map +1 -1
  224. package/ts_build/src/dataset/diffs/jsonl.js.map +1 -1
  225. package/ts_build/src/embeddings.js +7 -9
  226. package/ts_build/src/embeddings.js.map +1 -1
  227. package/ts_build/src/index.js +10 -10
  228. package/ts_build/src/index.js.map +1 -1
  229. package/ts_build/src/plugins/GitPlugin.d.ts +39 -0
  230. package/ts_build/src/plugins/GitPlugin.js +439 -0
  231. package/ts_build/src/plugins/GitPlugin.js.map +1 -0
  232. package/ts_build/src/plugins/LinterPlugin.d.ts +15 -0
  233. package/ts_build/src/plugins/LinterPlugin.js +65 -0
  234. package/ts_build/src/plugins/LinterPlugin.js.map +1 -0
  235. package/ts_build/src/plugins/PluginBase.d.ts +4 -3
  236. package/ts_build/src/plugins/PluginBase.js +3 -3
  237. package/ts_build/src/plugins/PluginBase.js.map +1 -1
  238. package/ts_build/src/plugins/asana.d.ts +3 -1
  239. package/ts_build/src/plugins/asana.js +3 -2
  240. package/ts_build/src/plugins/asana.js.map +1 -1
  241. package/ts_build/src/plugins/downloader/plugin.d.ts +3 -1
  242. package/ts_build/src/plugins/downloader/plugin.js +3 -2
  243. package/ts_build/src/plugins/downloader/plugin.js.map +1 -1
  244. package/ts_build/src/plugins/embedding.d.ts +5 -1
  245. package/ts_build/src/plugins/embedding.js +15 -3
  246. package/ts_build/src/plugins/embedding.js.map +1 -1
  247. package/ts_build/src/plugins/figma.d.ts +3 -1
  248. package/ts_build/src/plugins/figma.js +28 -4
  249. package/ts_build/src/plugins/figma.js.map +1 -1
  250. package/ts_build/src/plugins/github.d.ts +3 -1
  251. package/ts_build/src/plugins/github.js +3 -2
  252. package/ts_build/src/plugins/github.js.map +1 -1
  253. package/ts_build/src/plugins/jira.d.ts +3 -1
  254. package/ts_build/src/plugins/jira.js +3 -2
  255. package/ts_build/src/plugins/jira.js.map +1 -1
  256. package/ts_build/src/plugins/language.d.ts +7 -4
  257. package/ts_build/src/plugins/language.js +85 -20
  258. package/ts_build/src/plugins/language.js.map +1 -1
  259. package/ts_build/src/plugins/linear.d.ts +3 -1
  260. package/ts_build/src/plugins/linear.js +3 -2
  261. package/ts_build/src/plugins/linear.js.map +1 -1
  262. package/ts_build/src/plugins/notion.d.ts +3 -1
  263. package/ts_build/src/plugins/notion.js +3 -2
  264. package/ts_build/src/plugins/notion.js.map +1 -1
  265. package/ts_build/src/plugins/plugins.d.ts +4 -3
  266. package/ts_build/src/plugins/plugins.js +24 -14
  267. package/ts_build/src/plugins/plugins.js.map +1 -1
  268. package/ts_build/src/plugins/tree-sitter/editor.d.ts +34 -0
  269. package/ts_build/src/plugins/tree-sitter/editor.js +218 -0
  270. package/ts_build/src/plugins/tree-sitter/editor.js.map +1 -0
  271. package/ts_build/src/plugins/tree-sitter/human-readable-paths-new.d.ts +29 -0
  272. package/ts_build/src/plugins/tree-sitter/human-readable-paths-new.js +538 -0
  273. package/ts_build/src/plugins/tree-sitter/human-readable-paths-new.js.map +1 -0
  274. package/ts_build/src/plugins/tree-sitter/human-readable-paths.d.ts +22 -0
  275. package/ts_build/src/plugins/tree-sitter/human-readable-paths.js +332 -0
  276. package/ts_build/src/plugins/tree-sitter/human-readable-paths.js.map +1 -0
  277. package/ts_build/src/plugins/tree-sitter/lang-packs/index.d.ts +8 -0
  278. package/ts_build/src/plugins/tree-sitter/lang-packs/index.js +26 -0
  279. package/ts_build/src/plugins/tree-sitter/lang-packs/index.js.map +1 -0
  280. package/ts_build/src/plugins/tree-sitter/lang-packs/java.d.ts +2 -0
  281. package/ts_build/src/plugins/tree-sitter/lang-packs/java.js +61 -0
  282. package/ts_build/src/plugins/tree-sitter/lang-packs/java.js.map +1 -0
  283. package/ts_build/src/plugins/tree-sitter/lang-packs/javascript.d.ts +2 -0
  284. package/ts_build/src/plugins/tree-sitter/lang-packs/javascript.js +59 -0
  285. package/ts_build/src/plugins/tree-sitter/lang-packs/javascript.js.map +1 -0
  286. package/ts_build/src/plugins/tree-sitter/lang-packs/python.d.ts +2 -0
  287. package/ts_build/src/plugins/tree-sitter/lang-packs/python.js +47 -0
  288. package/ts_build/src/plugins/tree-sitter/lang-packs/python.js.map +1 -0
  289. package/ts_build/src/plugins/tree-sitter/lang-packs/types.d.ts +43 -0
  290. package/ts_build/src/plugins/tree-sitter/lang-packs/types.js +3 -0
  291. package/ts_build/src/plugins/tree-sitter/lang-packs/types.js.map +1 -0
  292. package/ts_build/src/plugins/tree-sitter/lang-packs/typescript.d.ts +2 -0
  293. package/ts_build/src/plugins/tree-sitter/lang-packs/typescript.js +50 -0
  294. package/ts_build/src/plugins/tree-sitter/lang-packs/typescript.js.map +1 -0
  295. package/ts_build/src/plugins/tree-sitter/parser.d.ts +75 -0
  296. package/ts_build/src/plugins/tree-sitter/parser.js +306 -0
  297. package/ts_build/src/plugins/tree-sitter/parser.js.map +1 -0
  298. package/ts_build/src/plugins/tree-sitter/simple-paths.d.ts +22 -0
  299. package/ts_build/src/plugins/tree-sitter/simple-paths.js +332 -0
  300. package/ts_build/src/plugins/tree-sitter/simple-paths.js.map +1 -0
  301. package/ts_build/src/plugins/types.d.ts +10 -0
  302. package/ts_build/src/plugins/url.d.ts +3 -2
  303. package/ts_build/src/plugins/url.js +3 -2
  304. package/ts_build/src/plugins/url.js.map +1 -1
  305. package/ts_build/src/plugins/vim.d.ts +4 -2
  306. package/ts_build/src/plugins/vim.js +6 -8
  307. package/ts_build/src/plugins/vim.js.map +1 -1
  308. package/ts_build/src/processors/CustomVariables.js +12 -3
  309. package/ts_build/src/processors/CustomVariables.js.map +1 -1
  310. package/ts_build/src/processors/TokenCompressor.js +8 -11
  311. package/ts_build/src/processors/TokenCompressor.js.map +1 -1
  312. package/ts_build/src/processors/ToolResponseCache.d.ts +2 -2
  313. package/ts_build/src/processors/ToolResponseCache.js +12 -2
  314. package/ts_build/src/processors/ToolResponseCache.js.map +1 -1
  315. package/ts_build/src/services/EmbeddingService.d.ts +10 -1
  316. package/ts_build/src/services/EmbeddingService.js +12 -12
  317. package/ts_build/src/services/EmbeddingService.js.map +1 -1
  318. package/ts_build/src/services/EventService.d.ts +7 -0
  319. package/ts_build/src/services/EventService.js +49 -0
  320. package/ts_build/src/services/EventService.js.map +1 -1
  321. package/ts_build/src/services/Mcp.js +8 -0
  322. package/ts_build/src/services/Mcp.js.map +1 -1
  323. package/ts_build/src/services/S3.js +4 -3
  324. package/ts_build/src/services/S3.js.map +1 -1
  325. package/ts_build/src/services/Tools.d.ts +1 -0
  326. package/ts_build/src/services/Tools.js +97 -35
  327. package/ts_build/src/services/Tools.js.map +1 -1
  328. package/ts_build/src/services/index.d.ts +4 -5
  329. package/ts_build/src/services/index.js +14 -9
  330. package/ts_build/src/services/index.js.map +1 -1
  331. package/ts_build/src/services/types.js +3 -3
  332. package/ts_build/src/services/types.js.map +1 -1
  333. package/ts_build/src/types.d.ts +7 -1
  334. package/ts_build/src/types.js +4 -0
  335. package/ts_build/src/types.js.map +1 -1
  336. package/ts_build/src/worker.js +12 -1
  337. package/ts_build/src/worker.js.map +1 -1
  338. package/ts_build/tests/clients/AIClient.test.d.ts +1 -0
  339. package/ts_build/tests/clients/AIClient.test.js +377 -0
  340. package/ts_build/tests/clients/AIClient.test.js.map +1 -0
  341. package/ts_build/tests/languagePlugin.test.js +217 -11
  342. package/ts_build/tests/languagePlugin.test.js.map +1 -1
  343. package/ts_build/tests/manual/agent-events/event-handler-reliability.test.d.ts +1 -0
  344. package/ts_build/tests/manual/agent-events/event-handler-reliability.test.js +315 -0
  345. package/ts_build/tests/manual/agent-events/event-handler-reliability.test.js.map +1 -0
  346. package/ts_build/tests/manual/agent-events/run-test.d.ts +2 -0
  347. package/ts_build/tests/manual/agent-events/run-test.js +148 -0
  348. package/ts_build/tests/manual/agent-events/run-test.js.map +1 -0
  349. package/ts_build/tests/manual/file-edits/figma.test.d.ts +1 -0
  350. package/ts_build/tests/manual/file-edits/figma.test.js +47 -0
  351. package/ts_build/tests/manual/file-edits/figma.test.js.map +1 -0
  352. package/ts_build/tests/manual/file-edits/fileblocks/readwrite.test.d.ts +1 -0
  353. package/ts_build/tests/manual/file-edits/fileblocks/readwrite.test.js +100 -0
  354. package/ts_build/tests/manual/file-edits/fileblocks/readwrite.test.js.map +1 -0
  355. package/ts_build/tests/manual/file-edits/patching.test.d.ts +1 -0
  356. package/ts_build/tests/manual/file-edits/patching.test.js +119 -0
  357. package/ts_build/tests/manual/file-edits/patching.test.js.map +1 -0
  358. package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.d.ts +1 -0
  359. package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js +277 -0
  360. package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js.map +1 -0
  361. package/ts_build/tests/plugins/language/languagePlugin-integration.test.d.ts +1 -0
  362. package/ts_build/tests/plugins/language/languagePlugin-integration.test.js +331 -0
  363. package/ts_build/tests/plugins/language/languagePlugin-integration.test.js.map +1 -0
  364. package/ts_build/tests/plugins/language/languagePlugin.test.d.ts +1 -0
  365. package/ts_build/tests/plugins/language/languagePlugin.test.js +286 -0
  366. package/ts_build/tests/plugins/language/languagePlugin.test.js.map +1 -0
  367. package/ts_build/tests/processors/Base64ImageDetector.test.d.ts +1 -0
  368. package/ts_build/tests/processors/Base64ImageDetector.test.js +351 -0
  369. package/ts_build/tests/processors/Base64ImageDetector.test.js.map +1 -0
  370. package/ts_build/tests/processors/CustomVariables.test.d.ts +1 -0
  371. package/ts_build/tests/processors/CustomVariables.test.js +351 -0
  372. package/ts_build/tests/processors/CustomVariables.test.js.map +1 -0
  373. package/ts_build/tests/processors/HarmonyToolProcessor.test.d.ts +1 -0
  374. package/ts_build/tests/processors/HarmonyToolProcessor.test.js +382 -0
  375. package/ts_build/tests/processors/HarmonyToolProcessor.test.js.map +1 -0
  376. package/ts_build/tests/processors/TokenCompressor.test.d.ts +1 -0
  377. package/ts_build/tests/processors/TokenCompressor.test.js +300 -0
  378. package/ts_build/tests/processors/TokenCompressor.test.js.map +1 -0
  379. package/ts_build/tests/processors/ToolResponseCache.test.d.ts +1 -0
  380. package/ts_build/tests/processors/ToolResponseCache.test.js +539 -0
  381. package/ts_build/tests/processors/ToolResponseCache.test.js.map +1 -0
  382. package/ts_build/tests/services/Plugins/plugin-event-integration.test.d.ts +1 -0
  383. package/ts_build/tests/services/Plugins/plugin-event-integration.test.js +232 -0
  384. package/ts_build/tests/services/Plugins/plugin-event-integration.test.js.map +1 -0
  385. package/ts_build/tests/services/Tools.test.d.ts +1 -0
  386. package/ts_build/tests/services/Tools.test.js +1059 -0
  387. package/ts_build/tests/services/Tools.test.js.map +1 -0
  388. package/ts_build/tests/test.spec.js +110 -68
  389. package/ts_build/tests/test.spec.js.map +1 -1
  390. package/ts_build/tests/tree-sitter/editor.test.d.ts +1 -0
  391. package/ts_build/tests/tree-sitter/editor.test.js +85 -0
  392. package/ts_build/tests/tree-sitter/editor.test.js.map +1 -0
  393. package/ts_build/tests/tree-sitter/invalid.test.d.ts +1 -0
  394. package/ts_build/tests/tree-sitter/invalid.test.js +198 -0
  395. package/ts_build/tests/tree-sitter/invalid.test.js.map +1 -0
  396. package/ts_build/tests/tree-sitter/paths/common-edits.test.d.ts +1 -0
  397. package/ts_build/tests/tree-sitter/paths/common-edits.test.js +347 -0
  398. package/ts_build/tests/tree-sitter/paths/common-edits.test.js.map +1 -0
  399. package/ts_build/tests/tree-sitter/paths/debug-exact-position.test.d.ts +1 -0
  400. package/ts_build/tests/tree-sitter/paths/debug-exact-position.test.js +35 -0
  401. package/ts_build/tests/tree-sitter/paths/debug-exact-position.test.js.map +1 -0
  402. package/ts_build/tests/tree-sitter/paths/debug-line-indexing.test.d.ts +1 -0
  403. package/ts_build/tests/tree-sitter/paths/debug-line-indexing.test.js +38 -0
  404. package/ts_build/tests/tree-sitter/paths/debug-line-indexing.test.js.map +1 -0
  405. package/ts_build/tests/tree-sitter/paths/debug-paths.test.d.ts +1 -0
  406. package/ts_build/tests/tree-sitter/paths/debug-paths.test.js +74 -0
  407. package/ts_build/tests/tree-sitter/paths/debug-paths.test.js.map +1 -0
  408. package/ts_build/tests/tree-sitter/paths/human-readable-paths.test.d.ts +1 -0
  409. package/ts_build/tests/tree-sitter/paths/human-readable-paths.test.js +302 -0
  410. package/ts_build/tests/tree-sitter/paths/human-readable-paths.test.js.map +1 -0
  411. package/ts_build/tests/tree-sitter/paths/paths.test.d.ts +1 -0
  412. package/ts_build/tests/tree-sitter/paths/paths.test.js +116 -0
  413. package/ts_build/tests/tree-sitter/paths/paths.test.js.map +1 -0
  414. package/ts_build/tests/tree-sitter/paths/simple-paths.test.d.ts +1 -0
  415. package/ts_build/tests/tree-sitter/paths/simple-paths.test.js +302 -0
  416. package/ts_build/tests/tree-sitter/paths/simple-paths.test.js.map +1 -0
  417. package/ts_build/tests/tree-sitter/sample-after.d.ts +11 -0
  418. package/ts_build/tests/tree-sitter/sample-after.js +44 -0
  419. package/ts_build/tests/tree-sitter/sample-after.js.map +1 -0
  420. package/ts_build/tests/tree-sitter/sample-before.d.ts +9 -0
  421. package/ts_build/tests/tree-sitter/sample-before.js +28 -0
  422. package/ts_build/tests/tree-sitter/sample-before.js.map +1 -0
  423. package/ts_build/tests/tree-sitter/test-files/completely-broken.d.ts +2 -0
  424. package/ts_build/tests/tree-sitter/test-files/completely-broken.js +17 -0
  425. package/ts_build/tests/tree-sitter/test-files/completely-broken.js.map +1 -0
  426. package/ts_build/tests/tree-sitter/test-files/duplicate-braces.d.ts +8 -0
  427. package/ts_build/tests/tree-sitter/test-files/duplicate-braces.js +38 -0
  428. package/ts_build/tests/tree-sitter/test-files/duplicate-braces.js.map +1 -0
  429. package/ts_build/tests/tree-sitter/test-files/invalid-nesting.d.ts +8 -0
  430. package/ts_build/tests/tree-sitter/test-files/invalid-nesting.js +38 -0
  431. package/ts_build/tests/tree-sitter/test-files/invalid-nesting.js.map +1 -0
  432. package/ts_build/tests/tree-sitter/test-files/malformed-signature.d.ts +8 -0
  433. package/ts_build/tests/tree-sitter/test-files/malformed-signature.js +38 -0
  434. package/ts_build/tests/tree-sitter/test-files/malformed-signature.js.map +1 -0
  435. package/ts_build/tests/tree-sitter/test-files/mismatched-parens.d.ts +10 -0
  436. package/ts_build/tests/tree-sitter/test-files/mismatched-parens.js +38 -0
  437. package/ts_build/tests/tree-sitter/test-files/mismatched-parens.js.map +1 -0
  438. package/ts_build/tests/tree-sitter/test-files/missing-semicolon.d.ts +8 -0
  439. package/ts_build/tests/tree-sitter/test-files/missing-semicolon.js +38 -0
  440. package/ts_build/tests/tree-sitter/test-files/missing-semicolon.js.map +1 -0
  441. package/ts_build/tests/tree-sitter/test-files/partially-broken.d.ts +6 -0
  442. package/ts_build/tests/tree-sitter/test-files/partially-broken.js +20 -0
  443. package/ts_build/tests/tree-sitter/test-files/partially-broken.js.map +1 -0
  444. package/ts_build/tests/tree-sitter/test-files/specific-errors.d.ts +7 -0
  445. package/ts_build/tests/tree-sitter/test-files/specific-errors.js +14 -0
  446. package/ts_build/tests/tree-sitter/test-files/specific-errors.js.map +1 -0
  447. package/ts_build/tests/tree-sitter/test-files/unclosed-string.d.ts +8 -0
  448. package/ts_build/tests/tree-sitter/test-files/unclosed-string.js +38 -0
  449. package/ts_build/tests/tree-sitter/test-files/unclosed-string.js.map +1 -0
  450. package/ts_build/tests/tree-sitter/tree-sitter.test.d.ts +1 -0
  451. package/ts_build/tests/tree-sitter/tree-sitter.test.js +185 -0
  452. package/ts_build/tests/tree-sitter/tree-sitter.test.js.map +1 -0
  453. package/tsconfig.json +2 -1
  454. package/tests/languagePlugin.test.ts +0 -74
  455. /package/src/chat/modules/{index.js → index.ts} +0 -0
  456. /package/tests/{integration → manual/file-edits}/patching/input.txt +0 -0
  457. /package/tests/{integration → manual/file-edits}/patching/output.txt +0 -0
  458. /package/tests/{integration → manual/file-edits}/patching/patch.txt +0 -0
  459. /package/tests/{integration → manual/file-edits}/patching/unseen.txt +0 -0
@@ -0,0 +1,467 @@
1
+ import { LanguageAgnosticParser, SyntaxNode, Tree } from "./parser";
2
+ import { getLanguagePack, LanguagePackConfig } from "./lang-packs";
3
+ import { Query } from "tree-sitter";
4
+
5
+ export interface SimplePathMatch {
6
+ node: SyntaxNode;
7
+ path: string;
8
+ simplePath: string;
9
+ description: string;
10
+ }
11
+
12
+ export class SimplePathResolver {
13
+ private parser: LanguageAgnosticParser;
14
+ private languagePack: LanguagePackConfig;
15
+
16
+ constructor(parser: LanguageAgnosticParser) {
17
+ this.parser = parser;
18
+ this.languagePack = parser.getLanguagePack();
19
+ }
20
+
21
+ /**
22
+ * Execute a tree-sitter query and return matches with capture names
23
+ */
24
+ private executeQuery(
25
+ tree: Tree,
26
+ queryString: string
27
+ ): { node: SyntaxNode; captures: Record<string, SyntaxNode> }[] {
28
+ try {
29
+ const language = this.parser.parser.getLanguage(); // Access internal parser
30
+ if (!language) return [];
31
+
32
+ const query = new Query(language, queryString);
33
+ const matches = query.matches(tree.rootNode);
34
+
35
+ return matches.map((match) => {
36
+ const captures: Record<string, SyntaxNode> = {};
37
+ for (const capture of match.captures) {
38
+ captures[capture.name] = capture.node;
39
+ }
40
+ return {
41
+ node: match.captures[0]?.node, // Main node
42
+ captures,
43
+ };
44
+ });
45
+ } catch (error) {
46
+ console.warn("Failed to execute tree-sitter query:", error);
47
+ console.warn("Query that failed:", JSON.stringify(queryString));
48
+ return [];
49
+ }
50
+ }
51
+ /**
52
+ * Find all nodes of a specific type using the language pack
53
+ */
54
+ private findNodesByQuery(
55
+ tree: Tree,
56
+ queryType: keyof LanguagePackConfig["queries"]
57
+ ): { node: SyntaxNode; captures: Record<string, SyntaxNode> }[] {
58
+ if (!this.languagePack || !this.languagePack.queries[queryType]) {
59
+ return [];
60
+ }
61
+ return this.executeQuery(tree, this.languagePack.queries[queryType]);
62
+ }
63
+
64
+ /**
65
+ * Parse a path to detect block syntax like describe("name") vs regular paths
66
+ */
67
+ private parseSimplePath(simplePath: string): {
68
+ type: "block" | "regular";
69
+ functionName?: string;
70
+ argument?: string;
71
+ parts: string[];
72
+ } {
73
+ // Check for function call syntax like describe("name") or test("should work")
74
+ const blockPattern = /^(\w+)\s*\(\s*["'`]([^"'`]*)["'`]\s*\)$/;
75
+ const blockMatch = simplePath.match(blockPattern);
76
+
77
+ if (blockMatch) {
78
+ return {
79
+ type: "block",
80
+ functionName: blockMatch[1],
81
+ argument: blockMatch[2],
82
+ parts: [blockMatch[1]],
83
+ };
84
+ }
85
+
86
+ // Check for parameterless function calls like beforeEach()
87
+ const parameterlessBlockPattern = /^(\w+)\s*\(\s*\)$/;
88
+ const parameterlessMatch = simplePath.match(parameterlessBlockPattern);
89
+
90
+ if (parameterlessMatch) {
91
+ return {
92
+ type: "block",
93
+ functionName: parameterlessMatch[1],
94
+ parts: [parameterlessMatch[1]],
95
+ };
96
+ }
97
+
98
+ // Regular path like "ClassName.methodName" or just "name"
99
+ return {
100
+ type: "regular",
101
+ parts: simplePath.split("."),
102
+ };
103
+ }
104
+ /**
105
+ * Find block matches for syntax like describe("name") or beforeEach()
106
+ */
107
+ private findBlockMatches(
108
+ tree: Tree,
109
+ functionName: string,
110
+ argument: string | undefined,
111
+ simplePath: string
112
+ ): SimplePathMatch[] {
113
+ const matches: SimplePathMatch[] = [];
114
+ const blockMatches = this.findNodesByQuery(tree, "blocks");
115
+
116
+ for (const match of blockMatches) {
117
+ const calleeNode = match.captures.callee;
118
+ const nameNode = match.captures.name;
119
+
120
+ if (!calleeNode || calleeNode.text !== functionName) {
121
+ continue;
122
+ }
123
+
124
+ // For parameterless blocks like beforeEach(), just match the function name
125
+ if (!argument) {
126
+ matches.push({
127
+ node: match.node,
128
+ path: this.getNodePath(tree.rootNode, match.node),
129
+ simplePath,
130
+ description: `${functionName} block`,
131
+ });
132
+ continue;
133
+ }
134
+
135
+ // For blocks with arguments, match the argument text
136
+ if (nameNode) {
137
+ // Extract string content from quotes
138
+ let nameText = nameNode.text;
139
+ if (
140
+ (nameText.startsWith('"') && nameText.endsWith('"')) ||
141
+ (nameText.startsWith("'") && nameText.endsWith("'")) ||
142
+ (nameText.startsWith("`") && nameText.endsWith("`"))
143
+ ) {
144
+ nameText = nameText.slice(1, -1);
145
+ }
146
+
147
+ if (nameText === argument) {
148
+ matches.push({
149
+ node: match.node,
150
+ path: this.getNodePath(tree.rootNode, match.node),
151
+ simplePath,
152
+ description: `${functionName} block: ${argument}`,
153
+ });
154
+ }
155
+ }
156
+ }
157
+
158
+ return matches;
159
+ }
160
+ /**
161
+ * Find nodes using human-readable paths like:
162
+ * - "ClassName.methodName" - finds a method in a class
163
+ * - "ClassName" - finds a class declaration
164
+ * - "methodName" - finds any method with that name
165
+ * - "ClassName.propertyName" - finds a property in a class
166
+ * - "describe(\"test name\")" - finds a describe block
167
+ */
168
+ findBySimplePath(tree: Tree, simplePath: string): SimplePathMatch[] {
169
+ if (!tree.rootNode) {
170
+ return [];
171
+ }
172
+
173
+ const matches: SimplePathMatch[] = [];
174
+ const pathInfo = this.parseSimplePath(simplePath);
175
+ const parts = pathInfo.parts;
176
+
177
+ // Handle block syntax like describe("Authentication") or beforeEach()
178
+ if (pathInfo.type === "block") {
179
+ return this.findBlockMatches(
180
+ tree,
181
+ pathInfo.functionName!,
182
+ pathInfo.argument,
183
+ simplePath
184
+ );
185
+ }
186
+
187
+ if (parts.length === 1) {
188
+ // Single part - could be class, method, or property
189
+ const singleName = parts[0];
190
+
191
+ // Check for classes
192
+ const classMatches = this.findNodesByQuery(tree, "classes");
193
+ for (const match of classMatches) {
194
+ const nameNode = match.captures.name;
195
+ if (nameNode && nameNode.text === singleName) {
196
+ matches.push({
197
+ node: match.node,
198
+ path: this.getNodePath(tree.rootNode, match.node),
199
+ simplePath,
200
+ description: `Class declaration: ${singleName}`,
201
+ });
202
+ }
203
+ }
204
+ // Check for methods
205
+ const methodMatches = this.findNodesByQuery(tree, "methods");
206
+ for (const match of methodMatches) {
207
+ const nameNode = match.captures.name;
208
+ if (nameNode && nameNode.text === singleName) {
209
+ const className = this.findContainingClassName(tree, match.node);
210
+ const description = className
211
+ ? `${singleName} method in class ${className}`
212
+ : `Method declaration: ${singleName}`;
213
+ matches.push({
214
+ node: match.node,
215
+ path: this.getNodePath(tree.rootNode, match.node),
216
+ simplePath,
217
+ description,
218
+ });
219
+ }
220
+ }
221
+
222
+ // Check for properties
223
+ const propertyMatches = this.findNodesByQuery(tree, "properties");
224
+ for (const match of propertyMatches) {
225
+ const nameNode = match.captures.name;
226
+ if (nameNode && nameNode.text === singleName) {
227
+ matches.push({
228
+ node: match.node,
229
+ path: this.getNodePath(tree.rootNode, match.node),
230
+ simplePath,
231
+ description: `Property declaration: ${singleName}`,
232
+ });
233
+ }
234
+ }
235
+
236
+ // Check for generic blocks like describe(), test(), it(), etc.
237
+ const blockMatches = this.findNodesByQuery(tree, "blocks");
238
+ for (const match of blockMatches) {
239
+ const calleeNode = match.captures.callee;
240
+ const nameNode = match.captures.name;
241
+
242
+ // Check if this is a parameterless call matching the search term
243
+ if (calleeNode && calleeNode.text === singleName) {
244
+ matches.push({
245
+ node: match.node,
246
+ path: this.getNodePath(tree.rootNode, match.node),
247
+ simplePath,
248
+ description: `${singleName} block`,
249
+ });
250
+ continue;
251
+ }
252
+
253
+ if (nameNode && nameNode.text === singleName && calleeNode) {
254
+ matches.push({
255
+ node: match.node,
256
+ path: this.getNodePath(tree.rootNode, match.node),
257
+ simplePath,
258
+ description: `${calleeNode.text} block: ${singleName}`,
259
+ });
260
+ }
261
+ }
262
+ } else if (parts.length === 2) {
263
+ const [className, memberName] = parts;
264
+ // Find classes with the given name
265
+ const classMatches = this.findNodesByQuery(tree, "classes");
266
+ for (const classMatch of classMatches) {
267
+ const classNameNode = classMatch.captures.name;
268
+ if (classNameNode && classNameNode.text === className) {
269
+ // Look for methods in this class
270
+ const methodMatches = this.findNodesByQuery(tree, "methods");
271
+ for (const methodMatch of methodMatches) {
272
+ const methodNameNode = methodMatch.captures.name;
273
+ if (methodNameNode && methodNameNode.text === memberName) {
274
+ // Check if this method is within the target class
275
+ if (this.isNodeWithinNode(methodMatch.node, classMatch.node)) {
276
+ matches.push({
277
+ node: methodMatch.node,
278
+ path: this.getNodePath(tree.rootNode, methodMatch.node),
279
+ simplePath,
280
+ description: `${memberName} method in class ${className}`,
281
+ });
282
+ }
283
+ }
284
+ }
285
+
286
+ // Look for properties in this class
287
+ const propertyMatches = this.findNodesByQuery(tree, "properties");
288
+ for (const propertyMatch of propertyMatches) {
289
+ const propertyNameNode = propertyMatch.captures.name;
290
+ if (propertyNameNode && propertyNameNode.text === memberName) {
291
+ // Check if this property is within the target class
292
+ if (this.isNodeWithinNode(propertyMatch.node, classMatch.node)) {
293
+ matches.push({
294
+ node: propertyMatch.node,
295
+ path: this.getNodePath(tree.rootNode, propertyMatch.node),
296
+ simplePath,
297
+ description: `Property ${memberName} in class ${className}`,
298
+ });
299
+ }
300
+ }
301
+ }
302
+ }
303
+ }
304
+ }
305
+
306
+ return matches;
307
+ }
308
+ /**
309
+ * Find the containing class name for a method node
310
+ */
311
+ private findContainingClassName(
312
+ tree: Tree,
313
+ methodNode: SyntaxNode
314
+ ): string | null {
315
+ if (!this.languagePack) return null;
316
+
317
+ // Find all classes and check if this method is within any of them
318
+ const classMatches = this.findNodesByQuery(tree, "classes");
319
+
320
+ for (const classMatch of classMatches) {
321
+ if (this.isNodeWithinNode(methodNode, classMatch.node)) {
322
+ const nameNode = classMatch.captures.name;
323
+ return nameNode ? nameNode.text : null;
324
+ }
325
+ }
326
+ return null;
327
+ }
328
+
329
+ /**
330
+ * Get the parser instance (for testing or advanced usage)
331
+ */
332
+ getParser(): LanguageAgnosticParser {
333
+ return this.parser;
334
+ }
335
+
336
+ private getNodePath(rootNode: SyntaxNode, targetNode: SyntaxNode): string {
337
+ const path: string[] = [];
338
+ let current: SyntaxNode | null = targetNode;
339
+
340
+ while (current && current !== rootNode) {
341
+ if (current.parent) {
342
+ const siblings = current.parent.children;
343
+ const index = siblings.indexOf(current);
344
+ path.unshift(`${current.type}[${index}]`);
345
+ current = current.parent;
346
+ } else {
347
+ break;
348
+ }
349
+ }
350
+
351
+ return path.join("/");
352
+ }
353
+ /**
354
+ * Get all possible human-readable paths for a tree
355
+ */
356
+ getAllSimplePaths(tree: Tree): string[] {
357
+ const paths: string[] = [];
358
+
359
+ if (!this.languagePack || !tree.rootNode) {
360
+ return paths;
361
+ }
362
+
363
+ // Add class names
364
+ const classMatches = this.findNodesByQuery(tree, "classes");
365
+ for (const classMatch of classMatches) {
366
+ const classNameNode = classMatch.captures.name;
367
+ if (classNameNode && classNameNode.text) {
368
+ const className = classNameNode.text;
369
+ paths.push(className);
370
+
371
+ // Add methods within this class
372
+ const methodMatches = this.findNodesByQuery(tree, "methods");
373
+ for (const methodMatch of methodMatches) {
374
+ const methodNameNode = methodMatch.captures.name;
375
+ if (
376
+ methodNameNode &&
377
+ methodNameNode.text &&
378
+ this.isNodeWithinNode(methodMatch.node, classMatch.node)
379
+ ) {
380
+ const methodName = methodNameNode.text;
381
+ paths.push(`${className}.${methodName}`);
382
+ }
383
+ }
384
+
385
+ // Add properties within this class
386
+ const propertyMatches = this.findNodesByQuery(tree, "properties");
387
+ for (const propertyMatch of propertyMatches) {
388
+ const propertyNameNode = propertyMatch.captures.name;
389
+ if (
390
+ propertyNameNode &&
391
+ propertyNameNode.text &&
392
+ this.isNodeWithinNode(propertyMatch.node, classMatch.node)
393
+ ) {
394
+ const propertyName = propertyNameNode.text;
395
+ paths.push(`${className}.${propertyName}`);
396
+ }
397
+ }
398
+ }
399
+ }
400
+ // Add standalone methods (not within classes)
401
+ const standaloneMethods = this.findNodesByQuery(tree, "methods");
402
+ for (const methodMatch of standaloneMethods) {
403
+ const methodNameNode = methodMatch.captures.name;
404
+ if (methodNameNode && methodNameNode.text) {
405
+ const methodName = methodNameNode.text;
406
+
407
+ // Check if this method is NOT within a class
408
+ let isWithinClass = false;
409
+ for (const classMatch of classMatches) {
410
+ if (this.isNodeWithinNode(methodMatch.node, classMatch.node)) {
411
+ isWithinClass = true;
412
+ break;
413
+ }
414
+ }
415
+
416
+ if (!isWithinClass) {
417
+ paths.push(methodName);
418
+ }
419
+ }
420
+ }
421
+
422
+ // Add blocks
423
+ const blockMatches = this.findNodesByQuery(tree, "blocks");
424
+ for (const blockMatch of blockMatches) {
425
+ const calleeNode = blockMatch.captures.callee;
426
+ const nameNode = blockMatch.captures.name;
427
+
428
+ if (calleeNode && calleeNode.text) {
429
+ const callee = calleeNode.text;
430
+
431
+ if (nameNode && nameNode.text) {
432
+ // Extract the name from quotes if needed
433
+ let name = nameNode.text;
434
+ if (
435
+ (name.startsWith('"') && name.endsWith('"')) ||
436
+ (name.startsWith("'") && name.endsWith("'"))
437
+ ) {
438
+ name = name.slice(1, -1);
439
+ }
440
+ paths.push(`${callee}("${name}")`);
441
+ } else {
442
+ // Block without name parameter
443
+ paths.push(`${callee}()`);
444
+ }
445
+ }
446
+ }
447
+
448
+ return paths;
449
+ }
450
+
451
+ /**
452
+ * Helper method to check if one node is contained within another
453
+ */
454
+ private isNodeWithinNode(
455
+ childNode: SyntaxNode,
456
+ parentNode: SyntaxNode
457
+ ): boolean {
458
+ let current = childNode.parent;
459
+ while (current) {
460
+ if (current === parentNode) {
461
+ return true;
462
+ }
463
+ current = current.parent;
464
+ }
465
+ return false;
466
+ }
467
+ }
@@ -1,4 +1,7 @@
1
1
  import { Embeddable, MinimalEmbedding } from "../types";
2
+ import { AgentService, EventService, ToolsService } from "../services";
3
+ import { AIClient } from "../clients";
4
+ import { PluginService } from "./plugins";
2
5
 
3
6
  export interface PluginMeta {
4
7
  key: string;
@@ -16,3 +19,11 @@ export interface Plugin {
16
19
 
17
20
  meta: PluginMeta;
18
21
  }
22
+
23
+ export interface PluginContext {
24
+ Agents?: AgentService;
25
+ Events?: EventService;
26
+ Clients?: AIClient;
27
+ Tools?: ToolsService;
28
+ Plugins?: PluginService;
29
+ }
@@ -1,5 +1,5 @@
1
1
  import { PluginBase, PluginMeta } from "./PluginBase";
2
- import { Plugin } from "./types";
2
+ import { Plugin, PluginContext } from "./types";
3
3
  import { MinimalEmbedding } from "../types";
4
4
  import axios from "axios";
5
5
  import * as cheerio from "cheerio";
@@ -12,8 +12,10 @@ export class UrlPlugin extends PluginBase implements Plugin {
12
12
  requires: [],
13
13
  };
14
14
 
15
- constructor() {
16
- super(UrlPlugin.meta);
15
+ meta = UrlPlugin.meta;
16
+
17
+ constructor(context: PluginContext) {
18
+ super(context);
17
19
  }
18
20
 
19
21
  async embed(userPrompt: string): Promise<MinimalEmbedding[]> {
@@ -1,16 +1,19 @@
1
- import glob from "glob";
1
+ import { globSync } from "glob";
2
2
  import { readFile, fileExists, fileStat } from "../utils";
3
3
  import { PluginBase, PluginMeta } from "./PluginBase";
4
+ import { PluginContext } from "./types";
4
5
 
5
6
  export class VimPlugin extends PluginBase {
6
7
  static readonly meta: PluginMeta = {
7
8
  key: "vim",
8
9
  name: "Vim Plugin",
9
- requires: []
10
+ requires: [],
10
11
  };
11
12
 
12
- constructor() {
13
- super(VimPlugin.meta);
13
+ meta = VimPlugin.meta;
14
+
15
+ constructor(context: PluginContext) {
16
+ super(context);
14
17
  }
15
18
 
16
19
  async embed(userPrompt: string) {
@@ -18,7 +21,7 @@ export class VimPlugin extends PluginBase {
18
21
  }
19
22
 
20
23
  async getVimFiles() {
21
- const vimFiles = await glob.sync("./**/*.swp", { dot: true });
24
+ const vimFiles = globSync("./**/*.swp", { dot: true });
22
25
  return vimFiles;
23
26
  }
24
27
 
@@ -136,14 +136,28 @@ export class CustomVariables {
136
136
  }
137
137
 
138
138
  /**
139
- * Recursively processes a value to substitute {{variable}} patterns
139
+ * Processes a value to substitute {{variableName}} patterns
140
140
  */
141
141
  private substituteVariables(
142
142
  value: any,
143
143
  processedVars: Set<string> = new Set()
144
144
  ): any {
145
145
  if (typeof value === "string") {
146
- // Find all {{variable}} patterns
146
+ // Check if ALL variables are undefined - if so, return just the error message for the first one
147
+ const variableMatches = value.match(/\{\{([a-zA-Z0-9_]+)\}\}/g);
148
+ if (variableMatches) {
149
+ const allUndefined = variableMatches.every(match => {
150
+ const varName = match.replace(/[{}]/g, '');
151
+ return !(varName in this.variables);
152
+ });
153
+
154
+ if (allUndefined && variableMatches.length > 0) {
155
+ const firstUndefinedVar = variableMatches[0].replace(/[{}]/g, '');
156
+ return `{{ERROR: Variable "${firstUndefinedVar}" is not defined}}`;
157
+ }
158
+ }
159
+
160
+ // Otherwise, proceed with partial substitution
147
161
  return value.replace(/\{\{([a-zA-Z0-9_]+)\}\}/g, (match, varName) => {
148
162
  // Prevent infinite recursion
149
163
  if (processedVars.has(varName)) {
@@ -156,11 +170,9 @@ export class CustomVariables {
156
170
 
157
171
  const varValue = this.variables[varName];
158
172
 
159
- // If the variable value is a string, recursively process it
173
+ // For nested variables, return the raw value without further processing
160
174
  if (typeof varValue === "string") {
161
- const newProcessedVars = new Set(processedVars);
162
- newProcessedVars.add(varName);
163
- return this.substituteVariables(varValue, newProcessedVars);
175
+ return varValue;
164
176
  }
165
177
 
166
178
  // For non-string values, convert to JSON
@@ -422,4 +434,4 @@ export const deleteVariableToolDefinition: Tool = {
422
434
  required: ["varName"],
423
435
  },
424
436
  },
425
- };
437
+ };
@@ -54,10 +54,6 @@ export class TokenCompressor {
54
54
  * Compresses a string into chunks from the end, creating a chain of references
55
55
  */
56
56
  public compressStringInChunks(content: string, path: string = ""): string {
57
- if (path === "" && this.estimateTokens(content) <= this.maxTokens) {
58
- return content;
59
- }
60
-
61
57
  if (content.length <= this.characterLimit) {
62
58
  return content;
63
59
  }
@@ -80,10 +76,14 @@ export class TokenCompressor {
80
76
  }
81
77
 
82
78
  // Store chunks and create chain of references
83
- for (let i = chunks.length - 1; i >= 0; i--) {
79
+ // First, generate all keys
80
+ for (let i = 0; i < chunks.length; i++) {
84
81
  const key = this.generateKey();
85
- chunkKeys.unshift(key);
82
+ chunkKeys.push(key);
83
+ }
86
84
 
85
+ // Then store chunks with proper linking
86
+ for (let i = 0; i < chunks.length; i++) {
87
87
  let chunkContent = chunks[i];
88
88
 
89
89
  // Add reference to next chunk if it exists
@@ -92,7 +92,7 @@ export class TokenCompressor {
92
92
  chunkContent += `\n\n[NEXT_CHUNK_KEY: ${nextKey}]`;
93
93
  }
94
94
 
95
- this.storeString(key, chunkContent);
95
+ this.storeString(chunkKeys[i], chunkContent);
96
96
  }
97
97
 
98
98
  // Return reference to the first chunk
@@ -114,11 +114,11 @@ export class TokenCompressor {
114
114
  public compressContent(content: string, path: string = ""): string {
115
115
  const tokens = this.estimateTokens(content);
116
116
 
117
- if (path === "" && tokens <= this.maxTokens) {
118
- return content;
119
- }
120
-
121
- if (tokens <= this.compressionThreshold) {
117
+ // For nested properties (path !== ""), use maxTokens to avoid recompressing stored data
118
+ // For top-level content (path === ""), use compressionThreshold to determine compression
119
+ const thresholdToUse = path === "" ? this.compressionThreshold : this.maxTokens;
120
+
121
+ if (tokens <= thresholdToUse) {
122
122
  return content;
123
123
  }
124
124
 
@@ -239,7 +239,7 @@ export class TokenCompressor {
239
239
 
240
240
  // If not JSON or compression wasn't effective, handle as regular string
241
241
  const tokens = this.estimateTokens(obj);
242
- if (tokens > this.characterLimit * 4) {
242
+ if (tokens > this.compressionThreshold) {
243
243
  const key = this.generateKey();
244
244
  this.storeString(key, obj);
245
245