@j0hanz/filesystem-context-mcp 1.0.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 (146) hide show
  1. package/README.md +369 -0
  2. package/dist/__tests__/errors.test.d.ts +2 -0
  3. package/dist/__tests__/errors.test.d.ts.map +1 -0
  4. package/dist/__tests__/errors.test.js +88 -0
  5. package/dist/__tests__/errors.test.js.map +1 -0
  6. package/dist/__tests__/file-operations.test.d.ts +2 -0
  7. package/dist/__tests__/file-operations.test.d.ts.map +1 -0
  8. package/dist/__tests__/file-operations.test.js +230 -0
  9. package/dist/__tests__/file-operations.test.js.map +1 -0
  10. package/dist/__tests__/lib/errors.test.d.ts +2 -0
  11. package/dist/__tests__/lib/errors.test.d.ts.map +1 -0
  12. package/dist/__tests__/lib/errors.test.js +156 -0
  13. package/dist/__tests__/lib/errors.test.js.map +1 -0
  14. package/dist/__tests__/lib/file-operations.test.d.ts +2 -0
  15. package/dist/__tests__/lib/file-operations.test.d.ts.map +1 -0
  16. package/dist/__tests__/lib/file-operations.test.js +417 -0
  17. package/dist/__tests__/lib/file-operations.test.js.map +1 -0
  18. package/dist/__tests__/lib/fs-helpers.test.d.ts +2 -0
  19. package/dist/__tests__/lib/fs-helpers.test.d.ts.map +1 -0
  20. package/dist/__tests__/lib/fs-helpers.test.js +183 -0
  21. package/dist/__tests__/lib/fs-helpers.test.js.map +1 -0
  22. package/dist/__tests__/lib/path-validation.test.d.ts +2 -0
  23. package/dist/__tests__/lib/path-validation.test.d.ts.map +1 -0
  24. package/dist/__tests__/lib/path-validation.test.js +103 -0
  25. package/dist/__tests__/lib/path-validation.test.js.map +1 -0
  26. package/dist/__tests__/path-validation.test.d.ts +2 -0
  27. package/dist/__tests__/path-validation.test.d.ts.map +1 -0
  28. package/dist/__tests__/path-validation.test.js +92 -0
  29. package/dist/__tests__/path-validation.test.js.map +1 -0
  30. package/dist/config/types.d.ts +222 -0
  31. package/dist/config/types.d.ts.map +1 -0
  32. package/dist/config/types.js +23 -0
  33. package/dist/config/types.js.map +1 -0
  34. package/dist/index.d.ts +3 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +50 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/lib/constants.d.ts +16 -0
  39. package/dist/lib/constants.d.ts.map +1 -0
  40. package/dist/lib/constants.js +335 -0
  41. package/dist/lib/constants.js.map +1 -0
  42. package/dist/lib/errors.d.ts +33 -0
  43. package/dist/lib/errors.d.ts.map +1 -0
  44. package/dist/lib/errors.js +205 -0
  45. package/dist/lib/errors.js.map +1 -0
  46. package/dist/lib/file-operations.d.ts +69 -0
  47. package/dist/lib/file-operations.d.ts.map +1 -0
  48. package/dist/lib/file-operations.js +1003 -0
  49. package/dist/lib/file-operations.js.map +1 -0
  50. package/dist/lib/formatters.d.ts +30 -0
  51. package/dist/lib/formatters.d.ts.map +1 -0
  52. package/dist/lib/formatters.js +204 -0
  53. package/dist/lib/formatters.js.map +1 -0
  54. package/dist/lib/fs-helpers.d.ts +29 -0
  55. package/dist/lib/fs-helpers.d.ts.map +1 -0
  56. package/dist/lib/fs-helpers.js +295 -0
  57. package/dist/lib/fs-helpers.js.map +1 -0
  58. package/dist/lib/path-utils.d.ts +12 -0
  59. package/dist/lib/path-utils.d.ts.map +1 -0
  60. package/dist/lib/path-utils.js +34 -0
  61. package/dist/lib/path-utils.js.map +1 -0
  62. package/dist/lib/path-validation.d.ts +31 -0
  63. package/dist/lib/path-validation.d.ts.map +1 -0
  64. package/dist/lib/path-validation.js +181 -0
  65. package/dist/lib/path-validation.js.map +1 -0
  66. package/dist/lib/roots-utils.d.ts +7 -0
  67. package/dist/lib/roots-utils.d.ts.map +1 -0
  68. package/dist/lib/roots-utils.js +39 -0
  69. package/dist/lib/roots-utils.js.map +1 -0
  70. package/dist/lib/types.d.ts +6 -0
  71. package/dist/lib/types.d.ts.map +1 -0
  72. package/dist/lib/types.js +2 -0
  73. package/dist/lib/types.js.map +1 -0
  74. package/dist/schemas/common.d.ts +41 -0
  75. package/dist/schemas/common.d.ts.map +1 -0
  76. package/dist/schemas/common.js +21 -0
  77. package/dist/schemas/common.js.map +1 -0
  78. package/dist/schemas/index.d.ts +3 -0
  79. package/dist/schemas/index.d.ts.map +1 -0
  80. package/dist/schemas/index.js +5 -0
  81. package/dist/schemas/index.js.map +1 -0
  82. package/dist/schemas/inputs.d.ts +72 -0
  83. package/dist/schemas/inputs.d.ts.map +1 -0
  84. package/dist/schemas/inputs.js +326 -0
  85. package/dist/schemas/inputs.js.map +1 -0
  86. package/dist/schemas/outputs.d.ts +476 -0
  87. package/dist/schemas/outputs.d.ts.map +1 -0
  88. package/dist/schemas/outputs.js +181 -0
  89. package/dist/schemas/outputs.js.map +1 -0
  90. package/dist/server.d.ts +5 -0
  91. package/dist/server.d.ts.map +1 -0
  92. package/dist/server.js +83 -0
  93. package/dist/server.js.map +1 -0
  94. package/dist/tools/analyze-directory.d.ts +3 -0
  95. package/dist/tools/analyze-directory.d.ts.map +1 -0
  96. package/dist/tools/analyze-directory.js +57 -0
  97. package/dist/tools/analyze-directory.js.map +1 -0
  98. package/dist/tools/directory-tree.d.ts +3 -0
  99. package/dist/tools/directory-tree.d.ts.map +1 -0
  100. package/dist/tools/directory-tree.js +47 -0
  101. package/dist/tools/directory-tree.js.map +1 -0
  102. package/dist/tools/get-file-info.d.ts +3 -0
  103. package/dist/tools/get-file-info.d.ts.map +1 -0
  104. package/dist/tools/get-file-info.js +44 -0
  105. package/dist/tools/get-file-info.js.map +1 -0
  106. package/dist/tools/index.d.ts +3 -0
  107. package/dist/tools/index.d.ts.map +1 -0
  108. package/dist/tools/index.js +23 -0
  109. package/dist/tools/index.js.map +1 -0
  110. package/dist/tools/list-allowed-dirs.d.ts +3 -0
  111. package/dist/tools/list-allowed-dirs.d.ts.map +1 -0
  112. package/dist/tools/list-allowed-dirs.js +23 -0
  113. package/dist/tools/list-allowed-dirs.js.map +1 -0
  114. package/dist/tools/list-directory.d.ts +3 -0
  115. package/dist/tools/list-directory.d.ts.map +1 -0
  116. package/dist/tools/list-directory.js +60 -0
  117. package/dist/tools/list-directory.js.map +1 -0
  118. package/dist/tools/read-file.d.ts +3 -0
  119. package/dist/tools/read-file.d.ts.map +1 -0
  120. package/dist/tools/read-file.js +55 -0
  121. package/dist/tools/read-file.js.map +1 -0
  122. package/dist/tools/read-media-file.d.ts +3 -0
  123. package/dist/tools/read-media-file.d.ts.map +1 -0
  124. package/dist/tools/read-media-file.js +48 -0
  125. package/dist/tools/read-media-file.js.map +1 -0
  126. package/dist/tools/read-multiple-files.d.ts +3 -0
  127. package/dist/tools/read-multiple-files.d.ts.map +1 -0
  128. package/dist/tools/read-multiple-files.js +53 -0
  129. package/dist/tools/read-multiple-files.js.map +1 -0
  130. package/dist/tools/search-content.d.ts +3 -0
  131. package/dist/tools/search-content.d.ts.map +1 -0
  132. package/dist/tools/search-content.js +67 -0
  133. package/dist/tools/search-content.js.map +1 -0
  134. package/dist/tools/search-files.d.ts +3 -0
  135. package/dist/tools/search-files.d.ts.map +1 -0
  136. package/dist/tools/search-files.js +51 -0
  137. package/dist/tools/search-files.js.map +1 -0
  138. package/dist/utils/index.d.ts +2 -0
  139. package/dist/utils/index.d.ts.map +1 -0
  140. package/dist/utils/index.js +2 -0
  141. package/dist/utils/index.js.map +1 -0
  142. package/dist/utils/response-helpers.d.ts +22 -0
  143. package/dist/utils/response-helpers.d.ts.map +1 -0
  144. package/dist/utils/response-helpers.js +24 -0
  145. package/dist/utils/response-helpers.js.map +1 -0
  146. package/package.json +61 -0
package/README.md ADDED
@@ -0,0 +1,369 @@
1
+ # Filesystem Context MCP Server
2
+
3
+ A secure Model Context Protocol (MCP) server for filesystem scanning, searching, and analysis. Built with TypeScript and the official MCP SDK.
4
+
5
+ ## Security Features
6
+
7
+ - **Path Validation**: All file operations are restricted to explicitly allowed directories
8
+ - **Symlink Attack Prevention**: Symlinks are resolved before validation to prevent escaping allowed directories
9
+ - **Path Traversal Protection**: Attempts to access paths outside allowed directories are blocked
10
+ - **Read-Only Operations**: All tools are marked with `readOnlyHint` annotation
11
+
12
+ ## Features
13
+
14
+ This server provides the following tools for filesystem operations:
15
+
16
+ | Tool | Description |
17
+ | -------------------------- | ------------------------------------------------------------ |
18
+ | `list_allowed_directories` | List directories this server is allowed to access |
19
+ | `list_directory` | List files and directories with optional recursive traversal |
20
+ | `search_files` | Search for files using glob patterns |
21
+ | `read_file` | Read file contents with optional line range |
22
+ | `read_multiple_files` | Read multiple files in parallel efficiently |
23
+ | `get_file_info` | Get detailed file/directory metadata |
24
+ | `search_content` | Search for text within files using regex patterns |
25
+ | `analyze_directory` | Analyze directory structure and get statistics |
26
+ | `directory_tree` | Get JSON tree structure of a directory |
27
+ | `read_media_file` | Read binary/media files as base64-encoded data |
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ # Clone the repository
33
+ git clone <repository-url>
34
+ cd filesystem-context-mcp
35
+
36
+ # Install dependencies
37
+ npm install
38
+
39
+ # Build the project
40
+ npm run build
41
+ ```
42
+
43
+ ## Usage
44
+
45
+ ### Running the Server
46
+
47
+ **Important**: You must specify at least one allowed directory when starting the server:
48
+
49
+ ```bash
50
+ # Production mode - specify allowed directories
51
+ node dist/index.js /path/to/allowed/dir1 /path/to/allowed/dir2
52
+
53
+ # Development mode with tsx
54
+ npx tsx src/index.ts /path/to/allowed/dir
55
+
56
+ # Windows example
57
+ node dist/index.js C:\Users\Projects C:\Users\Documents
58
+ ```
59
+
60
+ ### Testing with MCP Inspector
61
+
62
+ ```bash
63
+ npm run inspector
64
+ ```
65
+
66
+ Then connect to the server via stdio, providing allowed directories as arguments.
67
+
68
+ ### Configuration with MCP Clients
69
+
70
+ #### Claude Desktop
71
+
72
+ Add to your Claude Desktop config (`%APPDATA%\Claude\claude_desktop_config.json` on Windows):
73
+
74
+ ```json
75
+ {
76
+ "mcpServers": {
77
+ "filesystem-context": {
78
+ "command": "node",
79
+ "args": [
80
+ "C:\\path\\to\\filesystem-context-mcp\\dist\\index.js",
81
+ "C:\\Users\\Projects",
82
+ "C:\\Users\\Documents"
83
+ ]
84
+ }
85
+ }
86
+ }
87
+ ```
88
+
89
+ #### VS Code with Copilot
90
+
91
+ Add to your VS Code settings or `.vscode/mcp.json`:
92
+
93
+ ```json
94
+ {
95
+ "mcp": {
96
+ "servers": {
97
+ "filesystem-context": {
98
+ "command": "node",
99
+ "args": ["${workspaceFolder}/dist/index.js", "${workspaceFolder}"]
100
+ }
101
+ }
102
+ }
103
+ }
104
+ ```
105
+
106
+ ## Tool Documentation
107
+
108
+ All tools return both a human-readable `content` text block and a machine-friendly `structuredContent` payload (with `outputSchema` declared in the server).
109
+
110
+ ### list_directory
111
+
112
+ List all files and directories in a given path.
113
+
114
+ **Parameters:**
115
+
116
+ - `path` (string, required): The directory path to list
117
+ - `recursive` (boolean, default: false): Whether to list recursively
118
+ - `includeHidden` (boolean, default: false): Include hidden files (dotfiles)
119
+ - `maxDepth` (number, default: 10): Maximum depth for recursive listing
120
+ - `maxEntries` (number, optional): Maximum number of entries to return (prevents huge responses)
121
+
122
+ **Example:**
123
+
124
+ ```json
125
+ {
126
+ "path": "C:\\Users\\Projects",
127
+ "recursive": true,
128
+ "maxDepth": 2
129
+ }
130
+ ```
131
+
132
+ ### search_files
133
+
134
+ Search for files and directories matching a glob pattern.
135
+
136
+ **Parameters:**
137
+
138
+ - `path` (string, required): Base directory to search from
139
+ - `pattern` (string, required): Glob pattern to match (e.g. `**/*.ts`)
140
+ - `excludePatterns` (string[], optional): Glob patterns to exclude
141
+ - `maxResults` (number, optional): Maximum number of matches to return (prevents huge responses)
142
+
143
+ **Example:**
144
+
145
+ ```json
146
+ {
147
+ "path": "./src",
148
+ "pattern": "**/*.ts",
149
+ "excludePatterns": ["**/*.test.ts"]
150
+ }
151
+ ```
152
+
153
+ ### read_file
154
+
155
+ Read the contents of a file (optionally a line range).
156
+
157
+ **Parameters:**
158
+
159
+ - `path` (string, required): Path to the file
160
+ - `encoding` (string, default: "utf-8"): File encoding
161
+ - `maxSize` (number, default: 10485760): Maximum file size in bytes (default 10MB)
162
+ - `lineStart` (number, optional): Start line (1-based)
163
+ - `lineEnd` (number, optional): End line (inclusive)
164
+
165
+ **Example:**
166
+
167
+ ```json
168
+ {
169
+ "path": "./src/index.ts",
170
+ "lineStart": 1,
171
+ "lineEnd": 50
172
+ }
173
+ ```
174
+
175
+ ### get_file_info
176
+
177
+ Get detailed information about a file or directory.
178
+
179
+ **Parameters:**
180
+
181
+ - `path` (string, required): Path to the file or directory
182
+
183
+ **Returns:** File metadata including size, timestamps, permissions, and type.
184
+
185
+ ### search_content
186
+
187
+ Search for text content within files using a regular expression.
188
+
189
+ **Parameters:**
190
+
191
+ - `path` (string, required): Base directory to search in
192
+ - `pattern` (string, required): Regular expression pattern
193
+ - `filePattern` (string, default: "\*_/_"): Glob pattern to filter files
194
+ - `excludePatterns` (string[], optional): Glob patterns to exclude (e.g. `node_modules/**`)
195
+ - `caseSensitive` (boolean, default: false): Case-sensitive search
196
+ - `maxResults` (number, default: 100): Maximum number of matches to return
197
+ - `maxFileSize` (number, optional): Maximum file size in bytes to scan (default 1MB)
198
+ - `maxFilesScanned` (number, optional): Maximum number of files to scan before stopping
199
+ - `timeoutMs` (number, optional): Timeout in milliseconds for the search operation
200
+ - `skipBinary` (boolean, default: true): Skip likely-binary files
201
+
202
+ **Example:**
203
+
204
+ ```json
205
+ {
206
+ "path": "./src",
207
+ "pattern": "TODO:",
208
+ "filePattern": "**/*.ts",
209
+ "maxResults": 50
210
+ }
211
+ ```
212
+
213
+ ### analyze_directory
214
+
215
+ Analyze a directory structure and compute summary statistics.
216
+
217
+ **Parameters:**
218
+
219
+ - `path` (string, required): Directory path to analyze
220
+ - `maxDepth` (number, default: 10): Maximum depth to traverse
221
+ - `topN` (number, default: 10): Number of “top” items to return (largest/recent)
222
+
223
+ **Returns:** Statistics including file counts by extension, total size, largest files, and recently modified files.
224
+
225
+ ### list_allowed_directories
226
+
227
+ List all directories that this server is allowed to access.
228
+
229
+ **Parameters:** None
230
+
231
+ **Returns:** Array of allowed directory paths. Use this to understand the scope of available file operations.
232
+
233
+ ### read_multiple_files
234
+
235
+ Read the contents of multiple files in parallel. More efficient than reading files one by one.
236
+
237
+ **Parameters:**
238
+
239
+ - `paths` (string[], required): Array of file paths to read
240
+ - `encoding` (string, default: "utf-8"): File encoding
241
+ - `maxSize` (number, default: 10485760): Maximum file size in bytes per file (default 10MB)
242
+
243
+ **Example:**
244
+
245
+ ```json
246
+ {
247
+ "paths": ["./src/index.ts", "./src/server.ts", "./package.json"],
248
+ "encoding": "utf-8"
249
+ }
250
+ ```
251
+
252
+ **Returns:** Array of results, each containing the file path and either its content or an error message. Individual file errors do not fail the entire operation.
253
+
254
+ ### directory_tree
255
+
256
+ Get a JSON tree structure of a directory. More efficient for AI parsing than flat file lists.
257
+
258
+ **Parameters:**
259
+
260
+ - `path` (string, required): Directory path to build tree from
261
+ - `maxDepth` (number, default: 5): Maximum depth to traverse
262
+ - `excludePatterns` (string[], optional): Glob patterns to exclude (e.g., `node_modules`, `*.log`)
263
+ - `includeHidden` (boolean, default: false): Include hidden files and directories
264
+ - `includeSize` (boolean, default: false): Include file sizes in the tree
265
+
266
+ **Example:**
267
+
268
+ ```json
269
+ {
270
+ "path": "./src",
271
+ "maxDepth": 3,
272
+ "excludePatterns": ["__tests__"],
273
+ "includeSize": true
274
+ }
275
+ ```
276
+
277
+ **Returns:** Nested tree structure with files and directories, useful for understanding project structure.
278
+
279
+ ### read_media_file
280
+
281
+ Read a binary/media file (image, audio, video, etc.) and return it as base64-encoded data.
282
+
283
+ **Parameters:**
284
+
285
+ - `path` (string, required): Path to the media file
286
+ - `maxSize` (number, default: 52428800): Maximum file size in bytes (default 50MB)
287
+
288
+ **Example:**
289
+
290
+ ```json
291
+ {
292
+ "path": "./assets/logo.png"
293
+ }
294
+ ```
295
+
296
+ **Returns:** Object containing the file path, MIME type, size in bytes, and base64-encoded data.
297
+
298
+ ## Development
299
+
300
+ ```bash
301
+ # Run in development mode with hot reload
302
+ npm run dev
303
+
304
+ # Type checking
305
+ npm run type-check
306
+
307
+ # Linting
308
+ npm run lint
309
+
310
+ # Build for production
311
+ npm run build
312
+ ```
313
+
314
+ ## Architecture
315
+
316
+ ```text
317
+ filesystem-context-mcp/
318
+ ├── src/
319
+ │ ├── index.ts # Main server entry point
320
+ │ └── lib/
321
+ │ ├── types.ts # TypeScript interfaces
322
+ │ ├── path-utils.ts # Path normalization utilities
323
+ │ ├── path-validation.ts # Security validation
324
+ │ ├── file-operations.ts # Core file operations
325
+ │ └── formatters.ts # Output formatting
326
+ ├── dist/ # Compiled JavaScript output
327
+ ├── package.json # Project configuration
328
+ ├── tsconfig.json # TypeScript configuration
329
+ └── README.md # This file
330
+ ```
331
+
332
+ The server uses:
333
+
334
+ - **Transport**: StdioServerTransport for local MCP client integration
335
+ - **Schema Validation**: Zod for input/output validation
336
+ - **Glob Matching**: `fast-glob` for file pattern matching and `minimatch` for pattern testing
337
+ - **Security**: Path validation against allowed directories with symlink resolution
338
+
339
+ ## Security Considerations
340
+
341
+ - **Required Configuration**: You must specify allowed directories via command line arguments
342
+ - **Path Validation**: All paths are validated against allowed directories before any operation
343
+ - **Symlink Protection**: Symlinks are resolved to their real paths before validation
344
+ - **Read-Only**: The server only performs read operations (no file modifications)
345
+ - **Annotations**: All tools are marked with `readOnlyHint: true` for MCP client awareness
346
+
347
+ ## Troubleshooting
348
+
349
+ ### Server not starting
350
+
351
+ 1. Ensure Node.js >= 20.0.0 is installed
352
+ 2. Run `npm install` to install dependencies
353
+ 3. Run `npm run build` to compile TypeScript
354
+
355
+ ### Connection issues with MCP clients
356
+
357
+ 1. Check the path in your client configuration is correct
358
+ 2. Ensure the server is built (`npm run build`)
359
+ 3. Test with MCP Inspector first: `npx @modelcontextprotocol/inspector`
360
+
361
+ ### File access errors
362
+
363
+ 1. Verify the server process has read permissions
364
+ 2. Check that file paths are absolute or relative to the working directory
365
+ 3. Some files (binary, locked) may be skipped during search operations
366
+
367
+ ## License
368
+
369
+ MIT
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=errors.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/errors.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,88 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { classifyError, createDetailedError, ErrorCode, formatDetailedError, getSuggestion, } from '../lib/errors.js';
3
+ describe('Error Utilities', () => {
4
+ describe('classifyError', () => {
5
+ it('should classify access denied errors', () => {
6
+ const error = new Error('Path not within allowed directories');
7
+ expect(classifyError(error)).toBe(ErrorCode.E_ACCESS_DENIED);
8
+ });
9
+ it('should classify not found errors', () => {
10
+ const error = new Error('ENOENT: no such file or directory');
11
+ expect(classifyError(error)).toBe(ErrorCode.E_NOT_FOUND);
12
+ });
13
+ it('should classify not a file errors', () => {
14
+ const error = new Error('Not a file: /some/path');
15
+ expect(classifyError(error)).toBe(ErrorCode.E_NOT_FILE);
16
+ });
17
+ it('should classify file too large errors', () => {
18
+ const error = new Error('File too large: 100MB');
19
+ expect(classifyError(error)).toBe(ErrorCode.E_TOO_LARGE);
20
+ });
21
+ it('should classify permission errors', () => {
22
+ const error = new Error('EACCES: permission denied');
23
+ expect(classifyError(error)).toBe(ErrorCode.E_PERMISSION_DENIED);
24
+ });
25
+ it('should classify timeout errors', () => {
26
+ const error = new Error('Operation timeout');
27
+ expect(classifyError(error)).toBe(ErrorCode.E_TIMEOUT);
28
+ });
29
+ it('should return unknown for unrecognized errors', () => {
30
+ const error = new Error('Some random error');
31
+ expect(classifyError(error)).toBe(ErrorCode.E_UNKNOWN);
32
+ });
33
+ it('should handle non-Error objects', () => {
34
+ expect(classifyError('ENOENT error')).toBe(ErrorCode.E_NOT_FOUND);
35
+ expect(classifyError({ message: 'permission denied' })).toBe(ErrorCode.E_UNKNOWN);
36
+ });
37
+ });
38
+ describe('createDetailedError', () => {
39
+ it('should create detailed error object', () => {
40
+ const error = new Error('File not found');
41
+ const detailed = createDetailedError(error, '/some/path');
42
+ expect(detailed.code).toBe(ErrorCode.E_NOT_FOUND);
43
+ expect(detailed.message).toBe('File not found');
44
+ expect(detailed.path).toBe('/some/path');
45
+ expect(detailed.suggestion).toBeTruthy();
46
+ });
47
+ it('should include additional details', () => {
48
+ const error = new Error('Error');
49
+ const detailed = createDetailedError(error, '/path', { extra: 'info' });
50
+ expect(detailed.details).toEqual({ extra: 'info' });
51
+ });
52
+ });
53
+ describe('formatDetailedError', () => {
54
+ it('should format error for display', () => {
55
+ const detailed = {
56
+ code: ErrorCode.E_NOT_FOUND,
57
+ message: 'File not found',
58
+ path: '/some/path',
59
+ suggestion: 'Check the path exists',
60
+ };
61
+ const formatted = formatDetailedError(detailed);
62
+ expect(formatted).toContain('E_NOT_FOUND');
63
+ expect(formatted).toContain('File not found');
64
+ expect(formatted).toContain('/some/path');
65
+ expect(formatted).toContain('Check the path exists');
66
+ });
67
+ it('should handle missing optional fields', () => {
68
+ const detailed = {
69
+ code: ErrorCode.E_UNKNOWN,
70
+ message: 'Unknown error',
71
+ };
72
+ const formatted = formatDetailedError(detailed);
73
+ expect(formatted).toContain('E_UNKNOWN');
74
+ expect(formatted).toContain('Unknown error');
75
+ });
76
+ });
77
+ describe('getSuggestion', () => {
78
+ it('should return suggestions for all error codes', () => {
79
+ const errorCodes = Object.values(ErrorCode);
80
+ for (const code of errorCodes) {
81
+ const suggestion = getSuggestion(code);
82
+ expect(suggestion).toBeTruthy();
83
+ expect(typeof suggestion).toBe('string');
84
+ }
85
+ });
86
+ });
87
+ });
88
+ //# sourceMappingURL=errors.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.test.js","sourceRoot":"","sources":["../../src/__tests__/errors.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,SAAS,EACT,mBAAmB,EACnB,aAAa,GACd,MAAM,kBAAkB,CAAC;AAE1B,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC9C,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;YAC/D,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;YAC7D,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;YAClD,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;YACjD,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;YACrD,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;YACxC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YAC7C,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACvD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YAC7C,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACzC,MAAM,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YAClE,MAAM,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACpF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;QACnC,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;YAC1C,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;YAE1D,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YAClD,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAChD,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACzC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,UAAU,EAAE,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;YACjC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YAExE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;QACnC,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACzC,MAAM,QAAQ,GAAG;gBACf,IAAI,EAAE,SAAS,CAAC,WAAW;gBAC3B,OAAO,EAAE,gBAAgB;gBACzB,IAAI,EAAE,YAAY;gBAClB,UAAU,EAAE,uBAAuB;aACpC,CAAC;YAEF,MAAM,SAAS,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YAEhD,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;YAC3C,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;YAC9C,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YAC1C,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,QAAQ,GAAG;gBACf,IAAI,EAAE,SAAS,CAAC,SAAS;gBACzB,OAAO,EAAE,eAAe;aACzB,CAAC;YAEF,MAAM,SAAS,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YAEhD,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YACzC,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACvD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAE5C,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;gBAC9B,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;gBACvC,MAAM,CAAC,UAAU,CAAC,CAAC,UAAU,EAAE,CAAC;gBAChC,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=file-operations.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-operations.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/file-operations.test.ts"],"names":[],"mappings":""}