@vybestack/llxprt-code-core 0.1.12

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 (448) hide show
  1. package/dist/.last_build +0 -0
  2. package/dist/index.d.ts +7 -0
  3. package/dist/index.js +8 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/src/__mocks__/fs/promises.d.ts +11 -0
  6. package/dist/src/__mocks__/fs/promises.js +17 -0
  7. package/dist/src/__mocks__/fs/promises.js.map +1 -0
  8. package/dist/src/code_assist/codeAssist.d.ts +9 -0
  9. package/dist/src/code_assist/codeAssist.js +19 -0
  10. package/dist/src/code_assist/codeAssist.js.map +1 -0
  11. package/dist/src/code_assist/converter.d.ts +68 -0
  12. package/dist/src/code_assist/converter.js +125 -0
  13. package/dist/src/code_assist/converter.js.map +1 -0
  14. package/dist/src/code_assist/converter.test.d.ts +6 -0
  15. package/dist/src/code_assist/converter.test.js +229 -0
  16. package/dist/src/code_assist/converter.test.js.map +1 -0
  17. package/dist/src/code_assist/oauth2.d.ts +20 -0
  18. package/dist/src/code_assist/oauth2.js +339 -0
  19. package/dist/src/code_assist/oauth2.js.map +1 -0
  20. package/dist/src/code_assist/oauth2.test.d.ts +6 -0
  21. package/dist/src/code_assist/oauth2.test.js +249 -0
  22. package/dist/src/code_assist/oauth2.test.js.map +1 -0
  23. package/dist/src/code_assist/server.d.ts +39 -0
  24. package/dist/src/code_assist/server.js +191 -0
  25. package/dist/src/code_assist/server.js.map +1 -0
  26. package/dist/src/code_assist/server.test.d.ts +6 -0
  27. package/dist/src/code_assist/server.test.js +123 -0
  28. package/dist/src/code_assist/server.test.js.map +1 -0
  29. package/dist/src/code_assist/setup.d.ts +15 -0
  30. package/dist/src/code_assist/setup.js +67 -0
  31. package/dist/src/code_assist/setup.js.map +1 -0
  32. package/dist/src/code_assist/setup.test.d.ts +6 -0
  33. package/dist/src/code_assist/setup.test.js +62 -0
  34. package/dist/src/code_assist/setup.test.js.map +1 -0
  35. package/dist/src/code_assist/types.d.ts +148 -0
  36. package/dist/src/code_assist/types.js +46 -0
  37. package/dist/src/code_assist/types.js.map +1 -0
  38. package/dist/src/config/config.d.ts +212 -0
  39. package/dist/src/config/config.js +454 -0
  40. package/dist/src/config/config.js.map +1 -0
  41. package/dist/src/config/config.test.d.ts +6 -0
  42. package/dist/src/config/config.test.js +291 -0
  43. package/dist/src/config/config.test.js.map +1 -0
  44. package/dist/src/config/flashFallback.test.d.ts +6 -0
  45. package/dist/src/config/flashFallback.test.js +115 -0
  46. package/dist/src/config/flashFallback.test.js.map +1 -0
  47. package/dist/src/config/models.d.ts +8 -0
  48. package/dist/src/config/models.js +9 -0
  49. package/dist/src/config/models.js.map +1 -0
  50. package/dist/src/core/client.d.ts +59 -0
  51. package/dist/src/core/client.js +503 -0
  52. package/dist/src/core/client.js.map +1 -0
  53. package/dist/src/core/client.test.d.ts +6 -0
  54. package/dist/src/core/client.test.js +1006 -0
  55. package/dist/src/core/client.test.js.map +1 -0
  56. package/dist/src/core/contentGenerator.d.ts +36 -0
  57. package/dist/src/core/contentGenerator.js +79 -0
  58. package/dist/src/core/contentGenerator.js.map +1 -0
  59. package/dist/src/core/contentGenerator.test.d.ts +6 -0
  60. package/dist/src/core/contentGenerator.test.js +92 -0
  61. package/dist/src/core/contentGenerator.test.js.map +1 -0
  62. package/dist/src/core/coreToolScheduler.d.ts +104 -0
  63. package/dist/src/core/coreToolScheduler.js +413 -0
  64. package/dist/src/core/coreToolScheduler.js.map +1 -0
  65. package/dist/src/core/coreToolScheduler.test.d.ts +6 -0
  66. package/dist/src/core/coreToolScheduler.test.js +347 -0
  67. package/dist/src/core/coreToolScheduler.test.js.map +1 -0
  68. package/dist/src/core/geminiChat.d.ts +116 -0
  69. package/dist/src/core/geminiChat.js +513 -0
  70. package/dist/src/core/geminiChat.js.map +1 -0
  71. package/dist/src/core/geminiChat.test.d.ts +6 -0
  72. package/dist/src/core/geminiChat.test.js +424 -0
  73. package/dist/src/core/geminiChat.test.js.map +1 -0
  74. package/dist/src/core/geminiRequest.d.ts +13 -0
  75. package/dist/src/core/geminiRequest.js +45 -0
  76. package/dist/src/core/geminiRequest.js.map +1 -0
  77. package/dist/src/core/geminiRequest.test.d.ts +6 -0
  78. package/dist/src/core/geminiRequest.test.js +72 -0
  79. package/dist/src/core/geminiRequest.test.js.map +1 -0
  80. package/dist/src/core/logger.d.ts +38 -0
  81. package/dist/src/core/logger.js +237 -0
  82. package/dist/src/core/logger.js.map +1 -0
  83. package/dist/src/core/logger.test.d.ts +6 -0
  84. package/dist/src/core/logger.test.js +387 -0
  85. package/dist/src/core/logger.test.js.map +1 -0
  86. package/dist/src/core/modelCheck.d.ts +14 -0
  87. package/dist/src/core/modelCheck.js +55 -0
  88. package/dist/src/core/modelCheck.js.map +1 -0
  89. package/dist/src/core/nonInteractiveToolExecutor.d.ts +12 -0
  90. package/dist/src/core/nonInteractiveToolExecutor.js +93 -0
  91. package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -0
  92. package/dist/src/core/nonInteractiveToolExecutor.test.d.ts +6 -0
  93. package/dist/src/core/nonInteractiveToolExecutor.test.js +180 -0
  94. package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -0
  95. package/dist/src/core/prompts.d.ts +12 -0
  96. package/dist/src/core/prompts.js +418 -0
  97. package/dist/src/core/prompts.js.map +1 -0
  98. package/dist/src/core/prompts.test.d.ts +6 -0
  99. package/dist/src/core/prompts.test.js +97 -0
  100. package/dist/src/core/prompts.test.js.map +1 -0
  101. package/dist/src/core/tokenLimits.d.ts +10 -0
  102. package/dist/src/core/tokenLimits.js +75 -0
  103. package/dist/src/core/tokenLimits.js.map +1 -0
  104. package/dist/src/core/tokenLimits.test.d.ts +6 -0
  105. package/dist/src/core/tokenLimits.test.js +66 -0
  106. package/dist/src/core/tokenLimits.test.js.map +1 -0
  107. package/dist/src/core/turn.d.ts +116 -0
  108. package/dist/src/core/turn.js +131 -0
  109. package/dist/src/core/turn.js.map +1 -0
  110. package/dist/src/core/turn.test.d.ts +6 -0
  111. package/dist/src/core/turn.test.js +237 -0
  112. package/dist/src/core/turn.test.js.map +1 -0
  113. package/dist/src/index.d.ts +57 -0
  114. package/dist/src/index.js +64 -0
  115. package/dist/src/index.js.map +1 -0
  116. package/dist/src/index.test.d.ts +6 -0
  117. package/dist/src/index.test.js +12 -0
  118. package/dist/src/index.test.js.map +1 -0
  119. package/dist/src/providers/ProviderContentGenerator.d.ts +21 -0
  120. package/dist/src/providers/ProviderContentGenerator.js +52 -0
  121. package/dist/src/providers/ProviderContentGenerator.js.map +1 -0
  122. package/dist/src/providers/adapters/GeminiCompatibleWrapper.d.ts +68 -0
  123. package/dist/src/providers/adapters/GeminiCompatibleWrapper.js +549 -0
  124. package/dist/src/providers/adapters/GeminiCompatibleWrapper.js.map +1 -0
  125. package/dist/src/providers/adapters/GeminiCompatibleWrapper.test.d.ts +6 -0
  126. package/dist/src/providers/adapters/GeminiCompatibleWrapper.test.js +253 -0
  127. package/dist/src/providers/adapters/GeminiCompatibleWrapper.test.js.map +1 -0
  128. package/dist/src/providers/types.d.ts +82 -0
  129. package/dist/src/providers/types.js +7 -0
  130. package/dist/src/providers/types.js.map +1 -0
  131. package/dist/src/services/fileDiscoveryService.d.ts +35 -0
  132. package/dist/src/services/fileDiscoveryService.js +91 -0
  133. package/dist/src/services/fileDiscoveryService.js.map +1 -0
  134. package/dist/src/services/fileDiscoveryService.test.d.ts +6 -0
  135. package/dist/src/services/fileDiscoveryService.test.js +102 -0
  136. package/dist/src/services/fileDiscoveryService.test.js.map +1 -0
  137. package/dist/src/services/gitService.d.ts +21 -0
  138. package/dist/src/services/gitService.js +102 -0
  139. package/dist/src/services/gitService.js.map +1 -0
  140. package/dist/src/services/gitService.test.d.ts +6 -0
  141. package/dist/src/services/gitService.test.js +246 -0
  142. package/dist/src/services/gitService.test.js.map +1 -0
  143. package/dist/src/services/ideContext.d.ts +124 -0
  144. package/dist/src/services/ideContext.js +90 -0
  145. package/dist/src/services/ideContext.js.map +1 -0
  146. package/dist/src/services/ideContext.test.d.ts +6 -0
  147. package/dist/src/services/ideContext.test.js +101 -0
  148. package/dist/src/services/ideContext.test.js.map +1 -0
  149. package/dist/src/services/loopDetectionService.d.ts +35 -0
  150. package/dist/src/services/loopDetectionService.js +117 -0
  151. package/dist/src/services/loopDetectionService.js.map +1 -0
  152. package/dist/src/services/loopDetectionService.test.d.ts +6 -0
  153. package/dist/src/services/loopDetectionService.test.js +232 -0
  154. package/dist/src/services/loopDetectionService.test.js.map +1 -0
  155. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +35 -0
  156. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +424 -0
  157. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -0
  158. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +47 -0
  159. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +123 -0
  160. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -0
  161. package/dist/src/telemetry/constants.d.ts +20 -0
  162. package/dist/src/telemetry/constants.js +21 -0
  163. package/dist/src/telemetry/constants.js.map +1 -0
  164. package/dist/src/telemetry/index.d.ts +18 -0
  165. package/dist/src/telemetry/index.js +20 -0
  166. package/dist/src/telemetry/index.js.map +1 -0
  167. package/dist/src/telemetry/integration.test.circular.d.ts +6 -0
  168. package/dist/src/telemetry/integration.test.circular.js +53 -0
  169. package/dist/src/telemetry/integration.test.circular.js.map +1 -0
  170. package/dist/src/telemetry/loggers.d.ts +15 -0
  171. package/dist/src/telemetry/loggers.js +229 -0
  172. package/dist/src/telemetry/loggers.js.map +1 -0
  173. package/dist/src/telemetry/loggers.test.circular.d.ts +6 -0
  174. package/dist/src/telemetry/loggers.test.circular.js +100 -0
  175. package/dist/src/telemetry/loggers.test.circular.js.map +1 -0
  176. package/dist/src/telemetry/loggers.test.d.ts +6 -0
  177. package/dist/src/telemetry/loggers.test.js +558 -0
  178. package/dist/src/telemetry/loggers.test.js.map +1 -0
  179. package/dist/src/telemetry/metrics.d.ts +19 -0
  180. package/dist/src/telemetry/metrics.js +144 -0
  181. package/dist/src/telemetry/metrics.js.map +1 -0
  182. package/dist/src/telemetry/metrics.test.d.ts +6 -0
  183. package/dist/src/telemetry/metrics.test.js +162 -0
  184. package/dist/src/telemetry/metrics.test.js.map +1 -0
  185. package/dist/src/telemetry/sdk.d.ts +9 -0
  186. package/dist/src/telemetry/sdk.js +120 -0
  187. package/dist/src/telemetry/sdk.js.map +1 -0
  188. package/dist/src/telemetry/telemetry.test.d.ts +6 -0
  189. package/dist/src/telemetry/telemetry.test.js +52 -0
  190. package/dist/src/telemetry/telemetry.test.js.map +1 -0
  191. package/dist/src/telemetry/types.d.ts +115 -0
  192. package/dist/src/telemetry/types.js +217 -0
  193. package/dist/src/telemetry/types.js.map +1 -0
  194. package/dist/src/telemetry/uiTelemetry.d.ts +67 -0
  195. package/dist/src/telemetry/uiTelemetry.js +131 -0
  196. package/dist/src/telemetry/uiTelemetry.js.map +1 -0
  197. package/dist/src/telemetry/uiTelemetry.test.d.ts +6 -0
  198. package/dist/src/telemetry/uiTelemetry.test.js +412 -0
  199. package/dist/src/telemetry/uiTelemetry.test.js.map +1 -0
  200. package/dist/src/tools/diffOptions.d.ts +7 -0
  201. package/dist/src/tools/diffOptions.js +10 -0
  202. package/dist/src/tools/diffOptions.js.map +1 -0
  203. package/dist/src/tools/edit.d.ts +73 -0
  204. package/dist/src/tools/edit.js +343 -0
  205. package/dist/src/tools/edit.js.map +1 -0
  206. package/dist/src/tools/edit.test.d.ts +6 -0
  207. package/dist/src/tools/edit.test.js +500 -0
  208. package/dist/src/tools/edit.test.js.map +1 -0
  209. package/dist/src/tools/glob.d.ts +58 -0
  210. package/dist/src/tools/glob.js +193 -0
  211. package/dist/src/tools/glob.js.map +1 -0
  212. package/dist/src/tools/glob.test.d.ts +6 -0
  213. package/dist/src/tools/glob.test.js +294 -0
  214. package/dist/src/tools/glob.test.js.map +1 -0
  215. package/dist/src/tools/grep.d.ts +78 -0
  216. package/dist/src/tools/grep.js +422 -0
  217. package/dist/src/tools/grep.js.map +1 -0
  218. package/dist/src/tools/grep.test.d.ts +6 -0
  219. package/dist/src/tools/grep.test.js +188 -0
  220. package/dist/src/tools/grep.test.js.map +1 -0
  221. package/dist/src/tools/ls.d.ts +83 -0
  222. package/dist/src/tools/ls.js +194 -0
  223. package/dist/src/tools/ls.js.map +1 -0
  224. package/dist/src/tools/mcp-client.d.ts +112 -0
  225. package/dist/src/tools/mcp-client.js +332 -0
  226. package/dist/src/tools/mcp-client.js.map +1 -0
  227. package/dist/src/tools/mcp-client.test.d.ts +6 -0
  228. package/dist/src/tools/mcp-client.test.js +227 -0
  229. package/dist/src/tools/mcp-client.test.js.map +1 -0
  230. package/dist/src/tools/mcp-tool.d.ts +23 -0
  231. package/dist/src/tools/mcp-tool.js +119 -0
  232. package/dist/src/tools/mcp-tool.js.map +1 -0
  233. package/dist/src/tools/mcp-tool.test.d.ts +6 -0
  234. package/dist/src/tools/mcp-tool.test.js +173 -0
  235. package/dist/src/tools/mcp-tool.test.js.map +1 -0
  236. package/dist/src/tools/memoryTool.d.ts +28 -0
  237. package/dist/src/tools/memoryTool.js +172 -0
  238. package/dist/src/tools/memoryTool.js.map +1 -0
  239. package/dist/src/tools/memoryTool.test.d.ts +6 -0
  240. package/dist/src/tools/memoryTool.test.js +181 -0
  241. package/dist/src/tools/memoryTool.test.js.map +1 -0
  242. package/dist/src/tools/modifiable-tool.d.ts +29 -0
  243. package/dist/src/tools/modifiable-tool.js +85 -0
  244. package/dist/src/tools/modifiable-tool.js.map +1 -0
  245. package/dist/src/tools/modifiable-tool.test.d.ts +6 -0
  246. package/dist/src/tools/modifiable-tool.test.js +204 -0
  247. package/dist/src/tools/modifiable-tool.test.js.map +1 -0
  248. package/dist/src/tools/read-file.d.ts +35 -0
  249. package/dist/src/tools/read-file.js +106 -0
  250. package/dist/src/tools/read-file.js.map +1 -0
  251. package/dist/src/tools/read-file.test.d.ts +6 -0
  252. package/dist/src/tools/read-file.test.js +181 -0
  253. package/dist/src/tools/read-file.test.js.map +1 -0
  254. package/dist/src/tools/read-many-files.d.ts +59 -0
  255. package/dist/src/tools/read-many-files.js +321 -0
  256. package/dist/src/tools/read-many-files.js.map +1 -0
  257. package/dist/src/tools/read-many-files.test.d.ts +6 -0
  258. package/dist/src/tools/read-many-files.test.js +312 -0
  259. package/dist/src/tools/read-many-files.test.js.map +1 -0
  260. package/dist/src/tools/shell.d.ts +43 -0
  261. package/dist/src/tools/shell.js +435 -0
  262. package/dist/src/tools/shell.js.map +1 -0
  263. package/dist/src/tools/shell.test.d.ts +6 -0
  264. package/dist/src/tools/shell.test.js +407 -0
  265. package/dist/src/tools/shell.test.js.map +1 -0
  266. package/dist/src/tools/todo-read.d.ts +15 -0
  267. package/dist/src/tools/todo-read.js +66 -0
  268. package/dist/src/tools/todo-read.js.map +1 -0
  269. package/dist/src/tools/todo-read.test.d.ts +6 -0
  270. package/dist/src/tools/todo-read.test.js +158 -0
  271. package/dist/src/tools/todo-read.test.js.map +1 -0
  272. package/dist/src/tools/todo-schemas.d.ts +43 -0
  273. package/dist/src/tools/todo-schemas.js +16 -0
  274. package/dist/src/tools/todo-schemas.js.map +1 -0
  275. package/dist/src/tools/todo-schemas.test.d.ts +6 -0
  276. package/dist/src/tools/todo-schemas.test.js +152 -0
  277. package/dist/src/tools/todo-schemas.test.js.map +1 -0
  278. package/dist/src/tools/todo-store.d.ts +15 -0
  279. package/dist/src/tools/todo-store.js +59 -0
  280. package/dist/src/tools/todo-store.js.map +1 -0
  281. package/dist/src/tools/todo-store.test.d.ts +6 -0
  282. package/dist/src/tools/todo-store.test.js +175 -0
  283. package/dist/src/tools/todo-store.test.js.map +1 -0
  284. package/dist/src/tools/todo-write.d.ts +17 -0
  285. package/dist/src/tools/todo-write.js +98 -0
  286. package/dist/src/tools/todo-write.js.map +1 -0
  287. package/dist/src/tools/todo-write.test.d.ts +6 -0
  288. package/dist/src/tools/todo-write.test.js +208 -0
  289. package/dist/src/tools/todo-write.test.js.map +1 -0
  290. package/dist/src/tools/tool-registry.d.ts +67 -0
  291. package/dist/src/tools/tool-registry.js +326 -0
  292. package/dist/src/tools/tool-registry.js.map +1 -0
  293. package/dist/src/tools/tool-registry.test.d.ts +6 -0
  294. package/dist/src/tools/tool-registry.test.js +398 -0
  295. package/dist/src/tools/tool-registry.test.js.map +1 -0
  296. package/dist/src/tools/tools.d.ts +184 -0
  297. package/dist/src/tools/tools.js +88 -0
  298. package/dist/src/tools/tools.js.map +1 -0
  299. package/dist/src/tools/web-fetch.d.ts +29 -0
  300. package/dist/src/tools/web-fetch.js +243 -0
  301. package/dist/src/tools/web-fetch.js.map +1 -0
  302. package/dist/src/tools/web-fetch.test.d.ts +6 -0
  303. package/dist/src/tools/web-fetch.test.js +70 -0
  304. package/dist/src/tools/web-fetch.test.js.map +1 -0
  305. package/dist/src/tools/web-search.d.ts +49 -0
  306. package/dist/src/tools/web-search.js +120 -0
  307. package/dist/src/tools/web-search.js.map +1 -0
  308. package/dist/src/tools/write-file.d.ts +42 -0
  309. package/dist/src/tools/write-file.js +248 -0
  310. package/dist/src/tools/write-file.js.map +1 -0
  311. package/dist/src/tools/write-file.test.d.ts +6 -0
  312. package/dist/src/tools/write-file.test.js +413 -0
  313. package/dist/src/tools/write-file.test.js.map +1 -0
  314. package/dist/src/utils/LruCache.d.ts +13 -0
  315. package/dist/src/utils/LruCache.js +38 -0
  316. package/dist/src/utils/LruCache.js.map +1 -0
  317. package/dist/src/utils/bfsFileSearch.d.ts +22 -0
  318. package/dist/src/utils/bfsFileSearch.js +62 -0
  319. package/dist/src/utils/bfsFileSearch.js.map +1 -0
  320. package/dist/src/utils/bfsFileSearch.test.d.ts +6 -0
  321. package/dist/src/utils/bfsFileSearch.test.js +129 -0
  322. package/dist/src/utils/bfsFileSearch.test.js.map +1 -0
  323. package/dist/src/utils/editCorrector.d.ts +53 -0
  324. package/dist/src/utils/editCorrector.js +546 -0
  325. package/dist/src/utils/editCorrector.js.map +1 -0
  326. package/dist/src/utils/editCorrector.test.d.ts +6 -0
  327. package/dist/src/utils/editCorrector.test.js +564 -0
  328. package/dist/src/utils/editCorrector.test.js.map +1 -0
  329. package/dist/src/utils/editor.d.ts +28 -0
  330. package/dist/src/utils/editor.js +163 -0
  331. package/dist/src/utils/editor.js.map +1 -0
  332. package/dist/src/utils/editor.test.d.ts +6 -0
  333. package/dist/src/utils/editor.test.js +293 -0
  334. package/dist/src/utils/editor.test.js.map +1 -0
  335. package/dist/src/utils/errorReporting.d.ts +14 -0
  336. package/dist/src/utils/errorReporting.js +88 -0
  337. package/dist/src/utils/errorReporting.js.map +1 -0
  338. package/dist/src/utils/errorReporting.test.d.ts +6 -0
  339. package/dist/src/utils/errorReporting.test.js +124 -0
  340. package/dist/src/utils/errorReporting.test.js.map +1 -0
  341. package/dist/src/utils/errors.d.ts +14 -0
  342. package/dist/src/utils/errors.js +54 -0
  343. package/dist/src/utils/errors.js.map +1 -0
  344. package/dist/src/utils/fetch.d.ts +11 -0
  345. package/dist/src/utils/fetch.js +51 -0
  346. package/dist/src/utils/fetch.js.map +1 -0
  347. package/dist/src/utils/fileUtils.d.ts +49 -0
  348. package/dist/src/utils/fileUtils.js +286 -0
  349. package/dist/src/utils/fileUtils.js.map +1 -0
  350. package/dist/src/utils/fileUtils.test.d.ts +6 -0
  351. package/dist/src/utils/fileUtils.test.js +321 -0
  352. package/dist/src/utils/fileUtils.test.js.map +1 -0
  353. package/dist/src/utils/flashFallback.integration.test.d.ts +6 -0
  354. package/dist/src/utils/flashFallback.integration.test.js +112 -0
  355. package/dist/src/utils/flashFallback.integration.test.js.map +1 -0
  356. package/dist/src/utils/generateContentResponseUtilities.d.ts +14 -0
  357. package/dist/src/utils/generateContentResponseUtilities.js +92 -0
  358. package/dist/src/utils/generateContentResponseUtilities.js.map +1 -0
  359. package/dist/src/utils/generateContentResponseUtilities.test.d.ts +6 -0
  360. package/dist/src/utils/generateContentResponseUtilities.test.js +273 -0
  361. package/dist/src/utils/generateContentResponseUtilities.test.js.map +1 -0
  362. package/dist/src/utils/getFolderStructure.d.ts +30 -0
  363. package/dist/src/utils/getFolderStructure.js +247 -0
  364. package/dist/src/utils/getFolderStructure.js.map +1 -0
  365. package/dist/src/utils/getFolderStructure.test.d.ts +6 -0
  366. package/dist/src/utils/getFolderStructure.test.js +298 -0
  367. package/dist/src/utils/getFolderStructure.test.js.map +1 -0
  368. package/dist/src/utils/gitIgnoreParser.d.ts +20 -0
  369. package/dist/src/utils/gitIgnoreParser.js +64 -0
  370. package/dist/src/utils/gitIgnoreParser.js.map +1 -0
  371. package/dist/src/utils/gitIgnoreParser.test.d.ts +6 -0
  372. package/dist/src/utils/gitIgnoreParser.test.js +145 -0
  373. package/dist/src/utils/gitIgnoreParser.test.js.map +1 -0
  374. package/dist/src/utils/gitUtils.d.ts +17 -0
  375. package/dist/src/utils/gitUtils.js +61 -0
  376. package/dist/src/utils/gitUtils.js.map +1 -0
  377. package/dist/src/utils/memoryDiscovery.d.ts +14 -0
  378. package/dist/src/utils/memoryDiscovery.js +219 -0
  379. package/dist/src/utils/memoryDiscovery.js.map +1 -0
  380. package/dist/src/utils/memoryDiscovery.test.d.ts +6 -0
  381. package/dist/src/utils/memoryDiscovery.test.js +432 -0
  382. package/dist/src/utils/memoryDiscovery.test.js.map +1 -0
  383. package/dist/src/utils/memoryImportProcessor.d.ts +35 -0
  384. package/dist/src/utils/memoryImportProcessor.js +141 -0
  385. package/dist/src/utils/memoryImportProcessor.js.map +1 -0
  386. package/dist/src/utils/memoryImportProcessor.test.d.ts +6 -0
  387. package/dist/src/utils/memoryImportProcessor.test.js +170 -0
  388. package/dist/src/utils/memoryImportProcessor.test.js.map +1 -0
  389. package/dist/src/utils/messageInspectors.d.ts +8 -0
  390. package/dist/src/utils/messageInspectors.js +16 -0
  391. package/dist/src/utils/messageInspectors.js.map +1 -0
  392. package/dist/src/utils/nextSpeakerChecker.d.ts +12 -0
  393. package/dist/src/utils/nextSpeakerChecker.js +113 -0
  394. package/dist/src/utils/nextSpeakerChecker.js.map +1 -0
  395. package/dist/src/utils/nextSpeakerChecker.test.d.ts +6 -0
  396. package/dist/src/utils/nextSpeakerChecker.test.js +168 -0
  397. package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -0
  398. package/dist/src/utils/paths.d.ts +49 -0
  399. package/dist/src/utils/paths.js +145 -0
  400. package/dist/src/utils/paths.js.map +1 -0
  401. package/dist/src/utils/quotaErrorDetection.d.ts +22 -0
  402. package/dist/src/utils/quotaErrorDetection.js +67 -0
  403. package/dist/src/utils/quotaErrorDetection.js.map +1 -0
  404. package/dist/src/utils/retry.d.ts +21 -0
  405. package/dist/src/utils/retry.js +276 -0
  406. package/dist/src/utils/retry.js.map +1 -0
  407. package/dist/src/utils/retry.test.d.ts +6 -0
  408. package/dist/src/utils/retry.test.js +322 -0
  409. package/dist/src/utils/retry.test.js.map +1 -0
  410. package/dist/src/utils/safeJsonStringify.d.ts +13 -0
  411. package/dist/src/utils/safeJsonStringify.js +25 -0
  412. package/dist/src/utils/safeJsonStringify.js.map +1 -0
  413. package/dist/src/utils/safeJsonStringify.test.d.ts +6 -0
  414. package/dist/src/utils/safeJsonStringify.test.js +61 -0
  415. package/dist/src/utils/safeJsonStringify.test.js.map +1 -0
  416. package/dist/src/utils/schemaValidator.d.ts +23 -0
  417. package/dist/src/utils/schemaValidator.js +142 -0
  418. package/dist/src/utils/schemaValidator.js.map +1 -0
  419. package/dist/src/utils/schemaValidator.test.d.ts +6 -0
  420. package/dist/src/utils/schemaValidator.test.js +146 -0
  421. package/dist/src/utils/schemaValidator.test.js.map +1 -0
  422. package/dist/src/utils/session.d.ts +6 -0
  423. package/dist/src/utils/session.js +8 -0
  424. package/dist/src/utils/session.js.map +1 -0
  425. package/dist/src/utils/summarizer.d.ts +25 -0
  426. package/dist/src/utils/summarizer.js +80 -0
  427. package/dist/src/utils/summarizer.js.map +1 -0
  428. package/dist/src/utils/summarizer.test.d.ts +6 -0
  429. package/dist/src/utils/summarizer.test.js +131 -0
  430. package/dist/src/utils/summarizer.test.js.map +1 -0
  431. package/dist/src/utils/testUtils.d.ts +29 -0
  432. package/dist/src/utils/testUtils.js +70 -0
  433. package/dist/src/utils/testUtils.js.map +1 -0
  434. package/dist/src/utils/user_account.d.ts +9 -0
  435. package/dist/src/utils/user_account.js +99 -0
  436. package/dist/src/utils/user_account.js.map +1 -0
  437. package/dist/src/utils/user_account.test.d.ts +6 -0
  438. package/dist/src/utils/user_account.test.js +153 -0
  439. package/dist/src/utils/user_account.test.js.map +1 -0
  440. package/dist/src/utils/user_id.d.ts +11 -0
  441. package/dist/src/utils/user_id.js +49 -0
  442. package/dist/src/utils/user_id.js.map +1 -0
  443. package/dist/src/utils/user_id.test.d.ts +6 -0
  444. package/dist/src/utils/user_id.test.js +21 -0
  445. package/dist/src/utils/user_id.test.js.map +1 -0
  446. package/dist/tsconfig.tsbuildinfo +1 -0
  447. package/dist/vybestack-llxprt-code-core-0.1.12.tgz +0 -0
  448. package/package.json +62 -0
@@ -0,0 +1,321 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { BaseTool } from './tools.js';
7
+ import { SchemaValidator } from '../utils/schemaValidator.js';
8
+ import { getErrorMessage } from '../utils/errors.js';
9
+ import * as path from 'path';
10
+ import { glob } from 'glob';
11
+ import { getCurrentLlxprtMdFilename } from './memoryTool.js';
12
+ import { detectFileType, processSingleFileContent, DEFAULT_ENCODING, getSpecificMimeType, } from '../utils/fileUtils.js';
13
+ import { Type } from '@google/genai';
14
+ import { recordFileOperationMetric, FileOperation, } from '../telemetry/metrics.js';
15
+ /**
16
+ * Default exclusion patterns for commonly ignored directories and binary file types.
17
+ * These are compatible with glob ignore patterns.
18
+ * TODO(adh): Consider making this configurable or extendable through a command line argument.
19
+ * TODO(adh): Look into sharing this list with the glob tool.
20
+ */
21
+ const DEFAULT_EXCLUDES = [
22
+ '**/node_modules/**',
23
+ '**/.git/**',
24
+ '**/.vscode/**',
25
+ '**/.idea/**',
26
+ '**/dist/**',
27
+ '**/build/**',
28
+ '**/coverage/**',
29
+ '**/__pycache__/**',
30
+ '**/*.pyc',
31
+ '**/*.pyo',
32
+ '**/*.bin',
33
+ '**/*.exe',
34
+ '**/*.dll',
35
+ '**/*.so',
36
+ '**/*.dylib',
37
+ '**/*.class',
38
+ '**/*.jar',
39
+ '**/*.war',
40
+ '**/*.zip',
41
+ '**/*.tar',
42
+ '**/*.gz',
43
+ '**/*.bz2',
44
+ '**/*.rar',
45
+ '**/*.7z',
46
+ '**/*.doc',
47
+ '**/*.docx',
48
+ '**/*.xls',
49
+ '**/*.xlsx',
50
+ '**/*.ppt',
51
+ '**/*.pptx',
52
+ '**/*.odt',
53
+ '**/*.ods',
54
+ '**/*.odp',
55
+ '**/*.DS_Store',
56
+ '**/.env',
57
+ `**/${getCurrentLlxprtMdFilename()}`,
58
+ ];
59
+ const DEFAULT_OUTPUT_SEPARATOR_FORMAT = '--- {filePath} ---';
60
+ /**
61
+ * Tool implementation for finding and reading multiple text files from the local filesystem
62
+ * within a specified target directory. The content is concatenated.
63
+ * It is intended to run in an environment with access to the local file system (e.g., a Node.js backend).
64
+ */
65
+ export class ReadManyFilesTool extends BaseTool {
66
+ config;
67
+ static Name = 'read_many_files';
68
+ llxprtIgnorePatterns = [];
69
+ constructor(config) {
70
+ const parameterSchema = {
71
+ type: Type.OBJECT,
72
+ properties: {
73
+ paths: {
74
+ type: Type.ARRAY,
75
+ items: {
76
+ type: Type.STRING,
77
+ minLength: '1',
78
+ },
79
+ minItems: '1',
80
+ description: "Required. An array of glob patterns or paths relative to the tool's target directory. Examples: ['src/**/*.ts'], ['README.md', 'docs/']",
81
+ },
82
+ include: {
83
+ type: Type.ARRAY,
84
+ items: {
85
+ type: Type.STRING,
86
+ minLength: '1',
87
+ },
88
+ description: 'Optional. Additional glob patterns to include. These are merged with `paths`. Example: ["*.test.ts"] to specifically add test files if they were broadly excluded.',
89
+ default: [],
90
+ },
91
+ exclude: {
92
+ type: Type.ARRAY,
93
+ items: {
94
+ type: Type.STRING,
95
+ minLength: '1',
96
+ },
97
+ description: 'Optional. Glob patterns for files/directories to exclude. Added to default excludes if useDefaultExcludes is true. Example: ["**/*.log", "temp/"]',
98
+ default: [],
99
+ },
100
+ recursive: {
101
+ type: Type.BOOLEAN,
102
+ description: 'Optional. Whether to search recursively (primarily controlled by `**` in glob patterns). Defaults to true.',
103
+ default: true,
104
+ },
105
+ useDefaultExcludes: {
106
+ type: Type.BOOLEAN,
107
+ description: 'Optional. Whether to apply a list of default exclusion patterns (e.g., node_modules, .git, binary files). Defaults to true.',
108
+ default: true,
109
+ },
110
+ respect_git_ignore: {
111
+ type: Type.BOOLEAN,
112
+ description: 'Optional. Whether to respect .gitignore patterns when discovering files. Only available in git repositories. Defaults to true.',
113
+ default: true,
114
+ },
115
+ },
116
+ required: ['paths'],
117
+ };
118
+ super(ReadManyFilesTool.Name, 'ReadManyFiles', `Reads content from multiple files specified by paths or glob patterns within a configured target directory. For text files, it concatenates their content into a single string. It is primarily designed for text-based files. However, it can also process image (e.g., .png, .jpg) and PDF (.pdf) files if their file names or extensions are explicitly included in the 'paths' argument. For these explicitly requested non-text files, their data is read and included in a format suitable for model consumption (e.g., base64 encoded).
119
+
120
+ This tool is useful when you need to understand or analyze a collection of files, such as:
121
+ - Getting an overview of a codebase or parts of it (e.g., all TypeScript files in the 'src' directory).
122
+ - Finding where specific functionality is implemented if the user asks broad questions about code.
123
+ - Reviewing documentation files (e.g., all Markdown files in the 'docs' directory).
124
+ - Gathering context from multiple configuration files.
125
+ - When the user asks to "read all files in X directory" or "show me the content of all Y files".
126
+
127
+ Use this tool when the user's query implies needing the content of several files simultaneously for context, analysis, or summarization. For text files, it uses default UTF-8 encoding and a '--- {filePath} ---' separator between file contents. Ensure paths are relative to the target directory. Glob patterns like 'src/**/*.js' are supported. Avoid using for single files if a more specific single-file reading tool is available, unless the user specifically requests to process a list containing just one file via this tool. Other binary files (not explicitly requested as image/PDF) are generally skipped. Default excludes apply to common non-text files (except for explicitly requested images/PDFs) and large dependency directories unless 'useDefaultExcludes' is false.`, parameterSchema);
128
+ this.config = config;
129
+ this.llxprtIgnorePatterns = config
130
+ .getFileService()
131
+ .getGeminiIgnorePatterns();
132
+ }
133
+ validateParams(params) {
134
+ const errors = SchemaValidator.validate(this.schema.parameters, params);
135
+ if (errors) {
136
+ return errors;
137
+ }
138
+ return null;
139
+ }
140
+ getDescription(params) {
141
+ const allPatterns = [...params.paths, ...(params.include || [])];
142
+ const pathDesc = `using patterns: \`${allPatterns.join('`, `')}\` (within target directory: \`${this.config.getTargetDir()}\`)`;
143
+ // Determine the final list of exclusion patterns exactly as in execute method
144
+ const paramExcludes = params.exclude || [];
145
+ const paramUseDefaultExcludes = params.useDefaultExcludes !== false;
146
+ const finalExclusionPatternsForDescription = paramUseDefaultExcludes
147
+ ? [...DEFAULT_EXCLUDES, ...paramExcludes, ...this.llxprtIgnorePatterns]
148
+ : [...paramExcludes, ...this.llxprtIgnorePatterns];
149
+ let excludeDesc = `Excluding: ${finalExclusionPatternsForDescription.length > 0 ? `patterns like \`${finalExclusionPatternsForDescription.slice(0, 2).join('`, `')}${finalExclusionPatternsForDescription.length > 2 ? '...`' : '`'}` : 'none specified'}`;
150
+ // Add a note if .llxprtignore patterns contributed to the final list of exclusions
151
+ if (this.llxprtIgnorePatterns.length > 0) {
152
+ const geminiPatternsInEffect = this.llxprtIgnorePatterns.filter((p) => finalExclusionPatternsForDescription.includes(p)).length;
153
+ if (geminiPatternsInEffect > 0) {
154
+ excludeDesc += ` (includes ${geminiPatternsInEffect} from .llxprtignore)`;
155
+ }
156
+ }
157
+ return `Will attempt to read and concatenate files ${pathDesc}. ${excludeDesc}. File encoding: ${DEFAULT_ENCODING}. Separator: "${DEFAULT_OUTPUT_SEPARATOR_FORMAT.replace('{filePath}', 'path/to/file.ext')}".`;
158
+ }
159
+ async execute(params, signal) {
160
+ const validationError = this.validateParams(params);
161
+ if (validationError) {
162
+ return {
163
+ llmContent: `Error: Invalid parameters for ${this.displayName}. Reason: ${validationError}`,
164
+ returnDisplay: `## Parameter Error\n\n${validationError}`,
165
+ };
166
+ }
167
+ const { paths: inputPatterns, include = [], exclude = [], useDefaultExcludes = true, respect_git_ignore = true, } = params;
168
+ const respectGitIgnore = respect_git_ignore ?? this.config.getFileFilteringRespectGitIgnore();
169
+ // Get centralized file discovery service
170
+ const fileDiscovery = this.config.getFileService();
171
+ const filesToConsider = new Set();
172
+ const skippedFiles = [];
173
+ const processedFilesRelativePaths = [];
174
+ const contentParts = [];
175
+ const effectiveExcludes = useDefaultExcludes
176
+ ? [...DEFAULT_EXCLUDES, ...exclude, ...this.llxprtIgnorePatterns]
177
+ : [...exclude, ...this.llxprtIgnorePatterns];
178
+ const searchPatterns = [...inputPatterns, ...include];
179
+ if (searchPatterns.length === 0) {
180
+ return {
181
+ llmContent: 'No search paths or include patterns provided.',
182
+ returnDisplay: `## Information\n\nNo search paths or include patterns were specified. Nothing to read or concatenate.`,
183
+ };
184
+ }
185
+ try {
186
+ const entries = await glob(searchPatterns, {
187
+ cwd: this.config.getTargetDir(),
188
+ ignore: effectiveExcludes,
189
+ nodir: true,
190
+ dot: true,
191
+ absolute: true,
192
+ nocase: true,
193
+ signal,
194
+ });
195
+ const filteredEntries = respectGitIgnore
196
+ ? fileDiscovery
197
+ .filterFiles(entries.map((p) => path.relative(this.config.getTargetDir(), p)), {
198
+ respectGitIgnore,
199
+ })
200
+ .map((p) => path.resolve(this.config.getTargetDir(), p))
201
+ : entries;
202
+ let gitIgnoredCount = 0;
203
+ for (const absoluteFilePath of entries) {
204
+ // Security check: ensure the glob library didn't return something outside targetDir.
205
+ if (!absoluteFilePath.startsWith(this.config.getTargetDir())) {
206
+ skippedFiles.push({
207
+ path: absoluteFilePath,
208
+ reason: `Security: Glob library returned path outside target directory. Base: ${this.config.getTargetDir()}, Path: ${absoluteFilePath}`,
209
+ });
210
+ continue;
211
+ }
212
+ // Check if this file was filtered out by git ignore
213
+ if (respectGitIgnore && !filteredEntries.includes(absoluteFilePath)) {
214
+ gitIgnoredCount++;
215
+ continue;
216
+ }
217
+ filesToConsider.add(absoluteFilePath);
218
+ }
219
+ // Add info about git-ignored files if any were filtered
220
+ if (gitIgnoredCount > 0) {
221
+ skippedFiles.push({
222
+ path: `${gitIgnoredCount} file(s)`,
223
+ reason: 'ignored',
224
+ });
225
+ }
226
+ }
227
+ catch (error) {
228
+ return {
229
+ llmContent: `Error during file search: ${getErrorMessage(error)}`,
230
+ returnDisplay: `## File Search Error\n\nAn error occurred while searching for files:\n\`\`\`\n${getErrorMessage(error)}\n\`\`\``,
231
+ };
232
+ }
233
+ const sortedFiles = Array.from(filesToConsider).sort();
234
+ for (const filePath of sortedFiles) {
235
+ const relativePathForDisplay = path
236
+ .relative(this.config.getTargetDir(), filePath)
237
+ .replace(/\\/g, '/');
238
+ const fileType = detectFileType(filePath);
239
+ if (fileType === 'image' || fileType === 'pdf') {
240
+ const fileExtension = path.extname(filePath).toLowerCase();
241
+ const fileNameWithoutExtension = path.basename(filePath, fileExtension);
242
+ const requestedExplicitly = inputPatterns.some((pattern) => pattern.toLowerCase().includes(fileExtension) ||
243
+ pattern.includes(fileNameWithoutExtension));
244
+ if (!requestedExplicitly) {
245
+ skippedFiles.push({
246
+ path: relativePathForDisplay,
247
+ reason: 'asset file (image/pdf) was not explicitly requested by name or extension',
248
+ });
249
+ continue;
250
+ }
251
+ }
252
+ // Use processSingleFileContent for all file types now
253
+ const fileReadResult = await processSingleFileContent(filePath, this.config.getTargetDir());
254
+ if (fileReadResult.error) {
255
+ skippedFiles.push({
256
+ path: relativePathForDisplay,
257
+ reason: `Read error: ${fileReadResult.error}`,
258
+ });
259
+ }
260
+ else {
261
+ if (typeof fileReadResult.llmContent === 'string') {
262
+ const separator = DEFAULT_OUTPUT_SEPARATOR_FORMAT.replace('{filePath}', filePath);
263
+ contentParts.push(`${separator}\n\n${fileReadResult.llmContent}\n\n`);
264
+ }
265
+ else {
266
+ contentParts.push(fileReadResult.llmContent); // This is a Part for image/pdf
267
+ }
268
+ processedFilesRelativePaths.push(relativePathForDisplay);
269
+ const lines = typeof fileReadResult.llmContent === 'string'
270
+ ? fileReadResult.llmContent.split('\n').length
271
+ : undefined;
272
+ const mimetype = getSpecificMimeType(filePath);
273
+ recordFileOperationMetric(this.config, FileOperation.READ, lines, mimetype, path.extname(filePath));
274
+ }
275
+ }
276
+ let displayMessage = `### ReadManyFiles Result (Target Dir: \`${this.config.getTargetDir()}\`)\n\n`;
277
+ if (processedFilesRelativePaths.length > 0) {
278
+ displayMessage += `Successfully read and concatenated content from **${processedFilesRelativePaths.length} file(s)**.\n`;
279
+ if (processedFilesRelativePaths.length <= 10) {
280
+ displayMessage += `\n**Processed Files:**\n`;
281
+ processedFilesRelativePaths.forEach((p) => (displayMessage += `- \`${p}\`\n`));
282
+ }
283
+ else {
284
+ displayMessage += `\n**Processed Files (first 10 shown):**\n`;
285
+ processedFilesRelativePaths
286
+ .slice(0, 10)
287
+ .forEach((p) => (displayMessage += `- \`${p}\`\n`));
288
+ displayMessage += `- ...and ${processedFilesRelativePaths.length - 10} more.\n`;
289
+ }
290
+ }
291
+ if (skippedFiles.length > 0) {
292
+ if (processedFilesRelativePaths.length === 0) {
293
+ displayMessage += `No files were read and concatenated based on the criteria.\n`;
294
+ }
295
+ if (skippedFiles.length <= 5) {
296
+ displayMessage += `\n**Skipped ${skippedFiles.length} item(s):**\n`;
297
+ }
298
+ else {
299
+ displayMessage += `\n**Skipped ${skippedFiles.length} item(s) (first 5 shown):**\n`;
300
+ }
301
+ skippedFiles
302
+ .slice(0, 5)
303
+ .forEach((f) => (displayMessage += `- \`${f.path}\` (Reason: ${f.reason})\n`));
304
+ if (skippedFiles.length > 5) {
305
+ displayMessage += `- ...and ${skippedFiles.length - 5} more.\n`;
306
+ }
307
+ }
308
+ else if (processedFilesRelativePaths.length === 0 &&
309
+ skippedFiles.length === 0) {
310
+ displayMessage += `No files were read and concatenated based on the criteria.\n`;
311
+ }
312
+ if (contentParts.length === 0) {
313
+ contentParts.push('No files matching the criteria were found or all were skipped.');
314
+ }
315
+ return {
316
+ llmContent: contentParts,
317
+ returnDisplay: displayMessage.trim(),
318
+ };
319
+ }
320
+ }
321
+ //# sourceMappingURL=read-many-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-many-files.js","sourceRoot":"","sources":["../../../src/tools/read-many-files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export {};
@@ -0,0 +1,312 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
7
+ import { mockControl } from '../__mocks__/fs/promises.js';
8
+ import { ReadManyFilesTool } from './read-many-files.js';
9
+ import { FileDiscoveryService } from '../services/fileDiscoveryService.js';
10
+ import path from 'path';
11
+ import fs from 'fs'; // Actual fs for setup
12
+ import os from 'os';
13
+ vi.mock('mime-types', () => {
14
+ const lookup = (filename) => {
15
+ if (filename.endsWith('.ts') || filename.endsWith('.js')) {
16
+ return 'text/plain';
17
+ }
18
+ if (filename.endsWith('.png')) {
19
+ return 'image/png';
20
+ }
21
+ if (filename.endsWith('.pdf')) {
22
+ return 'application/pdf';
23
+ }
24
+ if (filename.endsWith('.mp3') || filename.endsWith('.wav')) {
25
+ return 'audio/mpeg';
26
+ }
27
+ if (filename.endsWith('.mp4') || filename.endsWith('.mov')) {
28
+ return 'video/mp4';
29
+ }
30
+ return false;
31
+ };
32
+ return {
33
+ default: {
34
+ lookup,
35
+ },
36
+ lookup,
37
+ };
38
+ });
39
+ describe('ReadManyFilesTool', () => {
40
+ let tool;
41
+ let tempRootDir;
42
+ let tempDirOutsideRoot;
43
+ let mockReadFileFn;
44
+ beforeEach(async () => {
45
+ tempRootDir = fs.mkdtempSync(path.join(os.tmpdir(), 'read-many-files-root-'));
46
+ tempDirOutsideRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'read-many-files-external-'));
47
+ fs.writeFileSync(path.join(tempRootDir, '.llxprtignore'), 'foo.*');
48
+ const fileService = new FileDiscoveryService(tempRootDir);
49
+ const mockConfig = {
50
+ getFileService: () => fileService,
51
+ getFileFilteringRespectGitIgnore: () => true,
52
+ getTargetDir: () => tempRootDir,
53
+ };
54
+ tool = new ReadManyFilesTool(mockConfig);
55
+ mockReadFileFn = mockControl.mockReadFile;
56
+ mockReadFileFn.mockReset();
57
+ mockReadFileFn.mockImplementation(async (filePath, options) => {
58
+ const fp = typeof filePath === 'string'
59
+ ? filePath
60
+ : filePath.toString();
61
+ if (fs.existsSync(fp)) {
62
+ const originalFs = await vi.importActual('fs');
63
+ return originalFs.promises.readFile(fp, options);
64
+ }
65
+ if (fp.endsWith('nonexistent-file.txt')) {
66
+ const err = new Error(`ENOENT: no such file or directory, open '${fp}'`);
67
+ err.code = 'ENOENT';
68
+ throw err;
69
+ }
70
+ if (fp.endsWith('unreadable.txt')) {
71
+ const err = new Error(`EACCES: permission denied, open '${fp}'`);
72
+ err.code = 'EACCES';
73
+ throw err;
74
+ }
75
+ if (fp.endsWith('.png'))
76
+ return Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]); // PNG header
77
+ if (fp.endsWith('.pdf'))
78
+ return Buffer.from('%PDF-1.4...'); // PDF start
79
+ if (fp.endsWith('binary.bin'))
80
+ return Buffer.from([0x00, 0x01, 0x02, 0x00, 0x03]);
81
+ const err = new Error(`ENOENT: no such file or directory, open '${fp}' (unmocked path)`);
82
+ err.code = 'ENOENT';
83
+ throw err;
84
+ });
85
+ });
86
+ afterEach(() => {
87
+ if (fs.existsSync(tempRootDir)) {
88
+ fs.rmSync(tempRootDir, { recursive: true, force: true });
89
+ }
90
+ if (fs.existsSync(tempDirOutsideRoot)) {
91
+ fs.rmSync(tempDirOutsideRoot, { recursive: true, force: true });
92
+ }
93
+ });
94
+ describe('validateParams', () => {
95
+ it('should return null for valid relative paths within root', () => {
96
+ const params = { paths: ['file1.txt', 'subdir/file2.txt'] };
97
+ expect(tool.validateParams(params)).toBeNull();
98
+ });
99
+ it('should return null for valid glob patterns within root', () => {
100
+ const params = { paths: ['*.txt', 'subdir/**/*.js'] };
101
+ expect(tool.validateParams(params)).toBeNull();
102
+ });
103
+ it('should return null for paths trying to escape the root (e.g., ../) as execute handles this', () => {
104
+ const params = { paths: ['../outside.txt'] };
105
+ expect(tool.validateParams(params)).toBeNull();
106
+ });
107
+ it('should return null for absolute paths as execute handles this', () => {
108
+ const params = { paths: [path.join(tempDirOutsideRoot, 'absolute.txt')] };
109
+ expect(tool.validateParams(params)).toBeNull();
110
+ });
111
+ it('should return error if paths array is empty', () => {
112
+ const params = { paths: [] };
113
+ expect(tool.validateParams(params)).toBe('params/paths must NOT have fewer than 1 items');
114
+ });
115
+ it('should return null for valid exclude and include patterns', () => {
116
+ const params = {
117
+ paths: ['src/**/*.ts'],
118
+ exclude: ['**/*.test.ts'],
119
+ include: ['src/utils/*.ts'],
120
+ };
121
+ expect(tool.validateParams(params)).toBeNull();
122
+ });
123
+ it('should return error if paths array contains an empty string', () => {
124
+ const params = { paths: ['file1.txt', ''] };
125
+ expect(tool.validateParams(params)).toBe('params/paths/1 must NOT have fewer than 1 characters');
126
+ });
127
+ it('should return error if include array contains non-string elements', () => {
128
+ const params = {
129
+ paths: ['file1.txt'],
130
+ include: ['*.ts', 123],
131
+ };
132
+ expect(tool.validateParams(params)).toBe('params/include/1 must be string');
133
+ });
134
+ it('should return error if exclude array contains non-string elements', () => {
135
+ const params = {
136
+ paths: ['file1.txt'],
137
+ exclude: ['*.log', {}],
138
+ };
139
+ expect(tool.validateParams(params)).toBe('params/exclude/1 must be string');
140
+ });
141
+ });
142
+ describe('execute', () => {
143
+ const createFile = (filePath, content = '') => {
144
+ const fullPath = path.join(tempRootDir, filePath);
145
+ fs.mkdirSync(path.dirname(fullPath), { recursive: true });
146
+ fs.writeFileSync(fullPath, content);
147
+ };
148
+ const createBinaryFile = (filePath, data) => {
149
+ const fullPath = path.join(tempRootDir, filePath);
150
+ fs.mkdirSync(path.dirname(fullPath), { recursive: true });
151
+ fs.writeFileSync(fullPath, data);
152
+ };
153
+ it('should read a single specified file', async () => {
154
+ createFile('file1.txt', 'Content of file1');
155
+ const params = { paths: ['file1.txt'] };
156
+ const result = await tool.execute(params, new AbortController().signal);
157
+ const expectedPath = path.join(tempRootDir, 'file1.txt');
158
+ expect(result.llmContent).toEqual([
159
+ `--- ${expectedPath} ---\n\nContent of file1\n\n`,
160
+ ]);
161
+ expect(result.returnDisplay).toContain('Successfully read and concatenated content from **1 file(s)**');
162
+ });
163
+ it('should read multiple specified files', async () => {
164
+ createFile('file1.txt', 'Content1');
165
+ createFile('subdir/file2.js', 'Content2');
166
+ const params = { paths: ['file1.txt', 'subdir/file2.js'] };
167
+ const result = await tool.execute(params, new AbortController().signal);
168
+ const content = result.llmContent;
169
+ const expectedPath1 = path.join(tempRootDir, 'file1.txt');
170
+ const expectedPath2 = path.join(tempRootDir, 'subdir/file2.js');
171
+ expect(content.some((c) => c.includes(`--- ${expectedPath1} ---\n\nContent1\n\n`))).toBe(true);
172
+ expect(content.some((c) => c.includes(`--- ${expectedPath2} ---\n\nContent2\n\n`))).toBe(true);
173
+ expect(result.returnDisplay).toContain('Successfully read and concatenated content from **2 file(s)**');
174
+ });
175
+ it('should handle glob patterns', async () => {
176
+ createFile('file.txt', 'Text file');
177
+ createFile('another.txt', 'Another text');
178
+ createFile('sub/data.json', '{}');
179
+ const params = { paths: ['*.txt'] };
180
+ const result = await tool.execute(params, new AbortController().signal);
181
+ const content = result.llmContent;
182
+ const expectedPath1 = path.join(tempRootDir, 'file.txt');
183
+ const expectedPath2 = path.join(tempRootDir, 'another.txt');
184
+ expect(content.some((c) => c.includes(`--- ${expectedPath1} ---\n\nText file\n\n`))).toBe(true);
185
+ expect(content.some((c) => c.includes(`--- ${expectedPath2} ---\n\nAnother text\n\n`))).toBe(true);
186
+ expect(content.find((c) => c.includes('sub/data.json'))).toBeUndefined();
187
+ expect(result.returnDisplay).toContain('Successfully read and concatenated content from **2 file(s)**');
188
+ });
189
+ it('should respect exclude patterns', async () => {
190
+ createFile('src/main.ts', 'Main content');
191
+ createFile('src/main.test.ts', 'Test content');
192
+ const params = { paths: ['src/**/*.ts'], exclude: ['**/*.test.ts'] };
193
+ const result = await tool.execute(params, new AbortController().signal);
194
+ const content = result.llmContent;
195
+ const expectedPath = path.join(tempRootDir, 'src/main.ts');
196
+ expect(content).toEqual([`--- ${expectedPath} ---\n\nMain content\n\n`]);
197
+ expect(content.find((c) => c.includes('src/main.test.ts'))).toBeUndefined();
198
+ expect(result.returnDisplay).toContain('Successfully read and concatenated content from **1 file(s)**');
199
+ });
200
+ it('should handle non-existent specific files gracefully', async () => {
201
+ const params = { paths: ['nonexistent-file.txt'] };
202
+ const result = await tool.execute(params, new AbortController().signal);
203
+ expect(result.llmContent).toEqual([
204
+ 'No files matching the criteria were found or all were skipped.',
205
+ ]);
206
+ expect(result.returnDisplay).toContain('No files were read and concatenated based on the criteria.');
207
+ });
208
+ it('should use default excludes', async () => {
209
+ createFile('node_modules/some-lib/index.js', 'lib code');
210
+ createFile('src/app.js', 'app code');
211
+ const params = { paths: ['**/*.js'] };
212
+ const result = await tool.execute(params, new AbortController().signal);
213
+ const content = result.llmContent;
214
+ const expectedPath = path.join(tempRootDir, 'src/app.js');
215
+ expect(content).toEqual([`--- ${expectedPath} ---\n\napp code\n\n`]);
216
+ expect(content.find((c) => c.includes('node_modules/some-lib/index.js'))).toBeUndefined();
217
+ expect(result.returnDisplay).toContain('Successfully read and concatenated content from **1 file(s)**');
218
+ });
219
+ it('should NOT use default excludes if useDefaultExcludes is false', async () => {
220
+ createFile('node_modules/some-lib/index.js', 'lib code');
221
+ createFile('src/app.js', 'app code');
222
+ const params = { paths: ['**/*.js'], useDefaultExcludes: false };
223
+ const result = await tool.execute(params, new AbortController().signal);
224
+ const content = result.llmContent;
225
+ const expectedPath1 = path.join(tempRootDir, 'node_modules/some-lib/index.js');
226
+ const expectedPath2 = path.join(tempRootDir, 'src/app.js');
227
+ expect(content.some((c) => c.includes(`--- ${expectedPath1} ---\n\nlib code\n\n`))).toBe(true);
228
+ expect(content.some((c) => c.includes(`--- ${expectedPath2} ---\n\napp code\n\n`))).toBe(true);
229
+ expect(result.returnDisplay).toContain('Successfully read and concatenated content from **2 file(s)**');
230
+ });
231
+ it('should include images as inlineData parts if explicitly requested by extension', async () => {
232
+ createBinaryFile('image.png', Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]));
233
+ const params = { paths: ['*.png'] }; // Explicitly requesting .png
234
+ const result = await tool.execute(params, new AbortController().signal);
235
+ expect(result.llmContent).toEqual([
236
+ {
237
+ inlineData: {
238
+ data: Buffer.from([
239
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,
240
+ ]).toString('base64'),
241
+ mimeType: 'image/png',
242
+ },
243
+ },
244
+ ]);
245
+ expect(result.returnDisplay).toContain('Successfully read and concatenated content from **1 file(s)**');
246
+ });
247
+ it('should include images as inlineData parts if explicitly requested by name', async () => {
248
+ createBinaryFile('myExactImage.png', Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]));
249
+ const params = { paths: ['myExactImage.png'] }; // Explicitly requesting by full name
250
+ const result = await tool.execute(params, new AbortController().signal);
251
+ expect(result.llmContent).toEqual([
252
+ {
253
+ inlineData: {
254
+ data: Buffer.from([
255
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,
256
+ ]).toString('base64'),
257
+ mimeType: 'image/png',
258
+ },
259
+ },
260
+ ]);
261
+ });
262
+ it('should skip PDF files if not explicitly requested by extension or name', async () => {
263
+ createBinaryFile('document.pdf', Buffer.from('%PDF-1.4...'));
264
+ createFile('notes.txt', 'text notes');
265
+ const params = { paths: ['*'] }; // Generic glob, not specific to .pdf
266
+ const result = await tool.execute(params, new AbortController().signal);
267
+ const content = result.llmContent;
268
+ const expectedPath = path.join(tempRootDir, 'notes.txt');
269
+ expect(content.some((c) => typeof c === 'string' &&
270
+ c.includes(`--- ${expectedPath} ---\n\ntext notes\n\n`))).toBe(true);
271
+ expect(result.returnDisplay).toContain('**Skipped 1 item(s):**');
272
+ expect(result.returnDisplay).toContain('- `document.pdf` (Reason: asset file (image/pdf) was not explicitly requested by name or extension)');
273
+ });
274
+ it('should include PDF files as inlineData parts if explicitly requested by extension', async () => {
275
+ createBinaryFile('important.pdf', Buffer.from('%PDF-1.4...'));
276
+ const params = { paths: ['*.pdf'] }; // Explicitly requesting .pdf files
277
+ const result = await tool.execute(params, new AbortController().signal);
278
+ expect(result.llmContent).toEqual([
279
+ {
280
+ inlineData: {
281
+ data: Buffer.from('%PDF-1.4...').toString('base64'),
282
+ mimeType: 'application/pdf',
283
+ },
284
+ },
285
+ ]);
286
+ });
287
+ it('should include PDF files as inlineData parts if explicitly requested by name', async () => {
288
+ createBinaryFile('report-final.pdf', Buffer.from('%PDF-1.4...'));
289
+ const params = { paths: ['report-final.pdf'] };
290
+ const result = await tool.execute(params, new AbortController().signal);
291
+ expect(result.llmContent).toEqual([
292
+ {
293
+ inlineData: {
294
+ data: Buffer.from('%PDF-1.4...').toString('base64'),
295
+ mimeType: 'application/pdf',
296
+ },
297
+ },
298
+ ]);
299
+ });
300
+ it('should return error if path is ignored by a .llxprtignore pattern', async () => {
301
+ createFile('foo.bar', '');
302
+ createFile('bar.ts', '');
303
+ createFile('foo.quux', '');
304
+ const params = { paths: ['foo.bar', 'bar.ts', 'foo.quux'] };
305
+ const result = await tool.execute(params, new AbortController().signal);
306
+ expect(result.returnDisplay).not.toContain('foo.bar');
307
+ expect(result.returnDisplay).not.toContain('foo.quux');
308
+ expect(result.returnDisplay).toContain('bar.ts');
309
+ });
310
+ });
311
+ });
312
+ //# sourceMappingURL=read-many-files.test.js.map