fileditor-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.
@@ -0,0 +1,371 @@
1
+ import { InsertContentHandler } from '../src/handlers/insertContent.js';
2
+ import { FileUtils } from '../src/utils/fileUtils.js';
3
+ import { describe, it, beforeEach, afterEach } from 'node:test';
4
+ import assert from 'node:assert';
5
+ import fs from 'fs/promises';
6
+ import { join } from 'path';
7
+ import { existsSync } from 'fs';
8
+
9
+ /**
10
+ * InsertContentHandler Test Class
11
+ * Test content insertion functionality
12
+ */
13
+ describe('InsertContentHandler', () => {
14
+
15
+ const testDir = './test_files_insert';
16
+ const testFile1 = join(testDir, 'test1.txt');
17
+ const testFile2 = join(testDir, 'test2.txt');
18
+ const baseContent = 'Line 1\nLine 2\nLine 3\nLine 4\nLine 5';
19
+
20
+ beforeEach(async () => {
21
+ // Set test workspace
22
+ FileUtils.setWorkspaceRoot(process.cwd());
23
+
24
+ // Create test directory and files
25
+ if (!existsSync(testDir)) {
26
+ await fs.mkdir(testDir, { recursive: true });
27
+ }
28
+ await fs.writeFile(testFile1, baseContent, 'utf8');
29
+ await fs.writeFile(testFile2, baseContent, 'utf8');
30
+ });
31
+
32
+ afterEach(async () => {
33
+ // Clean up test files
34
+ try {
35
+ if (existsSync(testFile1)) await fs.unlink(testFile1);
36
+ if (existsSync(testFile2)) await fs.unlink(testFile2);
37
+ if (existsSync(testDir)) await fs.rmdir(testDir);
38
+ } catch (error) {
39
+ console.warn('Failed to clean up test files:', error.message);
40
+ }
41
+ });
42
+
43
+ describe('Single File Insertion', () => {
44
+
45
+ it('should insert content before the specified line number', async () => {
46
+ const args = {
47
+ path: testFile1,
48
+ line: 3,
49
+ content: 'Inserted line'
50
+ };
51
+
52
+ const result = await InsertContentHandler.handle(args);
53
+
54
+ assert.strictEqual(result.content[0].type, 'text');
55
+ assert.ok(result.content[0].text.includes('Successfully inserted'));
56
+ assert.ok(result.content[0].text.includes('line 3'));
57
+
58
+ // Verify file content
59
+ const content = await fs.readFile(testFile1, 'utf8');
60
+ const lines = content.split('\n');
61
+ assert.strictEqual(lines[2], 'Inserted line');
62
+ assert.strictEqual(lines[3], 'Line 3');
63
+ assert.strictEqual(lines.length, 6); // Originally 5 lines + 1 inserted line
64
+ });
65
+
66
+ it('should insert content at the beginning of the file', async () => {
67
+ const args = {
68
+ path: testFile1,
69
+ line: 1,
70
+ content: 'First line'
71
+ };
72
+
73
+ const result = await InsertContentHandler.handle(args);
74
+
75
+ assert.strictEqual(result.content[0].type, 'text');
76
+ assert.ok(result.content[0].text.includes('Successfully inserted'));
77
+
78
+ // Verify file content
79
+ const content = await fs.readFile(testFile1, 'utf8');
80
+ const lines = content.split('\n');
81
+ assert.strictEqual(lines[0], 'First line');
82
+ assert.strictEqual(lines[1], 'Line 1');
83
+ });
84
+
85
+ it('should insert content at the end of the file (line=0)', async () => {
86
+ const args = {
87
+ path: testFile1,
88
+ line: 0,
89
+ content: 'Last line'
90
+ };
91
+
92
+ const result = await InsertContentHandler.handle(args);
93
+
94
+ assert.strictEqual(result.content[0].type, 'text');
95
+ assert.ok(result.content[0].text.includes('end of file'));
96
+
97
+ // Verify file content
98
+ const content = await fs.readFile(testFile1, 'utf8');
99
+ const lines = content.split('\n');
100
+ assert.strictEqual(lines[lines.length - 1], 'Last line');
101
+ assert.strictEqual(lines.length, 6);
102
+ });
103
+
104
+ it('should support negative line numbers for insertion', async () => {
105
+ const args = {
106
+ path: testFile1,
107
+ line: -1, // Insert before the last line
108
+ content: 'Before last line'
109
+ };
110
+
111
+ const result = await InsertContentHandler.handle(args);
112
+
113
+ assert.strictEqual(result.content[0].type, 'text');
114
+ assert.ok(result.content[0].text.includes('from end'));
115
+
116
+ // Verify file content
117
+ const content = await fs.readFile(testFile1, 'utf8');
118
+ const lines = content.split('\n');
119
+ assert.strictEqual(lines[4], 'Before last line');
120
+ assert.strictEqual(lines[5], 'Line 5');
121
+ });
122
+
123
+ it('should support inserting multiple lines of content', async () => {
124
+ const multiLineContent = 'Line A\nLine B\nLine C';
125
+ const args = {
126
+ path: testFile1,
127
+ line: 2,
128
+ content: multiLineContent
129
+ };
130
+
131
+ const result = await InsertContentHandler.handle(args);
132
+
133
+ assert.strictEqual(result.content[0].type, 'text');
134
+ assert.ok(result.content[0].text.includes('3 line(s)'));
135
+
136
+ // Verify file content
137
+ const content = await fs.readFile(testFile1, 'utf8');
138
+ const lines = content.split('\n');
139
+ assert.strictEqual(lines[1], 'Line A');
140
+ assert.strictEqual(lines[2], 'Line B');
141
+ assert.strictEqual(lines[3], 'Line C');
142
+ assert.strictEqual(lines[4], 'Line 2');
143
+ assert.strictEqual(lines.length, 8); // Originally 5 lines + 3 inserted lines
144
+ });
145
+
146
+ it('should throw an error if the file does not exist', async () => {
147
+ const args = {
148
+ path: './nonexistent.txt',
149
+ line: 1,
150
+ content: 'Some content'
151
+ };
152
+
153
+ await assert.rejects(
154
+ () => InsertContentHandler.handle(args),
155
+ (error) => error.message.includes('File not found')
156
+ );
157
+ });
158
+
159
+ it('should throw an error if the line number is out of range', async () => {
160
+ const args = {
161
+ path: testFile1,
162
+ line: 10, // Exceeds file length
163
+ content: 'Some content'
164
+ };
165
+
166
+ await assert.rejects(
167
+ () => InsertContentHandler.handle(args),
168
+ (error) => error.message.includes('exceeds file length')
169
+ );
170
+ });
171
+
172
+ it('should throw an error if the negative line number is out of range', async () => {
173
+ const args = {
174
+ path: testFile1,
175
+ line: -10, // Negative number too large
176
+ content: 'Some content'
177
+ };
178
+
179
+ await assert.rejects(
180
+ () => InsertContentHandler.handle(args),
181
+ (error) => error.message.includes('out of range')
182
+ );
183
+ });
184
+
185
+ });
186
+
187
+ describe('Multiple Files Insertion', () => {
188
+
189
+ it('should insert the same content at the same position in multiple files', async () => {
190
+ const args = {
191
+ path: [testFile1, testFile2],
192
+ line: 2,
193
+ content: 'Common insert'
194
+ };
195
+
196
+ const result = await InsertContentHandler.handle(args);
197
+
198
+ assert.strictEqual(result.content[0].type, 'text');
199
+ assert.ok(result.content[0].text.includes('Successfully processed 2 file(s)'));
200
+
201
+ // Verify content in both files
202
+ const content1 = await fs.readFile(testFile1, 'utf8');
203
+ const content2 = await fs.readFile(testFile2, 'utf8');
204
+
205
+ const lines1 = content1.split('\n');
206
+ const lines2 = content2.split('\n');
207
+
208
+ assert.strictEqual(lines1[1], 'Common insert');
209
+ assert.strictEqual(lines2[1], 'Common insert');
210
+ assert.strictEqual(lines1[2], 'Line 2');
211
+ assert.strictEqual(lines2[2], 'Line 2');
212
+ });
213
+
214
+ it('should insert different content at different positions in multiple files', async () => {
215
+ const args = {
216
+ path: [testFile1, testFile2],
217
+ line: [1, 3],
218
+ content: ['Insert at start', 'Insert at middle']
219
+ };
220
+
221
+ const result = await InsertContentHandler.handle(args);
222
+
223
+ assert.strictEqual(result.content[0].type, 'text');
224
+ assert.ok(result.content[0].text.includes('Successfully processed 2 file(s)'));
225
+
226
+ // Verify file content
227
+ const content1 = await fs.readFile(testFile1, 'utf8');
228
+ const content2 = await fs.readFile(testFile2, 'utf8');
229
+
230
+ const lines1 = content1.split('\n');
231
+ const lines2 = content2.split('\n');
232
+
233
+ assert.strictEqual(lines1[0], 'Insert at start');
234
+ assert.strictEqual(lines1[1], 'Line 1');
235
+
236
+ assert.strictEqual(lines2[2], 'Insert at middle');
237
+ assert.strictEqual(lines2[3], 'Line 3');
238
+ });
239
+
240
+ it('should throw an error if the line number array lengths do not match', async () => {
241
+ const args = {
242
+ path: [testFile1, testFile2],
243
+ line: [1], // Only one line number, but two files
244
+ content: ['Content 1', 'Content 2']
245
+ };
246
+
247
+ await assert.rejects(
248
+ () => InsertContentHandler.handle(args),
249
+ (error) => error.message.includes('must match file count')
250
+ );
251
+ });
252
+
253
+ it('should throw an error if the content array lengths do not match', async () => {
254
+ const args = {
255
+ path: [testFile1, testFile2],
256
+ line: [1, 2],
257
+ content: ['Only one content'] // Only one content, but two files
258
+ };
259
+
260
+ await assert.rejects(
261
+ () => InsertContentHandler.handle(args),
262
+ (error) => error.message.includes('must match file count')
263
+ );
264
+ });
265
+
266
+ it('should handle cases where some file operations fail', async () => {
267
+ const nonexistentFile = './nonexistent.txt';
268
+ const args = {
269
+ path: [testFile1, nonexistentFile],
270
+ line: [1, 1],
271
+ content: ['Valid content', 'Invalid content']
272
+ };
273
+
274
+ const result = await InsertContentHandler.handle(args);
275
+
276
+ assert.strictEqual(result.content[0].type, 'text');
277
+ const text = result.content[0].text;
278
+
279
+ assert.ok(text.includes('Successfully processed 1 file(s)'));
280
+ assert.ok(text.includes('Errors encountered'));
281
+ assert.ok(text.includes('File not found'));
282
+ });
283
+
284
+ });
285
+
286
+ describe('Edge Cases', () => {
287
+
288
+ it('should handle empty file insertion', async () => {
289
+ const emptyFile = join(testDir, 'empty.txt');
290
+ await fs.writeFile(emptyFile, '', 'utf8');
291
+
292
+ const args = {
293
+ path: emptyFile,
294
+ line: 0,
295
+ content: 'First content in empty file'
296
+ };
297
+
298
+ const result = await InsertContentHandler.handle(args);
299
+
300
+ assert.strictEqual(result.content[0].type, 'text');
301
+ assert.ok(result.content[0].text.includes('Successfully inserted'));
302
+ // Verify content
303
+ const content = await fs.readFile(emptyFile, 'utf8');
304
+ assert.strictEqual(content, '\nFirst content in empty file'); // Fix expected value
305
+
306
+ await fs.unlink(emptyFile);
307
+ });
308
+
309
+ it('should handle content with special characters', async () => {
310
+ const specialContent = 'Special: áéíóú Chinese @#$%^&*()';
311
+ const args = {
312
+ path: testFile1,
313
+ line: 1,
314
+ content: specialContent
315
+ };
316
+
317
+ const result = await InsertContentHandler.handle(args);
318
+
319
+ assert.strictEqual(result.content[0].type, 'text');
320
+ assert.ok(result.content[0].text.includes('Successfully inserted'));
321
+
322
+ // Verify special characters inserted correctly
323
+ const content = await fs.readFile(testFile1, 'utf8');
324
+ const lines = content.split('\n');
325
+ assert.strictEqual(lines[0], specialContent);
326
+ });
327
+
328
+ it('should handle empty string insertion', async () => {
329
+ const args = {
330
+ path: testFile1,
331
+ line: 2,
332
+ content: ''
333
+ };
334
+
335
+ const result = await InsertContentHandler.handle(args);
336
+
337
+ assert.strictEqual(result.content[0].type, 'text');
338
+ assert.ok(result.content[0].text.includes('Successfully inserted'));
339
+
340
+ // Verify empty line inserted
341
+ const content = await fs.readFile(testFile1, 'utf8');
342
+ const lines = content.split('\n');
343
+ assert.strictEqual(lines[1], '');
344
+ assert.strictEqual(lines[2], 'Line 2');
345
+ });
346
+
347
+ it('should handle large content insertion', async () => {
348
+ const bigContent = Array.from({ length: 100 }, (_, i) => `Big line ${i + 1}`).join('\n');
349
+ const args = {
350
+ path: testFile1,
351
+ line: 3,
352
+ content: bigContent
353
+ };
354
+
355
+ const result = await InsertContentHandler.handle(args);
356
+
357
+ assert.strictEqual(result.content[0].type, 'text');
358
+ assert.ok(result.content[0].text.includes('100 line(s)'));
359
+
360
+ // Verify file line count
361
+ const content = await fs.readFile(testFile1, 'utf8');
362
+ const lines = content.split('\n');
363
+ assert.strictEqual(lines.length, 105); // Originally 5 lines + 100 inserted lines
364
+ assert.strictEqual(lines[2], 'Big line 1');
365
+ assert.strictEqual(lines[101], 'Big line 100');
366
+ assert.strictEqual(lines[102], 'Line 3');
367
+ });
368
+
369
+ });
370
+
371
+ });
@@ -0,0 +1,302 @@
1
+ import { ListFilesHandler } from '../src/handlers/listFiles.js';
2
+ import { FileUtils } from '../src/utils/fileUtils.js';
3
+ import { describe, it, beforeEach, afterEach } from 'node:test';
4
+ import assert from 'node:assert';
5
+ import fs from 'fs/promises';
6
+ import { join } from 'path';
7
+ import { existsSync } from 'fs';
8
+
9
+ /**
10
+ * Test suite for ListFilesHandler.
11
+ * Tests the file listing functionality.
12
+ */
13
+ describe('ListFilesHandler', () => {
14
+
15
+ const testDir = './test_files_list';
16
+ const subDir1 = join(testDir, 'subdir1');
17
+ const subDir2 = join(testDir, 'subdir2');
18
+ const file1 = join(testDir, 'file1.txt');
19
+ const file2 = join(testDir, 'file2.js');
20
+ const subFile1 = join(subDir1, 'subfile1.txt');
21
+ const subFile2 = join(subDir2, 'subfile2.md');
22
+
23
+ beforeEach(async () => {
24
+ // Set up the test workspace
25
+ FileUtils.setWorkspaceRoot(process.cwd());
26
+
27
+ // Create test directory structure
28
+ await fs.mkdir(testDir, { recursive: true });
29
+ await fs.mkdir(subDir1, { recursive: true });
30
+ await fs.mkdir(subDir2, { recursive: true });
31
+
32
+ // Create test files
33
+ await fs.writeFile(file1, 'File 1 content', 'utf8');
34
+ await fs.writeFile(file2, 'File 2 content', 'utf8');
35
+ await fs.writeFile(subFile1, 'Sub file 1 content', 'utf8');
36
+ await fs.writeFile(subFile2, 'Sub file 2 content', 'utf8');
37
+ });
38
+
39
+ afterEach(async () => {
40
+ // Clean up test files and directories
41
+ try {
42
+ if (existsSync(subFile1)) await fs.unlink(subFile1);
43
+ if (existsSync(subFile2)) await fs.unlink(subFile2);
44
+ if (existsSync(file1)) await fs.unlink(file1);
45
+ if (existsSync(file2)) await fs.unlink(file2);
46
+ if (existsSync(subDir1)) await fs.rmdir(subDir1);
47
+ if (existsSync(subDir2)) await fs.rmdir(subDir2);
48
+ if (existsSync(testDir)) await fs.rmdir(testDir);
49
+ } catch (error) {
50
+ console.warn('Failed to clean up test files:', error.message);
51
+ }
52
+ });
53
+
54
+ describe('Non-recursive listing', () => {
55
+
56
+ it('should list files and subdirectories in a directory', async () => {
57
+ const args = { path: testDir };
58
+
59
+ const result = await ListFilesHandler.handle(args);
60
+
61
+ assert.strictEqual(result.content[0].type, 'text');
62
+ const text = result.content[0].text;
63
+
64
+ // Check for files
65
+ assert.ok(text.includes('file: file1.txt'));
66
+ assert.ok(text.includes('file: file2.js'));
67
+
68
+ // Check for directories
69
+ assert.ok(text.includes('directory: subdir1'));
70
+ assert.ok(text.includes('directory: subdir2'));
71
+
72
+ // Should not include files from subdirectories
73
+ assert.ok(!text.includes('subfile1.txt'));
74
+ assert.ok(!text.includes('subfile2.md'));
75
+ });
76
+
77
+ it('should handle empty directories', async () => {
78
+ const emptyDir = join(testDir, 'empty');
79
+ await fs.mkdir(emptyDir);
80
+
81
+ const args = { path: emptyDir };
82
+
83
+ const result = await ListFilesHandler.handle(args);
84
+
85
+ assert.strictEqual(result.content[0].type, 'text');
86
+ const text = result.content[0].text;
87
+ assert.strictEqual(text.trim(), '');
88
+
89
+ await fs.rmdir(emptyDir);
90
+ });
91
+
92
+ it('should throw an error when the directory does not exist', async () => {
93
+ const args = { path: './nonexistent_directory' };
94
+
95
+ await assert.rejects(
96
+ () => ListFilesHandler.handle(args),
97
+ (error) => error.message.includes('Failed to list files') &&
98
+ error.message.includes('Directory not found')
99
+ );
100
+ });
101
+
102
+ });
103
+
104
+ describe('Recursive listing', () => {
105
+
106
+ it('should recursively list all files and directories', async () => {
107
+ const args = {
108
+ path: testDir,
109
+ recursive: true
110
+ };
111
+
112
+ const result = await ListFilesHandler.handle(args);
113
+
114
+ assert.strictEqual(result.content[0].type, 'text');
115
+ const text = result.content[0].text;
116
+
117
+ // Check for root directory files
118
+ assert.ok(text.includes('file: file1.txt'));
119
+ assert.ok(text.includes('file: file2.js'));
120
+
121
+ // Check for root directory subdirectories
122
+ assert.ok(text.includes('directory: subdir1'));
123
+ assert.ok(text.includes('directory: subdir2'));
124
+
125
+ // Check for files in subdirectories
126
+ assert.ok(text.includes('file: subdir1/subfile1.txt'));
127
+ assert.ok(text.includes('file: subdir2/subfile2.md'));
128
+ });
129
+
130
+ it('should handle deeply nested directories', async () => {
131
+ // Create a deeper directory structure
132
+ const deepDir = join(subDir1, 'deep');
133
+ const deeperDir = join(deepDir, 'deeper');
134
+ const deepFile = join(deeperDir, 'deep_file.txt');
135
+
136
+ await fs.mkdir(deepDir);
137
+ await fs.mkdir(deeperDir);
138
+ await fs.writeFile(deepFile, 'Deep file content', 'utf8');
139
+
140
+ const args = {
141
+ path: testDir,
142
+ recursive: true
143
+ };
144
+
145
+ const result = await ListFilesHandler.handle(args);
146
+
147
+ assert.strictEqual(result.content[0].type, 'text');
148
+ const text = result.content[0].text;
149
+
150
+ assert.ok(text.includes('directory: subdir1/deep'));
151
+ assert.ok(text.includes('directory: subdir1/deep/deeper'));
152
+ assert.ok(text.includes('file: subdir1/deep/deeper/deep_file.txt'));
153
+
154
+ // Clean up deep files
155
+ await fs.unlink(deepFile);
156
+ await fs.rmdir(deeperDir);
157
+ await fs.rmdir(deepDir);
158
+ });
159
+
160
+ it('should handle cases with only subdirectories', async () => {
161
+ const onlyDirsPath = join(testDir, 'only_dirs');
162
+ const childDir1 = join(onlyDirsPath, 'child1');
163
+ const childDir2 = join(onlyDirsPath, 'child2');
164
+
165
+ await fs.mkdir(onlyDirsPath);
166
+ await fs.mkdir(childDir1);
167
+ await fs.mkdir(childDir2);
168
+
169
+ const args = {
170
+ path: onlyDirsPath,
171
+ recursive: true
172
+ };
173
+
174
+ const result = await ListFilesHandler.handle(args);
175
+
176
+ assert.strictEqual(result.content[0].type, 'text');
177
+ const text = result.content[0].text;
178
+
179
+ assert.ok(text.includes('directory: child1'));
180
+ assert.ok(text.includes('directory: child2'));
181
+ assert.ok(!text.includes('file:'));
182
+
183
+ // Cleanup
184
+ await fs.rmdir(childDir1);
185
+ await fs.rmdir(childDir2);
186
+ await fs.rmdir(onlyDirsPath);
187
+ });
188
+
189
+ });
190
+
191
+ describe('Path handling', () => {
192
+
193
+ it('should handle relative paths', async () => {
194
+ const args = { path: './test_files_list' };
195
+
196
+ const result = await ListFilesHandler.handle(args);
197
+
198
+ assert.strictEqual(result.content[0].type, 'text');
199
+ const text = result.content[0].text;
200
+ assert.ok(text.includes('file: file1.txt'));
201
+ });
202
+
203
+ it('should handle absolute paths', async () => {
204
+ const absolutePath = join(process.cwd(), testDir);
205
+ const args = { path: absolutePath };
206
+
207
+ const result = await ListFilesHandler.handle(args);
208
+
209
+ assert.strictEqual(result.content[0].type, 'text');
210
+ const text = result.content[0].text;
211
+ assert.ok(text.includes('file: file1.txt'));
212
+ });
213
+
214
+ it('should handle special characters in paths', async () => {
215
+ const specialDir = join(testDir, 'special dir with spaces');
216
+ const specialFile = join(specialDir, 'special-file_123.txt');
217
+
218
+ await fs.mkdir(specialDir);
219
+ await fs.writeFile(specialFile, 'Special content', 'utf8');
220
+
221
+ const args = { path: specialDir };
222
+
223
+ const result = await ListFilesHandler.handle(args);
224
+
225
+ assert.strictEqual(result.content[0].type, 'text');
226
+ const text = result.content[0].text;
227
+ assert.ok(text.includes('file: special-file_123.txt'));
228
+
229
+ // Cleanup
230
+ await fs.unlink(specialFile);
231
+ await fs.rmdir(specialDir);
232
+ });
233
+
234
+ });
235
+
236
+ describe('Edge cases', () => {
237
+
238
+ it('should handle directories with a large number of files', async () => {
239
+ const manyFilesDir = join(testDir, 'many_files');
240
+ await fs.mkdir(manyFilesDir);
241
+
242
+ // Create 100 files
243
+ const files = [];
244
+ for (let i = 0; i < 100; i++) {
245
+ const file = join(manyFilesDir, `file_${i.toString().padStart(3, '0')}.txt`);
246
+ await fs.writeFile(file, `Content ${i}`, 'utf8');
247
+ files.push(file);
248
+ }
249
+
250
+ const args = { path: manyFilesDir };
251
+
252
+ const result = await ListFilesHandler.handle(args);
253
+
254
+ assert.strictEqual(result.content[0].type, 'text');
255
+ const text = result.content[0].text;
256
+
257
+ // Check if some files exist
258
+ assert.ok(text.includes('file: file_000.txt'));
259
+ assert.ok(text.includes('file: file_050.txt'));
260
+ assert.ok(text.includes('file: file_099.txt'));
261
+
262
+ // Clean up files
263
+ for (const file of files) {
264
+ await fs.unlink(file);
265
+ }
266
+ await fs.rmdir(manyFilesDir);
267
+ });
268
+
269
+ it('should handle sorting of file and directory names', async () => {
270
+ const sortDir = join(testDir, 'sort_test');
271
+ await fs.mkdir(sortDir);
272
+
273
+ // Create some files and directories to test sorting
274
+ await fs.writeFile(join(sortDir, 'z_file.txt'), 'content', 'utf8');
275
+ await fs.writeFile(join(sortDir, 'a_file.txt'), 'content', 'utf8');
276
+ await fs.mkdir(join(sortDir, 'z_dir'));
277
+ await fs.mkdir(join(sortDir, 'a_dir'));
278
+
279
+ const args = { path: sortDir };
280
+
281
+ const result = await ListFilesHandler.handle(args);
282
+
283
+ assert.strictEqual(result.content[0].type, 'text');
284
+ const text = result.content[0].text;
285
+
286
+ // Verify all items are listed
287
+ assert.ok(text.includes('file: a_file.txt'));
288
+ assert.ok(text.includes('file: z_file.txt'));
289
+ assert.ok(text.includes('directory: a_dir'));
290
+ assert.ok(text.includes('directory: z_dir'));
291
+
292
+ // Cleanup
293
+ await fs.unlink(join(sortDir, 'z_file.txt'));
294
+ await fs.unlink(join(sortDir, 'a_file.txt'));
295
+ await fs.rmdir(join(sortDir, 'z_dir'));
296
+ await fs.rmdir(join(sortDir, 'a_dir'));
297
+ await fs.rmdir(sortDir);
298
+ });
299
+
300
+ });
301
+
302
+ });