@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.
- package/README.md +106 -29
- package/dist/__tests__/lib/errors.test.js +3 -23
- package/dist/__tests__/lib/errors.test.js.map +1 -1
- package/dist/__tests__/lib/file-operations.test.js +34 -0
- package/dist/__tests__/lib/file-operations.test.js.map +1 -1
- package/dist/__tests__/lib/path-validation.test.js +8 -0
- package/dist/__tests__/lib/path-validation.test.js.map +1 -1
- package/dist/__tests__/schemas/validators.test.js +101 -122
- package/dist/__tests__/schemas/validators.test.js.map +1 -1
- package/dist/__tests__/security/filesystem-boundary.test.js +1 -1
- package/dist/__tests__/security/filesystem-boundary.test.js.map +1 -1
- package/dist/config/types.d.ts +1 -85
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +0 -2
- package/dist/config/types.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/instructions.md +1 -2
- package/dist/lib/constants.d.ts +3 -1
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/constants.js +66 -258
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/errors.d.ts +25 -3
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +4 -94
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/file-operations/analyze-directory.d.ts +8 -0
- package/dist/lib/file-operations/analyze-directory.d.ts.map +1 -0
- package/dist/lib/file-operations/analyze-directory.js +117 -0
- package/dist/lib/file-operations/analyze-directory.js.map +1 -0
- package/dist/lib/file-operations/directory-items.d.ts +20 -0
- package/dist/lib/file-operations/directory-items.d.ts.map +1 -0
- package/dist/lib/file-operations/directory-items.js +85 -0
- package/dist/lib/file-operations/directory-items.js.map +1 -0
- package/dist/lib/file-operations/directory-iteration.d.ts +17 -0
- package/dist/lib/file-operations/directory-iteration.d.ts.map +1 -0
- package/dist/lib/file-operations/directory-iteration.js +55 -0
- package/dist/lib/file-operations/directory-iteration.js.map +1 -0
- package/dist/lib/file-operations/directory-tree.d.ts +9 -0
- package/dist/lib/file-operations/directory-tree.d.ts.map +1 -0
- package/dist/lib/file-operations/directory-tree.js +175 -0
- package/dist/lib/file-operations/directory-tree.js.map +1 -0
- package/dist/lib/file-operations/file-info.d.ts +3 -0
- package/dist/lib/file-operations/file-info.d.ts.map +1 -0
- package/dist/lib/file-operations/file-info.js +56 -0
- package/dist/lib/file-operations/file-info.js.map +1 -0
- package/dist/lib/file-operations/list-directory.d.ts +10 -0
- package/dist/lib/file-operations/list-directory.d.ts.map +1 -0
- package/dist/lib/file-operations/list-directory.js +189 -0
- package/dist/lib/file-operations/list-directory.js.map +1 -0
- package/dist/lib/file-operations/read-media-file.d.ts +5 -0
- package/dist/lib/file-operations/read-media-file.d.ts.map +1 -0
- package/dist/lib/file-operations/read-media-file.js +31 -0
- package/dist/lib/file-operations/read-media-file.js.map +1 -0
- package/dist/lib/file-operations/read-multiple-files.d.ts +16 -0
- package/dist/lib/file-operations/read-multiple-files.d.ts.map +1 -0
- package/dist/lib/file-operations/read-multiple-files.js +98 -0
- package/dist/lib/file-operations/read-multiple-files.js.map +1 -0
- package/dist/lib/file-operations/search-content.d.ts +16 -0
- package/dist/lib/file-operations/search-content.d.ts.map +1 -0
- package/dist/lib/file-operations/search-content.js +431 -0
- package/dist/lib/file-operations/search-content.js.map +1 -0
- package/dist/lib/file-operations/search-files.d.ts +9 -0
- package/dist/lib/file-operations/search-files.d.ts.map +1 -0
- package/dist/lib/file-operations/search-files.js +139 -0
- package/dist/lib/file-operations/search-files.js.map +1 -0
- package/dist/lib/file-operations/sorting.d.ts +12 -0
- package/dist/lib/file-operations/sorting.d.ts.map +1 -0
- package/dist/lib/file-operations/sorting.js +24 -0
- package/dist/lib/file-operations/sorting.js.map +1 -0
- package/dist/lib/file-operations.d.ts +9 -57
- package/dist/lib/file-operations.d.ts.map +1 -1
- package/dist/lib/file-operations.js +9 -773
- package/dist/lib/file-operations.js.map +1 -1
- package/dist/lib/fs-helpers/binary-detect.d.ts +3 -0
- package/dist/lib/fs-helpers/binary-detect.d.ts.map +1 -0
- package/dist/lib/fs-helpers/binary-detect.js +54 -0
- package/dist/lib/fs-helpers/binary-detect.js.map +1 -0
- package/dist/lib/fs-helpers/concurrency.d.ts +11 -0
- package/dist/lib/fs-helpers/concurrency.d.ts.map +1 -0
- package/dist/lib/fs-helpers/concurrency.js +95 -0
- package/dist/lib/fs-helpers/concurrency.js.map +1 -0
- package/dist/lib/fs-helpers/fs-utils.d.ts +5 -0
- package/dist/lib/fs-helpers/fs-utils.d.ts.map +1 -0
- package/dist/lib/fs-helpers/fs-utils.js +13 -0
- package/dist/lib/fs-helpers/fs-utils.js.map +1 -0
- package/dist/lib/fs-helpers/readers/head-file.d.ts +2 -0
- package/dist/lib/fs-helpers/readers/head-file.d.ts.map +1 -0
- package/dist/lib/fs-helpers/readers/head-file.js +73 -0
- package/dist/lib/fs-helpers/readers/head-file.js.map +1 -0
- package/dist/lib/fs-helpers/readers/line-range.d.ts +7 -0
- package/dist/lib/fs-helpers/readers/line-range.d.ts.map +1 -0
- package/dist/lib/fs-helpers/readers/line-range.js +46 -0
- package/dist/lib/fs-helpers/readers/line-range.js.map +1 -0
- package/dist/lib/fs-helpers/readers/read-file.d.ts +16 -0
- package/dist/lib/fs-helpers/readers/read-file.d.ts.map +1 -0
- package/dist/lib/fs-helpers/readers/read-file.js +87 -0
- package/dist/lib/fs-helpers/readers/read-file.js.map +1 -0
- package/dist/lib/fs-helpers/readers/tail-file.d.ts +2 -0
- package/dist/lib/fs-helpers/readers/tail-file.d.ts.map +1 -0
- package/dist/lib/fs-helpers/readers/tail-file.js +98 -0
- package/dist/lib/fs-helpers/readers/tail-file.js.map +1 -0
- package/dist/lib/fs-helpers/readers/utf8.d.ts +3 -0
- package/dist/lib/fs-helpers/readers/utf8.d.ts.map +1 -0
- package/dist/lib/fs-helpers/readers/utf8.js +22 -0
- package/dist/lib/fs-helpers/readers/utf8.js.map +1 -0
- package/dist/lib/fs-helpers/readers.d.ts +4 -0
- package/dist/lib/fs-helpers/readers.d.ts.map +1 -0
- package/dist/lib/fs-helpers/readers.js +4 -0
- package/dist/lib/fs-helpers/readers.js.map +1 -0
- package/dist/lib/fs-helpers.d.ts +4 -25
- package/dist/lib/fs-helpers.d.ts.map +1 -1
- package/dist/lib/fs-helpers.js +4 -327
- package/dist/lib/fs-helpers.js.map +1 -1
- package/dist/lib/path-validation/allowed-directories.d.ts +9 -0
- package/dist/lib/path-validation/allowed-directories.d.ts.map +1 -0
- package/dist/lib/path-validation/allowed-directories.js +94 -0
- package/dist/lib/path-validation/allowed-directories.js.map +1 -0
- package/dist/lib/path-validation/errors.d.ts +5 -0
- package/dist/lib/path-validation/errors.d.ts.map +1 -0
- package/dist/lib/path-validation/errors.js +33 -0
- package/dist/lib/path-validation/errors.js.map +1 -0
- package/dist/lib/path-validation/roots.d.ts +3 -0
- package/dist/lib/path-validation/roots.d.ts.map +1 -0
- package/dist/lib/path-validation/roots.js +49 -0
- package/dist/lib/path-validation/roots.js.map +1 -0
- package/dist/lib/path-validation/validators.d.ts +9 -0
- package/dist/lib/path-validation/validators.d.ts.map +1 -0
- package/dist/lib/path-validation/validators.js +70 -0
- package/dist/lib/path-validation/validators.js.map +1 -0
- package/dist/lib/path-validation.d.ts +3 -7
- package/dist/lib/path-validation.d.ts.map +1 -1
- package/dist/lib/path-validation.js +3 -141
- package/dist/lib/path-validation.js.map +1 -1
- package/dist/schemas/input-helpers.d.ts +8 -0
- package/dist/schemas/input-helpers.d.ts.map +1 -0
- package/dist/schemas/input-helpers.js +44 -0
- package/dist/schemas/input-helpers.js.map +1 -0
- package/dist/schemas/inputs.d.ts +8 -5
- package/dist/schemas/inputs.d.ts.map +1 -1
- package/dist/schemas/inputs.js +41 -64
- package/dist/schemas/inputs.js.map +1 -1
- package/dist/schemas/output-helpers.d.ts +24 -0
- package/dist/schemas/output-helpers.d.ts.map +1 -0
- package/dist/schemas/output-helpers.js +13 -0
- package/dist/schemas/output-helpers.js.map +1 -0
- package/dist/schemas/outputs.d.ts +476 -42
- package/dist/schemas/outputs.d.ts.map +1 -1
- package/dist/schemas/outputs.js +26 -41
- package/dist/schemas/outputs.js.map +1 -1
- package/dist/server.d.ts +9 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +28 -42
- package/dist/server.js.map +1 -1
- package/dist/tools/analyze-directory.d.ts.map +1 -1
- package/dist/tools/analyze-directory.js +115 -53
- package/dist/tools/analyze-directory.js.map +1 -1
- package/dist/tools/directory-tree.d.ts.map +1 -1
- package/dist/tools/directory-tree.js +86 -49
- package/dist/tools/directory-tree.js.map +1 -1
- package/dist/tools/get-file-info.d.ts.map +1 -1
- package/dist/tools/get-file-info.js +71 -37
- package/dist/tools/get-file-info.js.map +1 -1
- package/dist/tools/list-allowed-dirs.d.ts.map +1 -1
- package/dist/tools/list-allowed-dirs.js +48 -35
- package/dist/tools/list-allowed-dirs.js.map +1 -1
- package/dist/tools/list-directory.d.ts.map +1 -1
- package/dist/tools/list-directory.js +129 -58
- package/dist/tools/list-directory.js.map +1 -1
- package/dist/tools/read-file.d.ts.map +1 -1
- package/dist/tools/read-file.js +70 -56
- package/dist/tools/read-file.js.map +1 -1
- package/dist/tools/read-media-file.d.ts.map +1 -1
- package/dist/tools/read-media-file.js +39 -41
- package/dist/tools/read-media-file.js.map +1 -1
- package/dist/tools/read-multiple-files.d.ts.map +1 -1
- package/dist/tools/read-multiple-files.js +58 -50
- package/dist/tools/read-multiple-files.js.map +1 -1
- package/dist/tools/search-content.d.ts.map +1 -1
- package/dist/tools/search-content.js +146 -89
- package/dist/tools/search-content.js.map +1 -1
- package/dist/tools/search-files.d.ts.map +1 -1
- package/dist/tools/search-files.js +121 -50
- package/dist/tools/search-files.js.map +1 -1
- package/dist/tools/tool-response.d.ts +9 -0
- package/dist/tools/tool-response.d.ts.map +1 -0
- package/dist/tools/tool-response.js +7 -0
- package/dist/tools/tool-response.js.map +1 -0
- package/package.json +2 -1
- package/dist/__tests__/errors.test.d.ts +0 -2
- package/dist/__tests__/errors.test.d.ts.map +0 -1
- package/dist/__tests__/errors.test.js +0 -88
- package/dist/__tests__/errors.test.js.map +0 -1
- package/dist/__tests__/file-operations.test.d.ts +0 -2
- package/dist/__tests__/file-operations.test.d.ts.map +0 -1
- package/dist/__tests__/file-operations.test.js +0 -230
- package/dist/__tests__/file-operations.test.js.map +0 -1
- package/dist/__tests__/lib/formatters.test.d.ts +0 -2
- package/dist/__tests__/lib/formatters.test.d.ts.map +0 -1
- package/dist/__tests__/lib/formatters.test.js +0 -248
- package/dist/__tests__/lib/formatters.test.js.map +0 -1
- package/dist/__tests__/lib/image-parsing.test.d.ts +0 -2
- package/dist/__tests__/lib/image-parsing.test.d.ts.map +0 -1
- package/dist/__tests__/lib/image-parsing.test.js +0 -262
- package/dist/__tests__/lib/image-parsing.test.js.map +0 -1
- package/dist/__tests__/path-validation.test.d.ts +0 -2
- package/dist/__tests__/path-validation.test.d.ts.map +0 -1
- package/dist/__tests__/path-validation.test.js +0 -92
- package/dist/__tests__/path-validation.test.js.map +0 -1
- package/dist/lib/directory-helpers.d.ts +0 -4
- package/dist/lib/directory-helpers.d.ts.map +0 -1
- package/dist/lib/directory-helpers.js +0 -36
- package/dist/lib/directory-helpers.js.map +0 -1
- package/dist/lib/formatters.d.ts +0 -10
- package/dist/lib/formatters.d.ts.map +0 -1
- package/dist/lib/formatters.js +0 -202
- package/dist/lib/formatters.js.map +0 -1
- package/dist/lib/image-parsing.d.ts +0 -4
- package/dist/lib/image-parsing.d.ts.map +0 -1
- package/dist/lib/image-parsing.js +0 -124
- package/dist/lib/image-parsing.js.map +0 -1
- package/dist/lib/mcp-logger.d.ts +0 -11
- package/dist/lib/mcp-logger.d.ts.map +0 -1
- package/dist/lib/mcp-logger.js +0 -49
- package/dist/lib/mcp-logger.js.map +0 -1
- package/dist/lib/roots-utils.d.ts +0 -7
- package/dist/lib/roots-utils.d.ts.map +0 -1
- package/dist/lib/roots-utils.js +0 -39
- package/dist/lib/roots-utils.js.map +0 -1
- package/dist/lib/search-helpers.d.ts +0 -16
- package/dist/lib/search-helpers.d.ts.map +0 -1
- package/dist/lib/search-helpers.js +0 -169
- package/dist/lib/search-helpers.js.map +0 -1
- package/dist/lib/sorting.d.ts +0 -12
- package/dist/lib/sorting.d.ts.map +0 -1
- package/dist/lib/sorting.js +0 -41
- package/dist/lib/sorting.js.map +0 -1
- package/dist/lib/types.d.ts +0 -6
- package/dist/lib/types.d.ts.map +0 -1
- package/dist/lib/types.js +0 -2
- package/dist/lib/types.js.map +0 -1
- package/dist/prompts/analyze-codebase.d.ts +0 -3
- package/dist/prompts/analyze-codebase.d.ts.map +0 -1
- package/dist/prompts/analyze-codebase.js +0 -144
- package/dist/prompts/analyze-codebase.js.map +0 -1
- package/dist/prompts/filesystem-query.d.ts +0 -3
- package/dist/prompts/filesystem-query.d.ts.map +0 -1
- package/dist/prompts/filesystem-query.js +0 -168
- package/dist/prompts/filesystem-query.js.map +0 -1
- package/dist/prompts/find-duplicates.d.ts +0 -3
- package/dist/prompts/find-duplicates.d.ts.map +0 -1
- package/dist/prompts/find-duplicates.js +0 -77
- package/dist/prompts/find-duplicates.js.map +0 -1
- package/dist/prompts/index.d.ts +0 -3
- package/dist/prompts/index.d.ts.map +0 -1
- package/dist/prompts/index.js +0 -13
- package/dist/prompts/index.js.map +0 -1
- package/dist/prompts/project-overview.d.ts +0 -3
- package/dist/prompts/project-overview.d.ts.map +0 -1
- package/dist/prompts/project-overview.js +0 -122
- package/dist/prompts/project-overview.js.map +0 -1
- package/dist/prompts/search-and-replace.d.ts +0 -3
- package/dist/prompts/search-and-replace.d.ts.map +0 -1
- package/dist/prompts/search-and-replace.js +0 -130
- package/dist/prompts/search-and-replace.js.map +0 -1
- package/dist/prompts/shared.d.ts +0 -11
- package/dist/prompts/shared.d.ts.map +0 -1
- package/dist/prompts/shared.js +0 -32
- package/dist/prompts/shared.js.map +0 -1
- package/dist/resources/index.d.ts +0 -3
- package/dist/resources/index.d.ts.map +0 -1
- package/dist/resources/index.js +0 -54
- package/dist/resources/index.js.map +0 -1
- package/dist/schemas/validators.d.ts +0 -12
- package/dist/schemas/validators.d.ts.map +0 -1
- package/dist/schemas/validators.js +0 -35
- package/dist/schemas/validators.js.map +0 -1
- package/dist/utils/index.d.ts +0 -2
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -2
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/response-helpers.d.ts +0 -22
- package/dist/utils/response-helpers.d.ts.map +0 -1
- package/dist/utils/response-helpers.js +0 -24
- 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 +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"}
|
package/dist/lib/formatters.d.ts
DELETED
|
@@ -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"}
|
package/dist/lib/formatters.js
DELETED
|
@@ -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
|