@j0hanz/filesystem-context-mcp 1.2.5 → 1.2.7

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 (291) hide show
  1. package/README.md +19 -16
  2. package/dist/__tests__/lib/errors-classify.test.d.ts +2 -0
  3. package/dist/__tests__/lib/errors-classify.test.d.ts.map +1 -0
  4. package/dist/__tests__/lib/errors-classify.test.js +53 -0
  5. package/dist/__tests__/lib/errors-classify.test.js.map +1 -0
  6. package/dist/__tests__/lib/errors-detailed.test.d.ts +2 -0
  7. package/dist/__tests__/lib/errors-detailed.test.d.ts.map +1 -0
  8. package/dist/__tests__/lib/errors-detailed.test.js +38 -0
  9. package/dist/__tests__/lib/errors-detailed.test.js.map +1 -0
  10. package/dist/__tests__/lib/errors-is-node-error.test.d.ts +2 -0
  11. package/dist/__tests__/lib/errors-is-node-error.test.d.ts.map +1 -0
  12. package/dist/__tests__/lib/errors-is-node-error.test.js +21 -0
  13. package/dist/__tests__/lib/errors-is-node-error.test.js.map +1 -0
  14. package/dist/__tests__/lib/errors-mcp-error.test.d.ts +2 -0
  15. package/dist/__tests__/lib/errors-mcp-error.test.d.ts.map +1 -0
  16. package/dist/__tests__/lib/errors-mcp-error.test.js +29 -0
  17. package/dist/__tests__/lib/errors-mcp-error.test.js.map +1 -0
  18. package/dist/__tests__/lib/errors-node-map.test.d.ts +2 -0
  19. package/dist/__tests__/lib/errors-node-map.test.d.ts.map +1 -0
  20. package/dist/__tests__/lib/errors-node-map.test.js +16 -0
  21. package/dist/__tests__/lib/errors-node-map.test.js.map +1 -0
  22. package/dist/__tests__/lib/errors-suggestion.test.d.ts +2 -0
  23. package/dist/__tests__/lib/errors-suggestion.test.d.ts.map +1 -0
  24. package/dist/__tests__/lib/errors-suggestion.test.js +11 -0
  25. package/dist/__tests__/lib/errors-suggestion.test.js.map +1 -0
  26. package/dist/__tests__/lib/file-operations/analyze-directory-edge-cases.test.d.ts +2 -0
  27. package/dist/__tests__/lib/file-operations/analyze-directory-edge-cases.test.d.ts.map +1 -0
  28. package/dist/__tests__/lib/file-operations/analyze-directory-edge-cases.test.js +15 -0
  29. package/dist/__tests__/lib/file-operations/analyze-directory-edge-cases.test.js.map +1 -0
  30. package/dist/__tests__/lib/file-operations/analyze-directory.test.d.ts +2 -0
  31. package/dist/__tests__/lib/file-operations/analyze-directory.test.d.ts.map +1 -0
  32. package/dist/__tests__/lib/file-operations/analyze-directory.test.js +28 -0
  33. package/dist/__tests__/lib/file-operations/analyze-directory.test.js.map +1 -0
  34. package/dist/__tests__/lib/file-operations/directory-tree-edge-cases.test.d.ts +2 -0
  35. package/dist/__tests__/lib/file-operations/directory-tree-edge-cases.test.d.ts.map +1 -0
  36. package/dist/__tests__/lib/file-operations/directory-tree-edge-cases.test.js +29 -0
  37. package/dist/__tests__/lib/file-operations/directory-tree-edge-cases.test.js.map +1 -0
  38. package/dist/__tests__/lib/file-operations/directory-tree.test.d.ts +2 -0
  39. package/dist/__tests__/lib/file-operations/directory-tree.test.d.ts.map +1 -0
  40. package/dist/__tests__/lib/file-operations/directory-tree.test.js +75 -0
  41. package/dist/__tests__/lib/file-operations/directory-tree.test.js.map +1 -0
  42. package/dist/__tests__/lib/file-operations/get-file-info.test.d.ts +2 -0
  43. package/dist/__tests__/lib/file-operations/get-file-info.test.d.ts.map +1 -0
  44. package/dist/__tests__/lib/file-operations/get-file-info.test.js +17 -0
  45. package/dist/__tests__/lib/file-operations/get-file-info.test.js.map +1 -0
  46. package/dist/__tests__/lib/file-operations/list-directory-edge-cases.test.d.ts +2 -0
  47. package/dist/__tests__/lib/file-operations/list-directory-edge-cases.test.d.ts.map +1 -0
  48. package/dist/__tests__/lib/file-operations/list-directory-edge-cases.test.js +21 -0
  49. package/dist/__tests__/lib/file-operations/list-directory-edge-cases.test.js.map +1 -0
  50. package/dist/__tests__/lib/file-operations/list-directory.test.d.ts +2 -0
  51. package/dist/__tests__/lib/file-operations/list-directory.test.d.ts.map +1 -0
  52. package/dist/__tests__/lib/file-operations/list-directory.test.js +31 -0
  53. package/dist/__tests__/lib/file-operations/list-directory.test.js.map +1 -0
  54. package/dist/__tests__/lib/file-operations/read-media-file.test.d.ts +2 -0
  55. package/dist/__tests__/lib/file-operations/read-media-file.test.d.ts.map +1 -0
  56. package/dist/__tests__/lib/file-operations/read-media-file.test.js +21 -0
  57. package/dist/__tests__/lib/file-operations/read-media-file.test.js.map +1 -0
  58. package/dist/__tests__/lib/file-operations/read-multiple-files-edge-cases.test.d.ts +2 -0
  59. package/dist/__tests__/lib/file-operations/read-multiple-files-edge-cases.test.d.ts.map +1 -0
  60. package/dist/__tests__/lib/file-operations/read-multiple-files-edge-cases.test.js +19 -0
  61. package/dist/__tests__/lib/file-operations/read-multiple-files-edge-cases.test.js.map +1 -0
  62. package/dist/__tests__/lib/file-operations/read-multiple-files.test.d.ts +2 -0
  63. package/dist/__tests__/lib/file-operations/read-multiple-files.test.d.ts.map +1 -0
  64. package/dist/__tests__/lib/file-operations/read-multiple-files.test.js +39 -0
  65. package/dist/__tests__/lib/file-operations/read-multiple-files.test.js.map +1 -0
  66. package/dist/__tests__/lib/file-operations/search-content-edge-cases.test.d.ts +2 -0
  67. package/dist/__tests__/lib/file-operations/search-content-edge-cases.test.d.ts.map +1 -0
  68. package/dist/__tests__/lib/file-operations/search-content-edge-cases.test.js +57 -0
  69. package/dist/__tests__/lib/file-operations/search-content-edge-cases.test.js.map +1 -0
  70. package/dist/__tests__/lib/file-operations/search-content.test.d.ts +2 -0
  71. package/dist/__tests__/lib/file-operations/search-content.test.d.ts.map +1 -0
  72. package/dist/__tests__/lib/file-operations/search-content.test.js +73 -0
  73. package/dist/__tests__/lib/file-operations/search-content.test.js.map +1 -0
  74. package/dist/__tests__/lib/file-operations/search-files-edge-cases.test.d.ts +2 -0
  75. package/dist/__tests__/lib/file-operations/search-files-edge-cases.test.d.ts.map +1 -0
  76. package/dist/__tests__/lib/file-operations/search-files-edge-cases.test.js +13 -0
  77. package/dist/__tests__/lib/file-operations/search-files-edge-cases.test.js.map +1 -0
  78. package/dist/__tests__/lib/file-operations/search-files.test.d.ts +2 -0
  79. package/dist/__tests__/lib/file-operations/search-files.test.d.ts.map +1 -0
  80. package/dist/__tests__/lib/file-operations/search-files.test.js +31 -0
  81. package/dist/__tests__/lib/file-operations/search-files.test.js.map +1 -0
  82. package/dist/__tests__/lib/file-operations.test.js +11 -0
  83. package/dist/__tests__/lib/file-operations.test.js.map +1 -1
  84. package/dist/__tests__/lib/fixtures/file-ops-fixture.d.ts +7 -0
  85. package/dist/__tests__/lib/fixtures/file-ops-fixture.d.ts.map +1 -0
  86. package/dist/__tests__/lib/fixtures/file-ops-fixture.js +87 -0
  87. package/dist/__tests__/lib/fixtures/file-ops-fixture.js.map +1 -0
  88. package/dist/__tests__/lib/fixtures/file-ops-hooks.d.ts +2 -0
  89. package/dist/__tests__/lib/fixtures/file-ops-hooks.d.ts.map +1 -0
  90. package/dist/__tests__/lib/fixtures/file-ops-hooks.js +13 -0
  91. package/dist/__tests__/lib/fixtures/file-ops-hooks.js.map +1 -0
  92. package/dist/__tests__/lib/fs-helpers/file-type.test.d.ts +2 -0
  93. package/dist/__tests__/lib/fs-helpers/file-type.test.d.ts.map +1 -0
  94. package/dist/__tests__/lib/fs-helpers/file-type.test.js +15 -0
  95. package/dist/__tests__/lib/fs-helpers/file-type.test.js.map +1 -0
  96. package/dist/__tests__/lib/fs-helpers/head-file-edge-cases.test.d.ts +2 -0
  97. package/dist/__tests__/lib/fs-helpers/head-file-edge-cases.test.d.ts.map +1 -0
  98. package/dist/__tests__/lib/fs-helpers/head-file-edge-cases.test.js +19 -0
  99. package/dist/__tests__/lib/fs-helpers/head-file-edge-cases.test.js.map +1 -0
  100. package/dist/__tests__/lib/fs-helpers/head-file.test.d.ts +2 -0
  101. package/dist/__tests__/lib/fs-helpers/head-file.test.d.ts.map +1 -0
  102. package/dist/__tests__/lib/fs-helpers/head-file.test.js +12 -0
  103. package/dist/__tests__/lib/fs-helpers/head-file.test.js.map +1 -0
  104. package/dist/__tests__/lib/fs-helpers/is-hidden.test.d.ts +2 -0
  105. package/dist/__tests__/lib/fs-helpers/is-hidden.test.d.ts.map +1 -0
  106. package/dist/__tests__/lib/fs-helpers/is-hidden.test.js +7 -0
  107. package/dist/__tests__/lib/fs-helpers/is-hidden.test.js.map +1 -0
  108. package/dist/__tests__/lib/fs-helpers/is-probably-binary.test.d.ts +2 -0
  109. package/dist/__tests__/lib/fs-helpers/is-probably-binary.test.d.ts.map +1 -0
  110. package/dist/__tests__/lib/fs-helpers/is-probably-binary.test.js +33 -0
  111. package/dist/__tests__/lib/fs-helpers/is-probably-binary.test.js.map +1 -0
  112. package/dist/__tests__/lib/fs-helpers/read-file-edge-cases.test.d.ts +2 -0
  113. package/dist/__tests__/lib/fs-helpers/read-file-edge-cases.test.d.ts.map +1 -0
  114. package/dist/__tests__/lib/fs-helpers/read-file-edge-cases.test.js +41 -0
  115. package/dist/__tests__/lib/fs-helpers/read-file-edge-cases.test.js.map +1 -0
  116. package/dist/__tests__/lib/fs-helpers/read-file.test.d.ts +2 -0
  117. package/dist/__tests__/lib/fs-helpers/read-file.test.d.ts.map +1 -0
  118. package/dist/__tests__/lib/fs-helpers/read-file.test.js +21 -0
  119. package/dist/__tests__/lib/fs-helpers/read-file.test.js.map +1 -0
  120. package/dist/__tests__/lib/fs-helpers/tail-file-edge-cases.test.d.ts +2 -0
  121. package/dist/__tests__/lib/fs-helpers/tail-file-edge-cases.test.d.ts.map +1 -0
  122. package/dist/__tests__/lib/fs-helpers/tail-file-edge-cases.test.js +26 -0
  123. package/dist/__tests__/lib/fs-helpers/tail-file-edge-cases.test.js.map +1 -0
  124. package/dist/__tests__/lib/fs-helpers/tail-file.test.d.ts +2 -0
  125. package/dist/__tests__/lib/fs-helpers/tail-file.test.d.ts.map +1 -0
  126. package/dist/__tests__/lib/fs-helpers/tail-file.test.js +11 -0
  127. package/dist/__tests__/lib/fs-helpers/tail-file.test.js.map +1 -0
  128. package/dist/__tests__/lib/path-validation.test.js +93 -104
  129. package/dist/__tests__/lib/path-validation.test.js.map +1 -1
  130. package/dist/__tests__/schemas/validators.test.js +111 -115
  131. package/dist/__tests__/schemas/validators.test.js.map +1 -1
  132. package/dist/__tests__/security/filesystem-boundary.test.js +41 -36
  133. package/dist/__tests__/security/filesystem-boundary.test.js.map +1 -1
  134. package/dist/instructions.md +20 -19
  135. package/dist/lib/constants.d.ts +2 -0
  136. package/dist/lib/constants.d.ts.map +1 -1
  137. package/dist/lib/constants.js +2 -0
  138. package/dist/lib/constants.js.map +1 -1
  139. package/dist/lib/errors.d.ts +2 -18
  140. package/dist/lib/errors.d.ts.map +1 -1
  141. package/dist/lib/errors.js +57 -29
  142. package/dist/lib/errors.js.map +1 -1
  143. package/dist/lib/file-operations/analyze-directory.d.ts +1 -0
  144. package/dist/lib/file-operations/analyze-directory.d.ts.map +1 -1
  145. package/dist/lib/file-operations/analyze-directory.js +91 -40
  146. package/dist/lib/file-operations/analyze-directory.js.map +1 -1
  147. package/dist/lib/file-operations/directory-helpers.d.ts +2 -19
  148. package/dist/lib/file-operations/directory-helpers.d.ts.map +1 -1
  149. package/dist/lib/file-operations/directory-helpers.js +26 -90
  150. package/dist/lib/file-operations/directory-helpers.js.map +1 -1
  151. package/dist/lib/file-operations/directory-tree-helpers.d.ts +38 -0
  152. package/dist/lib/file-operations/directory-tree-helpers.d.ts.map +1 -0
  153. package/dist/lib/file-operations/directory-tree-helpers.js +167 -0
  154. package/dist/lib/file-operations/directory-tree-helpers.js.map +1 -0
  155. package/dist/lib/file-operations/directory-tree.d.ts.map +1 -1
  156. package/dist/lib/file-operations/directory-tree.js +44 -154
  157. package/dist/lib/file-operations/directory-tree.js.map +1 -1
  158. package/dist/lib/file-operations/list-directory-helpers.d.ts +2 -1
  159. package/dist/lib/file-operations/list-directory-helpers.d.ts.map +1 -1
  160. package/dist/lib/file-operations/list-directory-helpers.js +16 -4
  161. package/dist/lib/file-operations/list-directory-helpers.js.map +1 -1
  162. package/dist/lib/file-operations/list-directory.d.ts +4 -2
  163. package/dist/lib/file-operations/list-directory.d.ts.map +1 -1
  164. package/dist/lib/file-operations/list-directory.js +42 -20
  165. package/dist/lib/file-operations/list-directory.js.map +1 -1
  166. package/dist/lib/file-operations/pattern-validator.d.ts +0 -10
  167. package/dist/lib/file-operations/pattern-validator.d.ts.map +1 -1
  168. package/dist/lib/file-operations/pattern-validator.js +44 -43
  169. package/dist/lib/file-operations/pattern-validator.js.map +1 -1
  170. package/dist/lib/file-operations/read-multiple-files.d.ts +3 -2
  171. package/dist/lib/file-operations/read-multiple-files.d.ts.map +1 -1
  172. package/dist/lib/file-operations/read-multiple-files.js +46 -29
  173. package/dist/lib/file-operations/read-multiple-files.js.map +1 -1
  174. package/dist/lib/file-operations/search/context-manager.d.ts +2 -0
  175. package/dist/lib/file-operations/search/context-manager.d.ts.map +1 -1
  176. package/dist/lib/file-operations/search/context-manager.js +11 -6
  177. package/dist/lib/file-operations/search/context-manager.js.map +1 -1
  178. package/dist/lib/file-operations/search/engine-options.d.ts +19 -0
  179. package/dist/lib/file-operations/search/engine-options.d.ts.map +1 -0
  180. package/dist/lib/file-operations/search/engine-options.js +32 -0
  181. package/dist/lib/file-operations/search/engine-options.js.map +1 -0
  182. package/dist/lib/file-operations/search/engine-stream.d.ts +6 -0
  183. package/dist/lib/file-operations/search/engine-stream.d.ts.map +1 -0
  184. package/dist/lib/file-operations/search/engine-stream.js +130 -0
  185. package/dist/lib/file-operations/search/engine-stream.js.map +1 -0
  186. package/dist/lib/file-operations/search/engine.d.ts +1 -17
  187. package/dist/lib/file-operations/search/engine.d.ts.map +1 -1
  188. package/dist/lib/file-operations/search/engine.js +7 -117
  189. package/dist/lib/file-operations/search/engine.js.map +1 -1
  190. package/dist/lib/file-operations/search/file-processor.d.ts.map +1 -1
  191. package/dist/lib/file-operations/search/file-processor.js +33 -25
  192. package/dist/lib/file-operations/search/file-processor.js.map +1 -1
  193. package/dist/lib/file-operations/search/match-strategy.d.ts.map +1 -1
  194. package/dist/lib/file-operations/search/match-strategy.js +49 -54
  195. package/dist/lib/file-operations/search/match-strategy.js.map +1 -1
  196. package/dist/lib/file-operations/search-files-helpers.d.ts +42 -0
  197. package/dist/lib/file-operations/search-files-helpers.d.ts.map +1 -0
  198. package/dist/lib/file-operations/search-files-helpers.js +180 -0
  199. package/dist/lib/file-operations/search-files-helpers.js.map +1 -0
  200. package/dist/lib/file-operations/search-files.d.ts +2 -9
  201. package/dist/lib/file-operations/search-files.d.ts.map +1 -1
  202. package/dist/lib/file-operations/search-files.js +8 -129
  203. package/dist/lib/file-operations/search-files.js.map +1 -1
  204. package/dist/lib/file-operations/sorting.d.ts +3 -2
  205. package/dist/lib/file-operations/sorting.d.ts.map +1 -1
  206. package/dist/lib/fs-helpers/binary-detect.d.ts.map +1 -1
  207. package/dist/lib/fs-helpers/binary-detect.js +16 -10
  208. package/dist/lib/fs-helpers/binary-detect.js.map +1 -1
  209. package/dist/lib/fs-helpers/fs-utils.d.ts.map +1 -1
  210. package/dist/lib/fs-helpers/fs-utils.js +16 -10
  211. package/dist/lib/fs-helpers/fs-utils.js.map +1 -1
  212. package/dist/lib/fs-helpers/readers/line-range.d.ts +4 -2
  213. package/dist/lib/fs-helpers/readers/line-range.d.ts.map +1 -1
  214. package/dist/lib/fs-helpers/readers/line-range.js +21 -15
  215. package/dist/lib/fs-helpers/readers/line-range.js.map +1 -1
  216. package/dist/lib/fs-helpers/readers/read-file.d.ts +6 -3
  217. package/dist/lib/fs-helpers/readers/read-file.d.ts.map +1 -1
  218. package/dist/lib/fs-helpers/readers/read-file.js +58 -19
  219. package/dist/lib/fs-helpers/readers/read-file.js.map +1 -1
  220. package/dist/lib/fs-helpers/readers/tail-file.d.ts.map +1 -1
  221. package/dist/lib/fs-helpers/readers/tail-file.js +27 -10
  222. package/dist/lib/fs-helpers/readers/tail-file.js.map +1 -1
  223. package/dist/lib/fs-helpers/readers/utf8.d.ts.map +1 -1
  224. package/dist/lib/fs-helpers/readers/utf8.js +20 -10
  225. package/dist/lib/fs-helpers/readers/utf8.js.map +1 -1
  226. package/dist/lib/path-validation/allowed-directories.d.ts +1 -2
  227. package/dist/lib/path-validation/allowed-directories.d.ts.map +1 -1
  228. package/dist/lib/path-validation/allowed-directories.js +25 -15
  229. package/dist/lib/path-validation/allowed-directories.js.map +1 -1
  230. package/dist/lib/path-validation/errors.d.ts +0 -1
  231. package/dist/lib/path-validation/errors.d.ts.map +1 -1
  232. package/dist/lib/path-validation/errors.js +26 -12
  233. package/dist/lib/path-validation/errors.js.map +1 -1
  234. package/dist/lib/path-validation/validators.d.ts +1 -0
  235. package/dist/lib/path-validation/validators.d.ts.map +1 -1
  236. package/dist/lib/path-validation/validators.js +26 -3
  237. package/dist/lib/path-validation/validators.js.map +1 -1
  238. package/dist/lib/path-validation.d.ts +2 -2
  239. package/dist/lib/path-validation.d.ts.map +1 -1
  240. package/dist/lib/path-validation.js +2 -2
  241. package/dist/lib/path-validation.js.map +1 -1
  242. package/dist/schemas/input-helpers.d.ts +2 -1
  243. package/dist/schemas/input-helpers.d.ts.map +1 -1
  244. package/dist/schemas/input-helpers.js +10 -1
  245. package/dist/schemas/input-helpers.js.map +1 -1
  246. package/dist/schemas/inputs.d.ts +2 -1
  247. package/dist/schemas/inputs.d.ts.map +1 -1
  248. package/dist/schemas/inputs.js +2 -1
  249. package/dist/schemas/inputs.js.map +1 -1
  250. package/dist/schemas/outputs.d.ts +12 -12
  251. package/dist/server.d.ts.map +1 -1
  252. package/dist/server.js +79 -35
  253. package/dist/server.js.map +1 -1
  254. package/dist/tools/analyze-directory.d.ts.map +1 -1
  255. package/dist/tools/analyze-directory.js +8 -34
  256. package/dist/tools/analyze-directory.js.map +1 -1
  257. package/dist/tools/directory-tree.d.ts.map +1 -1
  258. package/dist/tools/directory-tree.js +14 -35
  259. package/dist/tools/directory-tree.js.map +1 -1
  260. package/dist/tools/get-file-info.d.ts.map +1 -1
  261. package/dist/tools/get-file-info.js +4 -15
  262. package/dist/tools/get-file-info.js.map +1 -1
  263. package/dist/tools/list-allowed-dirs.d.ts.map +1 -1
  264. package/dist/tools/list-allowed-dirs.js +10 -3
  265. package/dist/tools/list-allowed-dirs.js.map +1 -1
  266. package/dist/tools/list-directory.d.ts.map +1 -1
  267. package/dist/tools/list-directory.js +30 -53
  268. package/dist/tools/list-directory.js.map +1 -1
  269. package/dist/tools/read-file.d.ts.map +1 -1
  270. package/dist/tools/read-file.js +31 -23
  271. package/dist/tools/read-file.js.map +1 -1
  272. package/dist/tools/read-media-file.d.ts.map +1 -1
  273. package/dist/tools/read-media-file.js +3 -3
  274. package/dist/tools/read-media-file.js.map +1 -1
  275. package/dist/tools/read-multiple-files.d.ts.map +1 -1
  276. package/dist/tools/read-multiple-files.js +19 -18
  277. package/dist/tools/read-multiple-files.js.map +1 -1
  278. package/dist/tools/search-content.d.ts.map +1 -1
  279. package/dist/tools/search-content.js +23 -20
  280. package/dist/tools/search-content.js.map +1 -1
  281. package/dist/tools/search-files.d.ts.map +1 -1
  282. package/dist/tools/search-files.js +4 -30
  283. package/dist/tools/search-files.js.map +1 -1
  284. package/dist/tools/shared/formatting.d.ts +13 -0
  285. package/dist/tools/shared/formatting.d.ts.map +1 -0
  286. package/dist/tools/shared/formatting.js +31 -0
  287. package/dist/tools/shared/formatting.js.map +1 -0
  288. package/dist/tools/shared/search-formatting.d.ts.map +1 -1
  289. package/dist/tools/shared/search-formatting.js +32 -33
  290. package/dist/tools/shared/search-formatting.js.map +1 -1
  291. package/package.json +1 -1
package/README.md CHANGED
@@ -155,21 +155,23 @@ If neither CLI arguments nor MCP Roots provide directories, the server automatic
155
155
 
156
156
  All configuration values have sensible defaults and are optional. Only configure if you need to tune performance or resource usage.
157
157
 
158
- | Variable | Default | Range | Description |
159
- | -------------------------------- | --------------- | ----------- | ------------------------------------- |
160
- | `FILESYSTEM_CONTEXT_CONCURRENCY` | Auto (2x cores) | 1-100 | Maximum parallel file operations |
161
- | `TRAVERSAL_JOBS` | 8 | 1-50 | Directory traversal concurrency |
162
- | `REGEX_TIMEOUT` | 100 | 50-1000 | Regex matching timeout (milliseconds) |
163
- | `MAX_FILE_SIZE` | 10MB | 1MB-100MB | Maximum text file size (bytes) |
164
- | `MAX_MEDIA_SIZE` | 50MB | 1MB-500MB | Maximum media file size (bytes) |
165
- | `MAX_SEARCH_SIZE` | 1MB | 100KB-10MB | Maximum file size for content search |
166
- | `DEFAULT_DEPTH` | 10 | 1-100 | Default maximum recursion depth |
167
- | `DEFAULT_RESULTS` | 100 | 10-10000 | Default maximum search results |
168
- | `DEFAULT_SEARCH_MAX_FILES` | 20000 | 100-100000 | Default max files to scan in searches |
169
- | `DEFAULT_SEARCH_TIMEOUT` | 30000 | 100-3600000 | Default search timeout (milliseconds) |
170
- | `DEFAULT_TOP` | 10 | 1-1000 | Default top N items in analysis |
171
- | `DEFAULT_TREE` | 5 | 1-50 | Default directory tree depth |
172
- | `DEFAULT_TREE_MAX_FILES` | 5000 | 100-200000 | Default max files in directory tree |
158
+ | Variable | Default | Range | Description |
159
+ | -------------------------------- | --------------- | ----------- | ---------------------------------------- |
160
+ | `FILESYSTEM_CONTEXT_CONCURRENCY` | Auto (2x cores) | 1-100 | Maximum parallel file operations |
161
+ | `TRAVERSAL_JOBS` | 8 | 1-50 | Directory traversal concurrency |
162
+ | `REGEX_TIMEOUT` | 100 | 50-1000 | Regex matching timeout (milliseconds) |
163
+ | `MAX_FILE_SIZE` | 10MB | 1MB-100MB | Maximum text file size (bytes) |
164
+ | `MAX_MEDIA_SIZE` | 50MB | 1MB-500MB | Maximum media file size (bytes) |
165
+ | `MAX_SEARCH_SIZE` | 1MB | 100KB-10MB | Maximum file size for content search |
166
+ | `DEFAULT_DEPTH` | 10 | 1-100 | Default maximum recursion depth |
167
+ | `DEFAULT_RESULTS` | 100 | 10-10000 | Default maximum search results |
168
+ | `DEFAULT_LIST_MAX_ENTRIES` | 10000 | 100-100000 | Default max entries for list_directory |
169
+ | `DEFAULT_SEARCH_MAX_FILES` | 20000 | 100-100000 | Default max files to scan in searches |
170
+ | `DEFAULT_SEARCH_TIMEOUT` | 30000 | 100-3600000 | Default search timeout (milliseconds) |
171
+ | `DEFAULT_TOP` | 10 | 1-1000 | Default top N items in analysis |
172
+ | `DEFAULT_ANALYZE_MAX_ENTRIES` | 20000 | 100-100000 | Default max entries in analyze_directory |
173
+ | `DEFAULT_TREE` | 5 | 1-50 | Default directory tree depth |
174
+ | `DEFAULT_TREE_MAX_FILES` | 5000 | 100-200000 | Default max files in directory tree |
173
175
 
174
176
  > **💡 Tip:** See [CONFIGURATION.md](CONFIGURATION.md) for detailed environment variable usage examples, configuration profiles, and best practices for different use cases.
175
177
 
@@ -197,7 +199,7 @@ List contents of a directory with optional recursive listing.
197
199
  | `recursive` | boolean | ❌ | `false` | List recursively |
198
200
  | `includeHidden` | boolean | ❌ | `false` | Include hidden files |
199
201
  | `maxDepth` | number | ❌ | `10` | Maximum depth for recursive listing (0-100) |
200
- | `maxEntries` | number | ❌ | - | Maximum entries to return (1-100,000) |
202
+ | `maxEntries` | number | ❌ | `10000` | Maximum entries to return (1-100,000) |
201
203
  | `sortBy` | string | ❌ | `name` | Sort by: `name`, `size`, `modified`, `type` |
202
204
  | `includeSymlinkTargets` | boolean | ❌ | `false` | Include symlink target paths |
203
205
 
@@ -330,6 +332,7 @@ Analyze a directory structure and return statistics.
330
332
  | `path` | string | ✅ | - | Directory to analyze |
331
333
  | `maxDepth` | number | ❌ | `10` | Maximum depth to analyze (0-100) |
332
334
  | `topN` | number | ❌ | `10` | Number of top items to return (max 1000) |
335
+ | `maxEntries` | number | ? | `20000` | Maximum entries to scan (1-100,000) |
333
336
  | `excludePatterns` | string[] | ❌ | `[]` | Glob patterns to exclude |
334
337
  | `includeHidden` | boolean | ❌ | `false` | Include hidden files and directories |
335
338
 
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=errors-classify.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-classify.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/lib/errors-classify.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,53 @@
1
+ import { expect, it } from 'vitest';
2
+ import { classifyError, ErrorCode, McpError } from '../../lib/errors.js';
3
+ it('classifyError classifies ENOENT messages as not found', () => {
4
+ const error = new Error('ENOENT: no such file or directory');
5
+ expect(classifyError(error)).toBe(ErrorCode.E_NOT_FOUND);
6
+ });
7
+ it('classifyError returns unknown for unrecognized message-only errors', () => {
8
+ const error = new Error('Some random error');
9
+ expect(classifyError(error)).toBe(ErrorCode.E_UNKNOWN);
10
+ });
11
+ it('classifyError handles non-Error objects', () => {
12
+ expect(classifyError('ENOENT error')).toBe(ErrorCode.E_NOT_FOUND);
13
+ expect(classifyError({ message: 'permission denied' })).toBe(ErrorCode.E_UNKNOWN);
14
+ });
15
+ it('classifyError classifies Node.js EACCES error code', () => {
16
+ const error = Object.assign(new Error('permission denied'), {
17
+ code: 'EACCES',
18
+ });
19
+ expect(classifyError(error)).toBe(ErrorCode.E_PERMISSION_DENIED);
20
+ });
21
+ it('classifyError classifies Node.js EPERM error code', () => {
22
+ const error = Object.assign(new Error('operation not permitted'), {
23
+ code: 'EPERM',
24
+ });
25
+ expect(classifyError(error)).toBe(ErrorCode.E_PERMISSION_DENIED);
26
+ });
27
+ it('classifyError classifies Node.js EISDIR error code', () => {
28
+ const error = Object.assign(new Error('is a directory'), { code: 'EISDIR' });
29
+ expect(classifyError(error)).toBe(ErrorCode.E_NOT_FILE);
30
+ });
31
+ it('classifyError classifies Node.js ENOTDIR error code', () => {
32
+ const error = Object.assign(new Error('not a directory'), {
33
+ code: 'ENOTDIR',
34
+ });
35
+ expect(classifyError(error)).toBe(ErrorCode.E_NOT_DIRECTORY);
36
+ });
37
+ it('classifyError classifies Node.js ELOOP error code', () => {
38
+ const error = Object.assign(new Error('too many symbolic links'), {
39
+ code: 'ELOOP',
40
+ });
41
+ expect(classifyError(error)).toBe(ErrorCode.E_SYMLINK_NOT_ALLOWED);
42
+ });
43
+ it('classifyError classifies Node.js ETIMEDOUT error code', () => {
44
+ const error = Object.assign(new Error('operation timed out'), {
45
+ code: 'ETIMEDOUT',
46
+ });
47
+ expect(classifyError(error)).toBe(ErrorCode.E_TIMEOUT);
48
+ });
49
+ it('classifyError classifies McpError directly by its code', () => {
50
+ const error = new McpError(ErrorCode.E_TOO_LARGE, 'File too large', '/path/to/file');
51
+ expect(classifyError(error)).toBe(ErrorCode.E_TOO_LARGE);
52
+ });
53
+ //# sourceMappingURL=errors-classify.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-classify.test.js","sourceRoot":"","sources":["../../../src/__tests__/lib/errors-classify.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=errors-detailed.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-detailed.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/lib/errors-detailed.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,38 @@
1
+ import { expect, it } from 'vitest';
2
+ import { createDetailedError, ErrorCode, formatDetailedError, McpError, } from '../../lib/errors.js';
3
+ it('createDetailedError creates detailed error object', () => {
4
+ const error = new McpError(ErrorCode.E_NOT_FOUND, 'File not found', '/some/path');
5
+ const detailed = createDetailedError(error, '/some/path');
6
+ expect(detailed.code).toBe(ErrorCode.E_NOT_FOUND);
7
+ expect(detailed.message).toBe('File not found');
8
+ expect(detailed.path).toBe('/some/path');
9
+ expect(detailed.suggestion).toBeTruthy();
10
+ });
11
+ it('createDetailedError includes additional details', () => {
12
+ const error = new Error('Error');
13
+ const detailed = createDetailedError(error, '/path', { extra: 'info' });
14
+ expect(detailed.details).toEqual({ extra: 'info' });
15
+ });
16
+ it('formatDetailedError formats error for display', () => {
17
+ const detailed = {
18
+ code: ErrorCode.E_NOT_FOUND,
19
+ message: 'File not found',
20
+ path: '/some/path',
21
+ suggestion: 'Check the path exists',
22
+ };
23
+ const formatted = formatDetailedError(detailed);
24
+ expect(formatted).toContain('E_NOT_FOUND');
25
+ expect(formatted).toContain('File not found');
26
+ expect(formatted).toContain('/some/path');
27
+ expect(formatted).toContain('Check the path exists');
28
+ });
29
+ it('formatDetailedError handles missing optional fields', () => {
30
+ const detailed = {
31
+ code: ErrorCode.E_UNKNOWN,
32
+ message: 'Unknown error',
33
+ };
34
+ const formatted = formatDetailedError(detailed);
35
+ expect(formatted).toContain('E_UNKNOWN');
36
+ expect(formatted).toContain('Unknown error');
37
+ });
38
+ //# sourceMappingURL=errors-detailed.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-detailed.test.js","sourceRoot":"","sources":["../../../src/__tests__/lib/errors-detailed.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,mBAAmB,EACnB,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAE7B,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;IAC3D,MAAM,KAAK,GAAG,IAAI,QAAQ,CACxB,SAAS,CAAC,WAAW,EACrB,gBAAgB,EAChB,YAAY,CACb,CAAC;IACF,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAE1D,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAClD,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAChD,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACzC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,UAAU,EAAE,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;IACzD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IACxE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;IACvD,MAAM,QAAQ,GAAG;QACf,IAAI,EAAE,SAAS,CAAC,WAAW;QAC3B,OAAO,EAAE,gBAAgB;QACzB,IAAI,EAAE,YAAY;QAClB,UAAU,EAAE,uBAAuB;KACpC,CAAC;IAEF,MAAM,SAAS,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAEhD,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IAC3C,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAC9C,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAC1C,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;AACvD,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;IAC7D,MAAM,QAAQ,GAAG;QACf,IAAI,EAAE,SAAS,CAAC,SAAS;QACzB,OAAO,EAAE,eAAe;KACzB,CAAC;IAEF,MAAM,SAAS,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAEhD,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACzC,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=errors-is-node-error.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-is-node-error.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/lib/errors-is-node-error.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import { expect, it } from 'vitest';
2
+ import { isNodeError } from '../../lib/errors.js';
3
+ it('isNodeError returns true for Node.js ErrnoException', () => {
4
+ const error = Object.assign(new Error('test'), { code: 'ENOENT' });
5
+ expect(isNodeError(error)).toBe(true);
6
+ });
7
+ it('isNodeError returns false for Error without code', () => {
8
+ const error = new Error('test');
9
+ expect(isNodeError(error)).toBe(false);
10
+ });
11
+ it('isNodeError returns false for non-Error objects', () => {
12
+ expect(isNodeError('string')).toBe(false);
13
+ expect(isNodeError({ code: 'ENOENT' })).toBe(false);
14
+ expect(isNodeError(null)).toBe(false);
15
+ expect(isNodeError(undefined)).toBe(false);
16
+ });
17
+ it('isNodeError returns false for Error with non-string code', () => {
18
+ const error = Object.assign(new Error('test'), { code: 123 });
19
+ expect(isNodeError(error)).toBe(false);
20
+ });
21
+ //# sourceMappingURL=errors-is-node-error.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-is-node-error.test.js","sourceRoot":"","sources":["../../../src/__tests__/lib/errors-is-node-error.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;IAC7D,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IACnE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAC1D,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;IAChC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;IACzD,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC7C,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;IAClE,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9D,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=errors-mcp-error.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-mcp-error.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/lib/errors-mcp-error.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ import { expect, it } from 'vitest';
2
+ import { ErrorCode, McpError } from '../../lib/errors.js';
3
+ it('McpError creates error with all properties', () => {
4
+ const error = new McpError(ErrorCode.E_ACCESS_DENIED, 'Access denied', '/some/path', { extra: 'detail' });
5
+ expect(error.code).toBe(ErrorCode.E_ACCESS_DENIED);
6
+ expect(error.message).toBe('Access denied');
7
+ expect(error.path).toBe('/some/path');
8
+ expect(error.details).toEqual({ extra: 'detail' });
9
+ expect(error.name).toBe('McpError');
10
+ });
11
+ it('McpError supports cause chaining', () => {
12
+ const cause = new Error('Original error');
13
+ const error = new McpError(ErrorCode.E_NOT_FOUND, 'File not found', '/path', undefined, cause);
14
+ expect(error.cause).toBe(cause);
15
+ });
16
+ it('McpError is instanceof Error', () => {
17
+ const error = new McpError(ErrorCode.E_UNKNOWN, 'Test');
18
+ expect(error instanceof Error).toBe(true);
19
+ expect(error instanceof McpError).toBe(true);
20
+ });
21
+ it('McpError.fromError wraps existing errors', () => {
22
+ const original = new Error('Original');
23
+ original.stack = 'Original stack trace';
24
+ const mcpError = McpError.fromError(ErrorCode.E_NOT_FOUND, 'Wrapped error', original, '/path');
25
+ expect(mcpError.code).toBe(ErrorCode.E_NOT_FOUND);
26
+ expect(mcpError.cause).toBe(original);
27
+ expect(mcpError.stack).toContain('Caused by: Original stack trace');
28
+ });
29
+ //# sourceMappingURL=errors-mcp-error.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-mcp-error.test.js","sourceRoot":"","sources":["../../../src/__tests__/lib/errors-mcp-error.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE1D,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;IACpD,MAAM,KAAK,GAAG,IAAI,QAAQ,CACxB,SAAS,CAAC,eAAe,EACzB,eAAe,EACf,YAAY,EACZ,EAAE,KAAK,EAAE,QAAQ,EAAE,CACpB,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IACnD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC5C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACtC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACnD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AACtC,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;IAC1C,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,IAAI,QAAQ,CACxB,SAAS,CAAC,WAAW,EACrB,gBAAgB,EAChB,OAAO,EACP,SAAS,EACT,KAAK,CACN,CAAC;IACF,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;IACtC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACxD,MAAM,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,CAAC,KAAK,YAAY,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;IAClD,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;IACvC,QAAQ,CAAC,KAAK,GAAG,sBAAsB,CAAC;IAExC,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,CACjC,SAAS,CAAC,WAAW,EACrB,eAAe,EACf,QAAQ,EACR,OAAO,CACR,CAAC;IAEF,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAClD,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,iCAAiC,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=errors-node-map.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-node-map.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/lib/errors-node-map.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ import { expect, it } from 'vitest';
2
+ import { ErrorCode, NODE_ERROR_CODE_MAP } from '../../lib/errors.js';
3
+ it('NODE_ERROR_CODE_MAP maps common Node.js error codes', () => {
4
+ expect(NODE_ERROR_CODE_MAP.ENOENT).toBe(ErrorCode.E_NOT_FOUND);
5
+ expect(NODE_ERROR_CODE_MAP.EACCES).toBe(ErrorCode.E_PERMISSION_DENIED);
6
+ expect(NODE_ERROR_CODE_MAP.EPERM).toBe(ErrorCode.E_PERMISSION_DENIED);
7
+ expect(NODE_ERROR_CODE_MAP.EISDIR).toBe(ErrorCode.E_NOT_FILE);
8
+ expect(NODE_ERROR_CODE_MAP.ENOTDIR).toBe(ErrorCode.E_NOT_DIRECTORY);
9
+ expect(NODE_ERROR_CODE_MAP.ELOOP).toBe(ErrorCode.E_SYMLINK_NOT_ALLOWED);
10
+ expect(NODE_ERROR_CODE_MAP.ETIMEDOUT).toBe(ErrorCode.E_TIMEOUT);
11
+ });
12
+ it('NODE_ERROR_CODE_MAP handles resource exhaustion errors as timeout', () => {
13
+ expect(NODE_ERROR_CODE_MAP.EMFILE).toBe(ErrorCode.E_TIMEOUT);
14
+ expect(NODE_ERROR_CODE_MAP.ENFILE).toBe(ErrorCode.E_TIMEOUT);
15
+ });
16
+ //# sourceMappingURL=errors-node-map.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-node-map.test.js","sourceRoot":"","sources":["../../../src/__tests__/lib/errors-node-map.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAErE,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;IAC7D,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAC/D,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;IACvE,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;IACtE,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC9D,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IACpE,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;IACxE,MAAM,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;AAClE,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;IAC3E,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7D,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;AAC/D,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=errors-suggestion.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-suggestion.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/lib/errors-suggestion.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ import { expect, it } from 'vitest';
2
+ import { ErrorCode, getSuggestion } from '../../lib/errors.js';
3
+ it('getSuggestion returns suggestions for all error codes', () => {
4
+ const errorCodes = Object.values(ErrorCode);
5
+ for (const code of errorCodes) {
6
+ const suggestion = getSuggestion(code);
7
+ expect(suggestion).toBeTruthy();
8
+ expect(typeof suggestion).toBe('string');
9
+ }
10
+ });
11
+ //# sourceMappingURL=errors-suggestion.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-suggestion.test.js","sourceRoot":"","sources":["../../../src/__tests__/lib/errors-suggestion.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE/D,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;IAC/D,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC5C,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,CAAC,UAAU,CAAC,CAAC,UAAU,EAAE,CAAC;QAChC,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=analyze-directory-edge-cases.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze-directory-edge-cases.test.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/lib/file-operations/analyze-directory-edge-cases.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ import { expect, it } from 'vitest';
2
+ import { analyzeDirectory } from '../../../lib/file-operations.js';
3
+ import { useFileOpsFixture } from '../fixtures/file-ops-hooks.js';
4
+ const getTestDir = useFileOpsFixture();
5
+ it('analyzeDirectory handles topN=1', async () => {
6
+ const result = await analyzeDirectory(getTestDir(), { topN: 1 });
7
+ expect(result.analysis.largestFiles.length).toBeLessThanOrEqual(1);
8
+ expect(result.analysis.recentlyModified.length).toBeLessThanOrEqual(1);
9
+ });
10
+ it('analyzeDirectory correctly counts file types', async () => {
11
+ const result = await analyzeDirectory(getTestDir());
12
+ expect(result.analysis.fileTypes['.ts']).toBe(2);
13
+ expect(result.analysis.fileTypes['.md']).toBe(2);
14
+ });
15
+ //# sourceMappingURL=analyze-directory-edge-cases.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze-directory-edge-cases.test.js","sourceRoot":"","sources":["../../../../src/__tests__/lib/file-operations/analyze-directory-edge-cases.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;AAEvC,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;IAC/C,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IACjE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;IACnE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;IAC5D,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,UAAU,EAAE,CAAC,CAAC;IACpD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=analyze-directory.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze-directory.test.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/lib/file-operations/analyze-directory.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,28 @@
1
+ import * as path from 'node:path';
2
+ import { expect, it } from 'vitest';
3
+ import { analyzeDirectory } from '../../../lib/file-operations.js';
4
+ import { useFileOpsFixture } from '../fixtures/file-ops-hooks.js';
5
+ const getTestDir = useFileOpsFixture();
6
+ it('analyzeDirectory analyzes directory structure', async () => {
7
+ const result = await analyzeDirectory(getTestDir());
8
+ expect(result.analysis.totalFiles).toBeGreaterThan(0);
9
+ expect(result.analysis.totalDirectories).toBeGreaterThan(0);
10
+ expect(result.analysis.totalSize).toBeGreaterThan(0);
11
+ });
12
+ it('analyzeDirectory respects maxEntries and marks truncated', async () => {
13
+ const result = await analyzeDirectory(getTestDir(), { maxEntries: 1 });
14
+ expect(result.summary.truncated).toBe(true);
15
+ expect(result.analysis.totalFiles + result.analysis.totalDirectories).toBeLessThanOrEqual(1);
16
+ });
17
+ it('analyzeDirectory lists file types', async () => {
18
+ const result = await analyzeDirectory(getTestDir());
19
+ expect(Object.keys(result.analysis.fileTypes).length).toBeGreaterThan(0);
20
+ });
21
+ it('analyzeDirectory tracks largest files', async () => {
22
+ const result = await analyzeDirectory(getTestDir(), { topN: 5 });
23
+ expect(result.analysis.largestFiles.length).toBeLessThanOrEqual(5);
24
+ });
25
+ it('analyzeDirectory throws when path is a file', async () => {
26
+ await expect(analyzeDirectory(path.join(getTestDir(), 'README.md'))).rejects.toThrow(/Not a directory/i);
27
+ });
28
+ //# sourceMappingURL=analyze-directory.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze-directory.test.js","sourceRoot":"","sources":["../../../../src/__tests__/lib/file-operations/analyze-directory.test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;AAEvC,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;IAC7D,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,UAAU,EAAE,CAAC,CAAC;IACpD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACtD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC5D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AACvD,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;IACxE,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,UAAU,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IACvE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,CACJ,MAAM,CAAC,QAAQ,CAAC,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAC9D,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;AAC3B,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;IACjD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,UAAU,EAAE,CAAC,CAAC;IACpD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AAC3E,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;IACrD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IACjE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;IAC3D,MAAM,MAAM,CACV,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,WAAW,CAAC,CAAC,CACvD,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;AACxC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=directory-tree-edge-cases.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory-tree-edge-cases.test.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/lib/file-operations/directory-tree-edge-cases.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ import { expect, it } from 'vitest';
2
+ import { getDirectoryTree } from '../../../lib/file-operations.js';
3
+ import { useFileOpsFixture } from '../fixtures/file-ops-hooks.js';
4
+ const getTestDir = useFileOpsFixture();
5
+ function firstIndexOfType(children, type) {
6
+ const index = children.findIndex((child) => child.type === type);
7
+ return index >= 0 ? index : null;
8
+ }
9
+ function lastIndexOfType(children, type) {
10
+ for (let i = children.length - 1; i >= 0; i--) {
11
+ if (children[i]?.type === type)
12
+ return i;
13
+ }
14
+ return null;
15
+ }
16
+ it('getDirectoryTree handles deep nesting with truncation', async () => {
17
+ const result = await getDirectoryTree(getTestDir(), { maxDepth: 0 });
18
+ expect(result.summary.truncated).toBe(true);
19
+ });
20
+ it('getDirectoryTree sorts entries with directories first', async () => {
21
+ const result = await getDirectoryTree(getTestDir());
22
+ const children = result.tree.children ?? [];
23
+ const lastDirIndex = lastIndexOfType(children, 'directory');
24
+ const firstFileIndex = firstIndexOfType(children, 'file');
25
+ if (lastDirIndex !== null && firstFileIndex !== null) {
26
+ expect(lastDirIndex).toBeLessThan(firstFileIndex);
27
+ }
28
+ });
29
+ //# sourceMappingURL=directory-tree-edge-cases.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory-tree-edge-cases.test.js","sourceRoot":"","sources":["../../../../src/__tests__/lib/file-operations/directory-tree-edge-cases.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAMlE,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;AAEvC,SAAS,gBAAgB,CAAC,QAAqB,EAAE,IAAY;IAC3D,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IACjE,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACnC,CAAC;AAED,SAAS,eAAe,CAAC,QAAqB,EAAE,IAAY;IAC1D,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,KAAK,IAAI;YAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;IACrE,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IACrE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC9C,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;IACrE,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,UAAU,EAAE,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;IAC5C,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAC5D,MAAM,cAAc,GAAG,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC1D,IAAI,YAAY,KAAK,IAAI,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;QACrD,MAAM,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;IACpD,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=directory-tree.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory-tree.test.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/lib/file-operations/directory-tree.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,75 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import * as os from 'node:os';
3
+ import * as path from 'node:path';
4
+ import { expect, it } from 'vitest';
5
+ import { getDirectoryTree } from '../../../lib/file-operations.js';
6
+ import { useFileOpsFixture } from '../fixtures/file-ops-hooks.js';
7
+ const getTestDir = useFileOpsFixture();
8
+ function containsName(entry, name) {
9
+ if (entry.name === name)
10
+ return true;
11
+ if (!entry.children)
12
+ return false;
13
+ return entry.children.some((child) => containsName(child, name));
14
+ }
15
+ async function createOutsideDirectory() {
16
+ const outsideDir = await fs.mkdtemp(path.join(os.tmpdir(), 'mcp-outside-'));
17
+ await fs.writeFile(path.join(outsideDir, 'outside.txt'), 'outside');
18
+ return outsideDir;
19
+ }
20
+ async function tryCreateSymlink(baseDir, outsideDir) {
21
+ const linkPath = path.join(baseDir, 'escape');
22
+ const linkType = process.platform === 'win32' ? 'junction' : 'dir';
23
+ try {
24
+ await fs.symlink(outsideDir, linkPath, linkType);
25
+ return { linkPath, created: true };
26
+ }
27
+ catch {
28
+ return { linkPath, created: false };
29
+ }
30
+ }
31
+ async function cleanupSymlink(linkPath, outsideDir) {
32
+ await fs.rm(linkPath, { recursive: true, force: true }).catch(() => { });
33
+ await fs.rm(outsideDir, { recursive: true, force: true }).catch(() => { });
34
+ }
35
+ it('getDirectoryTree returns tree structure', async () => {
36
+ const result = await getDirectoryTree(getTestDir());
37
+ expect(result.tree.type).toBe('directory');
38
+ expect(result.tree.children).toBeDefined();
39
+ expect(result.tree.children?.length).toBeGreaterThan(0);
40
+ });
41
+ it('getDirectoryTree respects maxDepth', async () => {
42
+ const result = await getDirectoryTree(getTestDir(), { maxDepth: 1 });
43
+ expect(result.summary.maxDepthReached).toBeLessThanOrEqual(1);
44
+ });
45
+ it('getDirectoryTree excludes patterns', async () => {
46
+ const result = await getDirectoryTree(getTestDir(), {
47
+ excludePatterns: ['docs'],
48
+ });
49
+ const hasDocsDir = result.tree.children?.some((c) => c.name === 'docs');
50
+ expect(hasDocsDir).toBe(false);
51
+ });
52
+ it('getDirectoryTree includes sizes when specified', async () => {
53
+ const result = await getDirectoryTree(getTestDir(), { includeSize: true });
54
+ const fileEntry = result.tree.children?.find((c) => c.type === 'file');
55
+ expect(fileEntry?.size).toBeDefined();
56
+ });
57
+ it('getDirectoryTree skips symlinks that escape allowed directories', async () => {
58
+ const outsideDir = await createOutsideDirectory();
59
+ const { linkPath, created } = await tryCreateSymlink(getTestDir(), outsideDir);
60
+ try {
61
+ if (!created) {
62
+ expect(created).toBe(false);
63
+ return;
64
+ }
65
+ const result = await getDirectoryTree(getTestDir(), { maxDepth: 3 });
66
+ const childNames = (result.tree.children ?? []).map((c) => c.name);
67
+ expect(childNames.includes('escape')).toBe(false);
68
+ expect(containsName(result.tree, 'outside.txt')).toBe(false);
69
+ expect(result.summary.symlinksNotFollowed).toBeGreaterThanOrEqual(1);
70
+ }
71
+ finally {
72
+ await cleanupSymlink(linkPath, outsideDir);
73
+ }
74
+ });
75
+ //# sourceMappingURL=directory-tree.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory-tree.test.js","sourceRoot":"","sources":["../../../../src/__tests__/lib/file-operations/directory-tree.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=get-file-info.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-file-info.test.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/lib/file-operations/get-file-info.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,17 @@
1
+ import * as path from 'node:path';
2
+ import { expect, it } from 'vitest';
3
+ import { getFileInfo } from '../../../lib/file-operations.js';
4
+ import { useFileOpsFixture } from '../fixtures/file-ops-hooks.js';
5
+ const getTestDir = useFileOpsFixture();
6
+ it('getFileInfo returns file metadata', async () => {
7
+ const info = await getFileInfo(path.join(getTestDir(), 'README.md'));
8
+ expect(info.name).toBe('README.md');
9
+ expect(info.type).toBe('file');
10
+ expect(info.size).toBeGreaterThan(0);
11
+ expect(info.created).toBeInstanceOf(Date);
12
+ });
13
+ it('getFileInfo returns directory metadata', async () => {
14
+ const info = await getFileInfo(getTestDir());
15
+ expect(info.type).toBe('directory');
16
+ });
17
+ //# sourceMappingURL=get-file-info.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-file-info.test.js","sourceRoot":"","sources":["../../../../src/__tests__/lib/file-operations/get-file-info.test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;AAEvC,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;IACjD,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;IACrE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACpC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACrC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;IACtD,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,UAAU,EAAE,CAAC,CAAC;IAC7C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AACtC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=list-directory-edge-cases.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-directory-edge-cases.test.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/lib/file-operations/list-directory-edge-cases.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import * as path from 'node:path';
3
+ import { expect, it } from 'vitest';
4
+ import { listDirectory } from '../../../lib/file-operations.js';
5
+ import { useFileOpsFixture } from '../fixtures/file-ops-hooks.js';
6
+ const getTestDir = useFileOpsFixture();
7
+ it('listDirectory handles maxDepth=0', async () => {
8
+ const result = await listDirectory(getTestDir(), {
9
+ recursive: true,
10
+ maxDepth: 0,
11
+ });
12
+ expect(result.summary.maxDepthReached).toBe(0);
13
+ });
14
+ it('listDirectory handles empty directory', async () => {
15
+ const emptyDir = path.join(getTestDir(), 'empty-dir');
16
+ await fs.mkdir(emptyDir, { recursive: true });
17
+ const result = await listDirectory(emptyDir);
18
+ expect(result.entries.length).toBe(0);
19
+ await fs.rm(emptyDir, { recursive: true });
20
+ });
21
+ //# sourceMappingURL=list-directory-edge-cases.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-directory-edge-cases.test.js","sourceRoot":"","sources":["../../../../src/__tests__/lib/file-operations/list-directory-edge-cases.test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;AAEvC,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;IAChD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,EAAE;QAC/C,SAAS,EAAE,IAAI;QACf,QAAQ,EAAE,CAAC;KACZ,CAAC,CAAC;IACH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,WAAW,CAAC,CAAC;IACtD,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE9C,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEtC,MAAM,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7C,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=list-directory.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-directory.test.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/lib/file-operations/list-directory.test.ts"],"names":[],"mappings":""}