@nexus-cortex/executors 4.26.0

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 (365) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +2 -0
  3. package/README.md +13 -0
  4. package/dist/ExecutorRegistry.d.ts +89 -0
  5. package/dist/ExecutorRegistry.d.ts.map +1 -0
  6. package/dist/ExecutorRegistry.js +219 -0
  7. package/dist/ExecutorRegistry.js.map +1 -0
  8. package/dist/base/BaseTool.d.ts +108 -0
  9. package/dist/base/BaseTool.d.ts.map +1 -0
  10. package/dist/base/BaseTool.js +111 -0
  11. package/dist/base/BaseTool.js.map +1 -0
  12. package/dist/base/ToolRegistry.d.ts +141 -0
  13. package/dist/base/ToolRegistry.d.ts.map +1 -0
  14. package/dist/base/ToolRegistry.js +241 -0
  15. package/dist/base/ToolRegistry.js.map +1 -0
  16. package/dist/base/ToolResult.d.ts +63 -0
  17. package/dist/base/ToolResult.d.ts.map +1 -0
  18. package/dist/base/ToolResult.js +8 -0
  19. package/dist/base/ToolResult.js.map +1 -0
  20. package/dist/base/index.d.ts +10 -0
  21. package/dist/base/index.d.ts.map +1 -0
  22. package/dist/base/index.js +8 -0
  23. package/dist/base/index.js.map +1 -0
  24. package/dist/implementations/addon/CreateArtifactTool.d.ts +221 -0
  25. package/dist/implementations/addon/CreateArtifactTool.d.ts.map +1 -0
  26. package/dist/implementations/addon/CreateArtifactTool.js +1042 -0
  27. package/dist/implementations/addon/CreateArtifactTool.js.map +1 -0
  28. package/dist/implementations/addon/FrameDiffCache.d.ts +166 -0
  29. package/dist/implementations/addon/FrameDiffCache.d.ts.map +1 -0
  30. package/dist/implementations/addon/FrameDiffCache.js +395 -0
  31. package/dist/implementations/addon/FrameDiffCache.js.map +1 -0
  32. package/dist/implementations/addon/H264StreamEncoder.d.ts +84 -0
  33. package/dist/implementations/addon/H264StreamEncoder.d.ts.map +1 -0
  34. package/dist/implementations/addon/H264StreamEncoder.js +203 -0
  35. package/dist/implementations/addon/H264StreamEncoder.js.map +1 -0
  36. package/dist/implementations/addon/HybridScreenshotManager.d.ts +197 -0
  37. package/dist/implementations/addon/HybridScreenshotManager.d.ts.map +1 -0
  38. package/dist/implementations/addon/HybridScreenshotManager.js +415 -0
  39. package/dist/implementations/addon/HybridScreenshotManager.js.map +1 -0
  40. package/dist/implementations/addon/InspectSandboxTool.d.ts +54 -0
  41. package/dist/implementations/addon/InspectSandboxTool.d.ts.map +1 -0
  42. package/dist/implementations/addon/InspectSandboxTool.js +226 -0
  43. package/dist/implementations/addon/InspectSandboxTool.js.map +1 -0
  44. package/dist/implementations/addon/InteractWithSandboxTool.d.ts +90 -0
  45. package/dist/implementations/addon/InteractWithSandboxTool.d.ts.map +1 -0
  46. package/dist/implementations/addon/InteractWithSandboxTool.js +367 -0
  47. package/dist/implementations/addon/InteractWithSandboxTool.js.map +1 -0
  48. package/dist/implementations/addon/KeyframeDetector.d.ts +140 -0
  49. package/dist/implementations/addon/KeyframeDetector.d.ts.map +1 -0
  50. package/dist/implementations/addon/KeyframeDetector.js +390 -0
  51. package/dist/implementations/addon/KeyframeDetector.js.map +1 -0
  52. package/dist/implementations/addon/ModifySandboxTool.d.ts +62 -0
  53. package/dist/implementations/addon/ModifySandboxTool.d.ts.map +1 -0
  54. package/dist/implementations/addon/ModifySandboxTool.js +266 -0
  55. package/dist/implementations/addon/ModifySandboxTool.js.map +1 -0
  56. package/dist/implementations/addon/ReactArtifactBuilder.d.ts +27 -0
  57. package/dist/implementations/addon/ReactArtifactBuilder.d.ts.map +1 -0
  58. package/dist/implementations/addon/ReactArtifactBuilder.js +198 -0
  59. package/dist/implementations/addon/ReactArtifactBuilder.js.map +1 -0
  60. package/dist/implementations/addon/SandboxEventBroadcaster.d.ts +143 -0
  61. package/dist/implementations/addon/SandboxEventBroadcaster.d.ts.map +1 -0
  62. package/dist/implementations/addon/SandboxEventBroadcaster.js +258 -0
  63. package/dist/implementations/addon/SandboxEventBroadcaster.js.map +1 -0
  64. package/dist/implementations/addon/SandboxIntrospectionTools.d.ts +77 -0
  65. package/dist/implementations/addon/SandboxIntrospectionTools.d.ts.map +1 -0
  66. package/dist/implementations/addon/SandboxIntrospectionTools.js +292 -0
  67. package/dist/implementations/addon/SandboxIntrospectionTools.js.map +1 -0
  68. package/dist/implementations/addon/SandboxViewServer.d.ts +127 -0
  69. package/dist/implementations/addon/SandboxViewServer.d.ts.map +1 -0
  70. package/dist/implementations/addon/SandboxViewServer.js +775 -0
  71. package/dist/implementations/addon/SandboxViewServer.js.map +1 -0
  72. package/dist/implementations/addon/ScreenStream.d.ts +149 -0
  73. package/dist/implementations/addon/ScreenStream.d.ts.map +1 -0
  74. package/dist/implementations/addon/ScreenStream.js +306 -0
  75. package/dist/implementations/addon/ScreenStream.js.map +1 -0
  76. package/dist/implementations/addon/StopSandboxTool.d.ts +61 -0
  77. package/dist/implementations/addon/StopSandboxTool.d.ts.map +1 -0
  78. package/dist/implementations/addon/StopSandboxTool.js +252 -0
  79. package/dist/implementations/addon/StopSandboxTool.js.map +1 -0
  80. package/dist/implementations/addon/TerminalSandbox.d.ts +111 -0
  81. package/dist/implementations/addon/TerminalSandbox.d.ts.map +1 -0
  82. package/dist/implementations/addon/TerminalSandbox.js +345 -0
  83. package/dist/implementations/addon/TerminalSandbox.js.map +1 -0
  84. package/dist/implementations/addon/VisualFeedbackBridge.d.ts +367 -0
  85. package/dist/implementations/addon/VisualFeedbackBridge.d.ts.map +1 -0
  86. package/dist/implementations/addon/VisualFeedbackBridge.js +888 -0
  87. package/dist/implementations/addon/VisualFeedbackBridge.js.map +1 -0
  88. package/dist/implementations/addon/WindowManager.d.ts +138 -0
  89. package/dist/implementations/addon/WindowManager.d.ts.map +1 -0
  90. package/dist/implementations/addon/WindowManager.js +276 -0
  91. package/dist/implementations/addon/WindowManager.js.map +1 -0
  92. package/dist/implementations/addon/index.d.ts +29 -0
  93. package/dist/implementations/addon/index.d.ts.map +1 -0
  94. package/dist/implementations/addon/index.js +29 -0
  95. package/dist/implementations/addon/index.js.map +1 -0
  96. package/dist/implementations/addon/injectables/reactIntrospection.d.ts +57 -0
  97. package/dist/implementations/addon/injectables/reactIntrospection.d.ts.map +1 -0
  98. package/dist/implementations/addon/injectables/reactIntrospection.js +480 -0
  99. package/dist/implementations/addon/injectables/reactIntrospection.js.map +1 -0
  100. package/dist/implementations/addon/terminal-client.html +253 -0
  101. package/dist/implementations/agent/PRAgentTool.d.ts +37 -0
  102. package/dist/implementations/agent/PRAgentTool.d.ts.map +1 -0
  103. package/dist/implementations/agent/PRAgentTool.js +257 -0
  104. package/dist/implementations/agent/PRAgentTool.js.map +1 -0
  105. package/dist/implementations/agent/TaskTool.d.ts +76 -0
  106. package/dist/implementations/agent/TaskTool.d.ts.map +1 -0
  107. package/dist/implementations/agent/TaskTool.js +424 -0
  108. package/dist/implementations/agent/TaskTool.js.map +1 -0
  109. package/dist/implementations/agent/index.d.ts +5 -0
  110. package/dist/implementations/agent/index.d.ts.map +1 -0
  111. package/dist/implementations/agent/index.js +3 -0
  112. package/dist/implementations/agent/index.js.map +1 -0
  113. package/dist/implementations/execution/BackgroundProcessRegistry.d.ts +68 -0
  114. package/dist/implementations/execution/BackgroundProcessRegistry.d.ts.map +1 -0
  115. package/dist/implementations/execution/BackgroundProcessRegistry.js +146 -0
  116. package/dist/implementations/execution/BackgroundProcessRegistry.js.map +1 -0
  117. package/dist/implementations/execution/BashOutputTool.d.ts +42 -0
  118. package/dist/implementations/execution/BashOutputTool.d.ts.map +1 -0
  119. package/dist/implementations/execution/BashOutputTool.js +168 -0
  120. package/dist/implementations/execution/BashOutputTool.js.map +1 -0
  121. package/dist/implementations/execution/CodeExecuteTool.d.ts +31 -0
  122. package/dist/implementations/execution/CodeExecuteTool.d.ts.map +1 -0
  123. package/dist/implementations/execution/CodeExecuteTool.js +127 -0
  124. package/dist/implementations/execution/CodeExecuteTool.js.map +1 -0
  125. package/dist/implementations/execution/KillShellTool.d.ts +37 -0
  126. package/dist/implementations/execution/KillShellTool.d.ts.map +1 -0
  127. package/dist/implementations/execution/KillShellTool.js +144 -0
  128. package/dist/implementations/execution/KillShellTool.js.map +1 -0
  129. package/dist/implementations/execution/SearchToolsTool.d.ts +32 -0
  130. package/dist/implementations/execution/SearchToolsTool.d.ts.map +1 -0
  131. package/dist/implementations/execution/SearchToolsTool.js +109 -0
  132. package/dist/implementations/execution/SearchToolsTool.js.map +1 -0
  133. package/dist/implementations/execution/ShellTool.d.ts +108 -0
  134. package/dist/implementations/execution/ShellTool.d.ts.map +1 -0
  135. package/dist/implementations/execution/ShellTool.js +546 -0
  136. package/dist/implementations/execution/ShellTool.js.map +1 -0
  137. package/dist/implementations/execution/WorkspaceManagerTool.d.ts +40 -0
  138. package/dist/implementations/execution/WorkspaceManagerTool.d.ts.map +1 -0
  139. package/dist/implementations/execution/WorkspaceManagerTool.js +370 -0
  140. package/dist/implementations/execution/WorkspaceManagerTool.js.map +1 -0
  141. package/dist/implementations/execution/index.d.ts +13 -0
  142. package/dist/implementations/execution/index.d.ts.map +1 -0
  143. package/dist/implementations/execution/index.js +13 -0
  144. package/dist/implementations/execution/index.js.map +1 -0
  145. package/dist/implementations/extensions/EndTurnTool.d.ts +62 -0
  146. package/dist/implementations/extensions/EndTurnTool.d.ts.map +1 -0
  147. package/dist/implementations/extensions/EndTurnTool.js +172 -0
  148. package/dist/implementations/extensions/EndTurnTool.js.map +1 -0
  149. package/dist/implementations/extensions/ResearchBacklogTool.d.ts +37 -0
  150. package/dist/implementations/extensions/ResearchBacklogTool.d.ts.map +1 -0
  151. package/dist/implementations/extensions/ResearchBacklogTool.js +102 -0
  152. package/dist/implementations/extensions/ResearchBacklogTool.js.map +1 -0
  153. package/dist/implementations/extensions/SkillTool.d.ts +108 -0
  154. package/dist/implementations/extensions/SkillTool.d.ts.map +1 -0
  155. package/dist/implementations/extensions/SkillTool.js +351 -0
  156. package/dist/implementations/extensions/SkillTool.js.map +1 -0
  157. package/dist/implementations/extensions/SlashCommandTool.d.ts +112 -0
  158. package/dist/implementations/extensions/SlashCommandTool.d.ts.map +1 -0
  159. package/dist/implementations/extensions/SlashCommandTool.js +315 -0
  160. package/dist/implementations/extensions/SlashCommandTool.js.map +1 -0
  161. package/dist/implementations/extensions/index.d.ts +14 -0
  162. package/dist/implementations/extensions/index.d.ts.map +1 -0
  163. package/dist/implementations/extensions/index.js +10 -0
  164. package/dist/implementations/extensions/index.js.map +1 -0
  165. package/dist/implementations/file/EditTool.d.ts +232 -0
  166. package/dist/implementations/file/EditTool.d.ts.map +1 -0
  167. package/dist/implementations/file/EditTool.js +707 -0
  168. package/dist/implementations/file/EditTool.js.map +1 -0
  169. package/dist/implementations/file/ReadFileTool.d.ts +49 -0
  170. package/dist/implementations/file/ReadFileTool.d.ts.map +1 -0
  171. package/dist/implementations/file/ReadFileTool.js +225 -0
  172. package/dist/implementations/file/ReadFileTool.js.map +1 -0
  173. package/dist/implementations/file/WriteBinaryTool.d.ts +21 -0
  174. package/dist/implementations/file/WriteBinaryTool.d.ts.map +1 -0
  175. package/dist/implementations/file/WriteBinaryTool.js +153 -0
  176. package/dist/implementations/file/WriteBinaryTool.js.map +1 -0
  177. package/dist/implementations/file/WriteFileTool.d.ts +41 -0
  178. package/dist/implementations/file/WriteFileTool.d.ts.map +1 -0
  179. package/dist/implementations/file/WriteFileTool.js +220 -0
  180. package/dist/implementations/file/WriteFileTool.js.map +1 -0
  181. package/dist/implementations/file/index.d.ts +8 -0
  182. package/dist/implementations/file/index.d.ts.map +1 -0
  183. package/dist/implementations/file/index.js +8 -0
  184. package/dist/implementations/file/index.js.map +1 -0
  185. package/dist/implementations/historical/GetConversationSegmentTool.d.ts +44 -0
  186. package/dist/implementations/historical/GetConversationSegmentTool.d.ts.map +1 -0
  187. package/dist/implementations/historical/GetConversationSegmentTool.js +220 -0
  188. package/dist/implementations/historical/GetConversationSegmentTool.js.map +1 -0
  189. package/dist/implementations/historical/ListCompactionBoundariesTool.d.ts +36 -0
  190. package/dist/implementations/historical/ListCompactionBoundariesTool.d.ts.map +1 -0
  191. package/dist/implementations/historical/ListCompactionBoundariesTool.js +174 -0
  192. package/dist/implementations/historical/ListCompactionBoundariesTool.js.map +1 -0
  193. package/dist/implementations/historical/ListSessionsTool.d.ts +38 -0
  194. package/dist/implementations/historical/ListSessionsTool.d.ts.map +1 -0
  195. package/dist/implementations/historical/ListSessionsTool.js +140 -0
  196. package/dist/implementations/historical/ListSessionsTool.js.map +1 -0
  197. package/dist/implementations/historical/LoadSessionTool.d.ts +39 -0
  198. package/dist/implementations/historical/LoadSessionTool.d.ts.map +1 -0
  199. package/dist/implementations/historical/LoadSessionTool.js +171 -0
  200. package/dist/implementations/historical/LoadSessionTool.js.map +1 -0
  201. package/dist/implementations/historical/RequestHistoricalContextTool.d.ts +46 -0
  202. package/dist/implementations/historical/RequestHistoricalContextTool.d.ts.map +1 -0
  203. package/dist/implementations/historical/RequestHistoricalContextTool.js +224 -0
  204. package/dist/implementations/historical/RequestHistoricalContextTool.js.map +1 -0
  205. package/dist/implementations/historical/SearchConversationHistoryTool.d.ts +51 -0
  206. package/dist/implementations/historical/SearchConversationHistoryTool.d.ts.map +1 -0
  207. package/dist/implementations/historical/SearchConversationHistoryTool.js +306 -0
  208. package/dist/implementations/historical/SearchConversationHistoryTool.js.map +1 -0
  209. package/dist/implementations/historical/index.d.ts +12 -0
  210. package/dist/implementations/historical/index.d.ts.map +1 -0
  211. package/dist/implementations/historical/index.js +12 -0
  212. package/dist/implementations/historical/index.js.map +1 -0
  213. package/dist/implementations/index.d.ts +16 -0
  214. package/dist/implementations/index.d.ts.map +1 -0
  215. package/dist/implementations/index.js +28 -0
  216. package/dist/implementations/index.js.map +1 -0
  217. package/dist/implementations/mcp/DiscoveredMcpTool.d.ts +58 -0
  218. package/dist/implementations/mcp/DiscoveredMcpTool.d.ts.map +1 -0
  219. package/dist/implementations/mcp/DiscoveredMcpTool.js +269 -0
  220. package/dist/implementations/mcp/DiscoveredMcpTool.js.map +1 -0
  221. package/dist/implementations/mcp/index.d.ts +9 -0
  222. package/dist/implementations/mcp/index.d.ts.map +1 -0
  223. package/dist/implementations/mcp/index.js +8 -0
  224. package/dist/implementations/mcp/index.js.map +1 -0
  225. package/dist/implementations/notebook/NotebookEditTool.d.ts +96 -0
  226. package/dist/implementations/notebook/NotebookEditTool.d.ts.map +1 -0
  227. package/dist/implementations/notebook/NotebookEditTool.js +390 -0
  228. package/dist/implementations/notebook/NotebookEditTool.js.map +1 -0
  229. package/dist/implementations/notebook/index.d.ts +7 -0
  230. package/dist/implementations/notebook/index.d.ts.map +1 -0
  231. package/dist/implementations/notebook/index.js +7 -0
  232. package/dist/implementations/notebook/index.js.map +1 -0
  233. package/dist/implementations/search/GlobTool.d.ts +73 -0
  234. package/dist/implementations/search/GlobTool.d.ts.map +1 -0
  235. package/dist/implementations/search/GlobTool.js +213 -0
  236. package/dist/implementations/search/GlobTool.js.map +1 -0
  237. package/dist/implementations/search/GrepTool.d.ts +102 -0
  238. package/dist/implementations/search/GrepTool.d.ts.map +1 -0
  239. package/dist/implementations/search/GrepTool.js +754 -0
  240. package/dist/implementations/search/GrepTool.js.map +1 -0
  241. package/dist/implementations/search/index.d.ts +6 -0
  242. package/dist/implementations/search/index.d.ts.map +1 -0
  243. package/dist/implementations/search/index.js +6 -0
  244. package/dist/implementations/search/index.js.map +1 -0
  245. package/dist/implementations/tmux/TmuxSessionTool.d.ts +82 -0
  246. package/dist/implementations/tmux/TmuxSessionTool.d.ts.map +1 -0
  247. package/dist/implementations/tmux/TmuxSessionTool.js +371 -0
  248. package/dist/implementations/tmux/TmuxSessionTool.js.map +1 -0
  249. package/dist/implementations/tmux/TmuxViewServer.d.ts +86 -0
  250. package/dist/implementations/tmux/TmuxViewServer.d.ts.map +1 -0
  251. package/dist/implementations/tmux/TmuxViewServer.js +480 -0
  252. package/dist/implementations/tmux/TmuxViewServer.js.map +1 -0
  253. package/dist/implementations/tmux/index.d.ts +6 -0
  254. package/dist/implementations/tmux/index.d.ts.map +1 -0
  255. package/dist/implementations/tmux/index.js +6 -0
  256. package/dist/implementations/tmux/index.js.map +1 -0
  257. package/dist/implementations/ui/AskUserQuestionTool.d.ts +77 -0
  258. package/dist/implementations/ui/AskUserQuestionTool.d.ts.map +1 -0
  259. package/dist/implementations/ui/AskUserQuestionTool.js +241 -0
  260. package/dist/implementations/ui/AskUserQuestionTool.js.map +1 -0
  261. package/dist/implementations/ui/ExitPlanModeTool.d.ts +44 -0
  262. package/dist/implementations/ui/ExitPlanModeTool.d.ts.map +1 -0
  263. package/dist/implementations/ui/ExitPlanModeTool.js +150 -0
  264. package/dist/implementations/ui/ExitPlanModeTool.js.map +1 -0
  265. package/dist/implementations/ui/TodoWriteTool.d.ts +59 -0
  266. package/dist/implementations/ui/TodoWriteTool.d.ts.map +1 -0
  267. package/dist/implementations/ui/TodoWriteTool.js +315 -0
  268. package/dist/implementations/ui/TodoWriteTool.js.map +1 -0
  269. package/dist/implementations/ui/index.d.ts +9 -0
  270. package/dist/implementations/ui/index.d.ts.map +1 -0
  271. package/dist/implementations/ui/index.js +9 -0
  272. package/dist/implementations/ui/index.js.map +1 -0
  273. package/dist/implementations/web/BrowseTool.d.ts +43 -0
  274. package/dist/implementations/web/BrowseTool.d.ts.map +1 -0
  275. package/dist/implementations/web/BrowseTool.js +181 -0
  276. package/dist/implementations/web/BrowseTool.js.map +1 -0
  277. package/dist/implementations/web/SandboxTransferTool.d.ts +30 -0
  278. package/dist/implementations/web/SandboxTransferTool.d.ts.map +1 -0
  279. package/dist/implementations/web/SandboxTransferTool.js +261 -0
  280. package/dist/implementations/web/SandboxTransferTool.js.map +1 -0
  281. package/dist/implementations/web/WebFetchTool.d.ts +93 -0
  282. package/dist/implementations/web/WebFetchTool.d.ts.map +1 -0
  283. package/dist/implementations/web/WebFetchTool.js +484 -0
  284. package/dist/implementations/web/WebFetchTool.js.map +1 -0
  285. package/dist/implementations/web/WebSearchTool.d.ts +53 -0
  286. package/dist/implementations/web/WebSearchTool.d.ts.map +1 -0
  287. package/dist/implementations/web/WebSearchTool.js +227 -0
  288. package/dist/implementations/web/WebSearchTool.js.map +1 -0
  289. package/dist/implementations/web/escalateDirective.d.ts +11 -0
  290. package/dist/implementations/web/escalateDirective.d.ts.map +1 -0
  291. package/dist/implementations/web/escalateDirective.js +20 -0
  292. package/dist/implementations/web/escalateDirective.js.map +1 -0
  293. package/dist/implementations/web/index.d.ts +10 -0
  294. package/dist/implementations/web/index.d.ts.map +1 -0
  295. package/dist/implementations/web/index.js +10 -0
  296. package/dist/implementations/web/index.js.map +1 -0
  297. package/dist/implementations/web/webBackends.d.ts +65 -0
  298. package/dist/implementations/web/webBackends.d.ts.map +1 -0
  299. package/dist/implementations/web/webBackends.js +430 -0
  300. package/dist/implementations/web/webBackends.js.map +1 -0
  301. package/dist/implementations/web/webFetchRequestInit.d.ts +9 -0
  302. package/dist/implementations/web/webFetchRequestInit.d.ts.map +1 -0
  303. package/dist/implementations/web/webFetchRequestInit.js +21 -0
  304. package/dist/implementations/web/webFetchRequestInit.js.map +1 -0
  305. package/dist/index.d.ts +14 -0
  306. package/dist/index.d.ts.map +1 -0
  307. package/dist/index.js +18 -0
  308. package/dist/index.js.map +1 -0
  309. package/dist/utils/ArtifactRegistry.d.ts +138 -0
  310. package/dist/utils/ArtifactRegistry.d.ts.map +1 -0
  311. package/dist/utils/ArtifactRegistry.js +259 -0
  312. package/dist/utils/ArtifactRegistry.js.map +1 -0
  313. package/dist/utils/ChromiumBrowserManager.d.ts +56 -0
  314. package/dist/utils/ChromiumBrowserManager.d.ts.map +1 -0
  315. package/dist/utils/ChromiumBrowserManager.js +243 -0
  316. package/dist/utils/ChromiumBrowserManager.js.map +1 -0
  317. package/dist/utils/FileUtils.d.ts +81 -0
  318. package/dist/utils/FileUtils.d.ts.map +1 -0
  319. package/dist/utils/FileUtils.js +148 -0
  320. package/dist/utils/FileUtils.js.map +1 -0
  321. package/dist/utils/GitPolicy.d.ts +70 -0
  322. package/dist/utils/GitPolicy.d.ts.map +1 -0
  323. package/dist/utils/GitPolicy.js +166 -0
  324. package/dist/utils/GitPolicy.js.map +1 -0
  325. package/dist/utils/GitUtils.d.ts +18 -0
  326. package/dist/utils/GitUtils.d.ts.map +1 -0
  327. package/dist/utils/GitUtils.js +62 -0
  328. package/dist/utils/GitUtils.js.map +1 -0
  329. package/dist/utils/SandboxRegistry.d.ts +110 -0
  330. package/dist/utils/SandboxRegistry.d.ts.map +1 -0
  331. package/dist/utils/SandboxRegistry.js +220 -0
  332. package/dist/utils/SandboxRegistry.js.map +1 -0
  333. package/dist/utils/SchemaValidator.d.ts +21 -0
  334. package/dist/utils/SchemaValidator.d.ts.map +1 -0
  335. package/dist/utils/SchemaValidator.js +67 -0
  336. package/dist/utils/SchemaValidator.js.map +1 -0
  337. package/dist/utils/SessionLock.d.ts +96 -0
  338. package/dist/utils/SessionLock.d.ts.map +1 -0
  339. package/dist/utils/SessionLock.js +276 -0
  340. package/dist/utils/SessionLock.js.map +1 -0
  341. package/dist/utils/SessionPersistence.d.ts +89 -0
  342. package/dist/utils/SessionPersistence.d.ts.map +1 -0
  343. package/dist/utils/SessionPersistence.js +244 -0
  344. package/dist/utils/SessionPersistence.js.map +1 -0
  345. package/dist/utils/TextUtils.d.ts +77 -0
  346. package/dist/utils/TextUtils.d.ts.map +1 -0
  347. package/dist/utils/TextUtils.js +112 -0
  348. package/dist/utils/TextUtils.js.map +1 -0
  349. package/dist/utils/TmuxCapture.d.ts +94 -0
  350. package/dist/utils/TmuxCapture.d.ts.map +1 -0
  351. package/dist/utils/TmuxCapture.js +131 -0
  352. package/dist/utils/TmuxCapture.js.map +1 -0
  353. package/dist/utils/TmuxManager.d.ts +65 -0
  354. package/dist/utils/TmuxManager.d.ts.map +1 -0
  355. package/dist/utils/TmuxManager.js +304 -0
  356. package/dist/utils/TmuxManager.js.map +1 -0
  357. package/dist/utils/autoResearchPlanGate.d.ts +10 -0
  358. package/dist/utils/autoResearchPlanGate.d.ts.map +1 -0
  359. package/dist/utils/autoResearchPlanGate.js +57 -0
  360. package/dist/utils/autoResearchPlanGate.js.map +1 -0
  361. package/dist/utils/index.d.ts +19 -0
  362. package/dist/utils/index.d.ts.map +1 -0
  363. package/dist/utils/index.js +13 -0
  364. package/dist/utils/index.js.map +1 -0
  365. package/package.json +83 -0
@@ -0,0 +1,754 @@
1
+ /**
2
+ * Enhanced Grep Tool Executor with Native Command Support
3
+ *
4
+ * Implements a 4-tier fallback strategy for optimal performance:
5
+ * 1. ripgrep (rg) - Fastest (0.5-1s)
6
+ * 2. git grep - ⚡ Fast (1-2s, git repos only)
7
+ * 3. system grep - Good (2-5s)
8
+ * 4. JavaScript fallback - Portable (5-10s)
9
+ *
10
+ * Gracefully falls back if native commands are not available.
11
+ */
12
+ import fs from 'fs/promises';
13
+ import * as fsSync from 'fs';
14
+ import path from 'path';
15
+ import { EOL } from 'os';
16
+ import { spawn } from 'child_process';
17
+ import { globStream } from 'glob';
18
+ import { BaseTool } from '../../base/index.js';
19
+ import { SchemaValidator } from '../../utils/SchemaValidator.js';
20
+ import { makeRelative, shortenPath, } from '../../utils/FileUtils.js';
21
+ import { isGitRepository } from '../../utils/GitUtils.js';
22
+ /**
23
+ * Enhanced Grep Tool with Native Command Support
24
+ */
25
+ export class GrepTool extends BaseTool {
26
+ config;
27
+ static DEFAULT_MAX_RESULTS = 100; // Default limit for context efficiency
28
+ static HARD_MAX_RESULTS = 500; // Absolute maximum to prevent context overflow
29
+ static MAX_CONTENT_LENGTH = 30000; // ~30KB max output
30
+ // JS-fallback only: skip files above this size. Reading them into a single string
31
+ // throws "Invalid string length" once they exceed V8's ~512MB cap (e.g. the grok
32
+ // CLI's .grok/upload_queue git-diff blobs), and grepping a huge minified/blob file
33
+ // is never useful anyway. rg/grep handle large files natively; this guards Strategy 4.
34
+ static MAX_SEARCHABLE_FILE_BYTES = 20 * 1024 * 1024; // 20MB
35
+ constructor(config) {
36
+ super('Grep', 'SearchText', `Searches for a regular expression pattern within the content of files. Uses ripgrep, git grep, or system grep for optimal performance, with automatic fallback to JavaScript implementation.`, {
37
+ type: 'object',
38
+ properties: {
39
+ pattern: {
40
+ type: 'string',
41
+ description: "The regular expression pattern to search for (e.g., 'function\\\\s+myFunction').",
42
+ },
43
+ path: {
44
+ type: 'string',
45
+ description: 'Optional: File or directory to search within. For single-file searches, provide exact file path. For directory searches, all files will be scanned. Defaults to working directory.',
46
+ },
47
+ include: {
48
+ type: 'string',
49
+ description: "Optional: Glob pattern to filter files (e.g., '*.js', '**/*.{ts,tsx}').",
50
+ },
51
+ case_sensitive: {
52
+ type: 'boolean',
53
+ description: 'Optional: Case-sensitive search. Defaults to false.',
54
+ },
55
+ },
56
+ required: ['pattern'],
57
+ });
58
+ this.config = config;
59
+ }
60
+ validateToolParams(params) {
61
+ const schemaError = SchemaValidator.validate(this.parameterSchema, params);
62
+ if (schemaError) {
63
+ return schemaError;
64
+ }
65
+ // Validate regex pattern
66
+ try {
67
+ new RegExp(params.pattern);
68
+ }
69
+ catch (error) {
70
+ return `Invalid regular expression: ${params.pattern}. Error: ${error.message}`;
71
+ }
72
+ // Validate path (can be file or directory)
73
+ const searchPathAbsolute = path.resolve(this.config.workingDirectory, params.path || '.');
74
+ // Path validation: allow any absolute path (matching standard absolute-path behavior),
75
+ // but reject root "/" to prevent full-filesystem scans that hang tool execution.
76
+ if (!path.isAbsolute(searchPathAbsolute)) {
77
+ return `Search path must resolve to an absolute path: ${searchPathAbsolute}`;
78
+ }
79
+ if (searchPathAbsolute === '/') {
80
+ return `Searching from "/" would scan the entire filesystem. Use "." for the project directory or provide a specific path.`;
81
+ }
82
+ try {
83
+ if (!fsSync.existsSync(searchPathAbsolute)) {
84
+ return `Search path does not exist: ${searchPathAbsolute}`;
85
+ }
86
+ // Accept both files and directories
87
+ const stats = fsSync.statSync(searchPathAbsolute);
88
+ if (!stats.isFile() && !stats.isDirectory()) {
89
+ return `Search path must be a file or directory: ${searchPathAbsolute}`;
90
+ }
91
+ }
92
+ catch (error) {
93
+ return `Error accessing search path: ${error.message}`;
94
+ }
95
+ return null;
96
+ }
97
+ getDescription(params) {
98
+ if (!params?.pattern)
99
+ return 'Search file content';
100
+ let desc = `'${params.pattern}'`;
101
+ const globPattern = params.glob || params.include;
102
+ if (globPattern)
103
+ desc += ` in ${globPattern}`;
104
+ if (params.path) {
105
+ const resolved = path.resolve(this.config.workingDirectory, params.path);
106
+ const relative = makeRelative(resolved, this.config.workingDirectory);
107
+ desc += ` within ${shortenPath(relative)}`;
108
+ }
109
+ if (params.output_mode)
110
+ desc += ` (${params.output_mode})`;
111
+ return desc;
112
+ }
113
+ async execute(params, signal, updateOutput) {
114
+ const startTime = Date.now();
115
+ const validationError = this.validateToolParams(params);
116
+ if (validationError) {
117
+ return this.createErrorResult(validationError);
118
+ }
119
+ try {
120
+ const searchPathAbsolute = path.resolve(this.config.workingDirectory, params.path || '.');
121
+ const searchPathDisplay = params.path || '.';
122
+ // Normalize parameters (handle both new and legacy param names)
123
+ const globPattern = params.glob || params.include;
124
+ const caseInsensitive = params['-i'] ?? (params.case_sensitive === undefined ? false : !params.case_sensitive);
125
+ const outputMode = params.output_mode || 'files_with_matches'; // Default to files_with_matches for efficiency
126
+ // Apply default limit if not specified (prevents context overflow)
127
+ const headLimit = params.head_limit ?? GrepTool.DEFAULT_MAX_RESULTS;
128
+ const effectiveLimit = Math.min(headLimit, GrepTool.HARD_MAX_RESULTS);
129
+ const offset = params.offset ?? 0; // Pagination offset
130
+ const contextAfter = params['-A'];
131
+ const contextBefore = params['-B'];
132
+ const contextBoth = params['-C'];
133
+ const showLineNumbers = params['-n'] ?? true;
134
+ const fileType = params.type;
135
+ const multiline = params.multiline;
136
+ // Check if path is a file or directory
137
+ const stats = fsSync.statSync(searchPathAbsolute);
138
+ const isFile = stats.isFile();
139
+ // For single file searches, extract directory and filename
140
+ let searchDir;
141
+ let targetFile;
142
+ if (isFile) {
143
+ searchDir = path.dirname(searchPathAbsolute);
144
+ targetFile = path.basename(searchPathAbsolute);
145
+ }
146
+ else {
147
+ searchDir = searchPathAbsolute;
148
+ targetFile = undefined;
149
+ }
150
+ // Perform search with fallback strategies
151
+ // Pass effectiveLimit to enable early termination in native commands
152
+ const { matches, strategy } = await this.performGrepSearch(params.pattern, searchDir, globPattern, !caseInsensitive, // performGrepSearch expects caseSensitive, we have caseInsensitive
153
+ signal, targetFile, fileType, multiline, contextAfter, contextBefore, contextBoth, effectiveLimit);
154
+ if (matches.length === 0) {
155
+ const message = `No matches found for pattern "${params.pattern}" in "${searchPathDisplay}"${globPattern ? ` (filter: "${globPattern}")` : ''}.`;
156
+ if (updateOutput)
157
+ updateOutput('No matches found');
158
+ return this.createSuccessResult(message, {
159
+ executionTime: Date.now() - startTime,
160
+ matchCount: 0,
161
+ searchPath: searchPathAbsolute,
162
+ pattern: params.pattern,
163
+ strategy,
164
+ output_mode: outputMode,
165
+ });
166
+ }
167
+ // Apply offset and limit for pagination (already limited at source for ripgrep, but ensure hard cap)
168
+ const totalMatches = matches.length;
169
+ const afterOffset = matches.slice(offset);
170
+ const limitedMatches = afterOffset.slice(0, effectiveLimit);
171
+ const hasMore = offset + limitedMatches.length < totalMatches;
172
+ const remainingCount = totalMatches - offset - limitedMatches.length;
173
+ // Format results based on output_mode
174
+ let llmContent;
175
+ let matchCount;
176
+ if (outputMode === 'files_with_matches') {
177
+ // Return only unique file paths
178
+ const uniqueFiles = [...new Set(limitedMatches.map(m => m.filePath))];
179
+ matchCount = uniqueFiles.length;
180
+ const displayFiles = uniqueFiles.slice(0, GrepTool.HARD_MAX_RESULTS);
181
+ // Build result message with pagination guidance
182
+ if (offset > 0 || hasMore) {
183
+ const rangeStart = offset + 1;
184
+ const rangeEnd = offset + limitedMatches.length;
185
+ llmContent = `Found ${totalMatches} matches in files for "${params.pattern}" (showing matches ${rangeStart}-${rangeEnd})${globPattern ? ` (filter: "${globPattern}")` : ''}:\n`;
186
+ }
187
+ else {
188
+ llmContent = `Found ${totalMatches} matches in ${uniqueFiles.length} files for "${params.pattern}"${globPattern ? ` (filter: "${globPattern}")` : ''}:\n`;
189
+ }
190
+ llmContent += displayFiles.join('\n');
191
+ if (hasMore) {
192
+ const nextOffset = offset + limitedMatches.length;
193
+ llmContent += `\n\n[TRUNCATED] ${remainingCount} more matches available. To see next page, call grep again with offset=${nextOffset}`;
194
+ }
195
+ if (updateOutput)
196
+ updateOutput(`Found ${uniqueFiles.length} files`);
197
+ return this.createSuccessResult(llmContent, {
198
+ executionTime: Date.now() - startTime,
199
+ matchCount: totalMatches,
200
+ fileCount: uniqueFiles.length,
201
+ searchPath: searchPathAbsolute,
202
+ pattern: params.pattern,
203
+ strategy,
204
+ output_mode: outputMode,
205
+ offset,
206
+ hasMore,
207
+ nextOffset: hasMore ? offset + limitedMatches.length : undefined,
208
+ });
209
+ }
210
+ else if (outputMode === 'count') {
211
+ // Return match counts per file
212
+ const countsByFile = {};
213
+ for (const match of limitedMatches) {
214
+ countsByFile[match.filePath] = (countsByFile[match.filePath] || 0) + 1;
215
+ }
216
+ const fileEntries = Object.entries(countsByFile);
217
+ matchCount = fileEntries.length;
218
+ const displayEntries = fileEntries.slice(0, GrepTool.HARD_MAX_RESULTS);
219
+ // Build result message with pagination guidance
220
+ if (offset > 0 || hasMore) {
221
+ const rangeStart = offset + 1;
222
+ const rangeEnd = offset + limitedMatches.length;
223
+ llmContent = `Found ${totalMatches} matches for "${params.pattern}" (showing matches ${rangeStart}-${rangeEnd})${globPattern ? ` (filter: "${globPattern}")` : ''}:\n`;
224
+ }
225
+ else {
226
+ llmContent = `Found ${totalMatches} matches in ${fileEntries.length} files for "${params.pattern}"${globPattern ? ` (filter: "${globPattern}")` : ''}:\n`;
227
+ }
228
+ for (const [file, count] of displayEntries) {
229
+ llmContent += `${file}: ${count}\n`;
230
+ }
231
+ if (hasMore) {
232
+ const nextOffset = offset + limitedMatches.length;
233
+ llmContent += `\n[TRUNCATED] ${remainingCount} more matches available. To see next page, call grep again with offset=${nextOffset}`;
234
+ }
235
+ if (updateOutput)
236
+ updateOutput(`Found ${totalMatches} matches in ${fileEntries.length} files`);
237
+ return this.createSuccessResult(llmContent, {
238
+ executionTime: Date.now() - startTime,
239
+ matchCount: totalMatches,
240
+ fileCount: fileEntries.length,
241
+ searchPath: searchPathAbsolute,
242
+ pattern: params.pattern,
243
+ strategy,
244
+ output_mode: outputMode,
245
+ offset,
246
+ hasMore,
247
+ nextOffset: hasMore ? offset + limitedMatches.length : undefined,
248
+ });
249
+ }
250
+ // Default: content mode - show matching lines
251
+ const displayMatches = limitedMatches.slice(0, GrepTool.HARD_MAX_RESULTS);
252
+ const matchesByFile = this.groupMatchesByFile(displayMatches, searchDir);
253
+ matchCount = displayMatches.length;
254
+ const matchTerm = matchCount === 1 ? 'match' : 'matches';
255
+ // Build header with pagination info
256
+ if (offset > 0 || hasMore) {
257
+ const rangeStart = offset + 1;
258
+ const rangeEnd = offset + limitedMatches.length;
259
+ llmContent = `Found ${totalMatches} matches for "${params.pattern}" (showing ${rangeStart}-${rangeEnd}) in "${searchPathDisplay}"${globPattern ? ` (filter: "${globPattern}")` : ''} [using ${strategy}]:\n---\n`;
260
+ }
261
+ else {
262
+ llmContent = `Found ${matchCount} ${matchTerm} for "${params.pattern}" in "${searchPathDisplay}"${globPattern ? ` (filter: "${globPattern}")` : ''} [using ${strategy}]:\n---\n`;
263
+ }
264
+ let contentLength = llmContent.length;
265
+ let contentTruncated = false;
266
+ for (const filePath in matchesByFile) {
267
+ const fileMatches = matchesByFile[filePath];
268
+ if (!fileMatches)
269
+ continue;
270
+ const fileHeader = `File: ${filePath}\n`;
271
+ if (contentLength + fileHeader.length > GrepTool.MAX_CONTENT_LENGTH) {
272
+ contentTruncated = true;
273
+ break;
274
+ }
275
+ llmContent += fileHeader;
276
+ contentLength += fileHeader.length;
277
+ for (const match of fileMatches) {
278
+ const trimmedLine = match.line.trim();
279
+ const lineContent = showLineNumbers ? `L${match.lineNumber}: ${trimmedLine}\n` : `${trimmedLine}\n`;
280
+ if (contentLength + lineContent.length > GrepTool.MAX_CONTENT_LENGTH) {
281
+ contentTruncated = true;
282
+ break;
283
+ }
284
+ llmContent += lineContent;
285
+ contentLength += lineContent.length;
286
+ }
287
+ if (contentTruncated)
288
+ break;
289
+ llmContent += '---\n';
290
+ contentLength += 4;
291
+ }
292
+ // Add pagination guidance
293
+ if (hasMore || contentTruncated) {
294
+ const nextOffset = offset + limitedMatches.length;
295
+ llmContent += `\n[TRUNCATED] ${remainingCount} more matches available. To see next page, call grep again with offset=${nextOffset}`;
296
+ }
297
+ const returnDisplay = hasMore || offset > 0
298
+ ? `Found ${totalMatches} matches (showing ${matchCount})`
299
+ : `Found ${matchCount} ${matchTerm}`;
300
+ if (updateOutput)
301
+ updateOutput(returnDisplay);
302
+ return this.createSuccessResult(llmContent.trim(), {
303
+ executionTime: Date.now() - startTime,
304
+ matchCount: totalMatches,
305
+ displayedMatches: matchCount,
306
+ truncated: hasMore || contentTruncated,
307
+ searchPath: searchPathAbsolute,
308
+ pattern: params.pattern,
309
+ strategy,
310
+ output_mode: outputMode,
311
+ offset,
312
+ hasMore,
313
+ nextOffset: hasMore ? offset + limitedMatches.length : undefined,
314
+ });
315
+ }
316
+ catch (error) {
317
+ if (error.name === 'AbortError') {
318
+ return this.createErrorResult('Search was aborted');
319
+ }
320
+ return this.createErrorResult(`Search failed: ${error.message}`);
321
+ }
322
+ }
323
+ /**
324
+ * Performs grep search using best available strategy
325
+ *
326
+ * @param pattern - Regex pattern to search for
327
+ * @param absolutePath - Directory to search in
328
+ * @param include - Glob pattern for file filtering
329
+ * @param caseSensitive - Whether search is case-sensitive
330
+ * @param signal - Abort signal for cancellation
331
+ * @param targetFile - Optional: specific filename to search (single-file mode)
332
+ * @param fileType - Optional: file type filter (rg --type)
333
+ * @param multiline - Optional: enable multiline matching
334
+ * @param contextAfter - Optional: lines after match (-A)
335
+ * @param contextBefore - Optional: lines before match (-B)
336
+ * @param contextBoth - Optional: lines of context (-C)
337
+ * @param maxResults - Optional: maximum results (enables -m flag for ripgrep)
338
+ */
339
+ async performGrepSearch(pattern, absolutePath, include, caseSensitive = false, signal, targetFile, fileType, multiline, contextAfter, contextBefore, contextBoth, maxResults) {
340
+ // Strategy 1: ripgrep (rg) - Fastest
341
+ if (await this.isCommandAvailable('rg')) {
342
+ try {
343
+ const matches = await this.searchWithRipgrep(pattern, absolutePath, include, caseSensitive, targetFile, fileType, multiline, contextAfter, contextBefore, contextBoth, maxResults, signal);
344
+ return { matches, strategy: 'ripgrep' };
345
+ }
346
+ catch (error) {
347
+ // If aborted, propagate the error instead of falling back
348
+ if (error.message?.includes('aborted') || error.message?.includes('timed out')) {
349
+ throw error;
350
+ }
351
+ console.debug(`ripgrep failed: ${error.message}, falling back...`);
352
+ }
353
+ }
354
+ // Strategy 2: git grep - Fast (git repos only)
355
+ if (isGitRepository(absolutePath) && (await this.isCommandAvailable('git'))) {
356
+ try {
357
+ const matches = await this.searchWithGitGrep(pattern, absolutePath, include, caseSensitive, targetFile, signal);
358
+ return { matches, strategy: 'git grep' };
359
+ }
360
+ catch (error) {
361
+ // If aborted, propagate the error instead of falling back
362
+ if (error.message?.includes('aborted') || error.message?.includes('timed out')) {
363
+ throw error;
364
+ }
365
+ console.debug(`git grep failed: ${error.message}, falling back...`);
366
+ }
367
+ }
368
+ // Strategy 3: system grep - Good
369
+ if (await this.isCommandAvailable('grep')) {
370
+ try {
371
+ const matches = await this.searchWithSystemGrep(pattern, absolutePath, include, caseSensitive, targetFile, signal);
372
+ return { matches, strategy: 'system grep' };
373
+ }
374
+ catch (error) {
375
+ // If aborted, propagate the error instead of falling back
376
+ if (error.message?.includes('aborted') || error.message?.includes('timed out')) {
377
+ throw error;
378
+ }
379
+ console.debug(`system grep failed: ${error.message}, falling back...`);
380
+ }
381
+ }
382
+ // Strategy 4: JavaScript fallback - Portable
383
+ const matches = await this.searchWithJavaScript(pattern, absolutePath, include, caseSensitive, signal, targetFile, multiline);
384
+ return { matches, strategy: 'javascript' };
385
+ }
386
+ /**
387
+ * Strategy 1: Search with ripgrep (rg)
388
+ */
389
+ async searchWithRipgrep(pattern, cwd, include, caseSensitive = false, targetFile, fileType, multiline, contextAfter, contextBefore, contextBoth, maxResults, signal) {
390
+ const args = [
391
+ '--line-number',
392
+ '--no-heading',
393
+ '--with-filename',
394
+ '--color', 'never',
395
+ ];
396
+ if (!caseSensitive)
397
+ args.push('--ignore-case');
398
+ if (include)
399
+ args.push('--glob', include);
400
+ if (fileType)
401
+ args.push('--type', fileType);
402
+ if (multiline)
403
+ args.push('-U', '--multiline-dotall');
404
+ if (contextAfter)
405
+ args.push('-A', String(contextAfter));
406
+ if (contextBefore)
407
+ args.push('-B', String(contextBefore));
408
+ if (contextBoth)
409
+ args.push('-C', String(contextBoth));
410
+ // Early termination: limit results at source to save context tokens
411
+ if (maxResults && maxResults > 0)
412
+ args.push('-m', String(maxResults));
413
+ args.push(pattern);
414
+ // Single file mode: search specific file instead of directory
415
+ args.push(targetFile || '.');
416
+ const output = await this.executeCommand('rg', args, cwd, signal);
417
+ return this.parseGrepOutput(output, cwd);
418
+ }
419
+ /**
420
+ * Strategy 2: Search with git grep
421
+ */
422
+ async searchWithGitGrep(pattern, cwd, include, caseSensitive = false, targetFile, signal) {
423
+ const args = [
424
+ 'grep',
425
+ '--untracked',
426
+ '-n',
427
+ '-E',
428
+ ];
429
+ if (!caseSensitive)
430
+ args.push('--ignore-case');
431
+ args.push(pattern);
432
+ // Single file mode or directory mode
433
+ if (targetFile) {
434
+ args.push('--');
435
+ args.push(targetFile);
436
+ }
437
+ else if (include) {
438
+ args.push('--');
439
+ args.push(include);
440
+ }
441
+ const output = await this.executeCommand('git', args, cwd, signal);
442
+ return this.parseGrepOutput(output, cwd);
443
+ }
444
+ /**
445
+ * Strategy 3: Search with system grep
446
+ */
447
+ async searchWithSystemGrep(pattern, cwd, include, caseSensitive = false, targetFile, signal) {
448
+ // Single file mode: use different flags (no recursion)
449
+ const args = targetFile ? ['-n', '-H', '-E'] : ['-r', '-n', '-H', '-E'];
450
+ if (!caseSensitive)
451
+ args.push('--ignore-case');
452
+ // Only exclude directories when searching recursively
453
+ if (!targetFile) {
454
+ const excludeDirs = [
455
+ '.git',
456
+ 'node_modules',
457
+ 'bower_components',
458
+ 'dist',
459
+ 'build',
460
+ '.claude', // external coding-agent data dir
461
+ '.cortex', // Nexus Cortex runtime data
462
+ '.npm', // npm cache
463
+ '.pythonlibs', // Python libraries
464
+ '.config', // Configuration data
465
+ 'coverage', // Test coverage
466
+ '.next', // Next.js build
467
+ '.nuxt', // Nuxt.js build
468
+ '.cache', // General cache
469
+ 'tmp', // Temporary files
470
+ 'temp', // Temporary files
471
+ '__pycache__', // Python cache
472
+ '.pytest_cache', // Pytest cache
473
+ '.mypy_cache', // Mypy cache
474
+ 'vendor', // Vendor dependencies
475
+ '.venv', // Python virtual env
476
+ 'venv', // Python virtual env
477
+ 'env', // Environment
478
+ ];
479
+ excludeDirs.forEach(dir => args.push(`--exclude-dir=${dir}`));
480
+ if (include)
481
+ args.push(`--include=${include}`);
482
+ }
483
+ args.push(pattern);
484
+ // Single file mode: search specific file instead of directory
485
+ args.push(targetFile || '.');
486
+ const output = await this.executeCommand('grep', args, cwd, signal);
487
+ return this.parseGrepOutput(output, cwd);
488
+ }
489
+ /**
490
+ * Strategy 4: Pure JavaScript fallback
491
+ */
492
+ async searchWithJavaScript(pattern, absolutePath, include, caseSensitive = false, signal, targetFile, multiline) {
493
+ // Build regex flags
494
+ let flags = caseSensitive ? '' : 'i';
495
+ if (multiline)
496
+ flags += 'ms'; // multiline + dotAll
497
+ const regex = new RegExp(pattern, flags);
498
+ const allMatches = [];
499
+ // Single file mode: search only the target file
500
+ if (targetFile) {
501
+ const fileAbsolutePath = path.join(absolutePath, targetFile);
502
+ try {
503
+ const stat = await fs.stat(fileAbsolutePath);
504
+ if (stat.size > GrepTool.MAX_SEARCHABLE_FILE_BYTES) {
505
+ console.debug(`Skipping ${fileAbsolutePath}: ${stat.size} bytes exceeds search limit`);
506
+ return allMatches;
507
+ }
508
+ const content = await fs.readFile(fileAbsolutePath, 'utf8');
509
+ const lines = content.split(/\r?\n/);
510
+ lines.forEach((line, index) => {
511
+ if (regex.test(line)) {
512
+ allMatches.push({
513
+ filePath: targetFile,
514
+ lineNumber: index + 1,
515
+ line,
516
+ });
517
+ }
518
+ });
519
+ }
520
+ catch (error) {
521
+ console.debug(`Could not read ${fileAbsolutePath}: ${error.message}`);
522
+ }
523
+ return allMatches;
524
+ }
525
+ // Directory mode: search all matching files
526
+ const globPattern = include || '**/*';
527
+ // Minimal exclusions - let .gitignore/.rgignore handle the rest (ripgrep respects these)
528
+ // This matches the approach of delegating to ripgrep defaults
529
+ const ignorePatterns = [
530
+ '.git/**', // Git internals (ripgrep excludes by default)
531
+ 'node_modules/**', // Dependencies (usually in .gitignore but critical for performance)
532
+ '.claude/**', // external coding-agent data dir
533
+ '.cortex/**', // Nexus Cortex runtime data
534
+ '.grok/**', // xAI Grok CLI runtime data (upload_queue holds huge blobs)
535
+ ];
536
+ const filesStream = globStream(globPattern, {
537
+ cwd: absolutePath,
538
+ dot: true,
539
+ ignore: ignorePatterns,
540
+ absolute: true,
541
+ nodir: true,
542
+ signal,
543
+ });
544
+ for await (const filePath of filesStream) {
545
+ const fileAbsolutePath = filePath;
546
+ try {
547
+ const stat = await fs.stat(fileAbsolutePath);
548
+ if (stat.size > GrepTool.MAX_SEARCHABLE_FILE_BYTES) {
549
+ // Skip oversized files: reading them into a string can throw
550
+ // "Invalid string length", and they're never useful grep targets.
551
+ continue;
552
+ }
553
+ const content = await fs.readFile(fileAbsolutePath, 'utf8');
554
+ const lines = content.split(/\r?\n/);
555
+ lines.forEach((line, index) => {
556
+ if (regex.test(line)) {
557
+ allMatches.push({
558
+ filePath: path.relative(absolutePath, fileAbsolutePath) ||
559
+ path.basename(fileAbsolutePath),
560
+ lineNumber: index + 1,
561
+ line,
562
+ });
563
+ }
564
+ });
565
+ }
566
+ catch (error) {
567
+ if (error.code !== 'ENOENT' && error.code !== 'EISDIR') {
568
+ console.debug(`Could not read ${fileAbsolutePath}: ${error.message}`);
569
+ }
570
+ }
571
+ }
572
+ return allMatches;
573
+ }
574
+ /**
575
+ * Executes a command and returns stdout
576
+ * Supports abort signal for ESC key cancellation and timeout for runaway processes
577
+ */
578
+ executeCommand(command, args, cwd, signal, timeoutMs = 30000) {
579
+ return new Promise((resolve, reject) => {
580
+ // Check if already aborted before spawning
581
+ if (signal?.aborted) {
582
+ reject(new Error('Search was aborted'));
583
+ return;
584
+ }
585
+ const child = spawn(command, args, {
586
+ cwd,
587
+ windowsHide: true,
588
+ });
589
+ let killed = false;
590
+ let timedOut = false;
591
+ // Setup timeout to prevent runaway grep processes
592
+ const timeoutId = setTimeout(() => {
593
+ if (!killed) {
594
+ timedOut = true;
595
+ killed = true;
596
+ child.kill('SIGKILL');
597
+ }
598
+ }, timeoutMs);
599
+ // Setup abort signal handler for ESC key cancellation
600
+ const abortHandler = () => {
601
+ if (!killed) {
602
+ killed = true;
603
+ clearTimeout(timeoutId);
604
+ child.kill('SIGKILL');
605
+ }
606
+ };
607
+ if (signal) {
608
+ signal.addEventListener('abort', abortHandler, { once: true });
609
+ }
610
+ const stdoutChunks = [];
611
+ const stderrChunks = [];
612
+ child.stdout.on('data', (chunk) => stdoutChunks.push(chunk));
613
+ child.stderr.on('data', (chunk) => {
614
+ const str = chunk.toString();
615
+ // Suppress common harmless messages
616
+ if (!str.includes('Permission denied') && !/Is a directory/i.test(str)) {
617
+ stderrChunks.push(chunk);
618
+ }
619
+ });
620
+ child.on('error', (err) => {
621
+ clearTimeout(timeoutId);
622
+ if (signal) {
623
+ signal.removeEventListener('abort', abortHandler);
624
+ }
625
+ reject(new Error(`Failed to start ${command}: ${err.message}`));
626
+ });
627
+ child.on('close', (code) => {
628
+ clearTimeout(timeoutId);
629
+ if (signal) {
630
+ signal.removeEventListener('abort', abortHandler);
631
+ }
632
+ // Handle abort/timeout cases
633
+ if (signal?.aborted || killed) {
634
+ if (timedOut) {
635
+ reject(new Error(`Search timed out after ${timeoutMs / 1000} seconds`));
636
+ }
637
+ else {
638
+ reject(new Error('Search was aborted'));
639
+ }
640
+ return;
641
+ }
642
+ const stdout = Buffer.concat(stdoutChunks).toString('utf8');
643
+ const stderr = Buffer.concat(stderrChunks).toString('utf8').trim();
644
+ if (code === 0) {
645
+ resolve(stdout);
646
+ }
647
+ else if (code === 1) {
648
+ resolve(''); // No matches (not an error)
649
+ }
650
+ else {
651
+ reject(new Error(`${command} exited with code ${code}${stderr ? `: ${stderr}` : ''}`));
652
+ }
653
+ });
654
+ });
655
+ }
656
+ /**
657
+ * Checks if a command is available
658
+ */
659
+ isCommandAvailable(command) {
660
+ return new Promise((resolve) => {
661
+ const checkCmd = process.platform === 'win32' ? 'where' : 'command';
662
+ const checkArgs = process.platform === 'win32' ? [command] : ['-v', command];
663
+ try {
664
+ const child = spawn(checkCmd, checkArgs, {
665
+ stdio: 'ignore',
666
+ shell: process.platform === 'win32',
667
+ });
668
+ child.on('close', (code) => resolve(code === 0));
669
+ child.on('error', () => resolve(false));
670
+ }
671
+ catch {
672
+ resolve(false);
673
+ }
674
+ });
675
+ }
676
+ /**
677
+ * Parses grep-style output including context lines from -A/-B/-C flags.
678
+ * Match lines use colons: file:line:content
679
+ * Context lines use dashes: file-line-content
680
+ * Group separators: --
681
+ */
682
+ parseGrepOutput(output, basePath) {
683
+ const results = [];
684
+ if (!output)
685
+ return results;
686
+ const lines = output.split(EOL);
687
+ for (const line of lines) {
688
+ if (!line.trim())
689
+ continue;
690
+ // Skip group separators between match groups
691
+ if (line === '--')
692
+ continue;
693
+ // Try colon-separated match line: file:linenum:content
694
+ const firstColon = line.indexOf(':');
695
+ if (firstColon > 0) {
696
+ const secondColon = line.indexOf(':', firstColon + 1);
697
+ if (secondColon > 0) {
698
+ const filePathRaw = line.substring(0, firstColon);
699
+ const lineNumberStr = line.substring(firstColon + 1, secondColon);
700
+ const lineNumber = parseInt(lineNumberStr, 10);
701
+ if (!isNaN(lineNumber)) {
702
+ const absoluteFilePath = path.resolve(basePath, filePathRaw);
703
+ const relativeFilePath = path.relative(basePath, absoluteFilePath);
704
+ results.push({
705
+ filePath: relativeFilePath || path.basename(absoluteFilePath),
706
+ lineNumber,
707
+ line: line.substring(secondColon + 1),
708
+ });
709
+ continue;
710
+ }
711
+ }
712
+ }
713
+ // Try dash-separated context line: file-linenum-content
714
+ // Context lines from ripgrep -A/-B/-C use dashes instead of colons
715
+ const dashMatch = line.match(/^(.+?)-(\d+)-(.*)$/);
716
+ if (dashMatch) {
717
+ const [, filePathRaw, lineNumberStr, lineContent] = dashMatch;
718
+ const lineNumber = parseInt(lineNumberStr, 10);
719
+ if (!isNaN(lineNumber) && filePathRaw) {
720
+ const absoluteFilePath = path.resolve(basePath, filePathRaw);
721
+ const relativeFilePath = path.relative(basePath, absoluteFilePath);
722
+ results.push({
723
+ filePath: relativeFilePath || path.basename(absoluteFilePath),
724
+ lineNumber,
725
+ line: lineContent ?? '',
726
+ });
727
+ }
728
+ }
729
+ }
730
+ return results;
731
+ }
732
+ /**
733
+ * Groups matches by file and sorts by line number
734
+ */
735
+ groupMatchesByFile(matches, basePath) {
736
+ const matchesByFile = {};
737
+ for (const match of matches) {
738
+ const absoluteFilePath = path.resolve(basePath, match.filePath);
739
+ const relativeFilePath = path.relative(basePath, absoluteFilePath) || path.basename(absoluteFilePath);
740
+ if (!matchesByFile[relativeFilePath]) {
741
+ matchesByFile[relativeFilePath] = [];
742
+ }
743
+ matchesByFile[relativeFilePath].push(match);
744
+ }
745
+ for (const filePath in matchesByFile) {
746
+ const fileMatches = matchesByFile[filePath];
747
+ if (fileMatches) {
748
+ fileMatches.sort((a, b) => a.lineNumber - b.lineNumber);
749
+ }
750
+ }
751
+ return matchesByFile;
752
+ }
753
+ }
754
+ //# sourceMappingURL=GrepTool.js.map