@j0hanz/filesystem-mcp 2.1.7 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/README.md +8 -9
  2. package/dist/cli.d.ts +1 -2
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +29 -34
  5. package/dist/cli.js.map +1 -1
  6. package/dist/core/concurrency.d.ts +4 -7
  7. package/dist/core/concurrency.d.ts.map +1 -1
  8. package/dist/core/concurrency.js +4 -12
  9. package/dist/core/concurrency.js.map +1 -1
  10. package/dist/core/cursor.d.ts +11 -0
  11. package/dist/core/cursor.d.ts.map +1 -1
  12. package/dist/core/cursor.js +18 -20
  13. package/dist/core/cursor.js.map +1 -1
  14. package/dist/core/fmt.d.ts +2 -1
  15. package/dist/core/fmt.d.ts.map +1 -1
  16. package/dist/core/fmt.js +8 -15
  17. package/dist/core/fmt.js.map +1 -1
  18. package/dist/core/fs.d.ts +0 -14
  19. package/dist/core/fs.d.ts.map +1 -1
  20. package/dist/core/fs.js +1 -0
  21. package/dist/core/fs.js.map +1 -1
  22. package/dist/core/glob.d.ts +4 -16
  23. package/dist/core/glob.d.ts.map +1 -1
  24. package/dist/core/glob.js +16 -33
  25. package/dist/core/glob.js.map +1 -1
  26. package/dist/core/input-required.d.ts +10 -2
  27. package/dist/core/input-required.d.ts.map +1 -1
  28. package/dist/core/input-required.js +10 -0
  29. package/dist/core/input-required.js.map +1 -1
  30. package/dist/core/observability.d.ts.map +1 -1
  31. package/dist/core/observability.js +2 -1
  32. package/dist/core/observability.js.map +1 -1
  33. package/dist/core/path-completer.d.ts.map +1 -1
  34. package/dist/core/path-completer.js +4 -27
  35. package/dist/core/path-completer.js.map +1 -1
  36. package/dist/core/path-utils.d.ts +1 -1
  37. package/dist/core/path-utils.d.ts.map +1 -1
  38. package/dist/core/path-utils.js +2 -2
  39. package/dist/core/path-utils.js.map +1 -1
  40. package/dist/core/path.d.ts +7 -9
  41. package/dist/core/path.d.ts.map +1 -1
  42. package/dist/core/path.js +24 -42
  43. package/dist/core/path.js.map +1 -1
  44. package/dist/core/primitives.d.ts +7 -0
  45. package/dist/core/primitives.d.ts.map +1 -1
  46. package/dist/core/primitives.js +15 -8
  47. package/dist/core/primitives.js.map +1 -1
  48. package/dist/core/read.d.ts.map +1 -1
  49. package/dist/core/read.js +6 -23
  50. package/dist/core/read.js.map +1 -1
  51. package/dist/core/schema.d.ts.map +1 -1
  52. package/dist/core/schema.js +19 -74
  53. package/dist/core/schema.js.map +1 -1
  54. package/dist/core/search.d.ts +4 -11
  55. package/dist/core/search.d.ts.map +1 -1
  56. package/dist/core/search.js +11 -18
  57. package/dist/core/search.js.map +1 -1
  58. package/dist/core/store.d.ts.map +1 -1
  59. package/dist/core/store.js +6 -17
  60. package/dist/core/store.js.map +1 -1
  61. package/dist/core/util.d.ts.map +1 -1
  62. package/dist/core/util.js +2 -11
  63. package/dist/core/util.js.map +1 -1
  64. package/dist/index.js +15 -42
  65. package/dist/index.js.map +1 -1
  66. package/dist/instructions.js +11 -11
  67. package/dist/instructions.js.map +1 -1
  68. package/dist/prompts.d.ts.map +1 -1
  69. package/dist/prompts.js +17 -25
  70. package/dist/prompts.js.map +1 -1
  71. package/dist/resources.d.ts +4 -4
  72. package/dist/resources.d.ts.map +1 -1
  73. package/dist/resources.js +7 -17
  74. package/dist/resources.js.map +1 -1
  75. package/dist/server.d.ts +1 -12
  76. package/dist/server.d.ts.map +1 -1
  77. package/dist/server.js +15 -30
  78. package/dist/server.js.map +1 -1
  79. package/dist/tools/define.d.ts.map +1 -1
  80. package/dist/tools/define.js +39 -65
  81. package/dist/tools/define.js.map +1 -1
  82. package/dist/tools/delete.d.ts +2 -0
  83. package/dist/tools/delete.d.ts.map +1 -0
  84. package/dist/tools/{delete-file.js → delete.js} +35 -40
  85. package/dist/tools/delete.js.map +1 -0
  86. package/dist/tools/find-files.d.ts +2 -0
  87. package/dist/tools/find-files.d.ts.map +1 -0
  88. package/dist/tools/{search-files.js → find-files.js} +14 -19
  89. package/dist/tools/find-files.js.map +1 -0
  90. package/dist/tools/index.d.ts +6 -6
  91. package/dist/tools/index.d.ts.map +1 -1
  92. package/dist/tools/index.js +15 -15
  93. package/dist/tools/index.js.map +1 -1
  94. package/dist/tools/list-roots.d.ts +2 -0
  95. package/dist/tools/list-roots.d.ts.map +1 -0
  96. package/dist/tools/{roots.js → list-roots.js} +2 -2
  97. package/dist/tools/list-roots.js.map +1 -0
  98. package/dist/tools/list.d.ts.map +1 -1
  99. package/dist/tools/list.js +29 -37
  100. package/dist/tools/list.js.map +1 -1
  101. package/dist/tools/move.d.ts.map +1 -1
  102. package/dist/tools/move.js +5 -7
  103. package/dist/tools/move.js.map +1 -1
  104. package/dist/tools/progress.d.ts +1 -1
  105. package/dist/tools/progress.d.ts.map +1 -1
  106. package/dist/tools/progress.js.map +1 -1
  107. package/dist/tools/read.d.ts +1 -1
  108. package/dist/tools/read.d.ts.map +1 -1
  109. package/dist/tools/read.js +37 -43
  110. package/dist/tools/read.js.map +1 -1
  111. package/dist/tools/replace-text.d.ts +2 -0
  112. package/dist/tools/replace-text.d.ts.map +1 -0
  113. package/dist/tools/{replace-in-files.js → replace-text.js} +9 -23
  114. package/dist/tools/replace-text.js.map +1 -0
  115. package/dist/tools/search-text.d.ts +2 -0
  116. package/dist/tools/search-text.d.ts.map +1 -0
  117. package/dist/tools/{search-content.js → search-text.js} +10 -37
  118. package/dist/tools/search-text.js.map +1 -0
  119. package/dist/tools/stat.d.ts +1 -1
  120. package/dist/tools/stat.d.ts.map +1 -1
  121. package/dist/tools/stat.js +10 -38
  122. package/dist/tools/stat.js.map +1 -1
  123. package/dist/transport/http-policy.d.ts +18 -15
  124. package/dist/transport/http-policy.d.ts.map +1 -1
  125. package/dist/transport/http-policy.js +29 -39
  126. package/dist/transport/http-policy.js.map +1 -1
  127. package/dist/transport/http.d.ts.map +1 -1
  128. package/dist/transport/http.js +29 -39
  129. package/dist/transport/http.js.map +1 -1
  130. package/package.json +4 -7
  131. package/dist/tools/delete-file.d.ts +0 -2
  132. package/dist/tools/delete-file.d.ts.map +0 -1
  133. package/dist/tools/delete-file.js.map +0 -1
  134. package/dist/tools/replace-in-files.d.ts +0 -2
  135. package/dist/tools/replace-in-files.d.ts.map +0 -1
  136. package/dist/tools/replace-in-files.js.map +0 -1
  137. package/dist/tools/roots.d.ts +0 -2
  138. package/dist/tools/roots.d.ts.map +0 -1
  139. package/dist/tools/roots.js.map +0 -1
  140. package/dist/tools/search-content.d.ts +0 -2
  141. package/dist/tools/search-content.d.ts.map +0 -1
  142. package/dist/tools/search-content.js.map +0 -1
  143. package/dist/tools/search-files.d.ts +0 -2
  144. package/dist/tools/search-files.d.ts.map +0 -1
  145. package/dist/tools/search-files.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"fmt.js","sourceRoot":"","sources":["../../src/core/fmt.ts"],"names":[],"mappings":"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","sourcesContent":["import { basename } from 'node:path';\nimport { stripVTControlCharacters, styleText } from 'node:util';\n\nimport { MAX_SEARCH_RESULTS } from './util.js';\n\nexport interface ProgressCtx {\n label: string;\n subject?: string;\n scope?: string;\n current?: number;\n total?: number;\n detail?: string;\n error?: string;\n}\n\nexport type Phase = 'tick' | 'done' | 'fail';\n\nfunction buildBody(ctx: ProgressCtx, phase: Phase): string {\n const items: string[] = [];\n if (ctx.subject) {\n items.push(ctx.subject);\n }\n\n switch (phase) {\n case 'tick':\n if (ctx.current !== undefined && ctx.total !== undefined) {\n items.push(`${ctx.current}/${ctx.total}`);\n } else if (ctx.current !== undefined) {\n items.push(String(ctx.current));\n }\n break;\n case 'done':\n if (ctx.scope) {\n items.push(ctx.scope);\n }\n if (ctx.detail) {\n items.push(ctx.detail);\n }\n break;\n case 'fail':\n if (ctx.error) {\n items.push(ctx.error);\n }\n break;\n }\n\n return items.join(' · ');\n}\n\nexport function plainMessage(phase: Phase, ctx: ProgressCtx): string {\n const body = buildBody(ctx, phase);\n return body ? `${ctx.label}: ${body}` : `${ctx.label}:`;\n}\n\nexport function formatCount(count: number, singular: string, plural = `${singular}s`): string {\n return `${String(count)} ${count === 1 ? singular : plural}`;\n}\n\n/**\n * Short label for a path in summary text. `basename` returns '' for a root\n * (`C:\\`, `/`) and for a trailing-slash path, which rendered as a bare\n * separator in the per-path summaries, so fall back to the full path.\n */\nexport function pathLabel(path: string): string {\n return basename(path) || path;\n}\n\n/** Names past this point are noise in a summary line; structuredContent holds them all. */\nconst MAX_ROSTER_ITEMS = 20;\n\n/**\n * Join a per-path summary roster, capped. A 1000-path delete would otherwise\n * name every entry in the text block that `structuredContent` already carries\n * in full.\n */\nexport function joinRoster(items: readonly string[], separator = ' · '): string {\n if (items.length <= MAX_ROSTER_ITEMS) return items.join(separator);\n const shown = items.slice(0, MAX_ROSTER_ITEMS).join(separator);\n return `${shown}${separator}+${String(items.length - MAX_ROSTER_ITEMS)} more`;\n}\n\nexport function truncateProgressPattern(pattern: string, maxLength = 40): string {\n return pattern.length <= maxLength ? pattern : `${pattern.slice(0, maxLength)}…`;\n}\n\n/**\n * `stoppedReason` names the engine's own cap, and `maxResults` is also the name\n * of the caller's page-size argument — spelling the cap out keeps a caller who\n * passed `maxResults: 5` from reading their own argument back.\n */\nconst STOP_REASON_TEXT: Record<string, string> = {\n maxResults: `hit the server's ${String(MAX_SEARCH_RESULTS)}-result scan cap, not your maxResults`,\n timeout: 'hit the time limit, or the request was cancelled',\n};\n\n/**\n * The `//` lines a paged search appends to its text block. Paging and the\n * engine's stop state live in the structured half, which `defineTool` ships\n * under `_meta` for a tool that authors its own text — and no client renders\n * that. These lines are the only place a caller learns that more remains or\n * that the scan was cut. They are independent: a scan can stop early with too\n * few results to page, so a truncation with no cursor must still say so.\n * Prefixed `//` so neither can be mistaken for a result row.\n */\nexport function pageTrailer(p: {\n offset: number;\n shown: number;\n total: number;\n noun: string;\n tool: string;\n nextCursor?: string | undefined;\n stoppedReason?: string | undefined;\n}): string {\n const lines: string[] = [];\n // Position is owed on every page of a split set, including the last one —\n // which has no cursor and would otherwise read as the whole answer.\n if (p.offset > 0 || p.total > p.shown) {\n const next =\n p.nextCursor === undefined\n ? ''\n : ` Next page: ${p.tool} ${JSON.stringify({ cursor: p.nextCursor })}`;\n lines.push(\n `// showing ${String(p.offset + 1)}-${String(p.offset + p.shown)} of ${String(p.total)} ${p.noun}.${next}`,\n );\n }\n if (p.stoppedReason !== undefined) {\n const cause = STOP_REASON_TEXT[p.stoppedReason] ?? `stopped (${p.stoppedReason})`;\n lines.push(\n `// scan stopped early: ${cause}. That total is a floor, not the count. Narrow path or pattern for the rest.`,\n );\n }\n return lines.length > 0 ? `\\n\\n${lines.join('\\n')}` : '';\n}\n\n// ---------------------------------------------------------------------------\n// CLI color helpers\n// ---------------------------------------------------------------------------\n\nfunction isColorEnabled(): boolean {\n return process.stdout.isTTY && !process.env['NO_COLOR'];\n}\n\nexport function padEndVisible(s: string, width: number): string {\n const visible = stripVTControlCharacters(s).length;\n return visible >= width ? s : s + ' '.repeat(width - visible);\n}\n\ntype Style = Parameters<typeof styleText>[0];\n\n/** Same palette as above, but only when stdout wants color. */\nfunction tint(format: Style, text: string): string {\n return isColorEnabled() ? styleText(format, text) : text;\n}\n\nexport const cliFmt = {\n bold: (t: string) => tint('bold', t),\n dim: (t: string) => tint('dim', t),\n cyan: (t: string) => tint('cyan', t),\n yellow: (t: string) => tint('yellow', t),\n flag: (t: string) => tint('green', t),\n placeholder: (t: string) => tint('yellow', t),\n section: (t: string) => tint(['cyan', 'bold'], t),\n bool: (v: boolean) => (v ? tint('green', 'true') : tint('red', 'false')),\n};\n"]}
1
+ {"version":3,"file":"fmt.js","sourceRoot":"","sources":["../../src/core/fmt.ts"],"names":[],"mappings":"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","sourcesContent":["import { basename } from 'node:path';\nimport { stripVTControlCharacters, styleText } from 'node:util';\n\nimport { MAX_SEARCH_RESULTS } from './util.js';\n\nexport interface ProgressCtx {\n label: string;\n subject?: string;\n scope?: string;\n current?: number;\n total?: number;\n detail?: string;\n error?: string;\n}\n\ntype Phase = 'tick' | 'done' | 'fail';\n\nfunction buildBody(ctx: ProgressCtx, phase: Phase): string {\n const items: string[] = [];\n if (ctx.subject) {\n items.push(ctx.subject);\n }\n\n switch (phase) {\n case 'tick':\n if (ctx.current !== undefined && ctx.total !== undefined) {\n items.push(`${ctx.current}/${ctx.total}`);\n } else if (ctx.current !== undefined) {\n items.push(String(ctx.current));\n }\n break;\n case 'done':\n if (ctx.scope) {\n items.push(ctx.scope);\n }\n if (ctx.detail) {\n items.push(ctx.detail);\n }\n break;\n case 'fail':\n if (ctx.error) {\n items.push(ctx.error);\n }\n break;\n }\n\n return items.join(' · ');\n}\n\nexport function plainMessage(phase: Phase, ctx: ProgressCtx): string {\n const body = buildBody(ctx, phase);\n return body ? `${ctx.label}: ${body}` : `${ctx.label}:`;\n}\n\nexport function formatCount(count: number, singular: string, plural = `${singular}s`): string {\n return `${String(count)} ${count === 1 ? singular : plural}`;\n}\n\n/**\n * Short label for a path in summary text. `basename` returns '' for a root\n * (`C:\\`, `/`) and for a trailing-slash path, which rendered as a bare\n * separator in the per-path summaries, so fall back to the full path.\n */\nexport function pathLabel(path: string): string {\n return basename(path) || path;\n}\n\n/** Names past this point are noise in a summary line; structuredContent holds them all. */\nconst MAX_ROSTER_ITEMS = 20;\n\n/**\n * Join a per-path summary roster, capped. A 1000-path delete would otherwise\n * name every entry in the text block that `structuredContent` already carries\n * in full.\n */\nexport function joinRoster(items: readonly string[], separator = ' · '): string {\n if (items.length <= MAX_ROSTER_ITEMS) return items.join(separator);\n const shown = items.slice(0, MAX_ROSTER_ITEMS).join(separator);\n return `${shown}${separator}+${String(items.length - MAX_ROSTER_ITEMS)} more`;\n}\n\nexport function truncateProgressPattern(pattern: string, maxLength = 40): string {\n return pattern.length <= maxLength ? pattern : `${pattern.slice(0, maxLength)}…`;\n}\n\n/**\n * `stoppedReason` names the engine's own cap, and `maxResults` is also the name\n * of the caller's page-size argument — spelling the cap out keeps a caller who\n * passed `maxResults: 5` from reading their own argument back.\n */\nconst STOP_REASON_TEXT: Record<string, string> = {\n maxResults: `hit the server's ${String(MAX_SEARCH_RESULTS)}-result scan cap, not your maxResults`,\n timeout: 'hit the time limit, or the request was cancelled',\n};\n\n/**\n * The `//` lines a paged search appends to its text block. Paging and the\n * engine's stop state live in the structured half, which `defineTool` ships\n * under `_meta` for a tool that authors its own text — and no client renders\n * that. These lines are the only place a caller learns that more remains or\n * that the scan was cut. They are independent: a scan can stop early with too\n * few results to page, so a truncation with no cursor must still say so.\n * Prefixed `//` so neither can be mistaken for a result row.\n */\nexport function pageTrailer(p: {\n offset: number;\n shown: number;\n total: number;\n noun: string;\n tool: string;\n nextCursor?: string | undefined;\n stoppedReason?: string | undefined;\n}): string {\n const lines: string[] = [];\n // Position is owed on every page of a split set, including the last one —\n // which has no cursor and would otherwise read as the whole answer.\n if (p.offset > 0 || p.total > p.shown) {\n const next =\n p.nextCursor === undefined\n ? ''\n : ` Next page: ${p.tool} ${JSON.stringify({ cursor: p.nextCursor })}`;\n lines.push(\n `// showing ${String(p.offset + 1)}-${String(p.offset + p.shown)} of ${String(p.total)} ${p.noun}.${next}`,\n );\n }\n if (p.stoppedReason !== undefined) {\n const cause = STOP_REASON_TEXT[p.stoppedReason] ?? `stopped (${p.stoppedReason})`;\n lines.push(\n `// scan stopped early: ${cause}. That total is a floor, not the count. Narrow path or pattern for the rest.`,\n );\n }\n return lines.length > 0 ? `\\n\\n${lines.join('\\n')}` : '';\n}\n\n// ---------------------------------------------------------------------------\n// CLI color helpers\n// ---------------------------------------------------------------------------\n\nexport function padEndVisible(s: string, width: number): string {\n const visible = stripVTControlCharacters(s).length;\n return visible >= width ? s : s + ' '.repeat(width - visible);\n}\n\nexport const cliFmt = {\n bold: (t: string) => styleText('bold', t),\n dim: (t: string) => styleText('dim', t),\n cyan: (t: string) => styleText('cyan', t),\n yellow: (t: string) => styleText('yellow', t),\n flag: (t: string) => styleText('green', t),\n placeholder: (t: string) => styleText('yellow', t),\n section: (t: string) => styleText(['cyan', 'bold'], t),\n bool: (v: boolean) => (v ? styleText('green', 'true') : styleText('red', 'false')),\n};\n"]}
package/dist/core/fs.d.ts CHANGED
@@ -7,20 +7,6 @@ import type { ReadFileResult, ReadSpec } from './read.js';
7
7
  export type { FileType };
8
8
  export type { Stats };
9
9
  export type { FileHandle };
10
- export interface FileInfo {
11
- readonly name: string;
12
- readonly path: string;
13
- readonly type: FileType;
14
- readonly size: number;
15
- readonly tokenEstimate?: number;
16
- readonly created: Date;
17
- readonly modified: Date;
18
- readonly accessed: Date;
19
- readonly permissions: string;
20
- readonly isHidden: boolean;
21
- readonly mimeType?: string;
22
- readonly symlinkTarget?: string;
23
- }
24
10
  export declare function isHidden(name: string): boolean;
25
11
  export declare class GuardedFileSystem {
26
12
  readonly pathGuard: PathGuard;
@@ -1 +1 @@
1
- {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/core/fs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/core/fs.ts"],"names":[],"mappings":"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"}
package/dist/core/fs.js CHANGED
@@ -7,6 +7,7 @@ import { detectMimeFromContent } from './mime.js';
7
7
  import { Logger } from './observability.js';
8
8
  import { assertFileStats, createTooLargeError, normalizeSpec, readFileWithStats, readNormalized, } from './read.js';
9
9
  import { getMaxTextFileSize } from './util.js';
10
+ // ─── Domain primitives ────────────────────────────────────────────────────────
10
11
  async function atomicWriteFile(filePath, content, pathGuard, options = {}) {
11
12
  const { encoding = 'utf-8', signal } = options;
12
13
  let validPath = await pathGuard.validatePathForWrite(filePath);
@@ -1 +1 @@
1
- {"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/core/fs.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from 'node:crypto';\nimport type { Stats } from 'node:fs';\nimport type { FileHandle } from 'node:fs/promises';\nimport {\n chmod as fsChmod,\n cp as fsCp,\n lstat as fsLstat,\n mkdir as fsMkdir,\n open as fsOpen,\n opendir as fsOpendir,\n readFile as fsReadFile,\n readlink as fsReadlink,\n rename as fsRename,\n rm as fsRm,\n rmdir as fsRmdir,\n stat as fsStat,\n unlink as fsUnlink,\n writeFile as fsWriteFile,\n} from 'node:fs/promises';\nimport { dirname, isAbsolute, resolve } from 'node:path';\n\nimport { withAbort } from './concurrency.js';\nimport { ErrorCode, formatUnknownErrorMessage, FsError, isFsError, isNodeError } from './errors.js';\nimport { detectMimeFromContent } from './mime.js';\nimport { Logger } from './observability.js';\nimport type { PathGuard } from './path.js';\nimport type { EntryType as FileType } from './primitives.js';\nimport type { ReadFileResult, ReadSpec } from './read.js';\nimport {\n assertFileStats,\n createTooLargeError,\n normalizeSpec,\n readFileWithStats,\n readNormalized,\n} from './read.js';\nimport { getMaxTextFileSize } from './util.js';\n\nexport type { FileType };\nexport type { Stats };\nexport type { FileHandle };\n\n// ─── Domain primitives ────────────────────────────────────────────────────────\n\nexport interface FileInfo {\n readonly name: string;\n readonly path: string;\n readonly type: FileType;\n readonly size: number;\n readonly tokenEstimate?: number;\n readonly created: Date;\n readonly modified: Date;\n readonly accessed: Date;\n readonly permissions: string;\n readonly isHidden: boolean;\n readonly mimeType?: string;\n readonly symlinkTarget?: string;\n}\n\nasync function atomicWriteFile(\n filePath: string,\n content: string,\n pathGuard: PathGuard,\n options: { encoding?: BufferEncoding; signal?: AbortSignal | undefined } = {},\n): Promise<{ validPath: string }> {\n const { encoding = 'utf-8', signal } = options;\n let validPath = await pathGuard.validatePathForWrite(filePath);\n\n try {\n const stats = await fsLstat(validPath);\n if (stats.isSymbolicLink()) {\n const target = await fsReadlink(validPath);\n const resolvedTarget = isAbsolute(target) ? target : resolve(dirname(validPath), target);\n validPath = await pathGuard.validatePathForWrite(resolvedTarget);\n }\n } catch (error) {\n if (!isNodeError(error) || error.code !== 'ENOENT') {\n throw error;\n }\n }\n\n const tempSuffix = randomUUID().replace(/-/g, '').slice(0, 12);\n const tempPath = `${validPath}.${tempSuffix}.tmp`;\n\n // The rename below swaps in the temp file's inode, so the target would\n // inherit fsWriteFile's default 0o666 & ~umask — silently widening a 0600\n // file to 0644 on every write. Carry the existing mode across instead.\n let existingMode: number | undefined;\n try {\n existingMode = (await fsStat(validPath)).mode & 0o777;\n } catch (error) {\n // ENOENT is the normal new-file case: the default mode is correct there.\n // Anything else (EACCES, EIO) means the mode about to be overwritten could\n // not be read, and the write will silently widen the file — say so rather\n // than swallowing it.\n if (!isNodeError(error) || error.code !== 'ENOENT') {\n Logger.warn(\n `atomicWriteFile: cannot read the existing mode of ${validPath}; the write will use the default mode: ${formatUnknownErrorMessage(error)}`,\n );\n }\n }\n\n try {\n signal?.throwIfAborted();\n await fsWriteFile(tempPath, content, { encoding, signal });\n if (existingMode !== undefined) {\n await fsChmod(tempPath, existingMode);\n }\n await withAbort(fsRename(tempPath, validPath), signal);\n } catch (error) {\n try {\n await fsUnlink(tempPath);\n } catch (cleanupError) {\n Logger.warn(\n `Failed to clean up temp file ${tempPath} after write error (${formatUnknownErrorMessage(error)}): ${formatUnknownErrorMessage(cleanupError)}`,\n );\n }\n throw error;\n }\n return { validPath };\n}\n\nexport function isHidden(name: string): boolean {\n return name.startsWith('.');\n}\n\nexport class GuardedFileSystem {\n readonly pathGuard: PathGuard;\n\n constructor(pathGuard: PathGuard) {\n this.pathGuard = pathGuard;\n }\n\n async stat(\n filePath: string,\n options?: { signal?: AbortSignal },\n ): Promise<{ stats: Stats; validPath: string }> {\n const validPath = await this.pathGuard.validateExistingPath(filePath);\n const stats = await withAbort(fsStat(validPath), options?.signal);\n return { stats, validPath };\n }\n\n async lstat(\n filePath: string,\n options?: { signal?: AbortSignal },\n ): Promise<{ stats: Stats; validPath: string }> {\n const validPath = await this.pathGuard.validatePathForDelete(filePath);\n const stats = await withAbort(fsLstat(validPath), options?.signal);\n return { stats, validPath };\n }\n\n async readlink(\n filePath: string,\n options?: Parameters<typeof fsReadlink>[1],\n ): Promise<{ linkString: string; validPath: string }> {\n // validateExistingPath resolves through the symlink, so readlink would always\n // be handed the final target — a regular file — and fail EINVAL. This guard\n // keeps the link itself while still enforcing containment and the denylist.\n const validPath = await this.pathGuard.validatePathForDelete(filePath);\n const raw = await fsReadlink(validPath, options);\n const linkString = Buffer.isBuffer(raw) ? raw.toString('utf-8') : raw;\n return { linkString, validPath };\n }\n\n async mkdir(\n filePath: string,\n options?: Parameters<typeof fsMkdir>[1],\n ): Promise<{ validPath: string; result: string | undefined }> {\n const validPath = await this.pathGuard.validatePathForWrite(filePath);\n const result = await fsMkdir(validPath, options);\n return { validPath, result };\n }\n\n async rename(oldPath: string, newPath: string): Promise<{ validOld: string; validNew: string }> {\n // Not validateExistingPath: that resolves through a symlink, so renaming a\n // link would rename its target and leave the link dangling.\n const validOld = await this.pathGuard.validatePathForDelete(oldPath);\n const validNew = await this.pathGuard.validatePathForWrite(newPath);\n await fsRename(validOld, validNew);\n return { validOld, validNew };\n }\n\n async writeFile(\n filePath: string,\n content: string,\n options: { encoding?: BufferEncoding; signal?: AbortSignal | undefined } = {},\n ): Promise<{ validPath: string }> {\n return atomicWriteFile(filePath, content, this.pathGuard, options);\n }\n\n async rm(filePath: string, options?: Parameters<typeof fsRm>[1]): Promise<{ validPath: string }> {\n const validPath = await this.pathGuard.validatePathForDelete(filePath);\n await fsRm(validPath, options);\n return { validPath };\n }\n\n async rmdir(\n filePath: string,\n options?: Parameters<typeof fsRmdir>[1],\n ): Promise<{ validPath: string }> {\n const validPath = await this.pathGuard.validatePathForDelete(filePath);\n await fsRmdir(validPath, options);\n return { validPath };\n }\n\n async cp(\n source: string,\n destination: string,\n options?: Parameters<typeof fsCp>[2],\n ): Promise<{ validSource: string; validDest: string }> {\n // As in rename: keep the link itself so callers passing verbatimSymlinks\n // actually copy the link rather than a dereferenced target.\n const validSource = await this.pathGuard.validatePathForDelete(source);\n const validDest = await this.pathGuard.validatePathForWrite(destination);\n await fsCp(validSource, validDest, options);\n return { validSource, validDest };\n }\n\n async readFile(filePath: string, spec: ReadSpec): Promise<ReadFileResult> {\n const normalized = normalizeSpec(spec);\n const validPath = await this.pathGuard.validateExistingPath(filePath);\n normalized.signal?.throwIfAborted();\n const stats = await withAbort(fsStat(validPath), normalized.signal);\n return readNormalized(filePath, validPath, stats, normalized);\n }\n\n async readEditableText(\n filePath: string,\n options?: { signal?: AbortSignal; tool?: string },\n ): Promise<{ validPath: string; content: string; stats: Stats }> {\n const { stats, validPath } = await this.stat(filePath, options);\n const maxSize = getMaxTextFileSize();\n if (stats.size > maxSize) {\n // `tool` labels the TOO_LARGE message so the client sees which tool refused.\n throw new FsError(\n ErrorCode.TOO_LARGE,\n `File too large for ${options?.tool ?? 'edit'} (${stats.size} bytes > ${maxSize} bytes)`,\n filePath,\n { size: stats.size, maxFileSize: maxSize },\n );\n }\n const { content } = await readFileWithStats(filePath, validPath, stats, {\n kind: 'full',\n ...(options?.signal ? { signal: options.signal } : {}),\n });\n return { validPath, content, stats };\n }\n\n async readRaw(\n filePath: string,\n options?: { signal?: AbortSignal },\n ): Promise<{ content: Buffer; mimeType: string; isBinary: boolean }> {\n const validPath = await this.pathGuard.validateExistingPath(filePath);\n const stats = await withAbort(fsStat(validPath), options?.signal);\n assertFileStats(filePath, stats);\n // Enforce size limit before reading to avoid loading large files into memory.\n // Binary detection is best-effort, but this is a hard limit.\n const maxTextFileSize = getMaxTextFileSize();\n if (stats.size > maxTextFileSize) {\n throw createTooLargeError(stats.size, maxTextFileSize, filePath);\n }\n const content = await withAbort(fsReadFile(validPath), options?.signal);\n const mimeInfo = detectMimeFromContent(validPath, content);\n return {\n content,\n mimeType: mimeInfo.mimeType,\n isBinary: mimeInfo.kind !== 'text',\n };\n }\n\n async open(filePath: string): Promise<FileHandle> {\n const validPath = await this.pathGuard.validateExistingPath(filePath);\n return fsOpen(validPath, 'r');\n }\n\n // Single resolution + stat: validateExistingPathDetailed resolves the real\n // path (following symlinks, re-checking sensitivity) once, then we stat the\n // resolved target. Replaces the tool-side validateExistingPathDetailed +\n // fs.stat pair that re-validated through the free stat() guard.\n async statDetailed(\n filePath: string,\n options?: { signal?: AbortSignal },\n ): Promise<{ requestedPath: string; isSymlink: boolean; stats: Stats }> {\n const { requestedPath, resolvedPath, isSymlink } =\n await this.pathGuard.validateExistingPathDetailed(filePath);\n const stats = await withAbort(fsStat(resolvedPath), options?.signal);\n return { requestedPath, isSymlink, stats };\n }\n\n async hasChildrenUnchecked(dirPath: string): Promise<boolean> {\n const dir = await fsOpendir(dirPath);\n try {\n const entry = await dir.read();\n return entry !== null;\n } finally {\n await dir.close().catch((closeErr: unknown) => {\n Logger.warn(\n `Failed to close dir handle for ${dirPath}: ${formatUnknownErrorMessage(closeErr)}`,\n );\n });\n }\n }\n}\n\n/**\n * Returns whether `path` exists, treating \"not found\" as absent and logging any\n * other stat failure. Used for TOCTOU re-checks between plan and execute phases.\n */\nexport async function destExists(\n fs: Pick<GuardedFileSystem, 'stat'>,\n path: string,\n label: string,\n): Promise<boolean> {\n try {\n await fs.stat(path);\n return true;\n } catch (err) {\n const missing =\n (isNodeError(err) && err.code === 'ENOENT') ||\n (isFsError(err) && err.code === ErrorCode.NOT_FOUND);\n if (!missing) {\n Logger.warn(`${label}: dest stat failed unexpectedly for \"${path}\": ${String(err)}`);\n }\n return false;\n }\n}\n"]}
1
+ {"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/core/fs.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from 'node:crypto';\nimport type { Stats } from 'node:fs';\nimport type { FileHandle } from 'node:fs/promises';\nimport {\n chmod as fsChmod,\n cp as fsCp,\n lstat as fsLstat,\n mkdir as fsMkdir,\n open as fsOpen,\n opendir as fsOpendir,\n readFile as fsReadFile,\n readlink as fsReadlink,\n rename as fsRename,\n rm as fsRm,\n rmdir as fsRmdir,\n stat as fsStat,\n unlink as fsUnlink,\n writeFile as fsWriteFile,\n} from 'node:fs/promises';\nimport { dirname, isAbsolute, resolve } from 'node:path';\n\nimport { withAbort } from './concurrency.js';\nimport { ErrorCode, formatUnknownErrorMessage, FsError, isFsError, isNodeError } from './errors.js';\nimport { detectMimeFromContent } from './mime.js';\nimport { Logger } from './observability.js';\nimport type { PathGuard } from './path.js';\nimport type { EntryType as FileType } from './primitives.js';\nimport type { ReadFileResult, ReadSpec } from './read.js';\nimport {\n assertFileStats,\n createTooLargeError,\n normalizeSpec,\n readFileWithStats,\n readNormalized,\n} from './read.js';\nimport { getMaxTextFileSize } from './util.js';\n\nexport type { FileType };\nexport type { Stats };\nexport type { FileHandle };\n\n// ─── Domain primitives ────────────────────────────────────────────────────────\n\nasync function atomicWriteFile(\n filePath: string,\n content: string,\n pathGuard: PathGuard,\n options: { encoding?: BufferEncoding; signal?: AbortSignal | undefined } = {},\n): Promise<{ validPath: string }> {\n const { encoding = 'utf-8', signal } = options;\n let validPath = await pathGuard.validatePathForWrite(filePath);\n\n try {\n const stats = await fsLstat(validPath);\n if (stats.isSymbolicLink()) {\n const target = await fsReadlink(validPath);\n const resolvedTarget = isAbsolute(target) ? target : resolve(dirname(validPath), target);\n validPath = await pathGuard.validatePathForWrite(resolvedTarget);\n }\n } catch (error) {\n if (!isNodeError(error) || error.code !== 'ENOENT') {\n throw error;\n }\n }\n\n const tempSuffix = randomUUID().replace(/-/g, '').slice(0, 12);\n const tempPath = `${validPath}.${tempSuffix}.tmp`;\n\n // The rename below swaps in the temp file's inode, so the target would\n // inherit fsWriteFile's default 0o666 & ~umask — silently widening a 0600\n // file to 0644 on every write. Carry the existing mode across instead.\n let existingMode: number | undefined;\n try {\n existingMode = (await fsStat(validPath)).mode & 0o777;\n } catch (error) {\n // ENOENT is the normal new-file case: the default mode is correct there.\n // Anything else (EACCES, EIO) means the mode about to be overwritten could\n // not be read, and the write will silently widen the file — say so rather\n // than swallowing it.\n if (!isNodeError(error) || error.code !== 'ENOENT') {\n Logger.warn(\n `atomicWriteFile: cannot read the existing mode of ${validPath}; the write will use the default mode: ${formatUnknownErrorMessage(error)}`,\n );\n }\n }\n\n try {\n signal?.throwIfAborted();\n await fsWriteFile(tempPath, content, { encoding, signal });\n if (existingMode !== undefined) {\n await fsChmod(tempPath, existingMode);\n }\n await withAbort(fsRename(tempPath, validPath), signal);\n } catch (error) {\n try {\n await fsUnlink(tempPath);\n } catch (cleanupError) {\n Logger.warn(\n `Failed to clean up temp file ${tempPath} after write error (${formatUnknownErrorMessage(error)}): ${formatUnknownErrorMessage(cleanupError)}`,\n );\n }\n throw error;\n }\n return { validPath };\n}\n\nexport function isHidden(name: string): boolean {\n return name.startsWith('.');\n}\n\nexport class GuardedFileSystem {\n readonly pathGuard: PathGuard;\n\n constructor(pathGuard: PathGuard) {\n this.pathGuard = pathGuard;\n }\n\n async stat(\n filePath: string,\n options?: { signal?: AbortSignal },\n ): Promise<{ stats: Stats; validPath: string }> {\n const validPath = await this.pathGuard.validateExistingPath(filePath);\n const stats = await withAbort(fsStat(validPath), options?.signal);\n return { stats, validPath };\n }\n\n async lstat(\n filePath: string,\n options?: { signal?: AbortSignal },\n ): Promise<{ stats: Stats; validPath: string }> {\n const validPath = await this.pathGuard.validatePathForDelete(filePath);\n const stats = await withAbort(fsLstat(validPath), options?.signal);\n return { stats, validPath };\n }\n\n async readlink(\n filePath: string,\n options?: Parameters<typeof fsReadlink>[1],\n ): Promise<{ linkString: string; validPath: string }> {\n // validateExistingPath resolves through the symlink, so readlink would always\n // be handed the final target — a regular file — and fail EINVAL. This guard\n // keeps the link itself while still enforcing containment and the denylist.\n const validPath = await this.pathGuard.validatePathForDelete(filePath);\n const raw = await fsReadlink(validPath, options);\n const linkString = Buffer.isBuffer(raw) ? raw.toString('utf-8') : raw;\n return { linkString, validPath };\n }\n\n async mkdir(\n filePath: string,\n options?: Parameters<typeof fsMkdir>[1],\n ): Promise<{ validPath: string; result: string | undefined }> {\n const validPath = await this.pathGuard.validatePathForWrite(filePath);\n const result = await fsMkdir(validPath, options);\n return { validPath, result };\n }\n\n async rename(oldPath: string, newPath: string): Promise<{ validOld: string; validNew: string }> {\n // Not validateExistingPath: that resolves through a symlink, so renaming a\n // link would rename its target and leave the link dangling.\n const validOld = await this.pathGuard.validatePathForDelete(oldPath);\n const validNew = await this.pathGuard.validatePathForWrite(newPath);\n await fsRename(validOld, validNew);\n return { validOld, validNew };\n }\n\n async writeFile(\n filePath: string,\n content: string,\n options: { encoding?: BufferEncoding; signal?: AbortSignal | undefined } = {},\n ): Promise<{ validPath: string }> {\n return atomicWriteFile(filePath, content, this.pathGuard, options);\n }\n\n async rm(filePath: string, options?: Parameters<typeof fsRm>[1]): Promise<{ validPath: string }> {\n const validPath = await this.pathGuard.validatePathForDelete(filePath);\n await fsRm(validPath, options);\n return { validPath };\n }\n\n async rmdir(\n filePath: string,\n options?: Parameters<typeof fsRmdir>[1],\n ): Promise<{ validPath: string }> {\n const validPath = await this.pathGuard.validatePathForDelete(filePath);\n await fsRmdir(validPath, options);\n return { validPath };\n }\n\n async cp(\n source: string,\n destination: string,\n options?: Parameters<typeof fsCp>[2],\n ): Promise<{ validSource: string; validDest: string }> {\n // As in rename: keep the link itself so callers passing verbatimSymlinks\n // actually copy the link rather than a dereferenced target.\n const validSource = await this.pathGuard.validatePathForDelete(source);\n const validDest = await this.pathGuard.validatePathForWrite(destination);\n await fsCp(validSource, validDest, options);\n return { validSource, validDest };\n }\n\n async readFile(filePath: string, spec: ReadSpec): Promise<ReadFileResult> {\n const normalized = normalizeSpec(spec);\n const validPath = await this.pathGuard.validateExistingPath(filePath);\n normalized.signal?.throwIfAborted();\n const stats = await withAbort(fsStat(validPath), normalized.signal);\n return readNormalized(filePath, validPath, stats, normalized);\n }\n\n async readEditableText(\n filePath: string,\n options?: { signal?: AbortSignal; tool?: string },\n ): Promise<{ validPath: string; content: string; stats: Stats }> {\n const { stats, validPath } = await this.stat(filePath, options);\n const maxSize = getMaxTextFileSize();\n if (stats.size > maxSize) {\n // `tool` labels the TOO_LARGE message so the client sees which tool refused.\n throw new FsError(\n ErrorCode.TOO_LARGE,\n `File too large for ${options?.tool ?? 'edit'} (${stats.size} bytes > ${maxSize} bytes)`,\n filePath,\n { size: stats.size, maxFileSize: maxSize },\n );\n }\n const { content } = await readFileWithStats(filePath, validPath, stats, {\n kind: 'full',\n ...(options?.signal ? { signal: options.signal } : {}),\n });\n return { validPath, content, stats };\n }\n\n async readRaw(\n filePath: string,\n options?: { signal?: AbortSignal },\n ): Promise<{ content: Buffer; mimeType: string; isBinary: boolean }> {\n const validPath = await this.pathGuard.validateExistingPath(filePath);\n const stats = await withAbort(fsStat(validPath), options?.signal);\n assertFileStats(filePath, stats);\n // Enforce size limit before reading to avoid loading large files into memory.\n // Binary detection is best-effort, but this is a hard limit.\n const maxTextFileSize = getMaxTextFileSize();\n if (stats.size > maxTextFileSize) {\n throw createTooLargeError(stats.size, maxTextFileSize, filePath);\n }\n const content = await withAbort(fsReadFile(validPath), options?.signal);\n const mimeInfo = detectMimeFromContent(validPath, content);\n return {\n content,\n mimeType: mimeInfo.mimeType,\n isBinary: mimeInfo.kind !== 'text',\n };\n }\n\n async open(filePath: string): Promise<FileHandle> {\n const validPath = await this.pathGuard.validateExistingPath(filePath);\n return fsOpen(validPath, 'r');\n }\n\n // Single resolution + stat: validateExistingPathDetailed resolves the real\n // path (following symlinks, re-checking sensitivity) once, then we stat the\n // resolved target. Replaces the tool-side validateExistingPathDetailed +\n // fs.stat pair that re-validated through the free stat() guard.\n async statDetailed(\n filePath: string,\n options?: { signal?: AbortSignal },\n ): Promise<{ requestedPath: string; isSymlink: boolean; stats: Stats }> {\n const { requestedPath, resolvedPath, isSymlink } =\n await this.pathGuard.validateExistingPathDetailed(filePath);\n const stats = await withAbort(fsStat(resolvedPath), options?.signal);\n return { requestedPath, isSymlink, stats };\n }\n\n async hasChildrenUnchecked(dirPath: string): Promise<boolean> {\n const dir = await fsOpendir(dirPath);\n try {\n const entry = await dir.read();\n return entry !== null;\n } finally {\n await dir.close().catch((closeErr: unknown) => {\n Logger.warn(\n `Failed to close dir handle for ${dirPath}: ${formatUnknownErrorMessage(closeErr)}`,\n );\n });\n }\n }\n}\n\n/**\n * Returns whether `path` exists, treating \"not found\" as absent and logging any\n * other stat failure. Used for TOCTOU re-checks between plan and execute phases.\n */\nexport async function destExists(\n fs: Pick<GuardedFileSystem, 'stat'>,\n path: string,\n label: string,\n): Promise<boolean> {\n try {\n await fs.stat(path);\n return true;\n } catch (err) {\n const missing =\n (isNodeError(err) && err.code === 'ENOENT') ||\n (isFsError(err) && err.code === ErrorCode.NOT_FOUND);\n if (!missing) {\n Logger.warn(`${label}: dest stat failed unexpectedly for \"${path}\": ${String(err)}`);\n }\n return false;\n }\n}\n"]}
@@ -1,20 +1,7 @@
1
- import type { Ignore } from 'ignore';
2
1
  import { type DirentLike } from './primitives.js';
3
2
  import type { EntryType } from './primitives.js';
4
3
  export type { EntryType };
5
4
  export declare function isSafeGlobSyntax(pattern: string): boolean;
6
- export declare class GitignoreManager {
7
- private matchers;
8
- addMatcher(dir: string, matcher: Ignore): void;
9
- static load(root: string, signal?: AbortSignal): Promise<GitignoreManager>;
10
- size(): number;
11
- isIgnored(relativePath: string, isDirectory: boolean): boolean;
12
- private checkPath;
13
- }
14
- export declare function loadRootGitignore(root: string, signal?: AbortSignal): Promise<GitignoreManager | null>;
15
- export declare function isIgnoredByGitignore(matcher: GitignoreManager, root: string, absolutePath: string, options?: {
16
- isDirectory?: boolean;
17
- }): boolean;
18
5
  export interface GlobEntry {
19
6
  path: string;
20
7
  dirent: DirentLike;
@@ -22,14 +9,15 @@ export interface GlobEntry {
22
9
  export interface GlobEntriesOptions {
23
10
  cwd: string;
24
11
  pattern: string;
25
- excludePatterns?: readonly string[];
26
12
  includeHidden?: boolean;
27
13
  baseNameMatch?: boolean;
28
14
  maxDepth?: number;
29
15
  onlyFiles?: boolean;
30
16
  suppressErrors?: boolean;
31
- respectGitignore?: boolean;
17
+ /** Skip what a walk should not surface: DEFAULT_EXCLUDE_PATTERNS and .gitignore. */
18
+ skipIgnored?: boolean;
19
+ /** Bounds the `.gitignore` discovery `skipIgnored` runs before the walk. */
20
+ signal?: AbortSignal;
32
21
  }
33
22
  export declare function globEntries(options: GlobEntriesOptions): AsyncGenerator<GlobEntry>;
34
- export declare const DEFAULT_EXCLUDE_PATTERNS: string[];
35
23
  //# sourceMappingURL=glob.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["../../src/core/glob.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAOrC,OAAO,EAAE,KAAK,UAAU,EAAe,MAAM,iBAAiB,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAsBzD;AA4BD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAA6B;IAE7C,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;WAIjC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA6BhF,IAAI,IAAI,MAAM;IAId,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO;IAqB9D,OAAO,CAAC,SAAS;CA2ClB;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAMlC;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,GACtC,OAAO,CAIT;AAOD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAkOD,wBAAuB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,cAAc,CAAC,SAAS,CAAC,CAczF;AAED,eAAO,MAAM,wBAAwB,UA0CpC,CAAC"}
1
+ {"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["../../src/core/glob.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,UAAU,EAAe,MAAM,iBAAiB,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAsBzD;AAsJD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,oFAAoF;IACpF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAkND,wBAAuB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,cAAc,CAAC,SAAS,CAAC,CAczF"}
package/dist/core/glob.js CHANGED
@@ -46,7 +46,7 @@ async function loadGitignoreFiles(root, gitignorePaths, manager, signal) {
46
46
  }
47
47
  }, GLOB_BATCH_CONCURRENCY, signal);
48
48
  }
49
- export class GitignoreManager {
49
+ class GitignoreManager {
50
50
  matchers = new Map();
51
51
  addMatcher(dir, matcher) {
52
52
  this.matchers.set(dir, matcher);
@@ -144,19 +144,13 @@ export class GitignoreManager {
144
144
  return ignored;
145
145
  }
146
146
  }
147
- export async function loadRootGitignore(root, signal) {
147
+ async function loadRootGitignore(root, signal) {
148
148
  const manager = await GitignoreManager.load(root, signal);
149
149
  if (manager.size() === 0) {
150
150
  return null;
151
151
  }
152
152
  return manager;
153
153
  }
154
- export function isIgnoredByGitignore(matcher, root, absolutePath, options = {}) {
155
- const relativePath = relative(root, absolutePath);
156
- if (relativePath.length === 0)
157
- return false;
158
- return matcher.isIgnored(relativePath, Boolean(options.isDirectory));
159
- }
160
154
  const GLOB_MAGIC_RE = /[*?[\]{}!]/u;
161
155
  const GLOB_BATCH_CONCURRENCY = 64;
162
156
  const SEP = '/';
@@ -236,28 +230,14 @@ function normalizeGlobOptions(options) {
236
230
  const normalized = {
237
231
  cwd,
238
232
  patterns,
239
- exclude: (options.excludePatterns ?? []).map(toPosixPath),
233
+ exclude: options.skipIgnored ? DEFAULT_EXCLUDE_PATTERNS.map(toPosixPath) : [],
240
234
  suppressErrors: options.suppressErrors ?? false,
241
- respectGitignore: options.respectGitignore ?? false,
242
235
  };
243
236
  if (options.maxDepth !== undefined) {
244
237
  normalized.maxDepth = options.maxDepth;
245
238
  }
246
239
  return normalized;
247
240
  }
248
- function getRelativeDepth(relativePath) {
249
- const len = relativePath.length;
250
- if (len === 0)
251
- return 0;
252
- let count = 0;
253
- for (let i = 0; i < len; i++) {
254
- const code = relativePath.charCodeAt(i);
255
- if (code === 47 || code === 92) {
256
- count++;
257
- }
258
- }
259
- return count;
260
- }
261
241
  function resolveDirentBase(cwd, parentPath) {
262
242
  if (!parentPath)
263
243
  return cwd;
@@ -268,7 +248,7 @@ function* processDirentMatch(match, cwd, maxDepth, seen, onlyFiles) {
268
248
  const absolutePath = resolve(base, match.name);
269
249
  if (maxDepth !== undefined) {
270
250
  const rel = relative(cwd, absolutePath);
271
- if (getRelativeDepth(rel) > maxDepth)
251
+ if (rel.split(/[/\\]/u).length - 1 > maxDepth)
272
252
  return;
273
253
  }
274
254
  if (seen.has(absolutePath))
@@ -283,14 +263,12 @@ function createExcludeFilter(cwd, excludePatterns, gitignoreMatcher) {
283
263
  return excludePatterns;
284
264
  }
285
265
  return (match) => {
286
- const relPath = typeof match === 'string'
287
- ? match
288
- : match.parentPath
289
- ? relative(cwd, join(match.parentPath, match.name))
290
- : match.name;
266
+ const relPath = match.parentPath
267
+ ? relative(cwd, join(match.parentPath, match.name))
268
+ : match.name;
291
269
  const posixRel = toPosixPath(relPath);
292
270
  // Gitignore check
293
- const isDir = typeof match === 'string' ? false : match.isDirectory();
271
+ const isDir = match.isDirectory();
294
272
  if (gitignoreMatcher.isIgnored(posixRel, isDir)) {
295
273
  return true;
296
274
  }
@@ -321,6 +299,11 @@ async function* processGlobPattern(pattern, plan, seen, onlyFiles, excludeFunc)
321
299
  }
322
300
  try {
323
301
  for await (const match of iterable) {
302
+ // A function `exclude` only prunes descent in fs.glob — it still yields
303
+ // the rejected dirent itself, and any rejected entry below the top level.
304
+ // An array `exclude` drops both. Re-apply the predicate so the two agree.
305
+ if (typeof excludeFunc === 'function' && excludeFunc(match))
306
+ continue;
324
307
  yield* processDirentMatch(match, cwd, maxDepth, seen, onlyFiles);
325
308
  }
326
309
  }
@@ -332,8 +315,8 @@ async function* processGlobPattern(pattern, plan, seen, onlyFiles, excludeFunc)
332
315
  }
333
316
  export async function* globEntries(options) {
334
317
  let gitignoreMatcher = null;
335
- if (options.respectGitignore) {
336
- gitignoreMatcher = await loadRootGitignore(options.cwd);
318
+ if (options.skipIgnored) {
319
+ gitignoreMatcher = await loadRootGitignore(options.cwd, options.signal);
337
320
  }
338
321
  const plan = normalizeGlobOptions(options);
339
322
  const seen = new Set();
@@ -343,7 +326,7 @@ export async function* globEntries(options) {
343
326
  yield* processGlobPattern(pattern, plan, seen, onlyFiles, excludeFunc);
344
327
  }
345
328
  }
346
- export const DEFAULT_EXCLUDE_PATTERNS = [
329
+ const DEFAULT_EXCLUDE_PATTERNS = [
347
330
  '**/node_modules',
348
331
  '**/node_modules/**',
349
332
  '**/dist',
@@ -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 } 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 { type DirentLike, toPosixPath } from './primitives.js';\nimport type { EntryType } from './primitives.js';\n\nexport type { EntryType };\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 } = {},\n): boolean {\n const 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"]}
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 { type DirentLike, toPosixPath } from './primitives.js';\nimport type { EntryType } from './primitives.js';\n\nexport type { EntryType };\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\nclass 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\nasync 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\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_EXCLUDE_PATTERNS and .gitignore. */\n skipIgnored?: boolean;\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 exclude: 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 exclude: options.skipIgnored ? DEFAULT_EXCLUDE_PATTERNS.map(toPosixPath) : [],\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 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 (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\nfunction createExcludeFilter(\n cwd: string,\n excludePatterns: readonly string[],\n gitignoreMatcher?: GitignoreManager | null,\n): ((match: GlobDirentLike) => boolean) | readonly string[] {\n if (!gitignoreMatcher) {\n return excludePatterns;\n }\n\n return (match: GlobDirentLike) => {\n const relPath = 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 = 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: GlobDirentLike) => boolean) | readonly string[],\n): AsyncGenerator<GlobEntry> {\n const { cwd, maxDepth, suppressErrors } = plan;\n let iterable: AsyncIterable<GlobDirentLike>;\n try {\n iterable = fsGlob(pattern, {\n cwd,\n exclude: excludeFunc,\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 // 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 // An array `exclude` drops both. Re-apply the predicate so the two agree.\n if (typeof excludeFunc === 'function' && excludeFunc(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}\n\nexport async function* globEntries(options: GlobEntriesOptions): AsyncGenerator<GlobEntry> {\n let gitignoreMatcher: GitignoreManager | null = null;\n if (options.skipIgnored) {\n gitignoreMatcher = await loadRootGitignore(options.cwd, options.signal);\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\nconst 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"]}
@@ -12,7 +12,7 @@ export interface PendingState {
12
12
  readonly paths: readonly string[];
13
13
  }
14
14
  /** One embedded form-mode confirmation, keyed within the call. */
15
- export interface PendingInput {
15
+ interface PendingInput {
16
16
  /** Server-assigned key, unique within the `tools/call`. */
17
17
  readonly key: string;
18
18
  /** Human-readable prompt for this item. */
@@ -78,7 +78,7 @@ export declare function buildInputRequired(pending: PendingState, inputs: readon
78
78
  * One home for the R9 binding check means a future fix cannot miss two of three
79
79
  * sites. The caller supplies `buildInputs` so only the prompt text varies.
80
80
  */
81
- export interface PendingRoundTripOpts {
81
+ interface PendingRoundTripOpts {
82
82
  readonly op: PendingOp;
83
83
  readonly pending: readonly string[];
84
84
  readonly requestState: (() => PendingState | undefined) | undefined;
@@ -91,6 +91,14 @@ export interface PendingRoundTripOpts {
91
91
  readonly buildInputs: (pending: readonly string[]) => readonly PendingInput[];
92
92
  }
93
93
  export declare function pendingRoundTrip(opts: PendingRoundTripOpts): Promise<InputRequiredResult | undefined>;
94
+ /**
95
+ * Round-trip key for `pendingSorted[index]` — the single home of the
96
+ * `confirm_${i}` convention. The build side mints it with the map index; the
97
+ * read side re-derives it from the same sorted pending set the requestState
98
+ * binds (R9), so a format change lands here once instead of at six call
99
+ * sites.
100
+ */
101
+ export declare function confirmKey(index: number): string;
94
102
  /**
95
103
  * Read one pending item's boolean confirmation from a retried request's
96
104
  * `inputResponses`. Returns `true` only when the client explicitly accepted AND
@@ -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,EAClB,MAAM,8BAA8B,CAAC;AActC,mEAAmE;AACnE,KAAK,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,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;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC/D;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAiCD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,iBAAiB,CAAC,YAAY,CAG7D,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,SAAS;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,GACnD,YAAY,CAEd;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,SAAS;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,GACnD,YAAY,CAOd;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,SAAS,YAAY,EAAE,GAC9B,OAAO,CAAC,mBAAmB,CAAC,CA4C9B;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAM,YAAY,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;IACpE;;;;OAIG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAC7D,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,KAAK,SAAS,YAAY,EAAE,CAAC;CAC/E;AAwCD,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAqB1C;AAUD;;;;;;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"}
1
+ {"version":3,"file":"input-required.d.ts","sourceRoot":"","sources":["../../src/core/input-required.ts"],"names":[],"mappings":"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"}
@@ -172,6 +172,16 @@ export async function pendingRoundTrip(opts) {
172
172
  const ConfirmContent = z.object({ confirm: z.boolean() });
173
173
  const ChoiceContent = z.object({ choice: z.string() });
174
174
  const MultiChoiceContent = z.object({ choice: z.array(z.string()) });
175
+ /**
176
+ * Round-trip key for `pendingSorted[index]` — the single home of the
177
+ * `confirm_${i}` convention. The build side mints it with the map index; the
178
+ * read side re-derives it from the same sorted pending set the requestState
179
+ * binds (R9), so a format change lands here once instead of at six call
180
+ * sites.
181
+ */
182
+ export function confirmKey(index) {
183
+ return `confirm_${index}`;
184
+ }
175
185
  /**
176
186
  * Read one pending item's boolean confirmation from a retried request's
177
187
  * `inputResponses`. Returns `true` only when the client explicitly accepted AND