@j0hanz/filesystem-mcp 2.7.6 → 2.8.1

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 (129) hide show
  1. package/dist/cli.d.ts +1 -9
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +2 -2
  4. package/dist/cli.js.map +1 -1
  5. package/dist/core/cursor.d.ts +8 -0
  6. package/dist/core/cursor.d.ts.map +1 -1
  7. package/dist/core/cursor.js +14 -0
  8. package/dist/core/cursor.js.map +1 -1
  9. package/dist/core/errors.d.ts +4 -3
  10. package/dist/core/errors.d.ts.map +1 -1
  11. package/dist/core/errors.js +5 -16
  12. package/dist/core/errors.js.map +1 -1
  13. package/dist/core/fs.d.ts +11 -11
  14. package/dist/core/fs.d.ts.map +1 -1
  15. package/dist/core/fs.js +172 -83
  16. package/dist/core/fs.js.map +1 -1
  17. package/dist/core/glob.d.ts +8 -0
  18. package/dist/core/glob.d.ts.map +1 -1
  19. package/dist/core/glob.js +192 -29
  20. package/dist/core/glob.js.map +1 -1
  21. package/dist/core/input-required.d.ts +19 -0
  22. package/dist/core/input-required.d.ts.map +1 -1
  23. package/dist/core/input-required.js +20 -2
  24. package/dist/core/input-required.js.map +1 -1
  25. package/dist/core/observability.d.ts +2 -0
  26. package/dist/core/observability.d.ts.map +1 -1
  27. package/dist/core/observability.js +7 -0
  28. package/dist/core/observability.js.map +1 -1
  29. package/dist/core/path-completer.d.ts.map +1 -1
  30. package/dist/core/path-completer.js +11 -30
  31. package/dist/core/path-completer.js.map +1 -1
  32. package/dist/core/path-utils.d.ts +9 -6
  33. package/dist/core/path-utils.d.ts.map +1 -1
  34. package/dist/core/path-utils.js +13 -19
  35. package/dist/core/path-utils.js.map +1 -1
  36. package/dist/core/path.d.ts +1 -20
  37. package/dist/core/path.d.ts.map +1 -1
  38. package/dist/core/path.js +17 -69
  39. package/dist/core/path.js.map +1 -1
  40. package/dist/core/read.d.ts +7 -3
  41. package/dist/core/read.d.ts.map +1 -1
  42. package/dist/core/read.js +32 -50
  43. package/dist/core/read.js.map +1 -1
  44. package/dist/core/schema.d.ts +6 -1
  45. package/dist/core/schema.d.ts.map +1 -1
  46. package/dist/core/schema.js +17 -3
  47. package/dist/core/schema.js.map +1 -1
  48. package/dist/core/search.d.ts.map +1 -1
  49. package/dist/core/search.js +104 -51
  50. package/dist/core/search.js.map +1 -1
  51. package/dist/core/sensitive.d.ts.map +1 -1
  52. package/dist/core/sensitive.js +7 -14
  53. package/dist/core/sensitive.js.map +1 -1
  54. package/dist/core/store.d.ts +36 -1
  55. package/dist/core/store.d.ts.map +1 -1
  56. package/dist/core/store.js +71 -6
  57. package/dist/core/store.js.map +1 -1
  58. package/dist/core/util.d.ts +40 -5
  59. package/dist/core/util.d.ts.map +1 -1
  60. package/dist/core/util.js +75 -5
  61. package/dist/core/util.js.map +1 -1
  62. package/dist/index.js +5 -16
  63. package/dist/index.js.map +1 -1
  64. package/dist/prompts.d.ts +1 -1
  65. package/dist/prompts.d.ts.map +1 -1
  66. package/dist/prompts.js +1 -1
  67. package/dist/prompts.js.map +1 -1
  68. package/dist/resources.d.ts +6 -3
  69. package/dist/resources.d.ts.map +1 -1
  70. package/dist/resources.js +46 -25
  71. package/dist/resources.js.map +1 -1
  72. package/dist/server.d.ts +9 -6
  73. package/dist/server.d.ts.map +1 -1
  74. package/dist/server.js +8 -9
  75. package/dist/server.js.map +1 -1
  76. package/dist/tools/create.d.ts.map +1 -1
  77. package/dist/tools/create.js +13 -25
  78. package/dist/tools/create.js.map +1 -1
  79. package/dist/tools/define.d.ts +8 -7
  80. package/dist/tools/define.d.ts.map +1 -1
  81. package/dist/tools/define.js +48 -16
  82. package/dist/tools/define.js.map +1 -1
  83. package/dist/tools/delete.d.ts.map +1 -1
  84. package/dist/tools/delete.js +46 -27
  85. package/dist/tools/delete.js.map +1 -1
  86. package/dist/tools/edit.d.ts.map +1 -1
  87. package/dist/tools/edit.js +24 -39
  88. package/dist/tools/edit.js.map +1 -1
  89. package/dist/tools/find-files.d.ts.map +1 -1
  90. package/dist/tools/find-files.js +45 -62
  91. package/dist/tools/find-files.js.map +1 -1
  92. package/dist/tools/index.d.ts +3 -12
  93. package/dist/tools/index.d.ts.map +1 -1
  94. package/dist/tools/index.js +2 -10
  95. package/dist/tools/index.js.map +1 -1
  96. package/dist/tools/list.d.ts.map +1 -1
  97. package/dist/tools/list.js +81 -74
  98. package/dist/tools/list.js.map +1 -1
  99. package/dist/tools/move.d.ts.map +1 -1
  100. package/dist/tools/move.js +17 -14
  101. package/dist/tools/move.js.map +1 -1
  102. package/dist/tools/patch.d.ts.map +1 -1
  103. package/dist/tools/patch.js +3 -6
  104. package/dist/tools/patch.js.map +1 -1
  105. package/dist/tools/read.d.ts.map +1 -1
  106. package/dist/tools/read.js +31 -40
  107. package/dist/tools/read.js.map +1 -1
  108. package/dist/tools/replace-text.d.ts.map +1 -1
  109. package/dist/tools/replace-text.js +24 -33
  110. package/dist/tools/replace-text.js.map +1 -1
  111. package/dist/tools/search-text.d.ts.map +1 -1
  112. package/dist/tools/search-text.js +42 -69
  113. package/dist/tools/search-text.js.map +1 -1
  114. package/dist/transport/http-policy.d.ts +3 -2
  115. package/dist/transport/http-policy.d.ts.map +1 -1
  116. package/dist/transport/http-policy.js +3 -2
  117. package/dist/transport/http-policy.js.map +1 -1
  118. package/dist/transport/http.d.ts.map +1 -1
  119. package/dist/transport/http.js +2 -3
  120. package/dist/transport/http.js.map +1 -1
  121. package/dist/transport/shared.d.ts +7 -5
  122. package/dist/transport/shared.d.ts.map +1 -1
  123. package/dist/transport/shared.js +8 -2
  124. package/dist/transport/shared.js.map +1 -1
  125. package/dist/transport/stdio.d.ts +4 -1
  126. package/dist/transport/stdio.d.ts.map +1 -1
  127. package/dist/transport/stdio.js +45 -12
  128. package/dist/transport/stdio.js.map +1 -1
  129. package/package.json +3 -2
package/dist/core/glob.js CHANGED
@@ -1,29 +1,155 @@
1
1
  import { glob as fsGlob, readFile as fsReadFile, lstat } from 'node:fs/promises';
2
- import { basename, dirname, isAbsolute, join, relative, resolve } from 'node:path';
2
+ import { basename, dirname, join, matchesGlob, relative, resolve, win32 } from 'node:path';
3
3
  import ignore from 'ignore';
4
4
  import { processInParallel } from "./concurrency.js";
5
5
  import { formatUnknownErrorMessage } from "./errors.js";
6
6
  import { Logger } from "./observability.js";
7
- import { isPathInsideDirectory, isWindowsDriveRelativePath, toPosixPath } from "./path-utils.js";
7
+ import { IS_WINDOWS, isPathInsideDirectory, toPosixPath } from "./path-utils.js";
8
8
  import { MIB } from "./util.js";
9
- /** `..` bounded on both sides by a separator, a brace delimiter, or the pattern edge. */
10
- const TRAVERSAL_DOTDOT_RE = /(?:^|[/\\{,])\.\.(?=[/\\},]|$)/u;
9
+ /**
10
+ * More brace alternatives than this is not a file filter. fs.glob's matcher
11
+ * dedupes its alternatives pairwise, synchronously: `{1..100000}` pins the
12
+ * event loop for most of a minute, where 1024 costs tens of milliseconds.
13
+ */
14
+ export const MAX_BRACE_ALTERNATIVES = 1024;
15
+ /** Bound synchronous glob compilation when checking candidate traversal segments. */
16
+ export const MAX_DOTDOT_CHECK_CHARS = 4096;
17
+ // The range bodies fs.glob's brace expansion recognises, as it writes them.
18
+ const NUMERIC_RANGE_RE = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/u;
19
+ const ALPHA_RANGE_RE = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/u;
20
+ /** The values a range body (`x..y`, `x..y..step`) expands to, or `undefined` past the cap. */
21
+ function rangeValues(body) {
22
+ const alpha = ALPHA_RANGE_RE.test(body);
23
+ const [from = '', to = '', step = '1'] = body.split('..');
24
+ const bound = (end) => (alpha ? end.charCodeAt(0) : Number.parseInt(end, 10));
25
+ const start = bound(from);
26
+ const stop = bound(to);
27
+ const stride = Math.max(Math.abs(Number.parseInt(step, 10)), 1);
28
+ // Past 2^53 a step no longer moves the number (2^53 + 1 === 2^53), and past
29
+ // Number.MAX_VALUE it reads as Infinity: either way the loop below would
30
+ // never end. Refuse them like any other long range.
31
+ if (!Number.isSafeInteger(start) || !Number.isSafeInteger(stop))
32
+ return undefined;
33
+ if (Math.floor(Math.abs(stop - start) / stride) >= MAX_BRACE_ALTERNATIVES)
34
+ return undefined;
35
+ const values = [];
36
+ const direction = stop < start ? -1 : 1;
37
+ for (let i = start; (stop - i) * direction >= 0; i += stride * direction) {
38
+ // The engine drops a `\` a letter range passes through (`{Z..a}`), and
39
+ // digits can never spell a root or a `..`, so their padding is moot.
40
+ const char = String.fromCharCode(i);
41
+ values.push(alpha ? (char === '\\' ? '' : char) : String(i));
42
+ }
43
+ return values;
44
+ }
45
+ /**
46
+ * The leftmost `{…}` that fs.glob would expand: a comma list or a range.
47
+ * The expansion is textual, as fs.glob's is: a brace inside `[…]` still
48
+ * counts (unlike SensitiveMatcher's own glob dialect in sensitive.ts).
49
+ */
50
+ function firstBraceSet(pattern) {
51
+ const open = [];
52
+ let first;
53
+ for (let i = 0; i < pattern.length; i++) {
54
+ const char = pattern[i];
55
+ if (char === '{')
56
+ open.push({ at: i, commas: [] });
57
+ else if (char === ',')
58
+ open.at(-1)?.commas.push(i);
59
+ else if (char === '}') {
60
+ const set = open.pop();
61
+ if (!set || (first && first.at < set.at))
62
+ continue;
63
+ const body = pattern.slice(set.at + 1, i);
64
+ if (set.commas.length > 0 || NUMERIC_RANGE_RE.test(body) || ALPHA_RANGE_RE.test(body)) {
65
+ first = { ...set, close: i };
66
+ }
67
+ }
68
+ }
69
+ if (!first)
70
+ return undefined;
71
+ let alternatives;
72
+ if (first.commas.length > 0) {
73
+ alternatives = [];
74
+ let start = first.at + 1;
75
+ for (const end of [...first.commas, first.close]) {
76
+ alternatives.push(pattern.slice(start, end));
77
+ start = end + 1;
78
+ }
79
+ }
80
+ else {
81
+ alternatives = rangeValues(pattern.slice(first.at + 1, first.close));
82
+ }
83
+ return { pre: pattern.slice(0, first.at), alternatives, post: pattern.slice(first.close + 1) };
84
+ }
85
+ /** Every brace alternative of `pattern`, or `undefined` past the cap. */
86
+ function expandBraceSets(pattern, out = []) {
87
+ const set = firstBraceSet(pattern);
88
+ if (!set) {
89
+ out.push(pattern);
90
+ return out.length > MAX_BRACE_ALTERNATIVES ? undefined : out;
91
+ }
92
+ if (!set.alternatives)
93
+ return undefined;
94
+ for (const alternative of set.alternatives) {
95
+ if (!expandBraceSets(`${set.pre}${alternative}${set.post}`, out))
96
+ return undefined;
97
+ }
98
+ return out;
99
+ }
100
+ /** The characters minimatch can spell a literal `..` with: dots and one-character classes. */
101
+ const DOTDOT_SPELLING_RE = /^[.[\]-]+$/u;
102
+ /**
103
+ * Whether the glob engine reads this brace-free segment as `..`. readdir never
104
+ * yields `..`, so only a literal reaches it, and minimatch spells a literal dot
105
+ * as `.`, `[.]` or `[.-.]`. Any other character (`*`, `?`, an extglob, a
106
+ * letter) either makes the segment a pattern the walk never follows to `..`,
107
+ * or puts that character in the name. Only the rest is worth asking the engine
108
+ * about, so a long or exotic segment costs no compile; one the engine cannot
109
+ * compile is refused.
110
+ */
111
+ const isTraversalSegment = (segment) => {
112
+ try {
113
+ return matchesGlob('..', segment);
114
+ }
115
+ catch {
116
+ return true;
117
+ }
118
+ };
119
+ /**
120
+ * An alternative that starts at a root: `/x`, `//host/share`, `C:/x`, `C:x`,
121
+ * on any host. On Windows fs.glob also reads a literal first segment ending in
122
+ * `:` as a drive (`[C]:/x`); elsewhere that is an ordinary name (`logs:`).
123
+ */
124
+ const isRooted = (alternative) => win32.parse(alternative).root !== '' ||
125
+ (IS_WINDOWS && (alternative.split('/')[0] ?? '').endsWith(':'));
11
126
  export function isSafeGlobSyntax(pattern) {
12
127
  if (!pattern || pattern.trim().length === 0) {
13
128
  return false;
14
129
  }
15
- if (isAbsolute(pattern)) {
16
- return false;
17
- }
18
- if (isWindowsDriveRelativePath(pattern)) {
130
+ // The walk sees the pattern with `\` as `/` (normalizePattern), so check
131
+ // that form: `\etc\x` is `/etc/x` there, an absolute walk on any host.
132
+ // Brace sets can build a root or a `..` from parts (`{/etc,x}`, `..{,x}`,
133
+ // `.{Z..a}.`), so check every alternative, not the pattern as written.
134
+ // globEntries still drops any match outside its cwd: this check is what
135
+ // turns such a pattern into an error rather than a quietly narrower walk.
136
+ const alternatives = expandBraceSets(toPosixPath(pattern));
137
+ if (!alternatives)
19
138
  return false;
139
+ const segments = new Set();
140
+ for (const alternative of alternatives) {
141
+ if (isRooted(alternative))
142
+ return false;
143
+ for (const segment of alternative.split('/'))
144
+ segments.add(segment);
20
145
  }
21
- // Only a whole `..` — a path segment, or one alternative of a `{a,..}`
22
- // brace set — can traverse. `..` inside a segment (`[...slug]`, `v1..2.md`,
23
- // `[..]`) is a literal name or a character class, and PathGuard re-checks
24
- // containment on every resolved entry regardless.
25
- if (TRAVERSAL_DOTDOT_RE.test(pattern)) {
26
- return false;
146
+ let dotdotCheckChars = 0;
147
+ for (const segment of segments) {
148
+ if (!segment.includes('.') || !DOTDOT_SPELLING_RE.test(segment))
149
+ continue;
150
+ dotdotCheckChars += segment.length;
151
+ if (dotdotCheckChars > MAX_DOTDOT_CHECK_CHARS || isTraversalSegment(segment))
152
+ return false;
27
153
  }
28
154
  return true;
29
155
  }
@@ -101,11 +227,17 @@ class GitignoreManager {
101
227
  this.ancestors.push({ prefix, matcher });
102
228
  }
103
229
  /** `null` when no `.gitignore` was found, so callers skip the filter entirely. */
104
- static async load(root, signal, maxDepth, ignoreCeiling) {
230
+ static async load(root, includeHidden, signal, maxDepth, ignoreCeiling) {
105
231
  const manager = new GitignoreManager();
106
232
  try {
107
233
  const gitignorePaths = [];
108
- const gitignoreEntries = fsGlob('**/.gitignore', {
234
+ // Search dot-directories (.venv, .terraform, ...) for rules only when the
235
+ // walk includes hidden entries; for any other walk, enumerating every
236
+ // hidden tree would cost more than the walk itself.
237
+ const gitignorePatterns = includeHidden
238
+ ? [...buildHiddenPatterns('**/.gitignore')]
239
+ : ['**/.gitignore'];
240
+ const gitignoreEntries = fsGlob(gitignorePatterns, {
109
241
  cwd: root,
110
242
  // Skip what the walk itself skips, and stop one level past its depth
111
243
  // bound: a .gitignore at depth d only affects entries at depth >= d.
@@ -207,7 +339,6 @@ class GitignoreManager {
207
339
  const GLOB_MAGIC_RE = /[*?[\]{}!]/u;
208
340
  const GLOB_BATCH_CONCURRENCY = 64;
209
341
  const SEP = '/';
210
- const DOT_CHAR_CODE = 46;
211
342
  function normalizePattern(pattern, baseNameMatch) {
212
343
  const normalized = toPosixPath(pattern);
213
344
  if (!baseNameMatch)
@@ -230,6 +361,26 @@ function splitPatternPrefix(normalizedPattern) {
230
361
  remainder: segments.slice(splitIndex).join(SEP),
231
362
  };
232
363
  }
364
+ /**
365
+ * The segment matching the dot-prefixed names `segment` would match if fs.glob
366
+ * did not skip them, or `undefined` when there are none. Only a leading `*` or
367
+ * `?` stands for that dot: a literal never does, and a character class or a
368
+ * brace set is left as written rather than parsed.
369
+ */
370
+ function dotVariant(segment) {
371
+ // `*(…)` and `?(…)` are extglobs, not wildcards.
372
+ if (segment[1] === '(')
373
+ return undefined;
374
+ if (segment.startsWith('*'))
375
+ return `.${segment}`;
376
+ if (!segment.startsWith('?'))
377
+ return undefined;
378
+ // `?` is exactly one character, so the dot replaces it, unless what follows
379
+ // could leave just `.` or `..` (`?`, `?.`, `?{.,x}`, `?[.]`): the directory
380
+ // and its parent, not a dot-prefixed entry.
381
+ const rest = segment.slice(1);
382
+ return rest === '' || /^[.[{]/u.test(rest) ? undefined : `.${rest}`;
383
+ }
233
384
  function addFirstDotSegment(patterns, prefix, remainder) {
234
385
  if (remainder.length === 0)
235
386
  return;
@@ -237,9 +388,10 @@ function addFirstDotSegment(patterns, prefix, remainder) {
237
388
  const idx = segments.findIndex((seg) => seg !== '**' && seg.length > 0);
238
389
  if (idx !== -1) {
239
390
  const original = segments[idx];
240
- if (original && original.charCodeAt(0) !== DOT_CHAR_CODE) {
391
+ const dotted = original ? dotVariant(original) : undefined;
392
+ if (dotted) {
241
393
  const newSegments = [...segments];
242
- newSegments[idx] = `.${original}`;
394
+ newSegments[idx] = dotted;
243
395
  patterns.add(`${prefix}${newSegments.join(SEP)}`);
244
396
  }
245
397
  }
@@ -261,11 +413,12 @@ function expandHiddenGlobstars(patterns, prefix, remainder) {
261
413
  // starts with '.', and its `dot` option is not honored. So `**/*` alone misses
262
414
  // hidden files. Two depth-agnostic patterns cover everything the per-depth
263
415
  // unroll did: contents of dot-directories anywhere, and dotfiles/dotdirs
264
- // anywhere.
416
+ // anywhere (when the first segment after the globstar can match a dot).
265
417
  patterns.add(`${prefix}**/.*/**/${afterGlobstar}`);
266
- const addDotFile = afterGlobstar.length > 0 && afterGlobstar.charCodeAt(0) !== DOT_CHAR_CODE;
267
- if (addDotFile)
268
- patterns.add(`${prefix}**/.${afterGlobstar}`);
418
+ const [firstSegment = '', ...rest] = afterGlobstar.split(SEP);
419
+ const dotted = dotVariant(firstSegment);
420
+ if (dotted)
421
+ patterns.add(`${prefix}**/${[dotted, ...rest].join(SEP)}`);
269
422
  }
270
423
  function buildHiddenPatterns(normalizedPattern) {
271
424
  const patterns = new Set([normalizedPattern]);
@@ -292,6 +445,11 @@ function normalizeGlobOptions(options) {
292
445
  }
293
446
  function* processDirentMatch(match, cwd, maxDepth, seen, onlyFiles) {
294
447
  const absolutePath = resolve(cwd, match.parentPath, match.name);
448
+ // The walk's scope is its cwd, whatever the pattern spells: a `..` or a root
449
+ // the validator did not foresee must not reach a caller, where it would be
450
+ // read, rewritten, or counted and named as inaccessible.
451
+ if (!isPathInsideDirectory(cwd, absolutePath))
452
+ return;
295
453
  if (maxDepth !== undefined) {
296
454
  const rel = relative(cwd, absolutePath);
297
455
  if (rel.split(/[/\\]/u).length - 1 > maxDepth)
@@ -305,13 +463,12 @@ function* processDirentMatch(match, cwd, maxDepth, seen, onlyFiles) {
305
463
  yield { path: absolutePath, dirent: match };
306
464
  }
307
465
  function createWalkFilter(cwd, skipIgnored, gitignoreMatcher, maxDepth, signal) {
308
- if (!skipIgnored && maxDepth === undefined && signal === undefined)
309
- return undefined;
310
466
  // fs.glob can hand the predicate a dirent whose parentPath is "." — the walk
311
467
  // root, not the process cwd — when it re-visits a directory under `**` whose
312
468
  // name also exists in the process cwd. Resolving against `cwd` names the
313
469
  // entry the dirent describes; `join` would resolve it against the process.
314
- const relativeOf = (match) => toPosixPath(relative(cwd, resolve(cwd, match.parentPath, match.name)));
470
+ const absoluteOf = (match) => resolve(cwd, match.parentPath, match.name);
471
+ const relativeOf = (match) => toPosixPath(relative(cwd, absoluteOf(match)));
315
472
  // Every default exclude is a bare name that applies at any depth, so a Set
316
473
  // lookup per segment replaces compiling dozens of globs per entry.
317
474
  const excluded = (posixRel, isDir) => skipIgnored &&
@@ -323,6 +480,12 @@ function createWalkFilter(cwd, skipIgnored, gitignoreMatcher, maxDepth, signal)
323
480
  // pruning everything is the only way to stop a walk that yields nothing.
324
481
  if (signal?.aborted)
325
482
  return true;
483
+ // fs.glob asks before it queues a directory, so a walk that would
484
+ // climb to `../` or start at `/` stops at the edge instead of reading
485
+ // there. Not every climb asks (`**/..` does not): processDirentMatch is
486
+ // the gate, this only saves the walk.
487
+ if (!isPathInsideDirectory(cwd, absoluteOf(match)))
488
+ return true;
326
489
  const posixRel = relativeOf(match);
327
490
  const isDir = match.isDirectory();
328
491
  if (excluded(posixRel, isDir))
@@ -343,7 +506,7 @@ async function* processGlobPattern(pattern, plan, seen, onlyFiles, filter, signa
343
506
  try {
344
507
  iterable = fsGlob(pattern, {
345
508
  cwd,
346
- ...(filter ? { exclude: filter.prune } : {}),
509
+ exclude: filter.prune,
347
510
  withFileTypes: true,
348
511
  });
349
512
  }
@@ -359,7 +522,7 @@ async function* processGlobPattern(pattern, plan, seen, onlyFiles, filter, signa
359
522
  // A function `exclude` only prunes descent in fs.glob — it still yields
360
523
  // the rejected dirent itself, and any rejected entry below the top level.
361
524
  // Re-apply the ignore rules (not the depth bound) to drop those.
362
- if (filter?.isExcluded(match))
525
+ if (filter.isExcluded(match))
363
526
  continue;
364
527
  yield* processDirentMatch(match, cwd, maxDepth, seen, onlyFiles);
365
528
  }
@@ -375,7 +538,7 @@ async function* processGlobPattern(pattern, plan, seen, onlyFiles, filter, signa
375
538
  }
376
539
  export async function* globEntries(options) {
377
540
  const gitignoreMatcher = options.skipIgnored
378
- ? await GitignoreManager.load(options.cwd, options.signal, options.maxDepth, options.ignoreCeiling)
541
+ ? await GitignoreManager.load(options.cwd, options.includeHidden ?? false, options.signal, options.maxDepth, options.ignoreCeiling)
379
542
  : null;
380
543
  const plan = normalizeGlobOptions(options);
381
544
  const seen = new Set();
@@ -1 +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, lstat } from 'node:fs/promises';\nimport { basename, dirname, isAbsolute, join, relative, resolve } from 'node:path';\n\nimport type { Ignore } from 'ignore';\nimport ignore from 'ignore';\n\nimport { processInParallel } from './concurrency.ts';\nimport { formatUnknownErrorMessage } from './errors.ts';\nimport { Logger } from './observability.ts';\nimport type { DirentLike } from './path-utils.ts';\nimport { isPathInsideDirectory, isWindowsDriveRelativePath, toPosixPath } from './path-utils.ts';\nimport { MIB } from './util.ts';\n\n/** `..` bounded on both sides by a separator, a brace delimiter, or the pattern edge. */\nconst TRAVERSAL_DOTDOT_RE = /(?:^|[/\\\\{,])\\.\\.(?=[/\\\\},]|$)/u;\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 // Only a whole `..` — a path segment, or one alternative of a `{a,..}`\n // brace set — can traverse. `..` inside a segment (`[...slug]`, `v1..2.md`,\n // `[..]`) is a literal name or a character class, and PathGuard re-checks\n // containment on every resolved entry regardless.\n if (TRAVERSAL_DOTDOT_RE.test(pattern)) {\n return false;\n }\n return true;\n}\n\n/** A .gitignore past this size is not a .gitignore; skip it rather than read it. */\nconst MAX_GITIGNORE_BYTES = MIB;\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 // lstat, not stat: a symlinked .gitignore may point at a device, a\n // FIFO or a huge file outside the root. Only a plain, small file is a\n // rule set worth reading.\n const info = await lstat(absPath);\n if (!info.isFile() || info.size > MAX_GITIGNORE_BYTES) return;\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\n/**\n * Load `.gitignore` from each ancestor of `root` up to and including `ceiling`,\n * farthest first. A rule set that ignores `root` itself is skipped: the caller\n * named that directory on purpose, and applying the rule would empty the walk.\n */\nasync function loadAncestorGitignores(\n root: string,\n ceiling: string,\n manager: GitignoreManager,\n signal?: AbortSignal,\n): Promise<void> {\n const normalizedCeiling = resolve(ceiling);\n const chain: string[] = [];\n for (let dir = dirname(resolve(root)); ; dir = dirname(dir)) {\n if (!isPathInsideDirectory(normalizedCeiling, dir)) break;\n chain.push(dir);\n if (\n (isPathInsideDirectory(dir, normalizedCeiling) &&\n isPathInsideDirectory(normalizedCeiling, dir)) ||\n dirname(dir) === dir\n ) {\n break;\n }\n }\n for (const dir of chain.reverse()) {\n signal?.throwIfAborted();\n const file = join(dir, '.gitignore');\n try {\n const info = await lstat(file);\n if (!info.isFile() || info.size > MAX_GITIGNORE_BYTES) continue;\n const matcher = ignore().add(await fsReadFile(file, { encoding: 'utf-8', signal }));\n const prefix = toPosixPath(relative(dir, root));\n if (matcher.test(`${prefix}/`).ignored) continue;\n manager.addAncestorMatcher(prefix, matcher);\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') throw error;\n // ENOENT is the normal case (no .gitignore at this level); anything else is not worth a warning per walk\n }\n }\n}\n\nclass GitignoreManager {\n private matchers = new Map<string, Ignore>();\n /** Rules from directories above the walk root, farthest first; `prefix` re-bases a walk-relative path to that directory. */\n private ancestors: { prefix: string; matcher: Ignore }[] = [];\n\n addMatcher(dir: string, matcher: Ignore): void {\n this.matchers.set(dir, matcher);\n }\n\n addAncestorMatcher(prefix: string, matcher: Ignore): void {\n this.ancestors.push({ prefix, matcher });\n }\n\n /** `null` when no `.gitignore` was found, so callers skip the filter entirely. */\n static async load(\n root: string,\n signal?: AbortSignal,\n maxDepth?: number,\n ignoreCeiling?: string,\n ): Promise<GitignoreManager | null> {\n const manager = new GitignoreManager();\n try {\n const gitignorePaths: string[] = [];\n const gitignoreEntries = fsGlob('**/.gitignore', {\n cwd: root,\n // Skip what the walk itself skips, and stop one level past its depth\n // bound: a .gitignore at depth d only affects entries at depth >= d.\n exclude: (entry: string) => {\n if (signal?.aborted) return true;\n const name = basename(entry);\n if (name === '.hg' || name === '.svn' || DEFAULT_EXCLUDED_NAMES.has(name)) return true;\n return maxDepth !== undefined && toPosixPath(entry).split('/').length - 1 > maxDepth;\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 if (ignoreCeiling !== undefined) {\n await loadAncestorGitignores(root, ignoreCeiling, manager, signal);\n }\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.matchers.size === 0 && manager.ancestors.length === 0 ? null : manager;\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 for (const { prefix, matcher } of this.ancestors) {\n const res = matcher.test(`${prefix}/${pathToCheck}`);\n if (res.ignored) ignored = true;\n if (res.unignored) ignored = false;\n }\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\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 includeHidden?: boolean;\n baseNameMatch?: boolean;\n maxDepth?: number;\n onlyFiles?: boolean;\n suppressErrors?: boolean;\n /** Skip what a walk should not surface: DEFAULT_EXCLUDED_NAMES and .gitignore. */\n skipIgnored?: boolean;\n /**\n * Topmost directory whose `.gitignore` may apply to this walk — the allowed\n * root containing `cwd`. Ancestors of `cwd` up to and including it are\n * consulted; nothing above it is ever read. Ignored without `skipIgnored`.\n */\n ignoreCeiling?: string;\n /** Bounds the `.gitignore` discovery `skipIgnored` runs before the walk. */\n signal?: AbortSignal;\n}\n\ninterface NormalizedGlob {\n cwd: string;\n patterns: readonly string[];\n suppressErrors: boolean;\n maxDepth?: number;\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 suppressErrors: options.suppressErrors ?? false,\n };\n\n if (options.maxDepth !== undefined) {\n normalized.maxDepth = options.maxDepth;\n }\n\n return normalized;\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 absolutePath = resolve(cwd, match.parentPath, match.name);\n\n if (maxDepth !== undefined) {\n const rel = relative(cwd, absolutePath);\n if (rel.split(/[/\\\\]/u).length - 1 > 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\ninterface WalkFilter {\n /** Given to fs.glob: true stops descent into a directory. */\n prune: (match: GlobDirentLike) => boolean;\n /** Re-applied to yielded entries: the ignore rules only, never the depth bound. */\n isExcluded: (match: GlobDirentLike) => boolean;\n}\n\nfunction createWalkFilter(\n cwd: string,\n skipIgnored: boolean,\n gitignoreMatcher: GitignoreManager | null,\n maxDepth: number | undefined,\n signal: AbortSignal | undefined,\n): WalkFilter | undefined {\n if (!skipIgnored && maxDepth === undefined && signal === undefined) return undefined;\n\n // fs.glob can hand the predicate a dirent whose parentPath is \".\" — the walk\n // root, not the process cwd — when it re-visits a directory under `**` whose\n // name also exists in the process cwd. Resolving against `cwd` names the\n // entry the dirent describes; `join` would resolve it against the process.\n const relativeOf = (match: GlobDirentLike): string =>\n toPosixPath(relative(cwd, resolve(cwd, match.parentPath, match.name)));\n // Every default exclude is a bare name that applies at any depth, so a Set\n // lookup per segment replaces compiling dozens of globs per entry.\n const excluded = (posixRel: string, isDir: boolean): boolean =>\n skipIgnored &&\n (posixRel.split('/').some((segment) => DEFAULT_EXCLUDED_NAMES.has(segment)) ||\n (gitignoreMatcher?.isIgnored(posixRel, isDir) ?? false));\n\n return {\n prune: (match) => {\n // fs.glob takes no signal and calls this for every entry it visits, so\n // pruning everything is the only way to stop a walk that yields nothing.\n if (signal?.aborted) return true;\n const posixRel = relativeOf(match);\n const isDir = match.isDirectory();\n if (excluded(posixRel, isDir)) return true;\n // Stop descent one level past the depth bound. Pruning a directory *at*\n // the bound would drop it where fs.glob treats it as top-level, so prune\n // its children instead; processDirentMatch drops that extra level.\n if (maxDepth === undefined || !isDir) return false;\n return posixRel.split('/').length - 1 > maxDepth;\n },\n isExcluded: (match) => excluded(relativeOf(match), match.isDirectory()),\n };\n}\n\nasync function* processGlobPattern(\n pattern: string,\n plan: NormalizedGlob,\n seen: Set<string>,\n onlyFiles: boolean,\n filter: WalkFilter | undefined,\n signal: AbortSignal | undefined,\n): AsyncGenerator<GlobEntry> {\n const { cwd, maxDepth, suppressErrors } = plan;\n let iterable: AsyncIterable<GlobDirentLike>;\n try {\n iterable = fsGlob(pattern, {\n cwd,\n ...(filter ? { exclude: filter.prune } : {}),\n withFileTypes: true,\n }) as AsyncIterable<GlobDirentLike>;\n } catch (error) {\n if (suppressErrors) return;\n throw error;\n }\n\n try {\n for await (const match of iterable) {\n if (signal?.aborted) break;\n // A function `exclude` only prunes descent in fs.glob — it still yields\n // the rejected dirent itself, and any rejected entry below the top level.\n // Re-apply the ignore rules (not the depth bound) to drop those.\n if (filter?.isExcluded(match)) continue;\n yield* processDirentMatch(match, 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 // A pruned walk ends like a finished one. Say it was cut short, so no caller\n // reads \"the walk ended\" as \"the whole tree was seen\".\n signal?.throwIfAborted();\n}\n\nexport async function* globEntries(options: GlobEntriesOptions): AsyncGenerator<GlobEntry> {\n const gitignoreMatcher = options.skipIgnored\n ? await GitignoreManager.load(\n options.cwd,\n options.signal,\n options.maxDepth,\n options.ignoreCeiling,\n )\n : null;\n\n const plan = normalizeGlobOptions(options);\n const seen = new Set<string>();\n const onlyFiles = options.onlyFiles ?? true;\n const filter = createWalkFilter(\n plan.cwd,\n options.skipIgnored ?? false,\n gitignoreMatcher,\n plan.maxDepth,\n options.signal,\n );\n\n for (const pattern of plan.patterns) {\n yield* processGlobPattern(pattern, plan, seen, onlyFiles, filter, options.signal);\n }\n}\n\n/** Names a `skipIgnored` walk never enters or yields, at any depth. */\nconst DEFAULT_EXCLUDED_NAMES: ReadonlySet<string> = new Set([\n 'node_modules',\n 'dist',\n 'build',\n 'coverage',\n '.git',\n '.vscode',\n '.idea',\n '.DS_Store',\n '.next',\n '.nuxt',\n '.output',\n '.svelte-kit',\n '.cache',\n '.yarn',\n 'jspm_packages',\n 'bower_components',\n 'out',\n 'tmp',\n '.temp',\n 'npm-debug.log',\n 'yarn-debug.log',\n 'yarn-error.log',\n 'Thumbs.db',\n]);\n"]}
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, lstat } from 'node:fs/promises';\nimport { basename, dirname, join, matchesGlob, relative, resolve, win32 } from 'node:path';\n\nimport type { Ignore } from 'ignore';\nimport ignore from 'ignore';\n\nimport { processInParallel } from './concurrency.ts';\nimport { formatUnknownErrorMessage } from './errors.ts';\nimport { Logger } from './observability.ts';\nimport type { DirentLike } from './path-utils.ts';\nimport { IS_WINDOWS, isPathInsideDirectory, toPosixPath } from './path-utils.ts';\nimport { MIB } from './util.ts';\n\n/**\n * More brace alternatives than this is not a file filter. fs.glob's matcher\n * dedupes its alternatives pairwise, synchronously: `{1..100000}` pins the\n * event loop for most of a minute, where 1024 costs tens of milliseconds.\n */\nexport const MAX_BRACE_ALTERNATIVES = 1024;\n\n/** Bound synchronous glob compilation when checking candidate traversal segments. */\nexport const MAX_DOTDOT_CHECK_CHARS = 4096;\n\n// The range bodies fs.glob's brace expansion recognises, as it writes them.\nconst NUMERIC_RANGE_RE = /^-?\\d+\\.\\.-?\\d+(?:\\.\\.-?\\d+)?$/u;\nconst ALPHA_RANGE_RE = /^[a-zA-Z]\\.\\.[a-zA-Z](?:\\.\\.-?\\d+)?$/u;\n\n/** The values a range body (`x..y`, `x..y..step`) expands to, or `undefined` past the cap. */\nfunction rangeValues(body: string): string[] | undefined {\n const alpha = ALPHA_RANGE_RE.test(body);\n const [from = '', to = '', step = '1'] = body.split('..');\n const bound = (end: string): number => (alpha ? end.charCodeAt(0) : Number.parseInt(end, 10));\n const start = bound(from);\n const stop = bound(to);\n const stride = Math.max(Math.abs(Number.parseInt(step, 10)), 1);\n // Past 2^53 a step no longer moves the number (2^53 + 1 === 2^53), and past\n // Number.MAX_VALUE it reads as Infinity: either way the loop below would\n // never end. Refuse them like any other long range.\n if (!Number.isSafeInteger(start) || !Number.isSafeInteger(stop)) return undefined;\n if (Math.floor(Math.abs(stop - start) / stride) >= MAX_BRACE_ALTERNATIVES) return undefined;\n const values: string[] = [];\n const direction = stop < start ? -1 : 1;\n for (let i = start; (stop - i) * direction >= 0; i += stride * direction) {\n // The engine drops a `\\` a letter range passes through (`{Z..a}`), and\n // digits can never spell a root or a `..`, so their padding is moot.\n const char = String.fromCharCode(i);\n values.push(alpha ? (char === '\\\\' ? '' : char) : String(i));\n }\n return values;\n}\n\ninterface BraceSet {\n pre: string;\n /** `undefined` when the set alone expands past the cap. */\n alternatives: string[] | undefined;\n post: string;\n}\n\n/**\n * The leftmost `{…}` that fs.glob would expand: a comma list or a range.\n * The expansion is textual, as fs.glob's is: a brace inside `[…]` still\n * counts (unlike SensitiveMatcher's own glob dialect in sensitive.ts).\n */\nfunction firstBraceSet(pattern: string): BraceSet | undefined {\n const open: { at: number; commas: number[] }[] = [];\n let first: { at: number; commas: number[]; close: number } | undefined;\n for (let i = 0; i < pattern.length; i++) {\n const char = pattern[i];\n if (char === '{') open.push({ at: i, commas: [] });\n else if (char === ',') open.at(-1)?.commas.push(i);\n else if (char === '}') {\n const set = open.pop();\n if (!set || (first && first.at < set.at)) continue;\n const body = pattern.slice(set.at + 1, i);\n if (set.commas.length > 0 || NUMERIC_RANGE_RE.test(body) || ALPHA_RANGE_RE.test(body)) {\n first = { ...set, close: i };\n }\n }\n }\n if (!first) return undefined;\n let alternatives: string[] | undefined;\n if (first.commas.length > 0) {\n alternatives = [];\n let start = first.at + 1;\n for (const end of [...first.commas, first.close]) {\n alternatives.push(pattern.slice(start, end));\n start = end + 1;\n }\n } else {\n alternatives = rangeValues(pattern.slice(first.at + 1, first.close));\n }\n return { pre: pattern.slice(0, first.at), alternatives, post: pattern.slice(first.close + 1) };\n}\n\n/** Every brace alternative of `pattern`, or `undefined` past the cap. */\nfunction expandBraceSets(pattern: string, out: string[] = []): string[] | undefined {\n const set = firstBraceSet(pattern);\n if (!set) {\n out.push(pattern);\n return out.length > MAX_BRACE_ALTERNATIVES ? undefined : out;\n }\n if (!set.alternatives) return undefined;\n for (const alternative of set.alternatives) {\n if (!expandBraceSets(`${set.pre}${alternative}${set.post}`, out)) return undefined;\n }\n return out;\n}\n\n/** The characters minimatch can spell a literal `..` with: dots and one-character classes. */\nconst DOTDOT_SPELLING_RE = /^[.[\\]-]+$/u;\n\n/**\n * Whether the glob engine reads this brace-free segment as `..`. readdir never\n * yields `..`, so only a literal reaches it, and minimatch spells a literal dot\n * as `.`, `[.]` or `[.-.]`. Any other character (`*`, `?`, an extglob, a\n * letter) either makes the segment a pattern the walk never follows to `..`,\n * or puts that character in the name. Only the rest is worth asking the engine\n * about, so a long or exotic segment costs no compile; one the engine cannot\n * compile is refused.\n */\nconst isTraversalSegment = (segment: string): boolean => {\n try {\n return matchesGlob('..', segment);\n } catch {\n return true;\n }\n};\n\n/**\n * An alternative that starts at a root: `/x`, `//host/share`, `C:/x`, `C:x`,\n * on any host. On Windows fs.glob also reads a literal first segment ending in\n * `:` as a drive (`[C]:/x`); elsewhere that is an ordinary name (`logs:`).\n */\nconst isRooted = (alternative: string): boolean =>\n win32.parse(alternative).root !== '' ||\n (IS_WINDOWS && (alternative.split('/')[0] ?? '').endsWith(':'));\n\nexport function isSafeGlobSyntax(pattern: string): boolean {\n if (!pattern || pattern.trim().length === 0) {\n return false;\n }\n // The walk sees the pattern with `\\` as `/` (normalizePattern), so check\n // that form: `\\etc\\x` is `/etc/x` there, an absolute walk on any host.\n // Brace sets can build a root or a `..` from parts (`{/etc,x}`, `..{,x}`,\n // `.{Z..a}.`), so check every alternative, not the pattern as written.\n // globEntries still drops any match outside its cwd: this check is what\n // turns such a pattern into an error rather than a quietly narrower walk.\n const alternatives = expandBraceSets(toPosixPath(pattern));\n if (!alternatives) return false;\n const segments = new Set<string>();\n for (const alternative of alternatives) {\n if (isRooted(alternative)) return false;\n for (const segment of alternative.split('/')) segments.add(segment);\n }\n let dotdotCheckChars = 0;\n for (const segment of segments) {\n if (!segment.includes('.') || !DOTDOT_SPELLING_RE.test(segment)) continue;\n dotdotCheckChars += segment.length;\n if (dotdotCheckChars > MAX_DOTDOT_CHECK_CHARS || isTraversalSegment(segment)) return false;\n }\n return true;\n}\n\n/** A .gitignore past this size is not a .gitignore; skip it rather than read it. */\nconst MAX_GITIGNORE_BYTES = MIB;\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 // lstat, not stat: a symlinked .gitignore may point at a device, a\n // FIFO or a huge file outside the root. Only a plain, small file is a\n // rule set worth reading.\n const info = await lstat(absPath);\n if (!info.isFile() || info.size > MAX_GITIGNORE_BYTES) return;\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\n/**\n * Load `.gitignore` from each ancestor of `root` up to and including `ceiling`,\n * farthest first. A rule set that ignores `root` itself is skipped: the caller\n * named that directory on purpose, and applying the rule would empty the walk.\n */\nasync function loadAncestorGitignores(\n root: string,\n ceiling: string,\n manager: GitignoreManager,\n signal?: AbortSignal,\n): Promise<void> {\n const normalizedCeiling = resolve(ceiling);\n const chain: string[] = [];\n for (let dir = dirname(resolve(root)); ; dir = dirname(dir)) {\n if (!isPathInsideDirectory(normalizedCeiling, dir)) break;\n chain.push(dir);\n if (\n (isPathInsideDirectory(dir, normalizedCeiling) &&\n isPathInsideDirectory(normalizedCeiling, dir)) ||\n dirname(dir) === dir\n ) {\n break;\n }\n }\n for (const dir of chain.reverse()) {\n signal?.throwIfAborted();\n const file = join(dir, '.gitignore');\n try {\n const info = await lstat(file);\n if (!info.isFile() || info.size > MAX_GITIGNORE_BYTES) continue;\n const matcher = ignore().add(await fsReadFile(file, { encoding: 'utf-8', signal }));\n const prefix = toPosixPath(relative(dir, root));\n if (matcher.test(`${prefix}/`).ignored) continue;\n manager.addAncestorMatcher(prefix, matcher);\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') throw error;\n // ENOENT is the normal case (no .gitignore at this level); anything else is not worth a warning per walk\n }\n }\n}\n\nclass GitignoreManager {\n private matchers = new Map<string, Ignore>();\n /** Rules from directories above the walk root, farthest first; `prefix` re-bases a walk-relative path to that directory. */\n private ancestors: { prefix: string; matcher: Ignore }[] = [];\n\n addMatcher(dir: string, matcher: Ignore): void {\n this.matchers.set(dir, matcher);\n }\n\n addAncestorMatcher(prefix: string, matcher: Ignore): void {\n this.ancestors.push({ prefix, matcher });\n }\n\n /** `null` when no `.gitignore` was found, so callers skip the filter entirely. */\n static async load(\n root: string,\n includeHidden: boolean,\n signal?: AbortSignal,\n maxDepth?: number,\n ignoreCeiling?: string,\n ): Promise<GitignoreManager | null> {\n const manager = new GitignoreManager();\n try {\n const gitignorePaths: string[] = [];\n // Search dot-directories (.venv, .terraform, ...) for rules only when the\n // walk includes hidden entries; for any other walk, enumerating every\n // hidden tree would cost more than the walk itself.\n const gitignorePatterns = includeHidden\n ? [...buildHiddenPatterns('**/.gitignore')]\n : ['**/.gitignore'];\n const gitignoreEntries = fsGlob(gitignorePatterns, {\n cwd: root,\n // Skip what the walk itself skips, and stop one level past its depth\n // bound: a .gitignore at depth d only affects entries at depth >= d.\n exclude: (entry: string) => {\n if (signal?.aborted) return true;\n const name = basename(entry);\n if (name === '.hg' || name === '.svn' || DEFAULT_EXCLUDED_NAMES.has(name)) return true;\n return maxDepth !== undefined && toPosixPath(entry).split('/').length - 1 > maxDepth;\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 if (ignoreCeiling !== undefined) {\n await loadAncestorGitignores(root, ignoreCeiling, manager, signal);\n }\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.matchers.size === 0 && manager.ancestors.length === 0 ? null : manager;\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 for (const { prefix, matcher } of this.ancestors) {\n const res = matcher.test(`${prefix}/${pathToCheck}`);\n if (res.ignored) ignored = true;\n if (res.unignored) ignored = false;\n }\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\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 includeHidden?: boolean;\n baseNameMatch?: boolean;\n maxDepth?: number;\n onlyFiles?: boolean;\n suppressErrors?: boolean;\n /** Skip what a walk should not surface: DEFAULT_EXCLUDED_NAMES and .gitignore. */\n skipIgnored?: boolean;\n /**\n * Topmost directory whose `.gitignore` may apply to this walk — the allowed\n * root containing `cwd`. Ancestors of `cwd` up to and including it are\n * consulted; nothing above it is ever read. Ignored without `skipIgnored`.\n */\n ignoreCeiling?: string;\n /** Bounds the `.gitignore` discovery `skipIgnored` runs before the walk. */\n signal?: AbortSignal;\n}\n\ninterface NormalizedGlob {\n cwd: string;\n patterns: readonly string[];\n suppressErrors: boolean;\n maxDepth?: number;\n}\n\nconst GLOB_MAGIC_RE = /[*?[\\]{}!]/u;\nconst GLOB_BATCH_CONCURRENCY = 64;\nconst SEP = '/';\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\n/**\n * The segment matching the dot-prefixed names `segment` would match if fs.glob\n * did not skip them, or `undefined` when there are none. Only a leading `*` or\n * `?` stands for that dot: a literal never does, and a character class or a\n * brace set is left as written rather than parsed.\n */\nfunction dotVariant(segment: string): string | undefined {\n // `*(…)` and `?(…)` are extglobs, not wildcards.\n if (segment[1] === '(') return undefined;\n if (segment.startsWith('*')) return `.${segment}`;\n if (!segment.startsWith('?')) return undefined;\n // `?` is exactly one character, so the dot replaces it, unless what follows\n // could leave just `.` or `..` (`?`, `?.`, `?{.,x}`, `?[.]`): the directory\n // and its parent, not a dot-prefixed entry.\n const rest = segment.slice(1);\n return rest === '' || /^[.[{]/u.test(rest) ? undefined : `.${rest}`;\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 const dotted = original ? dotVariant(original) : undefined;\n if (dotted) {\n const newSegments = [...segments];\n newSegments[idx] = dotted;\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 (when the first segment after the globstar can match a dot).\n patterns.add(`${prefix}**/.*/**/${afterGlobstar}`);\n const [firstSegment = '', ...rest] = afterGlobstar.split(SEP);\n const dotted = dotVariant(firstSegment);\n if (dotted) patterns.add(`${prefix}**/${[dotted, ...rest].join(SEP)}`);\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 suppressErrors: options.suppressErrors ?? false,\n };\n\n if (options.maxDepth !== undefined) {\n normalized.maxDepth = options.maxDepth;\n }\n\n return normalized;\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 absolutePath = resolve(cwd, match.parentPath, match.name);\n // The walk's scope is its cwd, whatever the pattern spells: a `..` or a root\n // the validator did not foresee must not reach a caller, where it would be\n // read, rewritten, or counted and named as inaccessible.\n if (!isPathInsideDirectory(cwd, absolutePath)) return;\n\n if (maxDepth !== undefined) {\n const rel = relative(cwd, absolutePath);\n if (rel.split(/[/\\\\]/u).length - 1 > 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\ninterface WalkFilter {\n /** Given to fs.glob: true stops descent into a directory. */\n prune: (match: GlobDirentLike) => boolean;\n /** Re-applied to yielded entries: the ignore rules only, never the depth bound. */\n isExcluded: (match: GlobDirentLike) => boolean;\n}\n\nfunction createWalkFilter(\n cwd: string,\n skipIgnored: boolean,\n gitignoreMatcher: GitignoreManager | null,\n maxDepth: number | undefined,\n signal: AbortSignal | undefined,\n): WalkFilter {\n // fs.glob can hand the predicate a dirent whose parentPath is \".\" — the walk\n // root, not the process cwd — when it re-visits a directory under `**` whose\n // name also exists in the process cwd. Resolving against `cwd` names the\n // entry the dirent describes; `join` would resolve it against the process.\n const absoluteOf = (match: GlobDirentLike): string => resolve(cwd, match.parentPath, match.name);\n const relativeOf = (match: GlobDirentLike): string =>\n toPosixPath(relative(cwd, absoluteOf(match)));\n // Every default exclude is a bare name that applies at any depth, so a Set\n // lookup per segment replaces compiling dozens of globs per entry.\n const excluded = (posixRel: string, isDir: boolean): boolean =>\n skipIgnored &&\n (posixRel.split('/').some((segment) => DEFAULT_EXCLUDED_NAMES.has(segment)) ||\n (gitignoreMatcher?.isIgnored(posixRel, isDir) ?? false));\n\n return {\n prune: (match) => {\n // fs.glob takes no signal and calls this for every entry it visits, so\n // pruning everything is the only way to stop a walk that yields nothing.\n if (signal?.aborted) return true;\n // fs.glob asks before it queues a directory, so a walk that would\n // climb to `../` or start at `/` stops at the edge instead of reading\n // there. Not every climb asks (`**/..` does not): processDirentMatch is\n // the gate, this only saves the walk.\n if (!isPathInsideDirectory(cwd, absoluteOf(match))) return true;\n const posixRel = relativeOf(match);\n const isDir = match.isDirectory();\n if (excluded(posixRel, isDir)) return true;\n // Stop descent one level past the depth bound. Pruning a directory *at*\n // the bound would drop it where fs.glob treats it as top-level, so prune\n // its children instead; processDirentMatch drops that extra level.\n if (maxDepth === undefined || !isDir) return false;\n return posixRel.split('/').length - 1 > maxDepth;\n },\n isExcluded: (match) => excluded(relativeOf(match), match.isDirectory()),\n };\n}\n\nasync function* processGlobPattern(\n pattern: string,\n plan: NormalizedGlob,\n seen: Set<string>,\n onlyFiles: boolean,\n filter: WalkFilter,\n signal: AbortSignal | undefined,\n): AsyncGenerator<GlobEntry> {\n const { cwd, maxDepth, suppressErrors } = plan;\n let iterable: AsyncIterable<GlobDirentLike>;\n try {\n iterable = fsGlob(pattern, {\n cwd,\n exclude: filter.prune,\n withFileTypes: true,\n }) as AsyncIterable<GlobDirentLike>;\n } catch (error) {\n if (suppressErrors) return;\n throw error;\n }\n\n try {\n for await (const match of iterable) {\n if (signal?.aborted) break;\n // A function `exclude` only prunes descent in fs.glob — it still yields\n // the rejected dirent itself, and any rejected entry below the top level.\n // Re-apply the ignore rules (not the depth bound) to drop those.\n if (filter.isExcluded(match)) continue;\n yield* processDirentMatch(match, 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 // A pruned walk ends like a finished one. Say it was cut short, so no caller\n // reads \"the walk ended\" as \"the whole tree was seen\".\n signal?.throwIfAborted();\n}\n\nexport async function* globEntries(options: GlobEntriesOptions): AsyncGenerator<GlobEntry> {\n const gitignoreMatcher = options.skipIgnored\n ? await GitignoreManager.load(\n options.cwd,\n options.includeHidden ?? false,\n options.signal,\n options.maxDepth,\n options.ignoreCeiling,\n )\n : null;\n\n const plan = normalizeGlobOptions(options);\n const seen = new Set<string>();\n const onlyFiles = options.onlyFiles ?? true;\n const filter = createWalkFilter(\n plan.cwd,\n options.skipIgnored ?? false,\n gitignoreMatcher,\n plan.maxDepth,\n options.signal,\n );\n\n for (const pattern of plan.patterns) {\n yield* processGlobPattern(pattern, plan, seen, onlyFiles, filter, options.signal);\n }\n}\n\n/** Names a `skipIgnored` walk never enters or yields, at any depth. */\nconst DEFAULT_EXCLUDED_NAMES: ReadonlySet<string> = new Set([\n 'node_modules',\n 'dist',\n 'build',\n 'coverage',\n '.git',\n '.vscode',\n '.idea',\n '.DS_Store',\n '.next',\n '.nuxt',\n '.output',\n '.svelte-kit',\n '.cache',\n '.yarn',\n 'jspm_packages',\n 'bower_components',\n 'out',\n 'tmp',\n '.temp',\n 'npm-debug.log',\n 'yarn-debug.log',\n 'yarn-error.log',\n 'Thumbs.db',\n]);\n"]}
@@ -1,6 +1,15 @@
1
1
  import type { ClientCapabilities, InputRequiredResult, RequestStateCodec, ServerContext } from '@modelcontextprotocol/server';
2
+ import type { FileType } from './fs.ts';
2
3
  /** The destructive operation a pending confirmation authorizes. */
3
4
  type PendingOp = 'delete' | 'move' | 'copy' | 'create' | 'grant';
5
+ /** The original filesystem object covered by a recursive-delete confirmation. */
6
+ export interface PendingDeleteIdentity {
7
+ readonly path: string;
8
+ readonly itemType: FileType;
9
+ readonly dev: number;
10
+ readonly ino: number;
11
+ readonly birthtimeMs: number;
12
+ }
4
13
  /**
5
14
  * Integrity-protected state minted into an `input_required` result and echoed
6
15
  * back by the client on retry. `paths` is the sorted canonical set of target
@@ -10,6 +19,8 @@ type PendingOp = 'delete' | 'move' | 'copy' | 'create' | 'grant';
10
19
  export interface PendingState {
11
20
  readonly op: PendingOp;
12
21
  readonly paths: readonly string[];
22
+ /** Original objects, preserved on reissue; legacy tokens without these cannot authorize delete. */
23
+ readonly deleteIdentities?: readonly PendingDeleteIdentity[];
13
24
  /**
14
25
  * Set on the state of a round minted because the previous round's answer
15
26
  * was dropped by the SDK (`droppedInputResponseKeys`). Sealed in the HMAC
@@ -81,6 +92,7 @@ export declare function buildInputRequired(pending: PendingState, inputs: readon
81
92
  interface PendingRoundTripOpts {
82
93
  readonly op: PendingOp;
83
94
  readonly pending: readonly string[];
95
+ readonly deleteIdentities?: readonly PendingDeleteIdentity[];
84
96
  readonly buildInputs: (pending: readonly string[]) => readonly PendingInput[];
85
97
  }
86
98
  export declare function pendingRoundTrip(ctx: PendingCtx, opts: PendingRoundTripOpts): Promise<InputRequiredResult | undefined>;
@@ -133,5 +145,12 @@ export declare function readAcceptedMultiChoice(responses: Record<string, unknow
133
145
  * rather than as 'not answered'.
134
146
  */
135
147
  export declare function describeRefusal(ctx: Pick<PendingCtx, 'inputResponses' | 'droppedInputResponseKeys'>, key: string): string;
148
+ /**
149
+ * How the caller answered one item of a sorted pending set: `'accepted'` for
150
+ * `acceptChoice`, `'skipped'` for skip, otherwise the refusal's wording.
151
+ */
152
+ export declare function readPendingVerdict(ctx: Pick<PendingCtx, 'inputResponses' | 'droppedInputResponseKeys'>, pendingSorted: readonly string[], item: string, acceptChoice: string): 'accepted' | 'skipped' | {
153
+ refused: string;
154
+ };
136
155
  export {};
137
156
  //# sourceMappingURL=input-required.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"input-required.d.ts","sourceRoot":"","sources":["../../src/core/input-required.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,kBAAkB,EAElB,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACd,MAAM,8BAA8B,CAAC;AAetC,mEAAmE;AACnE,KAAK,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC;CAC1B;AAED,+EAA+E;AAC/E,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,YAAY,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;IACrE;;;;OAIG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAC7D,2EAA2E;IAC3E,QAAQ,CAAC,wBAAwB,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAClE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC9D,2FAA2F;IAC3F,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;CACnC;AAED,kEAAkE;AAClE,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAiCD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,iBAAiB,CAAC,YAAY,CAI1D,CAAC;AA6BL;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,SAAS,YAAY,EAAE,EAC/B,GAAG,EAAE,aAAa,GACjB,OAAO,CAAC,mBAAmB,CAAC,CAiB9B;AAED;;;;;;;;;;;;;;GAcG;AACH,UAAU,oBAAoB;IAC5B,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,KAAK,SAAS,YAAY,EAAE,CAAC;CAC/E;AAiDD,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,UAAU,EACf,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAwC1C;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC9C,GAAG,EAAE,MAAM,GACV,OAAO,CAET;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC9C,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,SAAS,CAEpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC9C,GAAG,EAAE,MAAM,GACV,MAAM,EAAE,GAAG,SAAS,CAEtB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,gBAAgB,GAAG,0BAA0B,CAAC,EACpE,GAAG,EAAE,MAAM,GACV,MAAM,CASR"}
1
+ {"version":3,"file":"input-required.d.ts","sourceRoot":"","sources":["../../src/core/input-required.ts"],"names":[],"mappings":"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"}
@@ -83,6 +83,7 @@ export async function buildInputRequired(pending, inputs, ctx) {
83
83
  const requestState = await requestStateCodec.mint({
84
84
  op: pending.op,
85
85
  paths: [...pending.paths].sort(),
86
+ ...(pending.deleteIdentities ? { deleteIdentities: pending.deleteIdentities } : {}),
86
87
  ...(pending.reissued ? { reissued: true } : {}),
87
88
  }, ctx);
88
89
  return inputRequired({ inputRequests, requestState });
@@ -137,7 +138,11 @@ export async function pendingRoundTrip(ctx, opts) {
137
138
  // tamper/mismatch error.
138
139
  if (state?.op !== opts.op) {
139
140
  assertCanElicit(opts.op, ctx.clientCapabilities);
140
- return buildInputRequired({ op: opts.op, paths: opts.pending }, opts.buildInputs(opts.pending), ctx.serverCtx);
141
+ return buildInputRequired({
142
+ op: opts.op,
143
+ paths: opts.pending,
144
+ ...(opts.deleteIdentities ? { deleteIdentities: opts.deleteIdentities } : {}),
145
+ }, opts.buildInputs(opts.pending), ctx.serverCtx);
141
146
  }
142
147
  // Retry for THIS op (R9): the verified state must bind the same pending set.
143
148
  if (!pathsEqual(state.paths, opts.pending)) {
@@ -151,7 +156,7 @@ export async function pendingRoundTrip(ctx, opts) {
151
156
  const dropped = new Set(ctx.droppedInputResponseKeys);
152
157
  const inputs = opts.buildInputs(opts.pending);
153
158
  if (inputs.some((input) => dropped.has(input.key))) {
154
- return buildInputRequired({ op: opts.op, paths: opts.pending, reissued: true }, inputs, ctx.serverCtx);
159
+ return buildInputRequired({ ...state, reissued: true }, inputs, ctx.serverCtx);
155
160
  }
156
161
  }
157
162
  return undefined;
@@ -225,6 +230,19 @@ export function describeRefusal(ctx, key) {
225
230
  return 'dismissed by the user';
226
231
  return 'answered without a valid choice';
227
232
  }
233
+ /**
234
+ * How the caller answered one item of a sorted pending set: `'accepted'` for
235
+ * `acceptChoice`, `'skipped'` for skip, otherwise the refusal's wording.
236
+ */
237
+ export function readPendingVerdict(ctx, pendingSorted, item, acceptChoice) {
238
+ const key = confirmKey(pendingSorted.indexOf(item));
239
+ const choice = readAcceptedChoice(ctx.inputResponses, key);
240
+ if (choice === acceptChoice)
241
+ return 'accepted';
242
+ if (choice === 'skip')
243
+ return 'skipped';
244
+ return { refused: describeRefusal(ctx, key) };
245
+ }
228
246
  /**
229
247
  * Order-independent equality of two sorted, de-duplicated path lists. Used to
230
248
  * compare a recomputed pending set against the `requestState`-bound set (R9):