@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
@@ -1,8 +1,7 @@
1
1
  import { Tool } from "../../clients/types";
2
2
  import { ChatCompletionTool } from "openai/resources/chat";
3
- import { Plugins } from "../../plugins/plugins";
4
3
 
5
- const pluginNames = Plugins.listPlugins().join(", ");
4
+ import { services } from "../../services";
6
5
  import * as github from "./github/definitions";
7
6
  import * as asana from "./asana/definitions";
8
7
  import * as ycmd from "./ycmd/definitions";
@@ -11,6 +10,15 @@ import { googleSearchDefinition } from "./googleSearch";
11
10
  import { executeScriptDefinition } from "./executeScript/definition";
12
11
  import { startAgentTaskDefinition } from "./startAgentTask";
13
12
 
13
+ function getPluginNames(): string {
14
+ try {
15
+ const { Plugins } = services();
16
+ return Plugins.listPlugins().join(", ");
17
+ } catch {
18
+ return "";
19
+ }
20
+ }
21
+
14
22
  export const includedTools = [
15
23
  {
16
24
  type: "function",
@@ -41,7 +49,7 @@ export const includedTools = [
41
49
  function: {
42
50
  name: "execCommand",
43
51
  description:
44
- "Execute a command in the system's command line interface. Use this to run tests and things in the terminal. Supports timeout functionality.",
52
+ "Execute a command in the system's command line interface. Use this to run tests and things in the terminal. Supports timeout functionality. Use timeout: -1 to wait indefinitely. Commands ending with '&' or with continueInBackground=true will run in the background and write logs to .knowhow/processes/<command_name>.txt with PID in the first line for cleanup.",
45
53
  parameters: {
46
54
  type: "object",
47
55
  positional: true,
@@ -53,18 +61,13 @@ export const includedTools = [
53
61
  timeout: {
54
62
  type: "number",
55
63
  description:
56
- "Timeout in milliseconds (optional). If not provided, defaults to 5000ms.",
64
+ "Timeout in milliseconds (optional). If not provided, defaults to 5000ms. Use -1 to wait indefinitely for command completion.",
57
65
  },
58
66
  continueInBackground: {
59
67
  type: "boolean",
60
68
  description:
61
69
  "Whether to let command continue in background on timeout (default: false). If false, command is killed on timeout.",
62
70
  },
63
- waitForCompletion: {
64
- type: "boolean",
65
- description:
66
- "Whether to wait for full completion regardless of timeout (default: false). When true, overrides timeout behavior.",
67
- },
68
71
  },
69
72
  required: ["command"],
70
73
  },
@@ -104,7 +107,7 @@ export const includedTools = [
104
107
  type: "function",
105
108
  function: {
106
109
  name: "callPlugin",
107
- description: `Call a specified plugin with given input. Plugins provide additional context from supported URLs or words. This is a read-only operation. Currently available plugins: ${pluginNames}`,
110
+ description: `Call a specified plugin with given input. Plugins provide additional context from supported URLs or words. This is a read-only operation. Currently available plugins: ${getPluginNames()}`,
108
111
  parameters: {
109
112
  type: "object",
110
113
  positional: true,
@@ -382,38 +385,66 @@ export const includedTools = [
382
385
  parameters: {
383
386
  type: "object",
384
387
  positional: true,
388
+ additionalProperties: false,
389
+ $defs: {
390
+ message: {
391
+ type: "object",
392
+ additionalProperties: false,
393
+ properties: {
394
+ role: {
395
+ type: "string",
396
+ enum: ["system", "user", "assistant", "tool"],
397
+ },
398
+ content: { type: "string" },
399
+ },
400
+ required: ["role", "content"],
401
+ },
402
+ toolLite: {
403
+ type: "object",
404
+ additionalProperties: false,
405
+ properties: {
406
+ type: { type: "string", enum: ["function"] },
407
+ function: {
408
+ type: "object",
409
+ additionalProperties: false,
410
+ properties: {
411
+ name: { type: "string" },
412
+ description: { type: "string" },
413
+ parameters: { type: "object" },
414
+ },
415
+ required: ["name", "parameters"],
416
+ },
417
+ },
418
+ required: ["type", "function"],
419
+ },
420
+ },
385
421
  properties: {
386
422
  provider: {
387
423
  type: "string",
388
424
  description:
389
425
  "The AI provider to use (e.g., 'openai', 'anthropic'). Use listAllModels to discover providers.",
390
426
  },
391
-
392
427
  options: {
393
428
  type: "object",
429
+ additionalProperties: false,
394
430
  description: "Provider-specific completion options",
395
431
  properties: {
396
- model: {
397
- type: "string",
398
- description: "The model to use",
399
- },
400
-
432
+ model: { type: "string", description: "The model to use" },
401
433
  messages: {
402
434
  type: "array",
403
435
  description: "The chat history for the completion",
404
- items: { $ref: "#/definitions/message" },
436
+ items: { $ref: "#/$defs/message" },
405
437
  minItems: 1,
406
438
  },
407
-
408
439
  max_tokens: {
409
440
  type: "number",
410
441
  description: "Maximum number of tokens to generate",
411
442
  },
412
-
413
443
  tools: {
414
444
  type: "array",
415
- description: "Tool definitions the model may call",
416
- items: { $ref: "#/definitions/tool" },
445
+ description:
446
+ "Tool definitions the model may call (non-recursive subset)",
447
+ items: { $ref: "#/$defs/toolLite" },
417
448
  },
418
449
  },
419
450
  required: ["model", "messages"],
@@ -421,54 +452,18 @@ export const includedTools = [
421
452
  },
422
453
  required: ["provider"],
423
454
  },
424
-
425
455
  returns: {
426
456
  type: "object",
427
457
  description: "The completion response from the AI provider",
428
458
  },
429
459
  },
430
-
431
- definitions: {
432
- message: {
433
- type: "object",
434
- properties: {
435
- role: {
436
- type: "string",
437
- enum: ["system", "user", "assistant", "tool"],
438
- },
439
- content: { type: "string" },
440
- },
441
- required: ["role", "content"],
442
- },
443
-
444
- tool: {
445
- type: "object",
446
- properties: {
447
- type: {
448
- type: "string",
449
- enum: ["function"],
450
- },
451
- function: {
452
- type: "object",
453
- properties: {
454
- name: { type: "string" },
455
- description: { type: "string" },
456
- parameters: { type: "object" },
457
- returns: { type: "object" },
458
- },
459
- required: ["name", "description", "parameters"],
460
- },
461
- },
462
- required: ["type", "function"],
463
- },
464
- },
465
460
  },
466
-
467
461
  {
468
462
  type: "function",
469
463
  function: {
470
464
  name: "listAllCompletionModels",
471
- description: "List all available completion models using the knowhow ai client",
465
+ description:
466
+ "List all available completion models using the knowhow ai client",
472
467
  parameters: {
473
468
  type: "object",
474
469
  properties: {},
@@ -476,7 +471,8 @@ export const includedTools = [
476
471
  },
477
472
  returns: {
478
473
  type: "object",
479
- description: "A dictionary of all available completion models for each provider",
474
+ description:
475
+ "A dictionary of all available completion models for each provider",
480
476
  },
481
477
  },
482
478
  },
@@ -485,7 +481,8 @@ export const includedTools = [
485
481
  type: "function",
486
482
  function: {
487
483
  name: "listAllEmbeddingModels",
488
- description: "List all available embedding models using the knowhow ai client",
484
+ description:
485
+ "List all available embedding models using the knowhow ai client",
489
486
  parameters: {
490
487
  type: "object",
491
488
  properties: {},
@@ -493,7 +490,8 @@ export const includedTools = [
493
490
  },
494
491
  returns: {
495
492
  type: "object",
496
- description: "A dictionary of all available embedding models for each provider",
493
+ description:
494
+ "A dictionary of all available embedding models for each provider",
497
495
  },
498
496
  },
499
497
  },
@@ -645,6 +643,149 @@ export const includedTools = [
645
643
  executeScriptDefinition,
646
644
  googleSearchDefinition,
647
645
  startAgentTaskDefinition,
646
+ {
647
+ type: "function",
648
+ function: {
649
+ name: "astListPaths",
650
+ description:
651
+ "List all available simple paths in a file using tree-sitter AST parsing. Useful for understanding the structure of a file before making targeted edits.",
652
+ parameters: {
653
+ type: "object",
654
+ positional: true,
655
+ properties: {
656
+ filePath: {
657
+ type: "string",
658
+ description: "The path to the file to analyze",
659
+ },
660
+ },
661
+ required: ["filePath"],
662
+ },
663
+ returns: {
664
+ type: "string",
665
+ description:
666
+ "JSON object containing all available AST paths in the file",
667
+ },
668
+ },
669
+ },
670
+ {
671
+ type: "function",
672
+ function: {
673
+ name: "astEditNode",
674
+ description:
675
+ "Update a node at a specific AST path in a file using tree-sitter parsing. Use astListPaths first to find available paths.",
676
+ parameters: {
677
+ type: "object",
678
+ positional: true,
679
+ properties: {
680
+ filePath: {
681
+ type: "string",
682
+ description: "The path to the file to edit",
683
+ },
684
+ path: {
685
+ type: "string",
686
+ description:
687
+ "The AST path to the node to update (from astListPaths)",
688
+ },
689
+ newContent: {
690
+ type: "string",
691
+ description: "The new content to replace the node with",
692
+ },
693
+ },
694
+ required: ["filePath", "path", "newContent"],
695
+ },
696
+ returns: {
697
+ type: "string",
698
+ description: "JSON object with edit result and updated file content",
699
+ },
700
+ },
701
+ },
702
+ {
703
+ type: "function",
704
+ function: {
705
+ name: "astAppendNode",
706
+ description:
707
+ "Append a child node to a specific AST path in a file using tree-sitter parsing. Use astListPaths first to find available paths.",
708
+ parameters: {
709
+ type: "object",
710
+ positional: true,
711
+ properties: {
712
+ filePath: {
713
+ type: "string",
714
+ description: "The path to the file to edit",
715
+ },
716
+ parentPath: {
717
+ type: "string",
718
+ description: "The AST path to the parent node (from astListPaths)",
719
+ },
720
+ newContent: {
721
+ type: "string",
722
+ description: "The content of the child node to append",
723
+ },
724
+ },
725
+ required: ["filePath", "parentPath", "newContent"],
726
+ },
727
+ returns: {
728
+ type: "string",
729
+ description: "JSON object with append result and updated file content",
730
+ },
731
+ },
732
+ },
733
+ {
734
+ type: "function",
735
+ function: {
736
+ name: "astDeleteNode",
737
+ description:
738
+ "Delete a node at a specific AST path in a file using tree-sitter parsing. Use astListPaths first to find available paths.",
739
+ parameters: {
740
+ type: "object",
741
+ positional: true,
742
+ properties: {
743
+ filePath: {
744
+ type: "string",
745
+ description: "The path to the file to edit",
746
+ },
747
+ path: {
748
+ type: "string",
749
+ description:
750
+ "The AST path to the node to delete (from astListPaths)",
751
+ },
752
+ },
753
+ required: ["filePath", "path"],
754
+ },
755
+ returns: {
756
+ type: "string",
757
+ description: "JSON object with delete result and updated file content",
758
+ },
759
+ },
760
+ },
761
+ {
762
+ type: "function",
763
+ function: {
764
+ name: "astGetPathForLine",
765
+ description:
766
+ "Get the AST path for a specific line of text in a file using tree-sitter parsing. Useful for finding the structural location of specific code.",
767
+ parameters: {
768
+ type: "object",
769
+ positional: true,
770
+ properties: {
771
+ filePath: {
772
+ type: "string",
773
+ description: "The path to the file to analyze",
774
+ },
775
+ searchText: {
776
+ type: "string",
777
+ description: "The text to search for in the file",
778
+ },
779
+ },
780
+ required: ["filePath", "searchText"],
781
+ },
782
+ returns: {
783
+ type: "string",
784
+ description:
785
+ "JSON object containing AST paths and locations for the matching text",
786
+ },
787
+ },
788
+ },
648
789
  ...asana.definitions,
649
790
  ...ycmd.definitions,
650
791
  ...github.definitions,
@@ -9,7 +9,7 @@ import {
9
9
  mkdir,
10
10
  splitByNewLines,
11
11
  } from "../../utils"; // Assuming these utils exist
12
- import { lintFile } from "./lintFile"; // Assuming this exists
12
+ import { services, ToolsService } from "../../services";
13
13
 
14
14
  // --- Utility Functions (Keep or Simplify) ---
15
15
 
@@ -127,10 +127,10 @@ export function parseHunks(patch: string): Hunk[] {
127
127
  const hunks: Hunk[] = [];
128
128
  let currentHunkLines: string[] = [];
129
129
  let currentHeader = "";
130
- let originalStart = 0,
131
- originalCount = 0,
132
- newStart = 0,
133
- newCount = 0;
130
+ let originalStart = 0;
131
+ let originalCount = 0;
132
+ let newStart = 0;
133
+ let newCount = 0;
134
134
 
135
135
  for (const line of patchLines) {
136
136
  if (line.startsWith("@@")) {
@@ -540,6 +540,13 @@ export async function patchFile(
540
540
  filePath: string,
541
541
  patch: string
542
542
  ): Promise<string> {
543
+ // Get context from bound ToolsService
544
+ const toolService = (
545
+ this instanceof ToolsService ? this : services().Tools
546
+ ) as ToolsService;
547
+
548
+ const context = toolService.getContext();
549
+
543
550
  let originalContent = "";
544
551
  try {
545
552
  if (!fs.existsSync(filePath)) {
@@ -625,22 +632,49 @@ export async function patchFile(
625
632
  console.log("Successfully applied the original patch.");
626
633
  }
627
634
 
635
+ const eventResults: any[] = [];
636
+ // Emit pre-edit blocking event
637
+ if (context.Events) {
638
+ eventResults.push(
639
+ ...(await context.Events.emitBlocking("file:pre-edit", {
640
+ filePath,
641
+ operation: "patch",
642
+ patch: appliedPatch,
643
+ originalContent,
644
+ updatedContent: updatedContent as string,
645
+ }))
646
+ );
647
+ }
648
+
628
649
  // Write the updated content
629
650
  await writeFile(filePath, updatedContent as string); // Type assertion needed as applyPatch might return boolean
630
651
 
631
- // Optional: Lint the result
632
- let lintResult = "";
633
- try {
634
- lintResult = await lintFile(filePath);
635
- } catch (lintError: any) {
636
- console.warn("Linting failed after patching:", lintError);
637
- lintResult = `Linting after patch failed: ${lintError.message}`;
652
+ // Emit post-edit blocking event to get event results
653
+ if (context.Events) {
654
+ eventResults.push(
655
+ ...(await context.Events.emitBlocking("file:post-edit", {
656
+ filePath,
657
+ operation: "patch",
658
+ patch: appliedPatch,
659
+ originalContent,
660
+ updatedContent: updatedContent as string,
661
+ }))
662
+ );
663
+ }
664
+
665
+ // Format event results
666
+ let eventResultsText = "";
667
+ if (eventResults && eventResults.length > 0) {
668
+ if (eventResults.length > 0) {
669
+ eventResultsText =
670
+ "\n\nAdditional Information:\n" +
671
+ JSON.stringify(eventResults, null, 2);
672
+ }
638
673
  }
639
674
 
640
675
  return `Patch applied successfully.${
641
676
  filePath ? ` Use readFile on ${filePath} to verify changes.` : ""
642
- }
643
- ${lintResult ? "\nLinting Result:\n" + lintResult : ""}`.trim();
677
+ }${eventResultsText}`.trim();
644
678
  } catch (e: any) {
645
679
  console.error(`Error in patchFile function for ${filePath}:`, e);
646
680
  // Save error only if it's not a controlled failure path that already saved
@@ -1,4 +1,5 @@
1
1
  import * as fs from "fs";
2
+ import { services, ToolsService } from "../../services";
2
3
  import { FileBlock } from "./types/fileblock";
3
4
 
4
5
  const BLOCK_SIZE = 500;
@@ -6,6 +7,21 @@ export async function readBlocks(
6
7
  filePath: string,
7
8
  blockNumbers: number[] = []
8
9
  ) {
10
+ // Get context from bound ToolsService
11
+ const toolService = (
12
+ this instanceof ToolsService ? this : services().Tools
13
+ ) as ToolsService;
14
+
15
+ const context = toolService.getContext();
16
+
17
+ // Emit pre-read blocking event
18
+ if (context.Events) {
19
+ await context.Events.emitBlocking("file:pre-read", {
20
+ filePath,
21
+ blockNumbers,
22
+ });
23
+ }
24
+
9
25
  const text = fs.readFileSync(filePath, "utf8");
10
26
 
11
27
  const lines = text.split("");
@@ -34,6 +50,15 @@ export async function readBlocks(
34
50
  }
35
51
 
36
52
  if (blockNumbers.length === 0) {
53
+ // Emit post-read non-blocking event
54
+ if (context.Events) {
55
+ await context.Events.emitNonBlocking("file:post-read", {
56
+ filePath,
57
+ blockNumbers,
58
+ content: blocks.map((block) => block.content).join(""),
59
+ });
60
+ }
61
+
37
62
  return blocks;
38
63
  }
39
64
 
@@ -45,5 +70,14 @@ export async function readBlocks(
45
70
  return blocks;
46
71
  }
47
72
 
73
+ // Emit post-read non-blocking event
74
+ if (context.Events) {
75
+ await context.Events.emitNonBlocking("file:post-read", {
76
+ filePath,
77
+ blockNumbers,
78
+ content: filtered.map((block) => block.content).join(""),
79
+ });
80
+ }
81
+
48
82
  return filtered;
49
83
  }
@@ -1,5 +1,6 @@
1
1
  import * as fs from "fs";
2
2
  import { fileExists } from "../../utils";
3
+ import { services, ToolsService } from "../../services";
3
4
  import { getConfiguredEmbeddings } from "../../embeddings";
4
5
  import { fileSearch } from "./fileSearch";
5
6
  import { createPatch } from "diff";
@@ -18,6 +19,20 @@ import { createPatch } from "diff";
18
19
  */
19
20
 
20
21
  export async function readFile(filePath: string): Promise<string> {
22
+ // Get context from bound ToolsService
23
+ const toolService = (
24
+ this instanceof ToolsService ? this : services().Tools
25
+ ) as ToolsService;
26
+
27
+ const context = toolService.getContext();
28
+
29
+ // Emit pre-read blocking event
30
+ if (context.Events) {
31
+ await context.Events.emitBlocking("file:pre-read", {
32
+ filePath,
33
+ });
34
+ }
35
+
21
36
  const exists = await fileExists(filePath);
22
37
 
23
38
  if (!exists) {
@@ -35,5 +50,13 @@ export async function readFile(filePath: string): Promise<string> {
35
50
  const text = fs.readFileSync(filePath, "utf8");
36
51
  const patch = createPatch(filePath, "", text);
37
52
 
53
+ // Emit post-read non-blocking event
54
+ if (context.Events) {
55
+ await context.Events.emitNonBlocking("file:post-read", {
56
+ filePath,
57
+ content: text,
58
+ });
59
+ }
60
+
38
61
  return patch;
39
62
  }
@@ -1,4 +1,6 @@
1
1
  import * as fs from "fs";
2
+ import { embed } from "../../";
3
+ import { lintFile } from ".";
2
4
  import { fileExists } from "../../utils";
3
5
 
4
6
  export async function stringReplace(
@@ -6,8 +8,15 @@ export async function stringReplace(
6
8
  replaceString: string,
7
9
  filePaths: string[]
8
10
  ): Promise<string> {
9
- if (!findString || replaceString === undefined || !filePaths || filePaths.length === 0) {
10
- throw new Error("findString, replaceString, and filePaths are all required parameters");
11
+ if (
12
+ !findString ||
13
+ replaceString === undefined ||
14
+ !filePaths ||
15
+ filePaths.length === 0
16
+ ) {
17
+ throw new Error(
18
+ "findString, replaceString, and filePaths are all required parameters"
19
+ );
11
20
  }
12
21
 
13
22
  const results: string[] = [];
@@ -23,24 +32,39 @@ export async function stringReplace(
23
32
 
24
33
  const content = fs.readFileSync(filePath, "utf8");
25
34
  const originalContent = content;
26
-
35
+
27
36
  // Count occurrences before replacement
28
37
  const matches = content.split(findString).length - 1;
29
-
38
+
30
39
  if (matches === 0) {
31
40
  results.push(`ℹ️ No matches found in: ${filePath}`);
32
41
  continue;
33
42
  }
34
43
 
35
44
  // Perform the replacement
36
- const newContent = content.replace(new RegExp(findString.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), replaceString);
37
-
45
+ const newContent = content.replace(
46
+ new RegExp(findString.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"),
47
+ replaceString
48
+ );
49
+
38
50
  // Write the modified content back to the file
39
51
  fs.writeFileSync(filePath, newContent);
40
-
52
+
41
53
  totalReplacements += matches;
42
54
  results.push(`✅ Replaced ${matches} occurrence(s) in: ${filePath}`);
43
-
55
+
56
+ let lintResult = "";
57
+ try {
58
+ lintResult = await lintFile(filePath);
59
+ if (lintResult) {
60
+ results.push(`$Linting Result:\n" + ${lintResult}`);
61
+ }
62
+ } catch (lintError: any) {
63
+ console.warn("Linting failed after patching:", lintError);
64
+ lintResult = `Linting after patch failed: ${lintError.message}`;
65
+ }
66
+
67
+ await embed();
44
68
  } catch (error) {
45
69
  results.push(`❌ Error processing ${filePath}: ${error.message}`);
46
70
  }
@@ -48,4 +72,4 @@ export async function stringReplace(
48
72
 
49
73
  const summary = `\n📊 Summary: ${totalReplacements} total replacements made across ${filePaths.length} file(s)`;
50
74
  return results.join("\n") + summary;
51
- }
75
+ }