@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.
Files changed (301) hide show
  1. package/README.md +333 -838
  2. package/dist/cli-help.d.ts +3 -0
  3. package/dist/cli-help.d.ts.map +1 -0
  4. package/dist/cli-help.js +169 -0
  5. package/dist/cli-help.js.map +1 -0
  6. package/dist/cli.d.ts +28 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +168 -123
  9. package/dist/cli.js.map +1 -0
  10. package/dist/core/concurrency.d.ts +70 -0
  11. package/dist/core/concurrency.d.ts.map +1 -0
  12. package/dist/core/concurrency.js +173 -0
  13. package/dist/core/concurrency.js.map +1 -0
  14. package/dist/core/config.d.ts +19 -0
  15. package/dist/core/config.d.ts.map +1 -0
  16. package/dist/core/config.js +11 -0
  17. package/dist/core/config.js.map +1 -0
  18. package/dist/core/cursor.d.ts +23 -0
  19. package/dist/core/cursor.d.ts.map +1 -0
  20. package/dist/core/cursor.js +62 -0
  21. package/dist/core/cursor.js.map +1 -0
  22. package/dist/core/errors.d.ts +96 -0
  23. package/dist/core/errors.d.ts.map +1 -0
  24. package/dist/core/errors.js +356 -0
  25. package/dist/core/errors.js.map +1 -0
  26. package/dist/core/file-uri.d.ts +24 -0
  27. package/dist/core/file-uri.d.ts.map +1 -0
  28. package/dist/core/file-uri.js +52 -0
  29. package/dist/core/file-uri.js.map +1 -0
  30. package/dist/core/fmt.d.ts +38 -0
  31. package/dist/core/fmt.d.ts.map +1 -0
  32. package/dist/core/fmt.js +109 -0
  33. package/dist/core/fmt.js.map +1 -0
  34. package/dist/core/fs.d.ts +108 -0
  35. package/dist/core/fs.d.ts.map +1 -0
  36. package/dist/core/fs.js +243 -0
  37. package/dist/core/fs.js.map +1 -0
  38. package/dist/core/glob.d.ts +41 -0
  39. package/dist/core/glob.d.ts.map +1 -0
  40. package/dist/core/glob.js +399 -0
  41. package/dist/core/glob.js.map +1 -0
  42. package/dist/core/input-required.d.ts +147 -0
  43. package/dist/core/input-required.d.ts.map +1 -0
  44. package/dist/core/input-required.js +261 -0
  45. package/dist/core/input-required.js.map +1 -0
  46. package/dist/core/mime.d.ts +15 -0
  47. package/dist/core/mime.d.ts.map +1 -0
  48. package/dist/core/mime.js +188 -0
  49. package/dist/core/mime.js.map +1 -0
  50. package/dist/core/observability.d.ts +10 -0
  51. package/dist/core/observability.d.ts.map +1 -0
  52. package/dist/core/observability.js +76 -0
  53. package/dist/core/observability.js.map +1 -0
  54. package/dist/core/page-store.d.ts +41 -0
  55. package/dist/core/page-store.d.ts.map +1 -0
  56. package/dist/core/page-store.js +74 -0
  57. package/dist/core/page-store.js.map +1 -0
  58. package/dist/core/path-completer.d.ts +10 -0
  59. package/dist/core/path-completer.d.ts.map +1 -0
  60. package/dist/core/path-completer.js +227 -0
  61. package/dist/core/path-completer.js.map +1 -0
  62. package/dist/core/path-discovery.d.ts +8 -0
  63. package/dist/core/path-discovery.d.ts.map +1 -0
  64. package/dist/core/path-discovery.js +105 -0
  65. package/dist/core/path-discovery.js.map +1 -0
  66. package/dist/core/path-utils.d.ts +9 -0
  67. package/dist/core/path-utils.d.ts.map +1 -0
  68. package/dist/core/path-utils.js +121 -0
  69. package/dist/core/path-utils.js.map +1 -0
  70. package/dist/core/path.d.ts +148 -0
  71. package/dist/core/path.d.ts.map +1 -0
  72. package/dist/core/path.js +674 -0
  73. package/dist/core/path.js.map +1 -0
  74. package/dist/core/primitives.d.ts +23 -0
  75. package/dist/core/primitives.d.ts.map +1 -0
  76. package/dist/core/primitives.js +54 -0
  77. package/dist/core/primitives.js.map +1 -0
  78. package/dist/core/read.d.ts +74 -0
  79. package/dist/core/read.d.ts.map +1 -0
  80. package/dist/core/read.js +562 -0
  81. package/dist/core/read.js.map +1 -0
  82. package/dist/core/schema.d.ts +139 -0
  83. package/dist/core/schema.d.ts.map +1 -0
  84. package/dist/core/schema.js +345 -0
  85. package/dist/core/schema.js.map +1 -0
  86. package/dist/core/search.d.ts +100 -0
  87. package/dist/core/search.d.ts.map +1 -0
  88. package/dist/core/search.js +248 -0
  89. package/dist/core/search.js.map +1 -0
  90. package/dist/core/sensitive.d.ts +6 -0
  91. package/dist/core/sensitive.d.ts.map +1 -0
  92. package/dist/core/sensitive.js +142 -0
  93. package/dist/core/sensitive.js.map +1 -0
  94. package/dist/core/store.d.ts +57 -0
  95. package/dist/core/store.d.ts.map +1 -0
  96. package/dist/core/store.js +162 -0
  97. package/dist/core/store.js.map +1 -0
  98. package/dist/core/util.d.ts +26 -0
  99. package/dist/core/util.d.ts.map +1 -0
  100. package/dist/core/util.js +66 -0
  101. package/dist/core/util.js.map +1 -0
  102. package/dist/core/watcher-registry.d.ts +68 -0
  103. package/dist/core/watcher-registry.d.ts.map +1 -0
  104. package/dist/core/watcher-registry.js +312 -0
  105. package/dist/core/watcher-registry.js.map +1 -0
  106. package/dist/http-policy.d.ts +121 -0
  107. package/dist/http-policy.d.ts.map +1 -0
  108. package/dist/http-policy.js +340 -0
  109. package/dist/http-policy.js.map +1 -0
  110. package/dist/index.d.ts +1 -0
  111. package/dist/index.d.ts.map +1 -0
  112. package/dist/index.js +77 -41
  113. package/dist/index.js.map +1 -0
  114. package/dist/instructions.d.ts +12 -0
  115. package/dist/instructions.d.ts.map +1 -0
  116. package/dist/instructions.js +71 -0
  117. package/dist/instructions.js.map +1 -0
  118. package/dist/prompts.d.ts +8 -6
  119. package/dist/prompts.d.ts.map +1 -0
  120. package/dist/prompts.js +74 -168
  121. package/dist/prompts.js.map +1 -0
  122. package/dist/resources.d.ts +73 -9
  123. package/dist/resources.d.ts.map +1 -0
  124. package/dist/resources.js +392 -163
  125. package/dist/resources.js.map +1 -0
  126. package/dist/server.d.ts +62 -1
  127. package/dist/server.d.ts.map +1 -0
  128. package/dist/server.js +139 -1
  129. package/dist/server.js.map +1 -0
  130. package/dist/tools/batch.d.ts +89 -0
  131. package/dist/tools/batch.d.ts.map +1 -0
  132. package/dist/tools/batch.js +157 -0
  133. package/dist/tools/batch.js.map +1 -0
  134. package/dist/tools/create.d.ts +2 -0
  135. package/dist/tools/create.d.ts.map +1 -0
  136. package/dist/tools/create.js +142 -0
  137. package/dist/tools/create.js.map +1 -0
  138. package/dist/tools/define.d.ts +110 -0
  139. package/dist/tools/define.d.ts.map +1 -0
  140. package/dist/tools/define.js +394 -0
  141. package/dist/tools/define.js.map +1 -0
  142. package/dist/tools/delete-file.d.ts +2 -4
  143. package/dist/tools/delete-file.d.ts.map +1 -0
  144. package/dist/tools/delete-file.js +330 -87
  145. package/dist/tools/delete-file.js.map +1 -0
  146. package/dist/tools/diff.d.ts +2 -0
  147. package/dist/tools/diff.d.ts.map +1 -0
  148. package/dist/tools/diff.js +94 -0
  149. package/dist/tools/diff.js.map +1 -0
  150. package/dist/tools/edit.d.ts +2 -0
  151. package/dist/tools/edit.d.ts.map +1 -0
  152. package/dist/tools/edit.js +442 -0
  153. package/dist/tools/edit.js.map +1 -0
  154. package/dist/tools/index.d.ts +26 -0
  155. package/dist/tools/index.d.ts.map +1 -0
  156. package/dist/tools/index.js +52 -0
  157. package/dist/tools/index.js.map +1 -0
  158. package/dist/tools/list.d.ts +2 -0
  159. package/dist/tools/list.d.ts.map +1 -0
  160. package/dist/tools/list.js +291 -0
  161. package/dist/tools/list.js.map +1 -0
  162. package/dist/tools/move.d.ts +2 -0
  163. package/dist/tools/move.d.ts.map +1 -0
  164. package/dist/tools/move.js +321 -0
  165. package/dist/tools/move.js.map +1 -0
  166. package/dist/tools/patch.d.ts +2 -0
  167. package/dist/tools/patch.d.ts.map +1 -0
  168. package/dist/tools/patch.js +155 -0
  169. package/dist/tools/patch.js.map +1 -0
  170. package/dist/tools/progress.d.ts +52 -0
  171. package/dist/tools/progress.d.ts.map +1 -0
  172. package/dist/tools/progress.js +172 -0
  173. package/dist/tools/progress.js.map +1 -0
  174. package/dist/tools/read.d.ts +2 -4
  175. package/dist/tools/read.d.ts.map +1 -0
  176. package/dist/tools/read.js +398 -152
  177. package/dist/tools/read.js.map +1 -0
  178. package/dist/tools/replace-in-files.d.ts +2 -4
  179. package/dist/tools/replace-in-files.d.ts.map +1 -0
  180. package/dist/tools/replace-in-files.js +435 -264
  181. package/dist/tools/replace-in-files.js.map +1 -0
  182. package/dist/tools/roots.d.ts +2 -4
  183. package/dist/tools/roots.d.ts.map +1 -0
  184. package/dist/tools/roots.js +29 -52
  185. package/dist/tools/roots.js.map +1 -0
  186. package/dist/tools/search-content.d.ts +2 -4
  187. package/dist/tools/search-content.d.ts.map +1 -0
  188. package/dist/tools/search-content.js +262 -228
  189. package/dist/tools/search-content.js.map +1 -0
  190. package/dist/tools/search-files.d.ts +2 -4
  191. package/dist/tools/search-files.d.ts.map +1 -0
  192. package/dist/tools/search-files.js +162 -161
  193. package/dist/tools/search-files.js.map +1 -0
  194. package/dist/tools/stat.d.ts +2 -4
  195. package/dist/tools/stat.d.ts.map +1 -0
  196. package/dist/tools/stat.js +202 -62
  197. package/dist/tools/stat.js.map +1 -0
  198. package/dist/transport/http.d.ts +5 -0
  199. package/dist/transport/http.d.ts.map +1 -0
  200. package/dist/transport/http.js +276 -0
  201. package/dist/transport/http.js.map +1 -0
  202. package/dist/transport/shared.d.ts +45 -0
  203. package/dist/transport/shared.d.ts.map +1 -0
  204. package/dist/transport/shared.js +65 -0
  205. package/dist/transport/shared.js.map +1 -0
  206. package/dist/transport/stdio.d.ts +32 -0
  207. package/dist/transport/stdio.d.ts.map +1 -0
  208. package/dist/transport/stdio.js +279 -0
  209. package/dist/transport/stdio.js.map +1 -0
  210. package/dist/transport.d.ts +5 -0
  211. package/dist/transport.d.ts.map +1 -0
  212. package/dist/transport.js +4 -0
  213. package/dist/transport.js.map +1 -0
  214. package/package.json +37 -46
  215. package/dist/assets/logo.svg +0 -35
  216. package/dist/completions.d.ts +0 -2
  217. package/dist/completions.js +0 -572
  218. package/dist/config.d.ts +0 -119
  219. package/dist/config.js +0 -31
  220. package/dist/lib/abort.d.ts +0 -7
  221. package/dist/lib/abort.js +0 -81
  222. package/dist/lib/constants.d.ts +0 -42
  223. package/dist/lib/constants.js +0 -313
  224. package/dist/lib/errors.d.ts +0 -28
  225. package/dist/lib/errors.js +0 -301
  226. package/dist/lib/file-operations/core.d.ts +0 -53
  227. package/dist/lib/file-operations/core.js +0 -144
  228. package/dist/lib/file-operations/metadata.d.ts +0 -77
  229. package/dist/lib/file-operations/metadata.js +0 -878
  230. package/dist/lib/file-operations/search.d.ts +0 -46
  231. package/dist/lib/file-operations/search.js +0 -1194
  232. package/dist/lib/file-operations/traversal.d.ts +0 -40
  233. package/dist/lib/file-operations/traversal.js +0 -310
  234. package/dist/lib/fs-helpers.d.ts +0 -46
  235. package/dist/lib/fs-helpers.js +0 -606
  236. package/dist/lib/globs.d.ts +0 -2
  237. package/dist/lib/globs.js +0 -19
  238. package/dist/lib/logger.d.ts +0 -27
  239. package/dist/lib/logger.js +0 -91
  240. package/dist/lib/observability.d.ts +0 -33
  241. package/dist/lib/observability.js +0 -373
  242. package/dist/lib/paths.d.ts +0 -35
  243. package/dist/lib/paths.js +0 -634
  244. package/dist/lib/resource-store.d.ts +0 -28
  245. package/dist/lib/resource-store.js +0 -195
  246. package/dist/lib/utils.d.ts +0 -7
  247. package/dist/lib/utils.js +0 -37
  248. package/dist/lib/zod-codecs.d.ts +0 -2
  249. package/dist/lib/zod-codecs.js +0 -18
  250. package/dist/pkg-info.d.ts +0 -7
  251. package/dist/pkg-info.js +0 -9
  252. package/dist/resources/generated-instructions.d.ts +0 -1
  253. package/dist/resources/generated-instructions.js +0 -105
  254. package/dist/resources/tool-catalog.d.ts +0 -2
  255. package/dist/resources/tool-catalog.js +0 -78
  256. package/dist/resources/tool-info.d.ts +0 -9
  257. package/dist/resources/tool-info.js +0 -206
  258. package/dist/resources/workflows.d.ts +0 -1
  259. package/dist/resources/workflows.js +0 -72
  260. package/dist/schemas.d.ts +0 -505
  261. package/dist/schemas.js +0 -676
  262. package/dist/server/bootstrap.d.ts +0 -6
  263. package/dist/server/bootstrap.js +0 -563
  264. package/dist/server/event-store.d.ts +0 -18
  265. package/dist/server/event-store.js +0 -71
  266. package/dist/server/roots-manager.d.ts +0 -28
  267. package/dist/server/roots-manager.js +0 -227
  268. package/dist/server/task-store.d.ts +0 -10
  269. package/dist/server/task-store.js +0 -91
  270. package/dist/tools/apply-patch.d.ts +0 -4
  271. package/dist/tools/apply-patch.js +0 -235
  272. package/dist/tools/calculate-hash.d.ts +0 -4
  273. package/dist/tools/calculate-hash.js +0 -187
  274. package/dist/tools/contract.d.ts +0 -50
  275. package/dist/tools/contract.js +0 -1
  276. package/dist/tools/create-directory.d.ts +0 -4
  277. package/dist/tools/create-directory.js +0 -68
  278. package/dist/tools/diff-files.d.ts +0 -4
  279. package/dist/tools/diff-files.js +0 -136
  280. package/dist/tools/edit-file.d.ts +0 -4
  281. package/dist/tools/edit-file.js +0 -256
  282. package/dist/tools/icons.d.ts +0 -15
  283. package/dist/tools/icons.js +0 -24
  284. package/dist/tools/list-directory.d.ts +0 -4
  285. package/dist/tools/list-directory.js +0 -218
  286. package/dist/tools/move-file.d.ts +0 -4
  287. package/dist/tools/move-file.js +0 -178
  288. package/dist/tools/read-multiple.d.ts +0 -4
  289. package/dist/tools/read-multiple.js +0 -207
  290. package/dist/tools/shared.d.ts +0 -172
  291. package/dist/tools/shared.js +0 -599
  292. package/dist/tools/stat-many.d.ts +0 -4
  293. package/dist/tools/stat-many.js +0 -104
  294. package/dist/tools/task-support.d.ts +0 -29
  295. package/dist/tools/task-support.js +0 -472
  296. package/dist/tools/tree.d.ts +0 -4
  297. package/dist/tools/tree.js +0 -102
  298. package/dist/tools/write-file.d.ts +0 -4
  299. package/dist/tools/write-file.js +0 -60
  300. package/dist/tools.d.ts +0 -5
  301. 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":"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","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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"}