@j0hanz/filesystem-context-mcp 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/README.md +106 -29
  2. package/dist/__tests__/lib/errors.test.js +3 -23
  3. package/dist/__tests__/lib/errors.test.js.map +1 -1
  4. package/dist/__tests__/lib/file-operations.test.js +34 -0
  5. package/dist/__tests__/lib/file-operations.test.js.map +1 -1
  6. package/dist/__tests__/lib/path-validation.test.js +8 -0
  7. package/dist/__tests__/lib/path-validation.test.js.map +1 -1
  8. package/dist/__tests__/schemas/validators.test.js +101 -122
  9. package/dist/__tests__/schemas/validators.test.js.map +1 -1
  10. package/dist/__tests__/security/filesystem-boundary.test.js +1 -1
  11. package/dist/__tests__/security/filesystem-boundary.test.js.map +1 -1
  12. package/dist/config/types.d.ts +1 -85
  13. package/dist/config/types.d.ts.map +1 -1
  14. package/dist/config/types.js +0 -2
  15. package/dist/config/types.js.map +1 -1
  16. package/dist/index.js +3 -3
  17. package/dist/index.js.map +1 -1
  18. package/dist/instructions.md +1 -2
  19. package/dist/lib/constants.d.ts +3 -1
  20. package/dist/lib/constants.d.ts.map +1 -1
  21. package/dist/lib/constants.js +66 -258
  22. package/dist/lib/constants.js.map +1 -1
  23. package/dist/lib/errors.d.ts +25 -3
  24. package/dist/lib/errors.d.ts.map +1 -1
  25. package/dist/lib/errors.js +4 -94
  26. package/dist/lib/errors.js.map +1 -1
  27. package/dist/lib/file-operations/analyze-directory.d.ts +8 -0
  28. package/dist/lib/file-operations/analyze-directory.d.ts.map +1 -0
  29. package/dist/lib/file-operations/analyze-directory.js +117 -0
  30. package/dist/lib/file-operations/analyze-directory.js.map +1 -0
  31. package/dist/lib/file-operations/directory-items.d.ts +20 -0
  32. package/dist/lib/file-operations/directory-items.d.ts.map +1 -0
  33. package/dist/lib/file-operations/directory-items.js +85 -0
  34. package/dist/lib/file-operations/directory-items.js.map +1 -0
  35. package/dist/lib/file-operations/directory-iteration.d.ts +17 -0
  36. package/dist/lib/file-operations/directory-iteration.d.ts.map +1 -0
  37. package/dist/lib/file-operations/directory-iteration.js +55 -0
  38. package/dist/lib/file-operations/directory-iteration.js.map +1 -0
  39. package/dist/lib/file-operations/directory-tree.d.ts +9 -0
  40. package/dist/lib/file-operations/directory-tree.d.ts.map +1 -0
  41. package/dist/lib/file-operations/directory-tree.js +175 -0
  42. package/dist/lib/file-operations/directory-tree.js.map +1 -0
  43. package/dist/lib/file-operations/file-info.d.ts +3 -0
  44. package/dist/lib/file-operations/file-info.d.ts.map +1 -0
  45. package/dist/lib/file-operations/file-info.js +56 -0
  46. package/dist/lib/file-operations/file-info.js.map +1 -0
  47. package/dist/lib/file-operations/list-directory.d.ts +10 -0
  48. package/dist/lib/file-operations/list-directory.d.ts.map +1 -0
  49. package/dist/lib/file-operations/list-directory.js +189 -0
  50. package/dist/lib/file-operations/list-directory.js.map +1 -0
  51. package/dist/lib/file-operations/read-media-file.d.ts +5 -0
  52. package/dist/lib/file-operations/read-media-file.d.ts.map +1 -0
  53. package/dist/lib/file-operations/read-media-file.js +31 -0
  54. package/dist/lib/file-operations/read-media-file.js.map +1 -0
  55. package/dist/lib/file-operations/read-multiple-files.d.ts +16 -0
  56. package/dist/lib/file-operations/read-multiple-files.d.ts.map +1 -0
  57. package/dist/lib/file-operations/read-multiple-files.js +98 -0
  58. package/dist/lib/file-operations/read-multiple-files.js.map +1 -0
  59. package/dist/lib/file-operations/search-content.d.ts +16 -0
  60. package/dist/lib/file-operations/search-content.d.ts.map +1 -0
  61. package/dist/lib/file-operations/search-content.js +431 -0
  62. package/dist/lib/file-operations/search-content.js.map +1 -0
  63. package/dist/lib/file-operations/search-files.d.ts +9 -0
  64. package/dist/lib/file-operations/search-files.d.ts.map +1 -0
  65. package/dist/lib/file-operations/search-files.js +139 -0
  66. package/dist/lib/file-operations/search-files.js.map +1 -0
  67. package/dist/lib/file-operations/sorting.d.ts +12 -0
  68. package/dist/lib/file-operations/sorting.d.ts.map +1 -0
  69. package/dist/lib/file-operations/sorting.js +24 -0
  70. package/dist/lib/file-operations/sorting.js.map +1 -0
  71. package/dist/lib/file-operations.d.ts +9 -57
  72. package/dist/lib/file-operations.d.ts.map +1 -1
  73. package/dist/lib/file-operations.js +9 -773
  74. package/dist/lib/file-operations.js.map +1 -1
  75. package/dist/lib/fs-helpers/binary-detect.d.ts +3 -0
  76. package/dist/lib/fs-helpers/binary-detect.d.ts.map +1 -0
  77. package/dist/lib/fs-helpers/binary-detect.js +54 -0
  78. package/dist/lib/fs-helpers/binary-detect.js.map +1 -0
  79. package/dist/lib/fs-helpers/concurrency.d.ts +11 -0
  80. package/dist/lib/fs-helpers/concurrency.d.ts.map +1 -0
  81. package/dist/lib/fs-helpers/concurrency.js +95 -0
  82. package/dist/lib/fs-helpers/concurrency.js.map +1 -0
  83. package/dist/lib/fs-helpers/fs-utils.d.ts +5 -0
  84. package/dist/lib/fs-helpers/fs-utils.d.ts.map +1 -0
  85. package/dist/lib/fs-helpers/fs-utils.js +13 -0
  86. package/dist/lib/fs-helpers/fs-utils.js.map +1 -0
  87. package/dist/lib/fs-helpers/readers/head-file.d.ts +2 -0
  88. package/dist/lib/fs-helpers/readers/head-file.d.ts.map +1 -0
  89. package/dist/lib/fs-helpers/readers/head-file.js +73 -0
  90. package/dist/lib/fs-helpers/readers/head-file.js.map +1 -0
  91. package/dist/lib/fs-helpers/readers/line-range.d.ts +7 -0
  92. package/dist/lib/fs-helpers/readers/line-range.d.ts.map +1 -0
  93. package/dist/lib/fs-helpers/readers/line-range.js +46 -0
  94. package/dist/lib/fs-helpers/readers/line-range.js.map +1 -0
  95. package/dist/lib/fs-helpers/readers/read-file.d.ts +16 -0
  96. package/dist/lib/fs-helpers/readers/read-file.d.ts.map +1 -0
  97. package/dist/lib/fs-helpers/readers/read-file.js +87 -0
  98. package/dist/lib/fs-helpers/readers/read-file.js.map +1 -0
  99. package/dist/lib/fs-helpers/readers/tail-file.d.ts +2 -0
  100. package/dist/lib/fs-helpers/readers/tail-file.d.ts.map +1 -0
  101. package/dist/lib/fs-helpers/readers/tail-file.js +98 -0
  102. package/dist/lib/fs-helpers/readers/tail-file.js.map +1 -0
  103. package/dist/lib/fs-helpers/readers/utf8.d.ts +3 -0
  104. package/dist/lib/fs-helpers/readers/utf8.d.ts.map +1 -0
  105. package/dist/lib/fs-helpers/readers/utf8.js +22 -0
  106. package/dist/lib/fs-helpers/readers/utf8.js.map +1 -0
  107. package/dist/lib/fs-helpers/readers.d.ts +4 -0
  108. package/dist/lib/fs-helpers/readers.d.ts.map +1 -0
  109. package/dist/lib/fs-helpers/readers.js +4 -0
  110. package/dist/lib/fs-helpers/readers.js.map +1 -0
  111. package/dist/lib/fs-helpers.d.ts +4 -25
  112. package/dist/lib/fs-helpers.d.ts.map +1 -1
  113. package/dist/lib/fs-helpers.js +4 -327
  114. package/dist/lib/fs-helpers.js.map +1 -1
  115. package/dist/lib/path-validation/allowed-directories.d.ts +9 -0
  116. package/dist/lib/path-validation/allowed-directories.d.ts.map +1 -0
  117. package/dist/lib/path-validation/allowed-directories.js +94 -0
  118. package/dist/lib/path-validation/allowed-directories.js.map +1 -0
  119. package/dist/lib/path-validation/errors.d.ts +5 -0
  120. package/dist/lib/path-validation/errors.d.ts.map +1 -0
  121. package/dist/lib/path-validation/errors.js +33 -0
  122. package/dist/lib/path-validation/errors.js.map +1 -0
  123. package/dist/lib/path-validation/roots.d.ts +3 -0
  124. package/dist/lib/path-validation/roots.d.ts.map +1 -0
  125. package/dist/lib/path-validation/roots.js +49 -0
  126. package/dist/lib/path-validation/roots.js.map +1 -0
  127. package/dist/lib/path-validation/validators.d.ts +9 -0
  128. package/dist/lib/path-validation/validators.d.ts.map +1 -0
  129. package/dist/lib/path-validation/validators.js +70 -0
  130. package/dist/lib/path-validation/validators.js.map +1 -0
  131. package/dist/lib/path-validation.d.ts +3 -7
  132. package/dist/lib/path-validation.d.ts.map +1 -1
  133. package/dist/lib/path-validation.js +3 -141
  134. package/dist/lib/path-validation.js.map +1 -1
  135. package/dist/schemas/input-helpers.d.ts +8 -0
  136. package/dist/schemas/input-helpers.d.ts.map +1 -0
  137. package/dist/schemas/input-helpers.js +44 -0
  138. package/dist/schemas/input-helpers.js.map +1 -0
  139. package/dist/schemas/inputs.d.ts +8 -5
  140. package/dist/schemas/inputs.d.ts.map +1 -1
  141. package/dist/schemas/inputs.js +41 -64
  142. package/dist/schemas/inputs.js.map +1 -1
  143. package/dist/schemas/output-helpers.d.ts +24 -0
  144. package/dist/schemas/output-helpers.d.ts.map +1 -0
  145. package/dist/schemas/output-helpers.js +13 -0
  146. package/dist/schemas/output-helpers.js.map +1 -0
  147. package/dist/schemas/outputs.d.ts +476 -42
  148. package/dist/schemas/outputs.d.ts.map +1 -1
  149. package/dist/schemas/outputs.js +26 -41
  150. package/dist/schemas/outputs.js.map +1 -1
  151. package/dist/server.d.ts +9 -1
  152. package/dist/server.d.ts.map +1 -1
  153. package/dist/server.js +28 -42
  154. package/dist/server.js.map +1 -1
  155. package/dist/tools/analyze-directory.d.ts.map +1 -1
  156. package/dist/tools/analyze-directory.js +115 -53
  157. package/dist/tools/analyze-directory.js.map +1 -1
  158. package/dist/tools/directory-tree.d.ts.map +1 -1
  159. package/dist/tools/directory-tree.js +86 -49
  160. package/dist/tools/directory-tree.js.map +1 -1
  161. package/dist/tools/get-file-info.d.ts.map +1 -1
  162. package/dist/tools/get-file-info.js +71 -37
  163. package/dist/tools/get-file-info.js.map +1 -1
  164. package/dist/tools/list-allowed-dirs.d.ts.map +1 -1
  165. package/dist/tools/list-allowed-dirs.js +48 -35
  166. package/dist/tools/list-allowed-dirs.js.map +1 -1
  167. package/dist/tools/list-directory.d.ts.map +1 -1
  168. package/dist/tools/list-directory.js +129 -58
  169. package/dist/tools/list-directory.js.map +1 -1
  170. package/dist/tools/read-file.d.ts.map +1 -1
  171. package/dist/tools/read-file.js +70 -56
  172. package/dist/tools/read-file.js.map +1 -1
  173. package/dist/tools/read-media-file.d.ts.map +1 -1
  174. package/dist/tools/read-media-file.js +39 -41
  175. package/dist/tools/read-media-file.js.map +1 -1
  176. package/dist/tools/read-multiple-files.d.ts.map +1 -1
  177. package/dist/tools/read-multiple-files.js +58 -50
  178. package/dist/tools/read-multiple-files.js.map +1 -1
  179. package/dist/tools/search-content.d.ts.map +1 -1
  180. package/dist/tools/search-content.js +146 -89
  181. package/dist/tools/search-content.js.map +1 -1
  182. package/dist/tools/search-files.d.ts.map +1 -1
  183. package/dist/tools/search-files.js +121 -50
  184. package/dist/tools/search-files.js.map +1 -1
  185. package/dist/tools/tool-response.d.ts +9 -0
  186. package/dist/tools/tool-response.d.ts.map +1 -0
  187. package/dist/tools/tool-response.js +7 -0
  188. package/dist/tools/tool-response.js.map +1 -0
  189. package/package.json +2 -1
  190. package/dist/__tests__/errors.test.d.ts +0 -2
  191. package/dist/__tests__/errors.test.d.ts.map +0 -1
  192. package/dist/__tests__/errors.test.js +0 -88
  193. package/dist/__tests__/errors.test.js.map +0 -1
  194. package/dist/__tests__/file-operations.test.d.ts +0 -2
  195. package/dist/__tests__/file-operations.test.d.ts.map +0 -1
  196. package/dist/__tests__/file-operations.test.js +0 -230
  197. package/dist/__tests__/file-operations.test.js.map +0 -1
  198. package/dist/__tests__/lib/formatters.test.d.ts +0 -2
  199. package/dist/__tests__/lib/formatters.test.d.ts.map +0 -1
  200. package/dist/__tests__/lib/formatters.test.js +0 -248
  201. package/dist/__tests__/lib/formatters.test.js.map +0 -1
  202. package/dist/__tests__/lib/image-parsing.test.d.ts +0 -2
  203. package/dist/__tests__/lib/image-parsing.test.d.ts.map +0 -1
  204. package/dist/__tests__/lib/image-parsing.test.js +0 -262
  205. package/dist/__tests__/lib/image-parsing.test.js.map +0 -1
  206. package/dist/__tests__/path-validation.test.d.ts +0 -2
  207. package/dist/__tests__/path-validation.test.d.ts.map +0 -1
  208. package/dist/__tests__/path-validation.test.js +0 -92
  209. package/dist/__tests__/path-validation.test.js.map +0 -1
  210. package/dist/lib/directory-helpers.d.ts +0 -4
  211. package/dist/lib/directory-helpers.d.ts.map +0 -1
  212. package/dist/lib/directory-helpers.js +0 -36
  213. package/dist/lib/directory-helpers.js.map +0 -1
  214. package/dist/lib/formatters.d.ts +0 -10
  215. package/dist/lib/formatters.d.ts.map +0 -1
  216. package/dist/lib/formatters.js +0 -202
  217. package/dist/lib/formatters.js.map +0 -1
  218. package/dist/lib/image-parsing.d.ts +0 -4
  219. package/dist/lib/image-parsing.d.ts.map +0 -1
  220. package/dist/lib/image-parsing.js +0 -124
  221. package/dist/lib/image-parsing.js.map +0 -1
  222. package/dist/lib/mcp-logger.d.ts +0 -11
  223. package/dist/lib/mcp-logger.d.ts.map +0 -1
  224. package/dist/lib/mcp-logger.js +0 -49
  225. package/dist/lib/mcp-logger.js.map +0 -1
  226. package/dist/lib/roots-utils.d.ts +0 -7
  227. package/dist/lib/roots-utils.d.ts.map +0 -1
  228. package/dist/lib/roots-utils.js +0 -39
  229. package/dist/lib/roots-utils.js.map +0 -1
  230. package/dist/lib/search-helpers.d.ts +0 -16
  231. package/dist/lib/search-helpers.d.ts.map +0 -1
  232. package/dist/lib/search-helpers.js +0 -169
  233. package/dist/lib/search-helpers.js.map +0 -1
  234. package/dist/lib/sorting.d.ts +0 -12
  235. package/dist/lib/sorting.d.ts.map +0 -1
  236. package/dist/lib/sorting.js +0 -41
  237. package/dist/lib/sorting.js.map +0 -1
  238. package/dist/lib/types.d.ts +0 -6
  239. package/dist/lib/types.d.ts.map +0 -1
  240. package/dist/lib/types.js +0 -2
  241. package/dist/lib/types.js.map +0 -1
  242. package/dist/prompts/analyze-codebase.d.ts +0 -3
  243. package/dist/prompts/analyze-codebase.d.ts.map +0 -1
  244. package/dist/prompts/analyze-codebase.js +0 -144
  245. package/dist/prompts/analyze-codebase.js.map +0 -1
  246. package/dist/prompts/filesystem-query.d.ts +0 -3
  247. package/dist/prompts/filesystem-query.d.ts.map +0 -1
  248. package/dist/prompts/filesystem-query.js +0 -168
  249. package/dist/prompts/filesystem-query.js.map +0 -1
  250. package/dist/prompts/find-duplicates.d.ts +0 -3
  251. package/dist/prompts/find-duplicates.d.ts.map +0 -1
  252. package/dist/prompts/find-duplicates.js +0 -77
  253. package/dist/prompts/find-duplicates.js.map +0 -1
  254. package/dist/prompts/index.d.ts +0 -3
  255. package/dist/prompts/index.d.ts.map +0 -1
  256. package/dist/prompts/index.js +0 -13
  257. package/dist/prompts/index.js.map +0 -1
  258. package/dist/prompts/project-overview.d.ts +0 -3
  259. package/dist/prompts/project-overview.d.ts.map +0 -1
  260. package/dist/prompts/project-overview.js +0 -122
  261. package/dist/prompts/project-overview.js.map +0 -1
  262. package/dist/prompts/search-and-replace.d.ts +0 -3
  263. package/dist/prompts/search-and-replace.d.ts.map +0 -1
  264. package/dist/prompts/search-and-replace.js +0 -130
  265. package/dist/prompts/search-and-replace.js.map +0 -1
  266. package/dist/prompts/shared.d.ts +0 -11
  267. package/dist/prompts/shared.d.ts.map +0 -1
  268. package/dist/prompts/shared.js +0 -32
  269. package/dist/prompts/shared.js.map +0 -1
  270. package/dist/resources/index.d.ts +0 -3
  271. package/dist/resources/index.d.ts.map +0 -1
  272. package/dist/resources/index.js +0 -54
  273. package/dist/resources/index.js.map +0 -1
  274. package/dist/schemas/validators.d.ts +0 -12
  275. package/dist/schemas/validators.d.ts.map +0 -1
  276. package/dist/schemas/validators.js +0 -35
  277. package/dist/schemas/validators.js.map +0 -1
  278. package/dist/utils/index.d.ts +0 -2
  279. package/dist/utils/index.d.ts.map +0 -1
  280. package/dist/utils/index.js +0 -2
  281. package/dist/utils/index.js.map +0 -1
  282. package/dist/utils/response-helpers.d.ts +0 -22
  283. package/dist/utils/response-helpers.d.ts.map +0 -1
  284. package/dist/utils/response-helpers.js +0 -24
  285. package/dist/utils/response-helpers.js.map +0 -1
@@ -1,262 +0,0 @@
1
- import * as fs from 'node:fs/promises';
2
- import * as os from 'node:os';
3
- import * as path from 'node:path';
4
- import { afterAll, beforeAll, describe, expect, it } from 'vitest';
5
- import { readMediaFile } from '../../lib/file-operations.js';
6
- import { normalizePath } from '../../lib/path-utils.js';
7
- import { setAllowedDirectories } from '../../lib/path-validation.js';
8
- describe('image parsing', () => {
9
- let testDir;
10
- // Test image generators - create minimal valid images
11
- const createMinimalPng = () => {
12
- // Minimal 1x1 transparent PNG
13
- return Buffer.from([
14
- 0x89,
15
- 0x50,
16
- 0x4e,
17
- 0x47,
18
- 0x0d,
19
- 0x0a,
20
- 0x1a,
21
- 0x0a, // PNG signature
22
- 0x00,
23
- 0x00,
24
- 0x00,
25
- 0x0d, // IHDR length
26
- 0x49,
27
- 0x48,
28
- 0x44,
29
- 0x52, // 'IHDR'
30
- 0x00,
31
- 0x00,
32
- 0x00,
33
- 0x01, // width: 1
34
- 0x00,
35
- 0x00,
36
- 0x00,
37
- 0x01, // height: 1
38
- 0x08,
39
- 0x06, // bit depth: 8, color type: RGBA
40
- 0x00,
41
- 0x00,
42
- 0x00, // compression, filter, interlace
43
- 0x1f,
44
- 0x15,
45
- 0xc4,
46
- 0x89, // CRC
47
- 0x00,
48
- 0x00,
49
- 0x00,
50
- 0x0a, // IDAT length
51
- 0x49,
52
- 0x44,
53
- 0x41,
54
- 0x54, // 'IDAT'
55
- 0x78,
56
- 0x9c,
57
- 0x63,
58
- 0x00,
59
- 0x01,
60
- 0x00,
61
- 0x00,
62
- 0x05,
63
- 0x00,
64
- 0x01, // compressed data
65
- 0x0d,
66
- 0x0a,
67
- 0x2d,
68
- 0xb4, // CRC
69
- 0x00,
70
- 0x00,
71
- 0x00,
72
- 0x00, // IEND length
73
- 0x49,
74
- 0x45,
75
- 0x4e,
76
- 0x44, // 'IEND'
77
- 0xae,
78
- 0x42,
79
- 0x60,
80
- 0x82, // CRC
81
- ]);
82
- };
83
- const createMinimalJpeg = (width, height) => {
84
- // Minimal JPEG with SOF0 frame containing dimensions
85
- const wHi = (width >> 8) & 0xff;
86
- const wLo = width & 0xff;
87
- const hHi = (height >> 8) & 0xff;
88
- const hLo = height & 0xff;
89
- return Buffer.from([
90
- 0xff,
91
- 0xd8, // SOI
92
- 0xff,
93
- 0xe0, // APP0
94
- 0x00,
95
- 0x10, // length
96
- 0x4a,
97
- 0x46,
98
- 0x49,
99
- 0x46,
100
- 0x00, // 'JFIF\0'
101
- 0x01,
102
- 0x01, // version
103
- 0x00, // aspect ratio units
104
- 0x00,
105
- 0x01, // X density
106
- 0x00,
107
- 0x01, // Y density
108
- 0x00,
109
- 0x00, // thumbnail dimensions
110
- 0xff,
111
- 0xc0, // SOF0 (baseline)
112
- 0x00,
113
- 0x0b, // length
114
- 0x08, // precision
115
- hHi,
116
- hLo, // height
117
- wHi,
118
- wLo, // width
119
- 0x01, // components
120
- 0x01,
121
- 0x11,
122
- 0x00, // component data
123
- 0xff,
124
- 0xd9, // EOI
125
- ]);
126
- };
127
- const createMinimalGif = (width, height) => {
128
- // Minimal GIF89a
129
- const wLo = width & 0xff;
130
- const wHi = (width >> 8) & 0xff;
131
- const hLo = height & 0xff;
132
- const hHi = (height >> 8) & 0xff;
133
- return Buffer.from([
134
- 0x47,
135
- 0x49,
136
- 0x46,
137
- 0x38,
138
- 0x39,
139
- 0x61, // GIF89a
140
- wLo,
141
- wHi, // width
142
- hLo,
143
- hHi, // height
144
- 0x00, // packed byte
145
- 0x00, // background color
146
- 0x00, // pixel aspect ratio
147
- 0x3b, // trailer
148
- ]);
149
- };
150
- const createMinimalBmp = (width, height) => {
151
- // Minimal BMP header
152
- const wBytes = Buffer.alloc(4);
153
- const hBytes = Buffer.alloc(4);
154
- wBytes.writeInt32LE(width, 0);
155
- hBytes.writeInt32LE(height, 0);
156
- return Buffer.concat([
157
- Buffer.from([0x42, 0x4d]), // 'BM'
158
- Buffer.alloc(4), // file size (placeholder)
159
- Buffer.alloc(4), // reserved
160
- Buffer.from([0x36, 0x00, 0x00, 0x00]), // pixel offset
161
- Buffer.from([0x28, 0x00, 0x00, 0x00]), // DIB header size
162
- wBytes, // width
163
- hBytes, // height
164
- Buffer.from([0x01, 0x00]), // planes
165
- Buffer.from([0x18, 0x00]), // bits per pixel
166
- Buffer.alloc(24), // rest of header
167
- ]);
168
- };
169
- const createMinimalWebp = (width, height) => {
170
- // Minimal VP8L WebP (lossless)
171
- // This creates a valid WebP header with VP8L chunk
172
- // Layout: RIFF[4] + size[4] + WEBP[4] + VP8L[4] + chunkSize[4] + signature[1] + packed[4]
173
- const wMinus1 = width - 1;
174
- const hMinus1 = height - 1;
175
- // VP8L packed bits at offset 21: 14-bit width, 14-bit height
176
- const packed = (wMinus1 & 0x3fff) | ((hMinus1 & 0x3fff) << 14);
177
- const signature = 0x2f; // VP8L signature byte
178
- // VP8L chunk data: signature byte + 4-byte packed dimensions
179
- const vp8lData = Buffer.alloc(5);
180
- vp8lData[0] = signature;
181
- vp8lData.writeUInt32LE(packed, 1);
182
- // Build the complete WebP file
183
- const buffer = Buffer.alloc(30);
184
- buffer.write('RIFF', 0);
185
- buffer.writeUInt32LE(22, 4); // File size - 8
186
- buffer.write('WEBP', 8);
187
- buffer.write('VP8L', 12);
188
- buffer.writeUInt32LE(5, 16); // VP8L chunk size
189
- vp8lData.copy(buffer, 20);
190
- return buffer;
191
- };
192
- beforeAll(async () => {
193
- testDir = await fs.mkdtemp(path.join(os.tmpdir(), 'mcp-img-test-'));
194
- setAllowedDirectories([normalizePath(testDir)]);
195
- // Create test images
196
- await fs.writeFile(path.join(testDir, 'test.png'), createMinimalPng());
197
- await fs.writeFile(path.join(testDir, 'test.jpg'), createMinimalJpeg(320, 240));
198
- await fs.writeFile(path.join(testDir, 'test.gif'), createMinimalGif(100, 50));
199
- await fs.writeFile(path.join(testDir, 'test.bmp'), createMinimalBmp(640, 480));
200
- await fs.writeFile(path.join(testDir, 'test.webp'), createMinimalWebp(200, 150));
201
- // Create a corrupt image (PNG signature but invalid data)
202
- await fs.writeFile(path.join(testDir, 'corrupt.png'), Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00]));
203
- });
204
- afterAll(async () => {
205
- await fs.rm(testDir, { recursive: true, force: true });
206
- });
207
- describe('PNG parsing', () => {
208
- it('should parse PNG dimensions correctly', async () => {
209
- const result = await readMediaFile(path.join(testDir, 'test.png'));
210
- expect(result.mimeType).toBe('image/png');
211
- expect(result.width).toBe(1);
212
- expect(result.height).toBe(1);
213
- expect(result.data).toBeDefined();
214
- });
215
- });
216
- describe('JPEG parsing', () => {
217
- it('should parse JPEG dimensions correctly', async () => {
218
- const result = await readMediaFile(path.join(testDir, 'test.jpg'));
219
- expect(result.mimeType).toBe('image/jpeg');
220
- expect(result.width).toBe(320);
221
- expect(result.height).toBe(240);
222
- expect(result.data).toBeDefined();
223
- });
224
- });
225
- describe('GIF parsing', () => {
226
- it('should parse GIF dimensions correctly', async () => {
227
- const result = await readMediaFile(path.join(testDir, 'test.gif'));
228
- expect(result.mimeType).toBe('image/gif');
229
- expect(result.width).toBe(100);
230
- expect(result.height).toBe(50);
231
- expect(result.data).toBeDefined();
232
- });
233
- });
234
- describe('BMP parsing', () => {
235
- it('should parse BMP dimensions correctly', async () => {
236
- const result = await readMediaFile(path.join(testDir, 'test.bmp'));
237
- expect(result.mimeType).toBe('image/bmp');
238
- expect(result.width).toBe(640);
239
- expect(result.height).toBe(480);
240
- expect(result.data).toBeDefined();
241
- });
242
- });
243
- describe('WebP parsing', () => {
244
- it('should parse WebP dimensions correctly', async () => {
245
- const result = await readMediaFile(path.join(testDir, 'test.webp'));
246
- expect(result.mimeType).toBe('image/webp');
247
- expect(result.width).toBe(200);
248
- expect(result.height).toBe(150);
249
- expect(result.data).toBeDefined();
250
- });
251
- });
252
- describe('corrupt image handling', () => {
253
- it('should handle corrupt PNG gracefully (no dimensions)', async () => {
254
- const result = await readMediaFile(path.join(testDir, 'corrupt.png'));
255
- expect(result.mimeType).toBe('image/png');
256
- // Corrupt images should not throw but may not have dimensions
257
- expect(result.data).toBeDefined();
258
- // Width/height may be undefined or 0 for corrupt images
259
- });
260
- });
261
- });
262
- //# sourceMappingURL=image-parsing.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"image-parsing.test.js","sourceRoot":"","sources":["../../../src/__tests__/lib/image-parsing.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=path-validation.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"path-validation.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/path-validation.test.ts"],"names":[],"mappings":""}
@@ -1,92 +0,0 @@
1
- import * as fs from 'node:fs/promises';
2
- import * as os from 'node:os';
3
- import * as path from 'node:path';
4
- import { afterAll, beforeAll, describe, expect, it } from 'vitest';
5
- import { getAllowedDirectories, setAllowedDirectories, validateExistingPath, } from '../lib/path-validation.js';
6
- import { normalizePath } from '../lib/path-utils.js';
7
- describe('Path Validation', () => {
8
- let testDir;
9
- let subDir;
10
- let testFile;
11
- beforeAll(async () => {
12
- // Create a temporary test directory
13
- testDir = await fs.mkdtemp(path.join(os.tmpdir(), 'mcp-test-'));
14
- subDir = path.join(testDir, 'subdir');
15
- await fs.mkdir(subDir);
16
- testFile = path.join(subDir, 'test.txt');
17
- await fs.writeFile(testFile, 'test content');
18
- // Set allowed directories to our test directory
19
- setAllowedDirectories([normalizePath(testDir)]);
20
- });
21
- afterAll(async () => {
22
- // Cleanup
23
- try {
24
- await fs.rm(testDir, { recursive: true, force: true });
25
- }
26
- catch {
27
- // Ignore cleanup errors
28
- }
29
- });
30
- describe('setAllowedDirectories / getAllowedDirectories', () => {
31
- it('should set and get allowed directories', () => {
32
- const dirs = ['/test/dir1', '/test/dir2'];
33
- setAllowedDirectories(dirs.map(normalizePath));
34
- const result = getAllowedDirectories();
35
- expect(result.length).toBe(2);
36
- // Reset to test directory
37
- setAllowedDirectories([normalizePath(testDir)]);
38
- });
39
- it('should return empty array when no directories set', () => {
40
- setAllowedDirectories([]);
41
- expect(getAllowedDirectories()).toEqual([]);
42
- // Reset to test directory
43
- setAllowedDirectories([normalizePath(testDir)]);
44
- });
45
- });
46
- describe('validateExistingPath', () => {
47
- it('should allow paths within allowed directories', async () => {
48
- const result = await validateExistingPath(testFile);
49
- expect(result).toContain('test.txt');
50
- });
51
- it('should allow the allowed directory itself', async () => {
52
- const result = await validateExistingPath(testDir);
53
- expect(result).toBeTruthy();
54
- });
55
- it('should allow subdirectories within allowed directories', async () => {
56
- const result = await validateExistingPath(subDir);
57
- expect(result).toContain('subdir');
58
- });
59
- it('should reject paths outside allowed directories', async () => {
60
- await expect(validateExistingPath('/etc/passwd')).rejects.toThrow();
61
- });
62
- it('should reject paths with .. traversal attempts', async () => {
63
- const traversalPath = path.join(testDir, '..', 'etc', 'passwd');
64
- await expect(validateExistingPath(traversalPath)).rejects.toThrow();
65
- });
66
- it('should reject non-existent paths', async () => {
67
- const nonExistent = path.join(testDir, 'non-existent-file.txt');
68
- await expect(validateExistingPath(nonExistent)).rejects.toThrow();
69
- });
70
- });
71
- describe('edge cases', () => {
72
- it('should handle paths with spaces', async () => {
73
- const dirWithSpaces = path.join(testDir, 'dir with spaces');
74
- await fs.mkdir(dirWithSpaces);
75
- const fileInDir = path.join(dirWithSpaces, 'file.txt');
76
- await fs.writeFile(fileInDir, 'content');
77
- const result = await validateExistingPath(fileInDir);
78
- expect(result).toContain('file.txt');
79
- await fs.rm(dirWithSpaces, { recursive: true });
80
- });
81
- it('should handle paths with special characters', async () => {
82
- const specialDir = path.join(testDir, 'special-chars_123');
83
- await fs.mkdir(specialDir);
84
- const fileInDir = path.join(specialDir, 'test_file-1.txt');
85
- await fs.writeFile(fileInDir, 'content');
86
- const result = await validateExistingPath(fileInDir);
87
- expect(result).toContain('test_file-1.txt');
88
- await fs.rm(specialDir, { recursive: true });
89
- });
90
- });
91
- });
92
- //# sourceMappingURL=path-validation.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"path-validation.test.js","sourceRoot":"","sources":["../../src/__tests__/path-validation.test.ts"],"names":[],"mappings":"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"}
@@ -1,4 +0,0 @@
1
- export declare function createExcludeMatcher(excludePatterns: string[]): (name: string, relativePath: string) => boolean;
2
- export declare function classifyAccessError(error: unknown): 'symlink' | 'inaccessible';
3
- export declare function insertSorted<T>(arr: T[], item: T, compare: (a: T, b: T) => number, maxLen: number): void;
4
- //# sourceMappingURL=directory-helpers.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"directory-helpers.d.ts","sourceRoot":"","sources":["../../src/lib/directory-helpers.ts"],"names":[],"mappings":"AAKA,wBAAgB,oBAAoB,CAClC,eAAe,EAAE,MAAM,EAAE,GACxB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,CAOjD;AAGD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,GACb,SAAS,GAAG,cAAc,CAS5B;AAID,wBAAgB,YAAY,CAAC,CAAC,EAC5B,GAAG,EAAE,CAAC,EAAE,EACR,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,EAC/B,MAAM,EAAE,MAAM,GACb,IAAI,CASN"}
@@ -1,36 +0,0 @@
1
- import { Minimatch } from 'minimatch';
2
- import { ErrorCode, McpError } from './errors.js';
3
- // Create matcher from exclude patterns
4
- export function createExcludeMatcher(excludePatterns) {
5
- if (excludePatterns.length === 0) {
6
- return () => false;
7
- }
8
- const matchers = excludePatterns.map((pattern) => new Minimatch(pattern));
9
- return (name, relativePath) => matchers.some((m) => m.match(name) || m.match(relativePath));
10
- }
11
- // Classify symlink/access errors for summary tracking
12
- export function classifyAccessError(error) {
13
- if (error instanceof McpError &&
14
- (error.code === ErrorCode.E_ACCESS_DENIED ||
15
- error.code === ErrorCode.E_SYMLINK_NOT_ALLOWED)) {
16
- return 'symlink';
17
- }
18
- return 'inaccessible';
19
- }
20
- // Insert item into sorted array maintaining sort order (descending by comparator)
21
- // Comparator should return negative if a < b, positive if a > b, 0 if equal
22
- export function insertSorted(arr, item, compare, maxLen) {
23
- if (maxLen <= 0)
24
- return;
25
- const idx = arr.findIndex((el) => compare(item, el) < 0);
26
- if (idx === -1) {
27
- if (arr.length < maxLen)
28
- arr.push(item);
29
- }
30
- else {
31
- arr.splice(idx, 0, item);
32
- if (arr.length > maxLen)
33
- arr.pop();
34
- }
35
- }
36
- //# sourceMappingURL=directory-helpers.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"directory-helpers.js","sourceRoot":"","sources":["../../src/lib/directory-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAElD,uCAAuC;AACvC,MAAM,UAAU,oBAAoB,CAClC,eAAyB;IAEzB,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC;IACrB,CAAC;IACD,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1E,OAAO,CAAC,IAAY,EAAE,YAAoB,EAAW,EAAE,CACrD,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,mBAAmB,CACjC,KAAc;IAEd,IACE,KAAK,YAAY,QAAQ;QACzB,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,eAAe;YACvC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,qBAAqB,CAAC,EACjD,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,kFAAkF;AAClF,4EAA4E;AAC5E,MAAM,UAAU,YAAY,CAC1B,GAAQ,EACR,IAAO,EACP,OAA+B,EAC/B,MAAc;IAEd,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO;IACxB,MAAM,GAAG,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QACf,IAAI,GAAG,CAAC,MAAM,GAAG,MAAM;YAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QACzB,IAAI,GAAG,CAAC,MAAM,GAAG,MAAM;YAAE,GAAG,CAAC,GAAG,EAAE,CAAC;IACrC,CAAC;AACH,CAAC"}
@@ -1,10 +0,0 @@
1
- import type { ContentMatch, DirectoryAnalysis, DirectoryEntry, FileInfo, OperationSummary, SearchResult, TreeEntry } from '../config/types.js';
2
- export declare function formatDirectoryListing(entries: DirectoryEntry[], basePath: string): string;
3
- export declare function formatSearchResults(results: SearchResult[]): string;
4
- export declare function formatContentMatches(matches: ContentMatch[]): string;
5
- export declare function formatFileInfo(info: FileInfo): string;
6
- export declare function formatDirectoryAnalysis(analysis: DirectoryAnalysis): string;
7
- export declare function formatTreeEntry(entry: TreeEntry, indent?: string): string;
8
- export declare function formatAllowedDirectories(dirs: string[]): string;
9
- export declare function formatOperationSummary(summary: OperationSummary): string;
10
- //# sourceMappingURL=formatters.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/lib/formatters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,QAAQ,EACR,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACV,MAAM,oBAAoB,CAAC;AAqB5B,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,cAAc,EAAE,EACzB,QAAQ,EAAE,MAAM,GACf,MAAM,CAsCR;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAenE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAoDpE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAsBrD;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,CAyC3E;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,SAAK,GAAG,MAAM,CAYrE;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAW/D;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CA0CxE"}
@@ -1,202 +0,0 @@
1
- const BYTES_PER_KILOBYTE = 1024;
2
- const BYTE_UNIT_LABELS = ['B', 'KB', 'MB', 'GB', 'TB'];
3
- const ANALYSIS_SEPARATOR_WIDTH = 50;
4
- const LINE_NUMBER_PAD_WIDTH = 4;
5
- function formatBytes(bytes) {
6
- if (bytes === 0)
7
- return '0 B';
8
- const unitIndex = Math.floor(Math.log(bytes) / Math.log(BYTES_PER_KILOBYTE));
9
- const unit = BYTE_UNIT_LABELS[unitIndex] ?? 'B';
10
- const value = bytes / Math.pow(BYTES_PER_KILOBYTE, unitIndex);
11
- return `${parseFloat(value.toFixed(2))} ${unit}`;
12
- }
13
- function formatDate(date) {
14
- return date.toISOString();
15
- }
16
- export function formatDirectoryListing(entries, basePath) {
17
- if (entries.length === 0) {
18
- return 'Directory is empty';
19
- }
20
- const lines = [`Contents of ${basePath}:`, ''];
21
- const dirs = entries.filter((e) => e.type === 'directory');
22
- const files = entries.filter((e) => e.type !== 'directory');
23
- if (dirs.length > 0) {
24
- lines.push('Directories:');
25
- for (const dir of dirs) {
26
- const symlinkSuffix = dir.symlinkTarget ? ` -> ${dir.symlinkTarget}` : '';
27
- lines.push(` [DIR] ${dir.relativePath}${symlinkSuffix}`);
28
- }
29
- lines.push('');
30
- }
31
- if (files.length > 0) {
32
- lines.push('Files:');
33
- for (const file of files) {
34
- const size = file.size !== undefined ? formatBytes(file.size) : undefined;
35
- const sizeSuffix = size !== undefined ? ` (${size})` : '';
36
- const typeTag = file.type === 'symlink' ? '[LINK]' : '[FILE]';
37
- const symlinkSuffix = file.symlinkTarget
38
- ? ` -> ${file.symlinkTarget}`
39
- : '';
40
- lines.push(` ${typeTag} ${file.relativePath}${sizeSuffix}${symlinkSuffix}`);
41
- }
42
- }
43
- lines.push('');
44
- lines.push(`Total: ${dirs.length} directories, ${files.length} files`);
45
- return lines.join('\n');
46
- }
47
- export function formatSearchResults(results) {
48
- if (results.length === 0) {
49
- return 'No matches found';
50
- }
51
- const lines = [`Found ${results.length} matches:`, ''];
52
- for (const result of results) {
53
- const typeTag = result.type === 'directory' ? '[DIR]' : '[FILE]';
54
- const size = result.size !== undefined ? ` (${formatBytes(result.size)})` : '';
55
- lines.push(`${typeTag} ${result.path}${size}`);
56
- }
57
- return lines.join('\n');
58
- }
59
- export function formatContentMatches(matches) {
60
- if (matches.length === 0) {
61
- return 'No matches found';
62
- }
63
- const lines = [`Found ${matches.length} matches:`, ''];
64
- const byFile = new Map();
65
- for (const match of matches) {
66
- const existing = byFile.get(match.file);
67
- if (existing) {
68
- existing.push(match);
69
- }
70
- else {
71
- byFile.set(match.file, [match]);
72
- }
73
- }
74
- for (const [file, fileMatches] of byFile) {
75
- lines.push(`${file}:`);
76
- for (const match of fileMatches) {
77
- if (match.contextBefore && match.contextBefore.length > 0) {
78
- for (let i = 0; i < match.contextBefore.length; i++) {
79
- const contextLine = match.contextBefore[i];
80
- const lineNum = match.line - match.contextBefore.length + i;
81
- lines.push(` ${String(lineNum).padStart(LINE_NUMBER_PAD_WIDTH)}: ${contextLine ?? ''}`);
82
- }
83
- }
84
- lines.push(` > ${String(match.line).padStart(LINE_NUMBER_PAD_WIDTH)}: ${match.content}`);
85
- if (match.contextAfter && match.contextAfter.length > 0) {
86
- for (let i = 0; i < match.contextAfter.length; i++) {
87
- const contextLine = match.contextAfter[i];
88
- const lineNum = match.line + 1 + i;
89
- lines.push(` ${String(lineNum).padStart(LINE_NUMBER_PAD_WIDTH)}: ${contextLine ?? ''}`);
90
- }
91
- }
92
- if ((match.contextBefore && match.contextBefore.length > 0) ||
93
- (match.contextAfter && match.contextAfter.length > 0)) {
94
- lines.push(' ---');
95
- }
96
- }
97
- lines.push('');
98
- }
99
- return lines.join('\n');
100
- }
101
- export function formatFileInfo(info) {
102
- const lines = [
103
- `Name: ${info.name}`,
104
- `Path: ${info.path}`,
105
- `Type: ${info.type}`,
106
- `Size: ${formatBytes(info.size)}`,
107
- `Created: ${formatDate(info.created)}`,
108
- `Modified: ${formatDate(info.modified)}`,
109
- `Accessed: ${formatDate(info.accessed)}`,
110
- `Permissions: ${info.permissions}`,
111
- `Hidden: ${info.isHidden ? 'Yes' : 'No'}`,
112
- ];
113
- if (info.mimeType) {
114
- lines.push(`MIME Type: ${info.mimeType}`);
115
- }
116
- if (info.symlinkTarget) {
117
- lines.push(`Symlink Target: ${info.symlinkTarget}`);
118
- }
119
- return lines.join('\n');
120
- }
121
- export function formatDirectoryAnalysis(analysis) {
122
- const lines = [
123
- `Directory Analysis: ${analysis.path}`,
124
- '='.repeat(ANALYSIS_SEPARATOR_WIDTH),
125
- '',
126
- 'Summary:',
127
- ` Total Files: ${analysis.totalFiles}`,
128
- ` Total Directories: ${analysis.totalDirectories}`,
129
- ` Total Size: ${formatBytes(analysis.totalSize)}`,
130
- ` Max Depth: ${analysis.maxDepth}`,
131
- '',
132
- ];
133
- if (Object.keys(analysis.fileTypes).length > 0) {
134
- lines.push('File Types:');
135
- const sorted = Object.entries(analysis.fileTypes).sort((a, b) => b[1] - a[1]);
136
- for (const [ext, count] of sorted) {
137
- lines.push(` ${ext}: ${count}`);
138
- }
139
- lines.push('');
140
- }
141
- if (analysis.largestFiles.length > 0) {
142
- lines.push('Largest Files:');
143
- for (const file of analysis.largestFiles) {
144
- lines.push(` ${formatBytes(file.size)} - ${file.path}`);
145
- }
146
- lines.push('');
147
- }
148
- if (analysis.recentlyModified.length > 0) {
149
- lines.push('Recently Modified:');
150
- for (const file of analysis.recentlyModified) {
151
- lines.push(` ${formatDate(file.modified)} - ${file.path}`);
152
- }
153
- }
154
- return lines.join('\n');
155
- }
156
- export function formatTreeEntry(entry, indent = '') {
157
- const lines = [];
158
- const icon = entry.type === 'directory' ? 'šŸ“' : 'šŸ“„';
159
- const sizeStr = entry.size !== undefined ? ` (${formatBytes(entry.size)})` : '';
160
- lines.push(`${indent}${icon} ${entry.name}${sizeStr}`);
161
- for (const child of entry.children ?? []) {
162
- lines.push(formatTreeEntry(child, `${indent} `));
163
- }
164
- return lines.join('\n');
165
- }
166
- export function formatAllowedDirectories(dirs) {
167
- if (dirs.length === 0) {
168
- return 'No directories are currently allowed.';
169
- }
170
- const lines = ['Allowed Directories:', ''];
171
- for (const dir of dirs) {
172
- lines.push(` - ${dir}`);
173
- }
174
- return lines.join('\n');
175
- }
176
- export function formatOperationSummary(summary) {
177
- const lines = [];
178
- if (summary.truncated) {
179
- lines.push(`\n\nāš ļø PARTIAL RESULTS: ${summary.truncatedReason ?? 'results truncated'}`);
180
- if (summary.tip) {
181
- lines.push(`Tip: ${summary.tip}`);
182
- }
183
- }
184
- if (summary.skippedTooLarge && summary.skippedTooLarge > 0) {
185
- lines.push(`Note: ${summary.skippedTooLarge} file(s) skipped (too large).`);
186
- }
187
- if (summary.skippedBinary && summary.skippedBinary > 0) {
188
- lines.push(`Note: ${summary.skippedBinary} file(s) skipped (binary).`);
189
- }
190
- if (summary.skippedInaccessible && summary.skippedInaccessible > 0) {
191
- lines.push(`Note: ${summary.skippedInaccessible} item(s) were inaccessible and skipped.`);
192
- }
193
- if (summary.symlinksNotFollowed && summary.symlinksNotFollowed > 0) {
194
- lines.push(`Note: ${summary.symlinksNotFollowed} symlink(s) were not followed (security).`);
195
- }
196
- if (summary.linesSkippedDueToRegexTimeout &&
197
- summary.linesSkippedDueToRegexTimeout > 0) {
198
- lines.push(`Note: ${summary.linesSkippedDueToRegexTimeout} line(s) skipped (regex timeout).`);
199
- }
200
- return lines.join('\n');
201
- }
202
- //# sourceMappingURL=formatters.js.map