@j0hanz/filesystem-mcp 1.19.0 → 2.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.
- package/README.md +333 -838
- package/dist/cli-help.d.ts +3 -0
- package/dist/cli-help.d.ts.map +1 -0
- package/dist/cli-help.js +169 -0
- package/dist/cli-help.js.map +1 -0
- package/dist/cli.d.ts +28 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +168 -123
- package/dist/cli.js.map +1 -0
- package/dist/core/concurrency.d.ts +70 -0
- package/dist/core/concurrency.d.ts.map +1 -0
- package/dist/core/concurrency.js +173 -0
- package/dist/core/concurrency.js.map +1 -0
- package/dist/core/config.d.ts +19 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +11 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/cursor.d.ts +23 -0
- package/dist/core/cursor.d.ts.map +1 -0
- package/dist/core/cursor.js +62 -0
- package/dist/core/cursor.js.map +1 -0
- package/dist/core/errors.d.ts +96 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +356 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/file-uri.d.ts +24 -0
- package/dist/core/file-uri.d.ts.map +1 -0
- package/dist/core/file-uri.js +52 -0
- package/dist/core/file-uri.js.map +1 -0
- package/dist/core/fmt.d.ts +38 -0
- package/dist/core/fmt.d.ts.map +1 -0
- package/dist/core/fmt.js +109 -0
- package/dist/core/fmt.js.map +1 -0
- package/dist/core/fs.d.ts +108 -0
- package/dist/core/fs.d.ts.map +1 -0
- package/dist/core/fs.js +243 -0
- package/dist/core/fs.js.map +1 -0
- package/dist/core/glob.d.ts +41 -0
- package/dist/core/glob.d.ts.map +1 -0
- package/dist/core/glob.js +399 -0
- package/dist/core/glob.js.map +1 -0
- package/dist/core/input-required.d.ts +147 -0
- package/dist/core/input-required.d.ts.map +1 -0
- package/dist/core/input-required.js +261 -0
- package/dist/core/input-required.js.map +1 -0
- package/dist/core/mime.d.ts +15 -0
- package/dist/core/mime.d.ts.map +1 -0
- package/dist/core/mime.js +188 -0
- package/dist/core/mime.js.map +1 -0
- package/dist/core/observability.d.ts +10 -0
- package/dist/core/observability.d.ts.map +1 -0
- package/dist/core/observability.js +76 -0
- package/dist/core/observability.js.map +1 -0
- package/dist/core/page-store.d.ts +41 -0
- package/dist/core/page-store.d.ts.map +1 -0
- package/dist/core/page-store.js +74 -0
- package/dist/core/page-store.js.map +1 -0
- package/dist/core/path-completer.d.ts +10 -0
- package/dist/core/path-completer.d.ts.map +1 -0
- package/dist/core/path-completer.js +227 -0
- package/dist/core/path-completer.js.map +1 -0
- package/dist/core/path-discovery.d.ts +8 -0
- package/dist/core/path-discovery.d.ts.map +1 -0
- package/dist/core/path-discovery.js +105 -0
- package/dist/core/path-discovery.js.map +1 -0
- package/dist/core/path-utils.d.ts +9 -0
- package/dist/core/path-utils.d.ts.map +1 -0
- package/dist/core/path-utils.js +121 -0
- package/dist/core/path-utils.js.map +1 -0
- package/dist/core/path.d.ts +148 -0
- package/dist/core/path.d.ts.map +1 -0
- package/dist/core/path.js +674 -0
- package/dist/core/path.js.map +1 -0
- package/dist/core/primitives.d.ts +23 -0
- package/dist/core/primitives.d.ts.map +1 -0
- package/dist/core/primitives.js +54 -0
- package/dist/core/primitives.js.map +1 -0
- package/dist/core/read.d.ts +74 -0
- package/dist/core/read.d.ts.map +1 -0
- package/dist/core/read.js +562 -0
- package/dist/core/read.js.map +1 -0
- package/dist/core/schema.d.ts +139 -0
- package/dist/core/schema.d.ts.map +1 -0
- package/dist/core/schema.js +345 -0
- package/dist/core/schema.js.map +1 -0
- package/dist/core/search.d.ts +100 -0
- package/dist/core/search.d.ts.map +1 -0
- package/dist/core/search.js +248 -0
- package/dist/core/search.js.map +1 -0
- package/dist/core/sensitive.d.ts +6 -0
- package/dist/core/sensitive.d.ts.map +1 -0
- package/dist/core/sensitive.js +142 -0
- package/dist/core/sensitive.js.map +1 -0
- package/dist/core/store.d.ts +57 -0
- package/dist/core/store.d.ts.map +1 -0
- package/dist/core/store.js +162 -0
- package/dist/core/store.js.map +1 -0
- package/dist/core/util.d.ts +26 -0
- package/dist/core/util.d.ts.map +1 -0
- package/dist/core/util.js +66 -0
- package/dist/core/util.js.map +1 -0
- package/dist/core/watcher-registry.d.ts +68 -0
- package/dist/core/watcher-registry.d.ts.map +1 -0
- package/dist/core/watcher-registry.js +312 -0
- package/dist/core/watcher-registry.js.map +1 -0
- package/dist/http-policy.d.ts +121 -0
- package/dist/http-policy.d.ts.map +1 -0
- package/dist/http-policy.js +340 -0
- package/dist/http-policy.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +77 -41
- package/dist/index.js.map +1 -0
- package/dist/instructions.d.ts +12 -0
- package/dist/instructions.d.ts.map +1 -0
- package/dist/instructions.js +71 -0
- package/dist/instructions.js.map +1 -0
- package/dist/prompts.d.ts +8 -6
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +74 -168
- package/dist/prompts.js.map +1 -0
- package/dist/resources.d.ts +73 -9
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +392 -163
- package/dist/resources.js.map +1 -0
- package/dist/server.d.ts +62 -1
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +139 -1
- package/dist/server.js.map +1 -0
- package/dist/tools/batch.d.ts +89 -0
- package/dist/tools/batch.d.ts.map +1 -0
- package/dist/tools/batch.js +157 -0
- package/dist/tools/batch.js.map +1 -0
- package/dist/tools/create.d.ts +2 -0
- package/dist/tools/create.d.ts.map +1 -0
- package/dist/tools/create.js +142 -0
- package/dist/tools/create.js.map +1 -0
- package/dist/tools/define.d.ts +110 -0
- package/dist/tools/define.d.ts.map +1 -0
- package/dist/tools/define.js +394 -0
- package/dist/tools/define.js.map +1 -0
- package/dist/tools/delete-file.d.ts +2 -4
- package/dist/tools/delete-file.d.ts.map +1 -0
- package/dist/tools/delete-file.js +330 -87
- package/dist/tools/delete-file.js.map +1 -0
- package/dist/tools/diff.d.ts +2 -0
- package/dist/tools/diff.d.ts.map +1 -0
- package/dist/tools/diff.js +94 -0
- package/dist/tools/diff.js.map +1 -0
- package/dist/tools/edit.d.ts +2 -0
- package/dist/tools/edit.d.ts.map +1 -0
- package/dist/tools/edit.js +442 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools/index.d.ts +26 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +52 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list.d.ts +2 -0
- package/dist/tools/list.d.ts.map +1 -0
- package/dist/tools/list.js +291 -0
- package/dist/tools/list.js.map +1 -0
- package/dist/tools/move.d.ts +2 -0
- package/dist/tools/move.d.ts.map +1 -0
- package/dist/tools/move.js +321 -0
- package/dist/tools/move.js.map +1 -0
- package/dist/tools/patch.d.ts +2 -0
- package/dist/tools/patch.d.ts.map +1 -0
- package/dist/tools/patch.js +155 -0
- package/dist/tools/patch.js.map +1 -0
- package/dist/tools/progress.d.ts +52 -0
- package/dist/tools/progress.d.ts.map +1 -0
- package/dist/tools/progress.js +172 -0
- package/dist/tools/progress.js.map +1 -0
- package/dist/tools/read.d.ts +2 -4
- package/dist/tools/read.d.ts.map +1 -0
- package/dist/tools/read.js +398 -152
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/replace-in-files.d.ts +2 -4
- package/dist/tools/replace-in-files.d.ts.map +1 -0
- package/dist/tools/replace-in-files.js +435 -264
- package/dist/tools/replace-in-files.js.map +1 -0
- package/dist/tools/roots.d.ts +2 -4
- package/dist/tools/roots.d.ts.map +1 -0
- package/dist/tools/roots.js +29 -52
- package/dist/tools/roots.js.map +1 -0
- package/dist/tools/search-content.d.ts +2 -4
- package/dist/tools/search-content.d.ts.map +1 -0
- package/dist/tools/search-content.js +262 -228
- package/dist/tools/search-content.js.map +1 -0
- package/dist/tools/search-files.d.ts +2 -4
- package/dist/tools/search-files.d.ts.map +1 -0
- package/dist/tools/search-files.js +162 -161
- package/dist/tools/search-files.js.map +1 -0
- package/dist/tools/stat.d.ts +2 -4
- package/dist/tools/stat.d.ts.map +1 -0
- package/dist/tools/stat.js +202 -62
- package/dist/tools/stat.js.map +1 -0
- package/dist/transport/http.d.ts +5 -0
- package/dist/transport/http.d.ts.map +1 -0
- package/dist/transport/http.js +276 -0
- package/dist/transport/http.js.map +1 -0
- package/dist/transport/shared.d.ts +45 -0
- package/dist/transport/shared.d.ts.map +1 -0
- package/dist/transport/shared.js +65 -0
- package/dist/transport/shared.js.map +1 -0
- package/dist/transport/stdio.d.ts +32 -0
- package/dist/transport/stdio.d.ts.map +1 -0
- package/dist/transport/stdio.js +279 -0
- package/dist/transport/stdio.js.map +1 -0
- package/dist/transport.d.ts +5 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +4 -0
- package/dist/transport.js.map +1 -0
- package/package.json +37 -46
- package/dist/assets/logo.svg +0 -35
- package/dist/completions.d.ts +0 -2
- package/dist/completions.js +0 -572
- package/dist/config.d.ts +0 -119
- package/dist/config.js +0 -31
- package/dist/lib/abort.d.ts +0 -7
- package/dist/lib/abort.js +0 -81
- package/dist/lib/constants.d.ts +0 -42
- package/dist/lib/constants.js +0 -313
- package/dist/lib/errors.d.ts +0 -28
- package/dist/lib/errors.js +0 -301
- package/dist/lib/file-operations/core.d.ts +0 -53
- package/dist/lib/file-operations/core.js +0 -144
- package/dist/lib/file-operations/metadata.d.ts +0 -77
- package/dist/lib/file-operations/metadata.js +0 -878
- package/dist/lib/file-operations/search.d.ts +0 -46
- package/dist/lib/file-operations/search.js +0 -1194
- package/dist/lib/file-operations/traversal.d.ts +0 -40
- package/dist/lib/file-operations/traversal.js +0 -310
- package/dist/lib/fs-helpers.d.ts +0 -46
- package/dist/lib/fs-helpers.js +0 -606
- package/dist/lib/globs.d.ts +0 -2
- package/dist/lib/globs.js +0 -19
- package/dist/lib/logger.d.ts +0 -27
- package/dist/lib/logger.js +0 -91
- package/dist/lib/observability.d.ts +0 -33
- package/dist/lib/observability.js +0 -373
- package/dist/lib/paths.d.ts +0 -35
- package/dist/lib/paths.js +0 -634
- package/dist/lib/resource-store.d.ts +0 -28
- package/dist/lib/resource-store.js +0 -195
- package/dist/lib/utils.d.ts +0 -7
- package/dist/lib/utils.js +0 -37
- package/dist/lib/zod-codecs.d.ts +0 -2
- package/dist/lib/zod-codecs.js +0 -18
- package/dist/pkg-info.d.ts +0 -7
- package/dist/pkg-info.js +0 -9
- package/dist/resources/generated-instructions.d.ts +0 -1
- package/dist/resources/generated-instructions.js +0 -105
- package/dist/resources/tool-catalog.d.ts +0 -2
- package/dist/resources/tool-catalog.js +0 -78
- package/dist/resources/tool-info.d.ts +0 -9
- package/dist/resources/tool-info.js +0 -206
- package/dist/resources/workflows.d.ts +0 -1
- package/dist/resources/workflows.js +0 -72
- package/dist/schemas.d.ts +0 -505
- package/dist/schemas.js +0 -676
- package/dist/server/bootstrap.d.ts +0 -6
- package/dist/server/bootstrap.js +0 -563
- package/dist/server/event-store.d.ts +0 -18
- package/dist/server/event-store.js +0 -71
- package/dist/server/roots-manager.d.ts +0 -28
- package/dist/server/roots-manager.js +0 -227
- package/dist/server/task-store.d.ts +0 -10
- package/dist/server/task-store.js +0 -91
- package/dist/tools/apply-patch.d.ts +0 -4
- package/dist/tools/apply-patch.js +0 -235
- package/dist/tools/calculate-hash.d.ts +0 -4
- package/dist/tools/calculate-hash.js +0 -187
- package/dist/tools/contract.d.ts +0 -50
- package/dist/tools/contract.js +0 -1
- package/dist/tools/create-directory.d.ts +0 -4
- package/dist/tools/create-directory.js +0 -68
- package/dist/tools/diff-files.d.ts +0 -4
- package/dist/tools/diff-files.js +0 -136
- package/dist/tools/edit-file.d.ts +0 -4
- package/dist/tools/edit-file.js +0 -256
- package/dist/tools/icons.d.ts +0 -15
- package/dist/tools/icons.js +0 -24
- package/dist/tools/list-directory.d.ts +0 -4
- package/dist/tools/list-directory.js +0 -218
- package/dist/tools/move-file.d.ts +0 -4
- package/dist/tools/move-file.js +0 -178
- package/dist/tools/read-multiple.d.ts +0 -4
- package/dist/tools/read-multiple.js +0 -207
- package/dist/tools/shared.d.ts +0 -172
- package/dist/tools/shared.js +0 -599
- package/dist/tools/stat-many.d.ts +0 -4
- package/dist/tools/stat-many.js +0 -104
- package/dist/tools/task-support.d.ts +0 -29
- package/dist/tools/task-support.js +0 -472
- package/dist/tools/tree.d.ts +0 -4
- package/dist/tools/tree.js +0 -102
- package/dist/tools/write-file.d.ts +0 -4
- package/dist/tools/write-file.js +0 -60
- package/dist/tools.d.ts +0 -5
- package/dist/tools.js +0 -54
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
import { glob as fsGlob, readFile as fsReadFile } from 'node:fs/promises';
|
|
2
|
+
import { basename, dirname, isAbsolute, join, posix, relative, resolve } from 'node:path';
|
|
3
|
+
import ignore from 'ignore';
|
|
4
|
+
import { processInParallel } from './concurrency.js';
|
|
5
|
+
import { formatUnknownErrorMessage } from './errors.js';
|
|
6
|
+
import { Logger } from './observability.js';
|
|
7
|
+
import { isWindowsDriveRelativePath } from './path-utils.js';
|
|
8
|
+
import { toPosixPath } from './primitives.js';
|
|
9
|
+
export function resolveEntryType(dirent) {
|
|
10
|
+
if (dirent.isDirectory())
|
|
11
|
+
return 'directory';
|
|
12
|
+
if (dirent.isFile())
|
|
13
|
+
return 'file';
|
|
14
|
+
if (dirent.isSymbolicLink())
|
|
15
|
+
return 'symlink';
|
|
16
|
+
return 'other';
|
|
17
|
+
}
|
|
18
|
+
export function isSafeGlobSyntax(pattern) {
|
|
19
|
+
if (!pattern || pattern.trim().length === 0) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
if (isAbsolute(pattern)) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
if (isWindowsDriveRelativePath(pattern)) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
if (pattern.includes('..')) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
// Reject glob-engine-specific traversal bypass forms that some engines
|
|
32
|
+
// expand as path separators or parent-directory references.
|
|
33
|
+
if (/\{[^}]*\.\.[^}]*\}/u.test(pattern)) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
if (pattern.includes('[..]')) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
async function loadGitignoreFiles(root, gitignorePaths, manager, signal) {
|
|
42
|
+
await processInParallel(gitignorePaths, async (relPath) => {
|
|
43
|
+
const absPath = join(root, relPath);
|
|
44
|
+
try {
|
|
45
|
+
const contents = await fsReadFile(absPath, { encoding: 'utf-8', signal });
|
|
46
|
+
const matcher = ignore();
|
|
47
|
+
matcher.add(contents);
|
|
48
|
+
const dir = toPosixPath(dirname(relPath));
|
|
49
|
+
manager.addMatcher(dir === '.' ? '' : dir, matcher);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
if (error instanceof Error && error.name === 'AbortError')
|
|
53
|
+
throw error;
|
|
54
|
+
Logger.warn(`Failed to read .gitignore at ${absPath}: ${formatUnknownErrorMessage(error)}`);
|
|
55
|
+
}
|
|
56
|
+
}, GLOB_BATCH_CONCURRENCY, signal);
|
|
57
|
+
}
|
|
58
|
+
export class GitignoreManager {
|
|
59
|
+
matchers = new Map();
|
|
60
|
+
addMatcher(dir, matcher) {
|
|
61
|
+
this.matchers.set(dir, matcher);
|
|
62
|
+
}
|
|
63
|
+
static async load(root, signal) {
|
|
64
|
+
const manager = new GitignoreManager();
|
|
65
|
+
try {
|
|
66
|
+
const gitignorePaths = [];
|
|
67
|
+
const gitignoreEntries = fsGlob('**/.gitignore', {
|
|
68
|
+
cwd: root,
|
|
69
|
+
exclude: (entry) => {
|
|
70
|
+
const name = basename(entry);
|
|
71
|
+
if (name === 'node_modules' || name === '.git' || name === '.hg' || name === '.svn') {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
for await (const match of gitignoreEntries) {
|
|
78
|
+
if (signal?.aborted)
|
|
79
|
+
break;
|
|
80
|
+
gitignorePaths.push(match);
|
|
81
|
+
}
|
|
82
|
+
await loadGitignoreFiles(root, gitignorePaths, manager, signal);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
if (error instanceof Error && error.name === 'AbortError')
|
|
86
|
+
throw error;
|
|
87
|
+
Logger.warn(`Failed to enumerate .gitignore files under ${root}: ${formatUnknownErrorMessage(error)}`);
|
|
88
|
+
}
|
|
89
|
+
return manager;
|
|
90
|
+
}
|
|
91
|
+
size() {
|
|
92
|
+
return this.matchers.size;
|
|
93
|
+
}
|
|
94
|
+
isIgnored(relativePath, isDirectory) {
|
|
95
|
+
const normalized = toPosixPath(relativePath);
|
|
96
|
+
if (normalized === '' || normalized === '.')
|
|
97
|
+
return false;
|
|
98
|
+
const parts = normalized.split('/');
|
|
99
|
+
// 1. Check parent directories first
|
|
100
|
+
let currentDir = '';
|
|
101
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
102
|
+
const part = parts[i];
|
|
103
|
+
if (!part)
|
|
104
|
+
continue;
|
|
105
|
+
currentDir = currentDir ? `${currentDir}/${part}` : part;
|
|
106
|
+
if (this.checkPath(currentDir, true)) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// 2. Check the file/directory itself
|
|
111
|
+
return this.checkPath(normalized, isDirectory);
|
|
112
|
+
}
|
|
113
|
+
checkPath(posixPath, isDirectory) {
|
|
114
|
+
const parts = posixPath.split('/');
|
|
115
|
+
const pathToCheck = isDirectory
|
|
116
|
+
? posixPath.endsWith('/')
|
|
117
|
+
? posixPath
|
|
118
|
+
: `${posixPath}/`
|
|
119
|
+
: posixPath;
|
|
120
|
+
let ignored = false;
|
|
121
|
+
// Check root level
|
|
122
|
+
const rootMatcher = this.matchers.get('');
|
|
123
|
+
if (rootMatcher) {
|
|
124
|
+
const res = rootMatcher.test(pathToCheck);
|
|
125
|
+
if (res.ignored)
|
|
126
|
+
ignored = true;
|
|
127
|
+
if (res.unignored)
|
|
128
|
+
ignored = false;
|
|
129
|
+
}
|
|
130
|
+
// Check subdirectories
|
|
131
|
+
let currentDir = '';
|
|
132
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
133
|
+
const part = parts[i];
|
|
134
|
+
if (!part)
|
|
135
|
+
continue;
|
|
136
|
+
currentDir = currentDir ? `${currentDir}/${part}` : part;
|
|
137
|
+
const matcher = this.matchers.get(currentDir);
|
|
138
|
+
if (matcher) {
|
|
139
|
+
const relParts = parts.slice(i + 1);
|
|
140
|
+
const relPath = relParts.join('/');
|
|
141
|
+
const relPathToCheck = isDirectory
|
|
142
|
+
? relPath.endsWith('/')
|
|
143
|
+
? relPath
|
|
144
|
+
: `${relPath}/`
|
|
145
|
+
: relPath;
|
|
146
|
+
const res = matcher.test(relPathToCheck);
|
|
147
|
+
if (res.ignored)
|
|
148
|
+
ignored = true;
|
|
149
|
+
if (res.unignored)
|
|
150
|
+
ignored = false;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return ignored;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
export async function loadRootGitignore(root, signal) {
|
|
157
|
+
const manager = await GitignoreManager.load(root, signal);
|
|
158
|
+
if (manager.size() === 0) {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
return manager;
|
|
162
|
+
}
|
|
163
|
+
export function isIgnoredByGitignore(matcher, root, absolutePath, options = {}) {
|
|
164
|
+
let { relativePath } = options;
|
|
165
|
+
relativePath ??= relative(root, absolutePath);
|
|
166
|
+
if (relativePath.length === 0)
|
|
167
|
+
return false;
|
|
168
|
+
return matcher.isIgnored(relativePath, Boolean(options.isDirectory));
|
|
169
|
+
}
|
|
170
|
+
const GLOB_MAGIC_RE = /[*?[\]{}!]/u;
|
|
171
|
+
const GLOB_BATCH_CONCURRENCY = 64;
|
|
172
|
+
const SEP = '/';
|
|
173
|
+
const DOT_CHAR_CODE = 46;
|
|
174
|
+
function normalizePattern(pattern, baseNameMatch) {
|
|
175
|
+
const normalized = toPosixPath(pattern);
|
|
176
|
+
if (!baseNameMatch)
|
|
177
|
+
return normalized;
|
|
178
|
+
if (normalized.includes(SEP))
|
|
179
|
+
return normalized;
|
|
180
|
+
return `**/${normalized}`;
|
|
181
|
+
}
|
|
182
|
+
function splitPatternPrefix(normalizedPattern) {
|
|
183
|
+
if (!GLOB_MAGIC_RE.test(normalizedPattern)) {
|
|
184
|
+
return { prefix: '', remainder: normalizedPattern };
|
|
185
|
+
}
|
|
186
|
+
const segments = normalizedPattern.split(SEP);
|
|
187
|
+
const splitIndex = segments.findIndex((seg) => GLOB_MAGIC_RE.test(seg));
|
|
188
|
+
if (splitIndex <= 0) {
|
|
189
|
+
return { prefix: '', remainder: normalizedPattern };
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
prefix: segments.slice(0, splitIndex).join(SEP) + SEP,
|
|
193
|
+
remainder: segments.slice(splitIndex).join(SEP),
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function addFirstDotSegment(patterns, prefix, remainder) {
|
|
197
|
+
if (remainder.length === 0)
|
|
198
|
+
return;
|
|
199
|
+
const segments = remainder.split(SEP);
|
|
200
|
+
const idx = segments.findIndex((seg) => seg !== '**' && seg.length > 0);
|
|
201
|
+
if (idx !== -1) {
|
|
202
|
+
const original = segments[idx];
|
|
203
|
+
if (original && original.charCodeAt(0) !== DOT_CHAR_CODE) {
|
|
204
|
+
const newSegments = [...segments];
|
|
205
|
+
newSegments[idx] = `.${original}`;
|
|
206
|
+
patterns.add(`${prefix}${newSegments.join(SEP)}`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
function expandHiddenGlobstars(patterns, prefix, remainder) {
|
|
211
|
+
// Trailing bare globstar — `src/**`, `**` (remainder is exactly `**`, no
|
|
212
|
+
// following segment). The pattern itself already matches every non-dot
|
|
213
|
+
// entry under the prefix; add the two hidden complements fs.glob skips:
|
|
214
|
+
// dotfiles/dot-dirs anywhere, and the contents of dot-dirs anywhere.
|
|
215
|
+
if (remainder === '**') {
|
|
216
|
+
patterns.add(`${prefix}**/.*`);
|
|
217
|
+
patterns.add(`${prefix}**/.*/**`);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (!remainder.startsWith('**/'))
|
|
221
|
+
return;
|
|
222
|
+
const afterGlobstar = remainder.slice(3);
|
|
223
|
+
// Node fs.glob skips leading-dot entries unless the matching segment itself
|
|
224
|
+
// starts with '.', and its `dot` option is not honored. So `**/*` alone misses
|
|
225
|
+
// hidden files. Two depth-agnostic patterns cover everything the per-depth
|
|
226
|
+
// unroll did: contents of dot-directories anywhere, and dotfiles/dotdirs
|
|
227
|
+
// anywhere.
|
|
228
|
+
patterns.add(`${prefix}**/.*/**/${afterGlobstar}`);
|
|
229
|
+
const addDotFile = afterGlobstar.length > 0 && afterGlobstar.charCodeAt(0) !== DOT_CHAR_CODE;
|
|
230
|
+
if (addDotFile)
|
|
231
|
+
patterns.add(`${prefix}**/.${afterGlobstar}`);
|
|
232
|
+
}
|
|
233
|
+
function buildHiddenPatterns(normalizedPattern) {
|
|
234
|
+
const patterns = new Set([normalizedPattern]);
|
|
235
|
+
const { prefix, remainder } = splitPatternPrefix(normalizedPattern);
|
|
236
|
+
addFirstDotSegment(patterns, prefix, remainder);
|
|
237
|
+
expandHiddenGlobstars(patterns, prefix, remainder);
|
|
238
|
+
return Array.from(patterns);
|
|
239
|
+
}
|
|
240
|
+
function normalizeGlobOptions(options) {
|
|
241
|
+
const cwd = resolve(options.cwd);
|
|
242
|
+
const normalizedPattern = normalizePattern(options.pattern, options.baseNameMatch ?? false);
|
|
243
|
+
const patterns = options.includeHidden
|
|
244
|
+
? buildHiddenPatterns(normalizedPattern)
|
|
245
|
+
: [normalizedPattern];
|
|
246
|
+
const normalized = {
|
|
247
|
+
cwd,
|
|
248
|
+
patterns,
|
|
249
|
+
exclude: (options.excludePatterns ?? []).map(toPosixPath),
|
|
250
|
+
suppressErrors: options.suppressErrors ?? false,
|
|
251
|
+
respectGitignore: options.respectGitignore ?? false,
|
|
252
|
+
};
|
|
253
|
+
if (options.maxDepth !== undefined) {
|
|
254
|
+
normalized.maxDepth = options.maxDepth;
|
|
255
|
+
}
|
|
256
|
+
return normalized;
|
|
257
|
+
}
|
|
258
|
+
function getRelativeDepth(relativePath) {
|
|
259
|
+
const len = relativePath.length;
|
|
260
|
+
if (len === 0)
|
|
261
|
+
return 0;
|
|
262
|
+
let count = 0;
|
|
263
|
+
for (let i = 0; i < len; i++) {
|
|
264
|
+
const code = relativePath.charCodeAt(i);
|
|
265
|
+
if (code === 47 || code === 92) {
|
|
266
|
+
count++;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return count;
|
|
270
|
+
}
|
|
271
|
+
function resolveDirentBase(cwd, parentPath) {
|
|
272
|
+
if (!parentPath)
|
|
273
|
+
return cwd;
|
|
274
|
+
return isAbsolute(parentPath) ? parentPath : resolve(cwd, parentPath);
|
|
275
|
+
}
|
|
276
|
+
function* processDirentMatch(match, cwd, maxDepth, seen, onlyFiles) {
|
|
277
|
+
const base = resolveDirentBase(cwd, match.parentPath);
|
|
278
|
+
const absolutePath = resolve(base, match.name);
|
|
279
|
+
if (maxDepth !== undefined) {
|
|
280
|
+
const rel = relative(cwd, absolutePath);
|
|
281
|
+
if (getRelativeDepth(rel) > maxDepth)
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
if (seen.has(absolutePath))
|
|
285
|
+
return;
|
|
286
|
+
seen.add(absolutePath);
|
|
287
|
+
if (onlyFiles && !match.isFile())
|
|
288
|
+
return;
|
|
289
|
+
yield { path: absolutePath, dirent: match };
|
|
290
|
+
}
|
|
291
|
+
function createExcludeFilter(cwd, excludePatterns, gitignoreMatcher) {
|
|
292
|
+
if (!gitignoreMatcher) {
|
|
293
|
+
return excludePatterns;
|
|
294
|
+
}
|
|
295
|
+
return (match) => {
|
|
296
|
+
const relPath = typeof match === 'string'
|
|
297
|
+
? match
|
|
298
|
+
: match.parentPath
|
|
299
|
+
? relative(cwd, join(match.parentPath, match.name))
|
|
300
|
+
: match.name;
|
|
301
|
+
const posixRel = toPosixPath(relPath);
|
|
302
|
+
// Gitignore check
|
|
303
|
+
const isDir = typeof match === 'string' ? false : match.isDirectory();
|
|
304
|
+
if (gitignoreMatcher.isIgnored(posixRel, isDir)) {
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
// Also check explicit exclude patterns
|
|
308
|
+
if (excludePatterns.length > 0) {
|
|
309
|
+
for (const ex of excludePatterns) {
|
|
310
|
+
if (posix.matchesGlob(posixRel, ex))
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return false;
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
async function* processGlobPattern(pattern, plan, seen, onlyFiles, excludeFunc) {
|
|
318
|
+
const { cwd, maxDepth, suppressErrors } = plan;
|
|
319
|
+
let iterable;
|
|
320
|
+
try {
|
|
321
|
+
iterable = fsGlob(pattern, {
|
|
322
|
+
cwd,
|
|
323
|
+
exclude: excludeFunc,
|
|
324
|
+
withFileTypes: true,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
catch (error) {
|
|
328
|
+
if (suppressErrors)
|
|
329
|
+
return;
|
|
330
|
+
throw error;
|
|
331
|
+
}
|
|
332
|
+
try {
|
|
333
|
+
for await (const match of iterable) {
|
|
334
|
+
yield* processDirentMatch(match, cwd, maxDepth, seen, onlyFiles);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
catch (error) {
|
|
338
|
+
if (!suppressErrors)
|
|
339
|
+
throw error;
|
|
340
|
+
Logger.warn(`globEntries: suppressed mid-walk error for pattern "${pattern}": ${formatUnknownErrorMessage(error)}`);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
export async function* globEntries(options) {
|
|
344
|
+
let gitignoreMatcher = null;
|
|
345
|
+
if (options.respectGitignore) {
|
|
346
|
+
gitignoreMatcher = await loadRootGitignore(options.cwd);
|
|
347
|
+
}
|
|
348
|
+
const plan = normalizeGlobOptions(options);
|
|
349
|
+
const seen = new Set();
|
|
350
|
+
const onlyFiles = options.onlyFiles ?? true;
|
|
351
|
+
const excludeFunc = createExcludeFilter(plan.cwd, plan.exclude, gitignoreMatcher);
|
|
352
|
+
for (const pattern of plan.patterns) {
|
|
353
|
+
yield* processGlobPattern(pattern, plan, seen, onlyFiles, excludeFunc);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
export const DEFAULT_EXCLUDE_PATTERNS = [
|
|
357
|
+
'**/node_modules',
|
|
358
|
+
'**/node_modules/**',
|
|
359
|
+
'**/dist',
|
|
360
|
+
'**/dist/**',
|
|
361
|
+
'**/build',
|
|
362
|
+
'**/build/**',
|
|
363
|
+
'**/coverage',
|
|
364
|
+
'**/coverage/**',
|
|
365
|
+
'**/.git',
|
|
366
|
+
'**/.git/**',
|
|
367
|
+
'**/.vscode',
|
|
368
|
+
'**/.vscode/**',
|
|
369
|
+
'**/.idea',
|
|
370
|
+
'**/.idea/**',
|
|
371
|
+
'**/.DS_Store',
|
|
372
|
+
'**/.next',
|
|
373
|
+
'**/.next/**',
|
|
374
|
+
'**/.nuxt',
|
|
375
|
+
'**/.nuxt/**',
|
|
376
|
+
'**/.output',
|
|
377
|
+
'**/.output/**',
|
|
378
|
+
'**/.svelte-kit',
|
|
379
|
+
'**/.svelte-kit/**',
|
|
380
|
+
'**/.cache',
|
|
381
|
+
'**/.cache/**',
|
|
382
|
+
'**/.yarn',
|
|
383
|
+
'**/.yarn/**',
|
|
384
|
+
'**/jspm_packages',
|
|
385
|
+
'**/jspm_packages/**',
|
|
386
|
+
'**/bower_components',
|
|
387
|
+
'**/bower_components/**',
|
|
388
|
+
'**/out',
|
|
389
|
+
'**/out/**',
|
|
390
|
+
'**/tmp',
|
|
391
|
+
'**/tmp/**',
|
|
392
|
+
'**/.temp',
|
|
393
|
+
'**/.temp/**',
|
|
394
|
+
'**/npm-debug.log',
|
|
395
|
+
'**/yarn-debug.log',
|
|
396
|
+
'**/yarn-error.log',
|
|
397
|
+
'**/Thumbs.db',
|
|
398
|
+
];
|
|
399
|
+
//# sourceMappingURL=glob.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glob.js","sourceRoot":"","sources":["../../src/core/glob.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,MAAM,EAAE,QAAQ,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAG1F,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAW9C,MAAM,UAAU,gBAAgB,CAAC,MAAkB;IACjD,IAAI,MAAM,CAAC,WAAW,EAAE;QAAE,OAAO,WAAW,CAAC;IAC7C,IAAI,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,MAAM,CAAC;IACnC,IAAI,MAAM,CAAC,cAAc,EAAE;QAAE,OAAO,SAAS,CAAC;IAC9C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,0BAA0B,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,uEAAuE;IACvE,4DAA4D;IAC5D,IAAI,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,kBAAkB,CAC/B,IAAY,EACZ,cAAiC,EACjC,OAAyB,EACzB,MAAoB;IAEpB,MAAM,iBAAiB,CACrB,cAAc,EACd,KAAK,EAAE,OAAO,EAAE,EAAE;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1E,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACtB,MAAM,GAAG,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;YAC1C,OAAO,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACtD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;gBAAE,MAAM,KAAK,CAAC;YACvE,MAAM,CAAC,IAAI,CAAC,gCAAgC,OAAO,KAAK,yBAAyB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC9F,CAAC;IACH,CAAC,EACD,sBAAsB,EACtB,MAAM,CACP,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,gBAAgB;IACnB,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE7C,UAAU,CAAC,GAAW,EAAE,OAAe;QACrC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,MAAoB;QAClD,MAAM,OAAO,GAAG,IAAI,gBAAgB,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,cAAc,GAAa,EAAE,CAAC;YACpC,MAAM,gBAAgB,GAAG,MAAM,CAAC,eAAe,EAAE;gBAC/C,GAAG,EAAE,IAAI;gBACT,OAAO,EAAE,CAAC,KAAa,EAAE,EAAE;oBACzB,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;oBAC7B,IAAI,IAAI,KAAK,cAAc,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;wBACpF,OAAO,IAAI,CAAC;oBACd,CAAC;oBACD,OAAO,KAAK,CAAC;gBACf,CAAC;aACF,CAAC,CAAC;YACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,gBAAgB,EAAE,CAAC;gBAC3C,IAAI,MAAM,EAAE,OAAO;oBAAE,MAAM;gBAC3B,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC7B,CAAC;YAED,MAAM,kBAAkB,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAClE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;gBAAE,MAAM,KAAK,CAAC;YACvE,MAAM,CAAC,IAAI,CACT,8CAA8C,IAAI,KAAK,yBAAyB,CAAC,KAAK,CAAC,EAAE,CAC1F,CAAC;QACJ,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED,SAAS,CAAC,YAAoB,EAAE,WAAoB;QAClD,MAAM,UAAU,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;QAC7C,IAAI,UAAU,KAAK,EAAE,IAAI,UAAU,KAAK,GAAG;YAAE,OAAO,KAAK,CAAC;QAC1D,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEpC,oCAAoC;QACpC,IAAI,UAAU,GAAG,EAAE,CAAC;QACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YAEzD,IAAI,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC;gBACrC,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,qCAAqC;QACrC,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACjD,CAAC;IAEO,SAAS,CAAC,SAAiB,EAAE,WAAoB;QACvD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,WAAW,GAAG,WAAW;YAC7B,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC;gBACvB,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,GAAG,SAAS,GAAG;YACnB,CAAC,CAAC,SAAS,CAAC;QAEd,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,mBAAmB;QACnB,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC1C,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAC1C,IAAI,GAAG,CAAC,OAAO;gBAAE,OAAO,GAAG,IAAI,CAAC;YAChC,IAAI,GAAG,CAAC,SAAS;gBAAE,OAAO,GAAG,KAAK,CAAC;QACrC,CAAC;QAED,uBAAuB;QACvB,IAAI,UAAU,GAAG,EAAE,CAAC;QACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YAEzD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC9C,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBACpC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACnC,MAAM,cAAc,GAAG,WAAW;oBAChC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;wBACrB,CAAC,CAAC,OAAO;wBACT,CAAC,CAAC,GAAG,OAAO,GAAG;oBACjB,CAAC,CAAC,OAAO,CAAC;gBAEZ,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBACzC,IAAI,GAAG,CAAC,OAAO;oBAAE,OAAO,GAAG,IAAI,CAAC;gBAChC,IAAI,GAAG,CAAC,SAAS;oBAAE,OAAO,GAAG,KAAK,CAAC;YACrC,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAY,EACZ,MAAoB;IAEpB,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1D,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,OAAyB,EACzB,IAAY,EACZ,YAAoB,EACpB,UAA4D,EAAE;IAE9D,IAAI,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IAC/B,YAAY,KAAK,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAC9C,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5C,OAAO,OAAO,CAAC,SAAS,CAAC,YAAY,EAAE,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;AACvE,CAAC;AAmCD,MAAM,aAAa,GAAG,aAAa,CAAC;AACpC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAClC,MAAM,GAAG,GAAG,GAAG,CAAC;AAChB,MAAM,aAAa,GAAG,EAAE,CAAC;AACzB,SAAS,gBAAgB,CAAC,OAAe,EAAE,aAAsB;IAC/D,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAExC,IAAI,CAAC,aAAa;QAAE,OAAO,UAAU,CAAC;IACtC,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,UAAU,CAAC;IAChD,OAAO,MAAM,UAAU,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,kBAAkB,CAAC,iBAAyB;IAInD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAC3C,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC;IACtD,CAAC;IAED,MAAM,QAAQ,GAAG,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAExE,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC;IACtD,CAAC;IAED,OAAO;QACL,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG;QACrD,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;KAChD,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAqB,EAAE,MAAc,EAAE,SAAiB;IAClF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACnC,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAExE,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QACf,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,QAAQ,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,aAAa,EAAE,CAAC;YACzD,MAAM,WAAW,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;YAClC,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,QAAQ,EAAE,CAAC;YAClC,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,QAAqB,EAAE,MAAc,EAAE,SAAiB;IACrF,yEAAyE;IACzE,uEAAuE;IACvE,wEAAwE;IACxE,qEAAqE;IACrE,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvB,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC;QAC/B,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,UAAU,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IAED,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO;IAEzC,MAAM,aAAa,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACzC,4EAA4E;IAC5E,+EAA+E;IAC/E,2EAA2E;IAC3E,yEAAyE;IACzE,YAAY;IACZ,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,YAAY,aAAa,EAAE,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,aAAa,CAAC;IAC7F,IAAI,UAAU;QAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,OAAO,aAAa,EAAE,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,mBAAmB,CAAC,iBAAyB;IACpD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACtD,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;IAEpE,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IAChD,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IAEnD,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,oBAAoB,CAAC,OAA2B;IACvD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,IAAI,KAAK,CAAC,CAAC;IAE5F,MAAM,QAAQ,GAAG,OAAO,CAAC,aAAa;QACpC,CAAC,CAAC,mBAAmB,CAAC,iBAAiB,CAAC;QACxC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;IAExB,MAAM,UAAU,GAAmB;QACjC,GAAG;QACH,QAAQ;QACR,OAAO,EAAE,CAAC,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC;QACzD,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,KAAK;QAC/C,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,KAAK;KACpD,CAAC;IAEF,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACnC,UAAU,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IACzC,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,gBAAgB,CAAC,YAAoB;IAC5C,MAAM,GAAG,GAAG,YAAY,CAAC,MAAM,CAAC;IAChC,IAAI,GAAG,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACxB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACxC,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;YAC/B,KAAK,EAAE,CAAC;QACV,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAW,EAAE,UAA8B;IACpE,IAAI,CAAC,UAAU;QAAE,OAAO,GAAG,CAAC;IAC5B,OAAO,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;AACxE,CAAC;AAED,QAAQ,CAAC,CAAC,kBAAkB,CAC1B,KAAqB,EACrB,GAAW,EACX,QAA4B,EAC5B,IAAiB,EACjB,SAAkB;IAElB,MAAM,IAAI,GAAG,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IACtD,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAE/C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QACxC,IAAI,gBAAgB,CAAC,GAAG,CAAC,GAAG,QAAQ;YAAE,OAAO;IAC/C,CAAC;IAED,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC;QAAE,OAAO;IACnC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAEvB,IAAI,SAAS,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;QAAE,OAAO;IACzC,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC9C,CAAC;AAED,SAAS,mBAAmB,CAC1B,GAAW,EACX,eAAkC,EAClC,gBAA0C;IAE1C,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,OAAO,CAAC,KAAgB,EAAE,EAAE;QAC1B,MAAM,OAAO,GACX,OAAO,KAAK,KAAK,QAAQ;YACvB,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,KAAK,CAAC,UAAU;gBAChB,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBACnD,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;QAEnB,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QAEtC,kBAAkB;QAClB,MAAM,KAAK,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;QACtE,IAAI,gBAAgB,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC;YAChD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,uCAAuC;QACvC,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,KAAK,MAAM,EAAE,IAAI,eAAe,EAAE,CAAC;gBACjC,IAAI,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC;oBAAE,OAAO,IAAI,CAAC;YACnD,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,SAAS,CAAC,CAAC,kBAAkB,CAChC,OAAe,EACf,IAAoB,EACpB,IAAiB,EACjB,SAAkB,EAClB,WAAgE;IAEhE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IAC/C,IAAI,QAAkC,CAAC;IACvC,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,CAAC,OAAO,EAAE;YACzB,GAAG;YACH,OAAO,EAAE,WAAW;YACpB,aAAa,EAAE,IAAI;SACpB,CAA6B,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,cAAc;YAAE,OAAO;QAC3B,MAAM,KAAK,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YACnC,KAAK,CAAC,CAAC,kBAAkB,CAAC,KAAuB,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,cAAc;YAAE,MAAM,KAAK,CAAC;QACjC,MAAM,CAAC,IAAI,CACT,uDAAuD,OAAO,MAAM,yBAAyB,CAAC,KAAK,CAAC,EAAE,CACvG,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,WAAW,CAAC,OAA2B;IAC5D,IAAI,gBAAgB,GAA4B,IAAI,CAAC;IACrD,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;QAC7B,gBAAgB,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,IAAI,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC;IAC5C,MAAM,WAAW,GAAG,mBAAmB,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;IAElF,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACpC,KAAK,CAAC,CAAC,kBAAkB,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IACzE,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,iBAAiB;IACjB,oBAAoB;IACpB,SAAS;IACT,YAAY;IACZ,UAAU;IACV,aAAa;IACb,aAAa;IACb,gBAAgB;IAChB,SAAS;IACT,YAAY;IACZ,YAAY;IACZ,eAAe;IACf,UAAU;IACV,aAAa;IACb,cAAc;IACd,UAAU;IACV,aAAa;IACb,UAAU;IACV,aAAa;IACb,YAAY;IACZ,eAAe;IACf,gBAAgB;IAChB,mBAAmB;IACnB,WAAW;IACX,cAAc;IACd,UAAU;IACV,aAAa;IACb,kBAAkB;IAClB,qBAAqB;IACrB,qBAAqB;IACrB,wBAAwB;IACxB,QAAQ;IACR,WAAW;IACX,QAAQ;IACR,WAAW;IACX,UAAU;IACV,aAAa;IACb,kBAAkB;IAClB,mBAAmB;IACnB,mBAAmB;IACnB,cAAc;CACf,CAAC","sourcesContent":["import { glob as fsGlob, readFile as fsReadFile } from 'node:fs/promises';\nimport { basename, dirname, isAbsolute, join, posix, relative, resolve } from 'node:path';\n\nimport type { Ignore } from 'ignore';\nimport ignore from 'ignore';\n\nimport { processInParallel } from './concurrency.js';\nimport { formatUnknownErrorMessage } from './errors.js';\nimport { Logger } from './observability.js';\nimport { isWindowsDriveRelativePath } from './path-utils.js';\nimport { toPosixPath } from './primitives.js';\nimport type { EntryType } from './primitives.js';\n\nexport type { EntryType };\n\nexport interface DirentLike {\n isDirectory(): boolean;\n isFile(): boolean;\n isSymbolicLink(): boolean;\n}\n\nexport function resolveEntryType(dirent: DirentLike): EntryType {\n if (dirent.isDirectory()) return 'directory';\n if (dirent.isFile()) return 'file';\n if (dirent.isSymbolicLink()) return 'symlink';\n return 'other';\n}\n\nexport function isSafeGlobSyntax(pattern: string): boolean {\n if (!pattern || pattern.trim().length === 0) {\n return false;\n }\n if (isAbsolute(pattern)) {\n return false;\n }\n if (isWindowsDriveRelativePath(pattern)) {\n return false;\n }\n if (pattern.includes('..')) {\n return false;\n }\n // Reject glob-engine-specific traversal bypass forms that some engines\n // expand as path separators or parent-directory references.\n if (/\\{[^}]*\\.\\.[^}]*\\}/u.test(pattern)) {\n return false;\n }\n if (pattern.includes('[..]')) {\n return false;\n }\n return true;\n}\n\nasync function loadGitignoreFiles(\n root: string,\n gitignorePaths: readonly string[],\n manager: GitignoreManager,\n signal?: AbortSignal,\n): Promise<void> {\n await processInParallel(\n gitignorePaths,\n async (relPath) => {\n const absPath = join(root, relPath);\n try {\n const contents = await fsReadFile(absPath, { encoding: 'utf-8', signal });\n const matcher = ignore();\n matcher.add(contents);\n const dir = toPosixPath(dirname(relPath));\n manager.addMatcher(dir === '.' ? '' : dir, matcher);\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') throw error;\n Logger.warn(`Failed to read .gitignore at ${absPath}: ${formatUnknownErrorMessage(error)}`);\n }\n },\n GLOB_BATCH_CONCURRENCY,\n signal,\n );\n}\n\nexport class GitignoreManager {\n private matchers = new Map<string, Ignore>();\n\n addMatcher(dir: string, matcher: Ignore): void {\n this.matchers.set(dir, matcher);\n }\n\n static async load(root: string, signal?: AbortSignal): Promise<GitignoreManager> {\n const manager = new GitignoreManager();\n try {\n const gitignorePaths: string[] = [];\n const gitignoreEntries = fsGlob('**/.gitignore', {\n cwd: root,\n exclude: (entry: string) => {\n const name = basename(entry);\n if (name === 'node_modules' || name === '.git' || name === '.hg' || name === '.svn') {\n return true;\n }\n return false;\n },\n });\n for await (const match of gitignoreEntries) {\n if (signal?.aborted) break;\n gitignorePaths.push(match);\n }\n\n await loadGitignoreFiles(root, gitignorePaths, manager, signal);\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') throw error;\n Logger.warn(\n `Failed to enumerate .gitignore files under ${root}: ${formatUnknownErrorMessage(error)}`,\n );\n }\n return manager;\n }\n\n size(): number {\n return this.matchers.size;\n }\n\n isIgnored(relativePath: string, isDirectory: boolean): boolean {\n const normalized = toPosixPath(relativePath);\n if (normalized === '' || normalized === '.') return false;\n const parts = normalized.split('/');\n\n // 1. Check parent directories first\n let currentDir = '';\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n if (!part) continue;\n currentDir = currentDir ? `${currentDir}/${part}` : part;\n\n if (this.checkPath(currentDir, true)) {\n return true;\n }\n }\n\n // 2. Check the file/directory itself\n return this.checkPath(normalized, isDirectory);\n }\n\n private checkPath(posixPath: string, isDirectory: boolean): boolean {\n const parts = posixPath.split('/');\n const pathToCheck = isDirectory\n ? posixPath.endsWith('/')\n ? posixPath\n : `${posixPath}/`\n : posixPath;\n\n let ignored = false;\n\n // Check root level\n const rootMatcher = this.matchers.get('');\n if (rootMatcher) {\n const res = rootMatcher.test(pathToCheck);\n if (res.ignored) ignored = true;\n if (res.unignored) ignored = false;\n }\n\n // Check subdirectories\n let currentDir = '';\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n if (!part) continue;\n currentDir = currentDir ? `${currentDir}/${part}` : part;\n\n const matcher = this.matchers.get(currentDir);\n if (matcher) {\n const relParts = parts.slice(i + 1);\n const relPath = relParts.join('/');\n const relPathToCheck = isDirectory\n ? relPath.endsWith('/')\n ? relPath\n : `${relPath}/`\n : relPath;\n\n const res = matcher.test(relPathToCheck);\n if (res.ignored) ignored = true;\n if (res.unignored) ignored = false;\n }\n }\n\n return ignored;\n }\n}\n\nexport async function loadRootGitignore(\n root: string,\n signal?: AbortSignal,\n): Promise<GitignoreManager | null> {\n const manager = await GitignoreManager.load(root, signal);\n if (manager.size() === 0) {\n return null;\n }\n return manager;\n}\n\nexport function isIgnoredByGitignore(\n matcher: GitignoreManager,\n root: string,\n absolutePath: string,\n options: { isDirectory?: boolean; relativePath?: string } = {},\n): boolean {\n let { relativePath } = options;\n relativePath ??= relative(root, absolutePath);\n if (relativePath.length === 0) return false;\n return matcher.isIgnored(relativePath, Boolean(options.isDirectory));\n}\n\ninterface GlobDirentLike extends DirentLike {\n name: string;\n parentPath?: string;\n}\n\nexport interface GlobEntry {\n path: string;\n dirent: DirentLike;\n}\n\nexport interface GlobEntriesOptions {\n cwd: string;\n pattern: string;\n excludePatterns?: readonly string[];\n includeHidden?: boolean;\n baseNameMatch?: boolean;\n maxDepth?: number;\n onlyFiles?: boolean;\n suppressErrors?: boolean;\n respectGitignore?: boolean;\n}\n\ntype GlobMatch = string | GlobDirentLike;\n\ninterface NormalizedGlob {\n cwd: string;\n patterns: readonly string[];\n exclude: readonly string[];\n suppressErrors: boolean;\n maxDepth?: number;\n respectGitignore: boolean;\n}\n\nconst GLOB_MAGIC_RE = /[*?[\\]{}!]/u;\nconst GLOB_BATCH_CONCURRENCY = 64;\nconst SEP = '/';\nconst DOT_CHAR_CODE = 46;\nfunction normalizePattern(pattern: string, baseNameMatch: boolean): string {\n const normalized = toPosixPath(pattern);\n\n if (!baseNameMatch) return normalized;\n if (normalized.includes(SEP)) return normalized;\n return `**/${normalized}`;\n}\n\nfunction splitPatternPrefix(normalizedPattern: string): {\n prefix: string;\n remainder: string;\n} {\n if (!GLOB_MAGIC_RE.test(normalizedPattern)) {\n return { prefix: '', remainder: normalizedPattern };\n }\n\n const segments = normalizedPattern.split(SEP);\n const splitIndex = segments.findIndex((seg) => GLOB_MAGIC_RE.test(seg));\n\n if (splitIndex <= 0) {\n return { prefix: '', remainder: normalizedPattern };\n }\n\n return {\n prefix: segments.slice(0, splitIndex).join(SEP) + SEP,\n remainder: segments.slice(splitIndex).join(SEP),\n };\n}\n\nfunction addFirstDotSegment(patterns: Set<string>, prefix: string, remainder: string): void {\n if (remainder.length === 0) return;\n const segments = remainder.split(SEP);\n const idx = segments.findIndex((seg) => seg !== '**' && seg.length > 0);\n\n if (idx !== -1) {\n const original = segments[idx];\n if (original && original.charCodeAt(0) !== DOT_CHAR_CODE) {\n const newSegments = [...segments];\n newSegments[idx] = `.${original}`;\n patterns.add(`${prefix}${newSegments.join(SEP)}`);\n }\n }\n}\n\nfunction expandHiddenGlobstars(patterns: Set<string>, prefix: string, remainder: string): void {\n // Trailing bare globstar — `src/**`, `**` (remainder is exactly `**`, no\n // following segment). The pattern itself already matches every non-dot\n // entry under the prefix; add the two hidden complements fs.glob skips:\n // dotfiles/dot-dirs anywhere, and the contents of dot-dirs anywhere.\n if (remainder === '**') {\n patterns.add(`${prefix}**/.*`);\n patterns.add(`${prefix}**/.*/**`);\n return;\n }\n\n if (!remainder.startsWith('**/')) return;\n\n const afterGlobstar = remainder.slice(3);\n // Node fs.glob skips leading-dot entries unless the matching segment itself\n // starts with '.', and its `dot` option is not honored. So `**/*` alone misses\n // hidden files. Two depth-agnostic patterns cover everything the per-depth\n // unroll did: contents of dot-directories anywhere, and dotfiles/dotdirs\n // anywhere.\n patterns.add(`${prefix}**/.*/**/${afterGlobstar}`);\n const addDotFile = afterGlobstar.length > 0 && afterGlobstar.charCodeAt(0) !== DOT_CHAR_CODE;\n if (addDotFile) patterns.add(`${prefix}**/.${afterGlobstar}`);\n}\n\nfunction buildHiddenPatterns(normalizedPattern: string): readonly string[] {\n const patterns = new Set<string>([normalizedPattern]);\n const { prefix, remainder } = splitPatternPrefix(normalizedPattern);\n\n addFirstDotSegment(patterns, prefix, remainder);\n expandHiddenGlobstars(patterns, prefix, remainder);\n\n return Array.from(patterns);\n}\n\nfunction normalizeGlobOptions(options: GlobEntriesOptions): NormalizedGlob {\n const cwd = resolve(options.cwd);\n const normalizedPattern = normalizePattern(options.pattern, options.baseNameMatch ?? false);\n\n const patterns = options.includeHidden\n ? buildHiddenPatterns(normalizedPattern)\n : [normalizedPattern];\n\n const normalized: NormalizedGlob = {\n cwd,\n patterns,\n exclude: (options.excludePatterns ?? []).map(toPosixPath),\n suppressErrors: options.suppressErrors ?? false,\n respectGitignore: options.respectGitignore ?? false,\n };\n\n if (options.maxDepth !== undefined) {\n normalized.maxDepth = options.maxDepth;\n }\n\n return normalized;\n}\n\nfunction getRelativeDepth(relativePath: string): number {\n const len = relativePath.length;\n if (len === 0) return 0;\n let count = 0;\n for (let i = 0; i < len; i++) {\n const code = relativePath.charCodeAt(i);\n if (code === 47 || code === 92) {\n count++;\n }\n }\n return count;\n}\n\nfunction resolveDirentBase(cwd: string, parentPath: string | undefined): string {\n if (!parentPath) return cwd;\n return isAbsolute(parentPath) ? parentPath : resolve(cwd, parentPath);\n}\n\nfunction* processDirentMatch(\n match: GlobDirentLike,\n cwd: string,\n maxDepth: number | undefined,\n seen: Set<string>,\n onlyFiles: boolean,\n): Generator<GlobEntry> {\n const base = resolveDirentBase(cwd, match.parentPath);\n const absolutePath = resolve(base, match.name);\n\n if (maxDepth !== undefined) {\n const rel = relative(cwd, absolutePath);\n if (getRelativeDepth(rel) > maxDepth) return;\n }\n\n if (seen.has(absolutePath)) return;\n seen.add(absolutePath);\n\n if (onlyFiles && !match.isFile()) return;\n yield { path: absolutePath, dirent: match };\n}\n\nfunction createExcludeFilter(\n cwd: string,\n excludePatterns: readonly string[],\n gitignoreMatcher?: GitignoreManager | null,\n): ((match: GlobMatch) => boolean) | readonly string[] {\n if (!gitignoreMatcher) {\n return excludePatterns;\n }\n\n return (match: GlobMatch) => {\n const relPath =\n typeof match === 'string'\n ? match\n : match.parentPath\n ? relative(cwd, join(match.parentPath, match.name))\n : match.name;\n\n const posixRel = toPosixPath(relPath);\n\n // Gitignore check\n const isDir = typeof match === 'string' ? false : match.isDirectory();\n if (gitignoreMatcher.isIgnored(posixRel, isDir)) {\n return true;\n }\n\n // Also check explicit exclude patterns\n if (excludePatterns.length > 0) {\n for (const ex of excludePatterns) {\n if (posix.matchesGlob(posixRel, ex)) return true;\n }\n }\n\n return false;\n };\n}\n\nasync function* processGlobPattern(\n pattern: string,\n plan: NormalizedGlob,\n seen: Set<string>,\n onlyFiles: boolean,\n excludeFunc: ((match: GlobMatch) => boolean) | readonly string[],\n): AsyncGenerator<GlobEntry> {\n const { cwd, maxDepth, suppressErrors } = plan;\n let iterable: AsyncIterable<GlobMatch>;\n try {\n iterable = fsGlob(pattern, {\n cwd,\n exclude: excludeFunc,\n withFileTypes: true,\n }) as AsyncIterable<GlobMatch>;\n } catch (error) {\n if (suppressErrors) return;\n throw error;\n }\n\n try {\n for await (const match of iterable) {\n yield* processDirentMatch(match as GlobDirentLike, cwd, maxDepth, seen, onlyFiles);\n }\n } catch (error) {\n if (!suppressErrors) throw error;\n Logger.warn(\n `globEntries: suppressed mid-walk error for pattern \"${pattern}\": ${formatUnknownErrorMessage(error)}`,\n );\n }\n}\n\nexport async function* globEntries(options: GlobEntriesOptions): AsyncGenerator<GlobEntry> {\n let gitignoreMatcher: GitignoreManager | null = null;\n if (options.respectGitignore) {\n gitignoreMatcher = await loadRootGitignore(options.cwd);\n }\n\n const plan = normalizeGlobOptions(options);\n const seen = new Set<string>();\n const onlyFiles = options.onlyFiles ?? true;\n const excludeFunc = createExcludeFilter(plan.cwd, plan.exclude, gitignoreMatcher);\n\n for (const pattern of plan.patterns) {\n yield* processGlobPattern(pattern, plan, seen, onlyFiles, excludeFunc);\n }\n}\n\nexport const DEFAULT_EXCLUDE_PATTERNS = [\n '**/node_modules',\n '**/node_modules/**',\n '**/dist',\n '**/dist/**',\n '**/build',\n '**/build/**',\n '**/coverage',\n '**/coverage/**',\n '**/.git',\n '**/.git/**',\n '**/.vscode',\n '**/.vscode/**',\n '**/.idea',\n '**/.idea/**',\n '**/.DS_Store',\n '**/.next',\n '**/.next/**',\n '**/.nuxt',\n '**/.nuxt/**',\n '**/.output',\n '**/.output/**',\n '**/.svelte-kit',\n '**/.svelte-kit/**',\n '**/.cache',\n '**/.cache/**',\n '**/.yarn',\n '**/.yarn/**',\n '**/jspm_packages',\n '**/jspm_packages/**',\n '**/bower_components',\n '**/bower_components/**',\n '**/out',\n '**/out/**',\n '**/tmp',\n '**/tmp/**',\n '**/.temp',\n '**/.temp/**',\n '**/npm-debug.log',\n '**/yarn-debug.log',\n '**/yarn-error.log',\n '**/Thumbs.db',\n];\n"]}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import type { ClientCapabilities, InputRequiredResult, RequestStateCodec } from '@modelcontextprotocol/server';
|
|
2
|
+
/** The destructive operation a pending confirmation authorizes. */
|
|
3
|
+
type PendingOp = 'delete' | 'move' | 'copy' | 'grant';
|
|
4
|
+
/**
|
|
5
|
+
* Integrity-protected state minted into an `input_required` result and echoed
|
|
6
|
+
* back by the client on retry. `paths` is the sorted canonical set of target
|
|
7
|
+
* paths the confirmation covers; the handler compares it to the retried
|
|
8
|
+
* request's parameters and rejects a mismatch (R9).
|
|
9
|
+
*/
|
|
10
|
+
export interface PendingState {
|
|
11
|
+
readonly op: PendingOp;
|
|
12
|
+
readonly paths: readonly string[];
|
|
13
|
+
}
|
|
14
|
+
/** One embedded form-mode confirmation, keyed within the call. */
|
|
15
|
+
export interface PendingInput {
|
|
16
|
+
/** Server-assigned key, unique within the `tools/call`. */
|
|
17
|
+
readonly key: string;
|
|
18
|
+
/** Human-readable prompt for this item. */
|
|
19
|
+
readonly message: string;
|
|
20
|
+
/**
|
|
21
|
+
* When set, the form offers a titled single-select enum (`choice` field)
|
|
22
|
+
* instead of a boolean `confirm`. Each entry is a `{ value, title }` pair.
|
|
23
|
+
*/
|
|
24
|
+
readonly choices?: readonly {
|
|
25
|
+
value: string;
|
|
26
|
+
title: string;
|
|
27
|
+
}[];
|
|
28
|
+
/** Preselected enum value (only meaningful with single-select `choices`). */
|
|
29
|
+
readonly defaultValue?: string;
|
|
30
|
+
/**
|
|
31
|
+
* When set with `choices`, the form offers a multi-select enum: `choice` is
|
|
32
|
+
* a string array (`MultiSelectEnumSchema` shape) and the caller reads the
|
|
33
|
+
* accepted set with `readAcceptedMultiChoice`. Single-select otherwise.
|
|
34
|
+
*/
|
|
35
|
+
readonly multi?: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Boot-time HTTP guard: when the HTTP leg is active (`FS_API_KEY` set) and
|
|
39
|
+
* `FS_REQUEST_STATE_KEY` is missing or <32 bytes, refuse to start —
|
|
40
|
+
* a multi-instance fleet behind a load balancer would otherwise silently break
|
|
41
|
+
* every `input_required` round that lands on a different instance (each node
|
|
42
|
+
* mints tokens with its own random per-boot key). No-op outside explicit fleet
|
|
43
|
+
* mode. Called from `startHttpServer`, never at module load.
|
|
44
|
+
*/
|
|
45
|
+
export declare function assertFleetRequestStateKey(fleet: boolean): void;
|
|
46
|
+
/**
|
|
47
|
+
* The codec: `mint` seals a `PendingState` into the opaque wire string a
|
|
48
|
+
* handler returns from `inputRequired({ requestState })`; `verify` drops into
|
|
49
|
+
* `ServerOptions.requestState.verify` and throws on tamper, expiry, or bind
|
|
50
|
+
* mismatch (the seam answers with the frozen `-32602`).
|
|
51
|
+
*/
|
|
52
|
+
export declare const requestStateCodec: RequestStateCodec<PendingState>;
|
|
53
|
+
/**
|
|
54
|
+
* Build a boolean confirmation input for one pending item. The schema uses a
|
|
55
|
+
* fixed `confirm` boolean field; the input request is keyed by `key` so a
|
|
56
|
+
* batched call carries one request per item under a distinct key.
|
|
57
|
+
*/
|
|
58
|
+
export declare function confirmInput(key: string, message: string): PendingInput;
|
|
59
|
+
/**
|
|
60
|
+
* Build a single-select enum confirmation input. The form renders a `choice`
|
|
61
|
+
* field whose options are the titled `choices`; the caller reads the selection
|
|
62
|
+
* with `readAcceptedChoice`. A `defaultValue` preselects one option.
|
|
63
|
+
*/
|
|
64
|
+
export declare function choiceInput(key: string, message: string, choices: readonly {
|
|
65
|
+
value: string;
|
|
66
|
+
title: string;
|
|
67
|
+
}[], defaultValue?: string): PendingInput;
|
|
68
|
+
/**
|
|
69
|
+
* Build a multi-select enum confirmation input. Like `choiceInput` but the
|
|
70
|
+
* form renders `choice` as a string array (`MultiSelectEnumSchema` shape), so
|
|
71
|
+
* the client may accept a subset; the caller reads the accepted set with
|
|
72
|
+
* `readAcceptedMultiChoice`.
|
|
73
|
+
*/
|
|
74
|
+
export declare function multiSelectInput(key: string, message: string, choices: readonly {
|
|
75
|
+
value: string;
|
|
76
|
+
title: string;
|
|
77
|
+
}[]): PendingInput;
|
|
78
|
+
/**
|
|
79
|
+
* Build an `input_required` result carrying one boolean confirmation per pending
|
|
80
|
+
* item, plus the integrity-protected `requestState` sealing the operation kind
|
|
81
|
+
* and sorted target paths. `mint` is async (HMAC + base64url).
|
|
82
|
+
*/
|
|
83
|
+
export declare function buildInputRequired(pending: PendingState, inputs: readonly PendingInput[]): Promise<InputRequiredResult>;
|
|
84
|
+
/**
|
|
85
|
+
* The shared read-state → `buildInputRequired` → mismatch-throw flow used by
|
|
86
|
+
* every destructive-confirmation handler (delete, move, grant). No verified
|
|
87
|
+
* state, OR a verified state belonging to a different `op` (e.g. a chained
|
|
88
|
+
* call's grant round already resolved and this is now that same call's own
|
|
89
|
+
* delete/move confirmation round), mints a fresh `input_required` for this
|
|
90
|
+
* op. A retry whose verified state matches this op but not the pending path
|
|
91
|
+
* set throws `FsError(INVALID_INPUT)` (R9) — uniformly surfaced as an
|
|
92
|
+
* `isError` tool result by the handler's catch. Returns `undefined` on a
|
|
93
|
+
* matching same-op retry so the caller proceeds.
|
|
94
|
+
*
|
|
95
|
+
* One home for the R9 binding check means a future fix cannot miss two of three
|
|
96
|
+
* sites. The caller supplies `buildInputs` so only the prompt text varies.
|
|
97
|
+
*/
|
|
98
|
+
export interface PendingRoundTripOpts {
|
|
99
|
+
readonly op: PendingOp;
|
|
100
|
+
readonly pending: readonly string[];
|
|
101
|
+
readonly requestState: (() => PendingState | undefined) | undefined;
|
|
102
|
+
/**
|
|
103
|
+
* What the client declared it can do, or `undefined` when this connection
|
|
104
|
+
* cannot say. Only a positively-absent `elicitation` short-circuits; see
|
|
105
|
+
* {@link assertCanElicit}.
|
|
106
|
+
*/
|
|
107
|
+
readonly clientCapabilities?: ClientCapabilities | undefined;
|
|
108
|
+
readonly buildInputs: (pending: readonly string[]) => readonly PendingInput[];
|
|
109
|
+
}
|
|
110
|
+
export declare function pendingRoundTrip(opts: PendingRoundTripOpts): Promise<InputRequiredResult | undefined>;
|
|
111
|
+
/**
|
|
112
|
+
* Read one pending item's boolean confirmation from a retried request's
|
|
113
|
+
* `inputResponses`. Returns `true` only when the client explicitly accepted AND
|
|
114
|
+
* the `confirm` field is `true`; every other outcome (decline, cancel, missing
|
|
115
|
+
* key, accept-without-confirm) returns `false`, which the caller reports as
|
|
116
|
+
* `CANCELLED` (R3 proceed, R4/R5 cancelled).
|
|
117
|
+
*/
|
|
118
|
+
export declare function readAcceptedConfirm(responses: Record<string, unknown> | undefined, key: string): boolean;
|
|
119
|
+
/**
|
|
120
|
+
* Read one pending item's enum selection from a retried request's
|
|
121
|
+
* `inputResponses`. Returns the chosen `value` only when the client explicitly
|
|
122
|
+
* accepted AND the `choice` field is a string; every other outcome (decline,
|
|
123
|
+
* cancel, missing key, accept-without-choice) returns `undefined`, which the
|
|
124
|
+
* caller reports as `CANCELLED` — same contract as the boolean reader.
|
|
125
|
+
*
|
|
126
|
+
* The shape is SDK-validated, but the returned value is NOT checked for
|
|
127
|
+
* membership in the `choices` offered in the request schema. Callers must
|
|
128
|
+
* compare against the expected values (e.g. `choice === 'overwrite'`) before
|
|
129
|
+
* acting — never echo the string back into a path or trust it as an enum
|
|
130
|
+
* member.
|
|
131
|
+
*/
|
|
132
|
+
export declare function readAcceptedChoice(responses: Record<string, unknown> | undefined, key: string): string | undefined;
|
|
133
|
+
/**
|
|
134
|
+
* Read one pending item's multi-select enum selection from a retried request's
|
|
135
|
+
* `inputResponses`. Returns the accepted `value`s only when the client
|
|
136
|
+
* explicitly accepted AND `choice` is a string array of strings; every other
|
|
137
|
+
* outcome (decline, cancel, missing key, accept-without-choice, non-array
|
|
138
|
+
* `choice`, non-string elements) returns `undefined`, which the caller reports
|
|
139
|
+
* as `CANCELLED` — same contract as the single-select reader.
|
|
140
|
+
*
|
|
141
|
+
* As with `readAcceptedChoice`, the returned values are NOT checked for
|
|
142
|
+
* membership in the offered `choices`; callers must compare against the
|
|
143
|
+
* expected set before acting.
|
|
144
|
+
*/
|
|
145
|
+
export declare function readAcceptedMultiChoice(responses: Record<string, unknown> | undefined, key: string): string[] | undefined;
|
|
146
|
+
export {};
|
|
147
|
+
//# sourceMappingURL=input-required.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-required.d.ts","sourceRoot":"","sources":["../../src/core/input-required.ts"],"names":[],"mappings":"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"}
|