@j0hanz/filesystem-mcp 1.19.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +333 -838
- package/dist/cli-help.d.ts +3 -0
- package/dist/cli-help.d.ts.map +1 -0
- package/dist/cli-help.js +169 -0
- package/dist/cli-help.js.map +1 -0
- package/dist/cli.d.ts +28 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +168 -123
- package/dist/cli.js.map +1 -0
- package/dist/core/concurrency.d.ts +70 -0
- package/dist/core/concurrency.d.ts.map +1 -0
- package/dist/core/concurrency.js +173 -0
- package/dist/core/concurrency.js.map +1 -0
- package/dist/core/config.d.ts +19 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +11 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/cursor.d.ts +23 -0
- package/dist/core/cursor.d.ts.map +1 -0
- package/dist/core/cursor.js +62 -0
- package/dist/core/cursor.js.map +1 -0
- package/dist/core/errors.d.ts +96 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +356 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/file-uri.d.ts +24 -0
- package/dist/core/file-uri.d.ts.map +1 -0
- package/dist/core/file-uri.js +52 -0
- package/dist/core/file-uri.js.map +1 -0
- package/dist/core/fmt.d.ts +38 -0
- package/dist/core/fmt.d.ts.map +1 -0
- package/dist/core/fmt.js +109 -0
- package/dist/core/fmt.js.map +1 -0
- package/dist/core/fs.d.ts +108 -0
- package/dist/core/fs.d.ts.map +1 -0
- package/dist/core/fs.js +243 -0
- package/dist/core/fs.js.map +1 -0
- package/dist/core/glob.d.ts +41 -0
- package/dist/core/glob.d.ts.map +1 -0
- package/dist/core/glob.js +399 -0
- package/dist/core/glob.js.map +1 -0
- package/dist/core/input-required.d.ts +147 -0
- package/dist/core/input-required.d.ts.map +1 -0
- package/dist/core/input-required.js +261 -0
- package/dist/core/input-required.js.map +1 -0
- package/dist/core/mime.d.ts +15 -0
- package/dist/core/mime.d.ts.map +1 -0
- package/dist/core/mime.js +188 -0
- package/dist/core/mime.js.map +1 -0
- package/dist/core/observability.d.ts +10 -0
- package/dist/core/observability.d.ts.map +1 -0
- package/dist/core/observability.js +76 -0
- package/dist/core/observability.js.map +1 -0
- package/dist/core/page-store.d.ts +41 -0
- package/dist/core/page-store.d.ts.map +1 -0
- package/dist/core/page-store.js +74 -0
- package/dist/core/page-store.js.map +1 -0
- package/dist/core/path-completer.d.ts +10 -0
- package/dist/core/path-completer.d.ts.map +1 -0
- package/dist/core/path-completer.js +227 -0
- package/dist/core/path-completer.js.map +1 -0
- package/dist/core/path-discovery.d.ts +8 -0
- package/dist/core/path-discovery.d.ts.map +1 -0
- package/dist/core/path-discovery.js +105 -0
- package/dist/core/path-discovery.js.map +1 -0
- package/dist/core/path-utils.d.ts +9 -0
- package/dist/core/path-utils.d.ts.map +1 -0
- package/dist/core/path-utils.js +121 -0
- package/dist/core/path-utils.js.map +1 -0
- package/dist/core/path.d.ts +148 -0
- package/dist/core/path.d.ts.map +1 -0
- package/dist/core/path.js +674 -0
- package/dist/core/path.js.map +1 -0
- package/dist/core/primitives.d.ts +23 -0
- package/dist/core/primitives.d.ts.map +1 -0
- package/dist/core/primitives.js +54 -0
- package/dist/core/primitives.js.map +1 -0
- package/dist/core/read.d.ts +74 -0
- package/dist/core/read.d.ts.map +1 -0
- package/dist/core/read.js +562 -0
- package/dist/core/read.js.map +1 -0
- package/dist/core/schema.d.ts +139 -0
- package/dist/core/schema.d.ts.map +1 -0
- package/dist/core/schema.js +345 -0
- package/dist/core/schema.js.map +1 -0
- package/dist/core/search.d.ts +100 -0
- package/dist/core/search.d.ts.map +1 -0
- package/dist/core/search.js +248 -0
- package/dist/core/search.js.map +1 -0
- package/dist/core/sensitive.d.ts +6 -0
- package/dist/core/sensitive.d.ts.map +1 -0
- package/dist/core/sensitive.js +142 -0
- package/dist/core/sensitive.js.map +1 -0
- package/dist/core/store.d.ts +57 -0
- package/dist/core/store.d.ts.map +1 -0
- package/dist/core/store.js +162 -0
- package/dist/core/store.js.map +1 -0
- package/dist/core/util.d.ts +26 -0
- package/dist/core/util.d.ts.map +1 -0
- package/dist/core/util.js +66 -0
- package/dist/core/util.js.map +1 -0
- package/dist/core/watcher-registry.d.ts +68 -0
- package/dist/core/watcher-registry.d.ts.map +1 -0
- package/dist/core/watcher-registry.js +312 -0
- package/dist/core/watcher-registry.js.map +1 -0
- package/dist/http-policy.d.ts +121 -0
- package/dist/http-policy.d.ts.map +1 -0
- package/dist/http-policy.js +340 -0
- package/dist/http-policy.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +77 -41
- package/dist/index.js.map +1 -0
- package/dist/instructions.d.ts +12 -0
- package/dist/instructions.d.ts.map +1 -0
- package/dist/instructions.js +71 -0
- package/dist/instructions.js.map +1 -0
- package/dist/prompts.d.ts +8 -6
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +74 -168
- package/dist/prompts.js.map +1 -0
- package/dist/resources.d.ts +73 -9
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +392 -163
- package/dist/resources.js.map +1 -0
- package/dist/server.d.ts +62 -1
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +139 -1
- package/dist/server.js.map +1 -0
- package/dist/tools/batch.d.ts +89 -0
- package/dist/tools/batch.d.ts.map +1 -0
- package/dist/tools/batch.js +157 -0
- package/dist/tools/batch.js.map +1 -0
- package/dist/tools/create.d.ts +2 -0
- package/dist/tools/create.d.ts.map +1 -0
- package/dist/tools/create.js +142 -0
- package/dist/tools/create.js.map +1 -0
- package/dist/tools/define.d.ts +110 -0
- package/dist/tools/define.d.ts.map +1 -0
- package/dist/tools/define.js +394 -0
- package/dist/tools/define.js.map +1 -0
- package/dist/tools/delete-file.d.ts +2 -4
- package/dist/tools/delete-file.d.ts.map +1 -0
- package/dist/tools/delete-file.js +330 -87
- package/dist/tools/delete-file.js.map +1 -0
- package/dist/tools/diff.d.ts +2 -0
- package/dist/tools/diff.d.ts.map +1 -0
- package/dist/tools/diff.js +94 -0
- package/dist/tools/diff.js.map +1 -0
- package/dist/tools/edit.d.ts +2 -0
- package/dist/tools/edit.d.ts.map +1 -0
- package/dist/tools/edit.js +442 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools/index.d.ts +26 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +52 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list.d.ts +2 -0
- package/dist/tools/list.d.ts.map +1 -0
- package/dist/tools/list.js +291 -0
- package/dist/tools/list.js.map +1 -0
- package/dist/tools/move.d.ts +2 -0
- package/dist/tools/move.d.ts.map +1 -0
- package/dist/tools/move.js +321 -0
- package/dist/tools/move.js.map +1 -0
- package/dist/tools/patch.d.ts +2 -0
- package/dist/tools/patch.d.ts.map +1 -0
- package/dist/tools/patch.js +155 -0
- package/dist/tools/patch.js.map +1 -0
- package/dist/tools/progress.d.ts +52 -0
- package/dist/tools/progress.d.ts.map +1 -0
- package/dist/tools/progress.js +172 -0
- package/dist/tools/progress.js.map +1 -0
- package/dist/tools/read.d.ts +2 -4
- package/dist/tools/read.d.ts.map +1 -0
- package/dist/tools/read.js +398 -152
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/replace-in-files.d.ts +2 -4
- package/dist/tools/replace-in-files.d.ts.map +1 -0
- package/dist/tools/replace-in-files.js +435 -264
- package/dist/tools/replace-in-files.js.map +1 -0
- package/dist/tools/roots.d.ts +2 -4
- package/dist/tools/roots.d.ts.map +1 -0
- package/dist/tools/roots.js +29 -52
- package/dist/tools/roots.js.map +1 -0
- package/dist/tools/search-content.d.ts +2 -4
- package/dist/tools/search-content.d.ts.map +1 -0
- package/dist/tools/search-content.js +262 -228
- package/dist/tools/search-content.js.map +1 -0
- package/dist/tools/search-files.d.ts +2 -4
- package/dist/tools/search-files.d.ts.map +1 -0
- package/dist/tools/search-files.js +162 -161
- package/dist/tools/search-files.js.map +1 -0
- package/dist/tools/stat.d.ts +2 -4
- package/dist/tools/stat.d.ts.map +1 -0
- package/dist/tools/stat.js +202 -62
- package/dist/tools/stat.js.map +1 -0
- package/dist/transport/http.d.ts +5 -0
- package/dist/transport/http.d.ts.map +1 -0
- package/dist/transport/http.js +276 -0
- package/dist/transport/http.js.map +1 -0
- package/dist/transport/shared.d.ts +45 -0
- package/dist/transport/shared.d.ts.map +1 -0
- package/dist/transport/shared.js +65 -0
- package/dist/transport/shared.js.map +1 -0
- package/dist/transport/stdio.d.ts +32 -0
- package/dist/transport/stdio.d.ts.map +1 -0
- package/dist/transport/stdio.js +279 -0
- package/dist/transport/stdio.js.map +1 -0
- package/dist/transport.d.ts +5 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +4 -0
- package/dist/transport.js.map +1 -0
- package/package.json +37 -46
- package/dist/assets/logo.svg +0 -35
- package/dist/completions.d.ts +0 -2
- package/dist/completions.js +0 -572
- package/dist/config.d.ts +0 -119
- package/dist/config.js +0 -31
- package/dist/lib/abort.d.ts +0 -7
- package/dist/lib/abort.js +0 -81
- package/dist/lib/constants.d.ts +0 -42
- package/dist/lib/constants.js +0 -313
- package/dist/lib/errors.d.ts +0 -28
- package/dist/lib/errors.js +0 -301
- package/dist/lib/file-operations/core.d.ts +0 -53
- package/dist/lib/file-operations/core.js +0 -144
- package/dist/lib/file-operations/metadata.d.ts +0 -77
- package/dist/lib/file-operations/metadata.js +0 -878
- package/dist/lib/file-operations/search.d.ts +0 -46
- package/dist/lib/file-operations/search.js +0 -1194
- package/dist/lib/file-operations/traversal.d.ts +0 -40
- package/dist/lib/file-operations/traversal.js +0 -310
- package/dist/lib/fs-helpers.d.ts +0 -46
- package/dist/lib/fs-helpers.js +0 -606
- package/dist/lib/globs.d.ts +0 -2
- package/dist/lib/globs.js +0 -19
- package/dist/lib/logger.d.ts +0 -27
- package/dist/lib/logger.js +0 -91
- package/dist/lib/observability.d.ts +0 -33
- package/dist/lib/observability.js +0 -373
- package/dist/lib/paths.d.ts +0 -35
- package/dist/lib/paths.js +0 -634
- package/dist/lib/resource-store.d.ts +0 -28
- package/dist/lib/resource-store.js +0 -195
- package/dist/lib/utils.d.ts +0 -7
- package/dist/lib/utils.js +0 -37
- package/dist/lib/zod-codecs.d.ts +0 -2
- package/dist/lib/zod-codecs.js +0 -18
- package/dist/pkg-info.d.ts +0 -7
- package/dist/pkg-info.js +0 -9
- package/dist/resources/generated-instructions.d.ts +0 -1
- package/dist/resources/generated-instructions.js +0 -105
- package/dist/resources/tool-catalog.d.ts +0 -2
- package/dist/resources/tool-catalog.js +0 -78
- package/dist/resources/tool-info.d.ts +0 -9
- package/dist/resources/tool-info.js +0 -206
- package/dist/resources/workflows.d.ts +0 -1
- package/dist/resources/workflows.js +0 -72
- package/dist/schemas.d.ts +0 -505
- package/dist/schemas.js +0 -676
- package/dist/server/bootstrap.d.ts +0 -6
- package/dist/server/bootstrap.js +0 -563
- package/dist/server/event-store.d.ts +0 -18
- package/dist/server/event-store.js +0 -71
- package/dist/server/roots-manager.d.ts +0 -28
- package/dist/server/roots-manager.js +0 -227
- package/dist/server/task-store.d.ts +0 -10
- package/dist/server/task-store.js +0 -91
- package/dist/tools/apply-patch.d.ts +0 -4
- package/dist/tools/apply-patch.js +0 -235
- package/dist/tools/calculate-hash.d.ts +0 -4
- package/dist/tools/calculate-hash.js +0 -187
- package/dist/tools/contract.d.ts +0 -50
- package/dist/tools/contract.js +0 -1
- package/dist/tools/create-directory.d.ts +0 -4
- package/dist/tools/create-directory.js +0 -68
- package/dist/tools/diff-files.d.ts +0 -4
- package/dist/tools/diff-files.js +0 -136
- package/dist/tools/edit-file.d.ts +0 -4
- package/dist/tools/edit-file.js +0 -256
- package/dist/tools/icons.d.ts +0 -15
- package/dist/tools/icons.js +0 -24
- package/dist/tools/list-directory.d.ts +0 -4
- package/dist/tools/list-directory.js +0 -218
- package/dist/tools/move-file.d.ts +0 -4
- package/dist/tools/move-file.js +0 -178
- package/dist/tools/read-multiple.d.ts +0 -4
- package/dist/tools/read-multiple.js +0 -207
- package/dist/tools/shared.d.ts +0 -172
- package/dist/tools/shared.js +0 -599
- package/dist/tools/stat-many.d.ts +0 -4
- package/dist/tools/stat-many.js +0 -104
- package/dist/tools/task-support.d.ts +0 -29
- package/dist/tools/task-support.js +0 -472
- package/dist/tools/tree.d.ts +0 -4
- package/dist/tools/tree.js +0 -102
- package/dist/tools/write-file.d.ts +0 -4
- package/dist/tools/write-file.js +0 -60
- package/dist/tools.d.ts +0 -5
- package/dist/tools.js +0 -54
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Stats } from 'node:fs';\nimport { stat } from 'node:fs/promises';\nimport { getSystemErrorMessage, getSystemErrorName, parseArgs as utilParseArgs } from 'node:util';\n\nimport { printHelpAndExit, printVersionAndExit } from './cli-help.js';\nimport { processInParallel } from './core/concurrency.js';\nimport { cli } from './core/config.js';\nimport { formatUnknownErrorMessage } from './core/errors.js';\nimport { cliFmt, padEndVisible } from './core/fmt.js';\nimport {\n getReservedDeviceNameForPath,\n isWindowsDriveRelativePath,\n normalizePath,\n} from './core/path-utils.js';\nimport { PathGuard } from './core/path.js';\nimport { IS_WINDOWS, isRecord, parseTrueEnvFlag } from './core/primitives.js';\nimport { getMaxTextFileSize } from './core/util.js';\nimport { registeredTools } from './tools/index.js';\n\nconst CLI_VALIDATE_CONCURRENCY = 8;\n\n// ════════════════════════════════════════════════════════════\n// Path & Config Utilities — pure functions and error types\n// ════════════════════════════════════════════════════════════\n\nexport class CliExitError extends Error {\n readonly exitCode: number;\n\n constructor(message: string, exitCode: number) {\n super(message);\n this.name = 'CliExitError';\n this.exitCode = exitCode;\n }\n}\n\nfunction validateCliPath(inputPath: string): void {\n if (inputPath.includes('\\0')) {\n throw new CliExitError('Path contains null bytes.', 1);\n }\n\n if (isWindowsDriveRelativePath(inputPath)) {\n throw new CliExitError(\n 'Windows drive-relative paths are not allowed. Use C:\\\\path or C:/path instead of C:path.',\n 1,\n );\n }\n\n const reserved = getReservedDeviceNameForPath(inputPath);\n if (reserved) {\n throw new CliExitError(`Windows reserved device name not allowed: ${reserved}.`, 1);\n }\n}\n\nfunction getSystemErrorDetails(error: unknown): {\n code: string | undefined;\n errno: number | undefined;\n} {\n if (!isRecord(error)) return { code: undefined, errno: undefined };\n const code = typeof error['code'] === 'string' ? error['code'] : undefined;\n const errno = typeof error['errno'] === 'number' ? error['errno'] : undefined;\n return { code, errno };\n}\n\nfunction normalizeDirectoryError(error: unknown, inputPath: string): Error {\n const { code, errno } = getSystemErrorDetails(error);\n if (error instanceof Error && code === undefined && errno === undefined) {\n return error;\n }\n\n if (typeof errno === 'number') {\n try {\n const name = getSystemErrorName(errno);\n const message = getSystemErrorMessage(errno);\n return new Error(`Cannot access directory ${inputPath} (${name}: ${message})`);\n } catch {\n // Fall through, but preserve raw errno value\n }\n return new Error(`Cannot access directory ${inputPath} (errno ${errno})`);\n }\n\n if (code) {\n return new Error(`Cannot access directory ${inputPath} (${code})`);\n }\n\n return new Error(`Cannot access directory ${inputPath}`);\n}\n\nfunction assertDirectory(stats: Stats, inputPath: string): void {\n if (stats.isDirectory()) return;\n throw new Error(`${inputPath} is not a directory`);\n}\n\nasync function validateDirectoryPath(inputPath: string, allowMissing = false): Promise<string> {\n const normalized = normalizePath(inputPath);\n\n try {\n const stats = await stat(normalized);\n assertDirectory(stats, inputPath);\n return normalized;\n } catch (error) {\n if (allowMissing) {\n if (error instanceof Error && error.message.includes('is not a directory')) {\n throw error;\n }\n return normalized;\n }\n throw normalizeDirectoryError(error, inputPath);\n }\n}\n\nasync function normalizeAndValidateDirs(\n paths: readonly string[],\n allowMissing = false,\n): Promise<string[]> {\n const { results, errors } = await processInParallel(\n [...paths],\n (p) => validateDirectoryPath(p, allowMissing),\n CLI_VALIDATE_CONCURRENCY,\n );\n if (errors.length === 0) {\n return deduplicateAllowedDirectories(results.map((r) => r.value));\n }\n const first = errors.reduce((prev, curr) => (curr.index < prev.index ? curr : prev));\n throw first.error;\n}\n\nfunction normalizeCliExitMessage(error: unknown): string {\n const rawMessage = formatUnknownErrorMessage(error);\n return rawMessage.startsWith('Error:') ? rawMessage : `Error: ${rawMessage}`;\n}\n\nfunction deduplicateAllowedDirectories(dirs: readonly string[]): string[] {\n const seen = new Set<string>();\n const deduplicated: string[] = [];\n\n for (const dir of dirs) {\n const key = IS_WINDOWS ? dir.toLowerCase() : dir;\n if (seen.has(key)) continue;\n seen.add(key);\n deduplicated.push(dir);\n }\n\n return deduplicated;\n}\n\nfunction parsePortOption(raw: unknown): number | undefined {\n // '' reads as unset: FS_PORT set-but-empty (compose templating) means stdio.\n if (raw === undefined || raw === '') return undefined;\n const n = Number(raw);\n if (!Number.isInteger(n) || n < 1 || n > 65535) {\n throw new CliExitError(`Error: --port / FS_PORT must be an integer between 1 and 65535`, 1);\n }\n return n;\n}\n\nconst CLI_PARSER_CONFIG = {\n options: {\n 'allow-cwd': { type: 'boolean', default: false },\n 'read-only': { type: 'boolean', default: false },\n safe: { type: 'boolean', default: false },\n 'print-config': { type: 'boolean', default: false },\n json: { type: 'boolean', default: false },\n port: { type: 'string' },\n help: { type: 'boolean', short: 'h' },\n version: { type: 'boolean', short: 'v' },\n 'log-level': { type: 'string' },\n 'http-host': { type: 'string' },\n 'api-key': { type: 'string' },\n 'allow-sensitive': { type: 'boolean', default: false },\n 'root-boundary': { type: 'string' },\n 'max-file-size': { type: 'string' },\n 'walk-cwd': { type: 'boolean', default: false },\n deny: { type: 'string', multiple: true },\n 'allow-missing-roots': { type: 'boolean', default: false },\n },\n strict: true,\n allowPositionals: true,\n} as const;\n\nexport async function parseArgs(): Promise<{\n allowedDirs: string[];\n allowCwd: boolean;\n port: number | undefined;\n readOnly: boolean;\n printConfig: boolean;\n json: boolean;\n httpHost: string | undefined;\n apiKey: string | undefined;\n}> {\n try {\n const parsed = utilParseArgs(CLI_PARSER_CONFIG);\n\n if (parsed.values.help) {\n printHelpAndExit();\n }\n\n if (parsed.values.version) {\n printVersionAndExit();\n }\n\n for (const positional of parsed.positionals) {\n validateCliPath(positional);\n }\n\n const vals = parsed.values as Record<string, unknown>;\n // `--http-host` and `--api-key` are returned to the caller and handed to\n // the server as config. Every other flag lands in the CLI-override store\n // (core/config.ts) — the one owner of the flag-beats-env rule — which deep\n // core readers (path, sensitive, observability, util) consult before\n // falling back to the operator's environment. Nothing writes process.env.\n const httpHost =\n typeof vals['http-host'] === 'string' ? vals['http-host'] : process.env['FS_HTTP_HOST'];\n const apiKey =\n typeof vals['api-key'] === 'string' ? vals['api-key'] : process.env['FS_API_KEY'];\n\n if (typeof vals['log-level'] === 'string') cli.logLevel = vals['log-level'];\n if (typeof vals['max-file-size'] === 'string') cli.maxFileSize = vals['max-file-size'];\n if (typeof vals['root-boundary'] === 'string') cli.rootBoundary = vals['root-boundary'];\n if (vals['allow-sensitive'] === true) cli.allowSensitive = true;\n if (vals['walk-cwd'] === true) cli.allowCwdWalk = true;\n if (vals['allow-missing-roots'] === true) cli.allowMissingRoots = true;\n if (Array.isArray(vals['deny'])) {\n const denyPatterns = vals['deny']\n .filter((entry): entry is string => typeof entry === 'string')\n .map((entry) => entry.trim())\n .filter(Boolean);\n if (denyPatterns.length > 0) cli.denyPatterns = [...new Set(denyPatterns)];\n }\n\n const allowCwd =\n (vals['allow-cwd'] as boolean) ||\n (vals['walk-cwd'] as boolean) ||\n parseTrueEnvFlag(process.env['FS_ALLOW_CWD_WALK'], 'FS_ALLOW_CWD_WALK');\n const readOnly = (vals['read-only'] as boolean) || (vals['safe'] as boolean);\n const printConfig = vals['print-config'] as boolean;\n const json = vals['json'] as boolean;\n const port = parsePortOption(parsed.values.port ?? process.env['FS_PORT']);\n const allowMissingRoots =\n (vals['allow-missing-roots'] as boolean) ||\n parseTrueEnvFlag(process.env['FS_ALLOW_MISSING_ROOTS'], 'FS_ALLOW_MISSING_ROOTS');\n\n let allowedDirs: string[] = [];\n try {\n allowedDirs =\n parsed.positionals.length > 0\n ? await normalizeAndValidateDirs(parsed.positionals, allowMissingRoots)\n : [];\n } catch (error: unknown) {\n throw new CliExitError(normalizeCliExitMessage(error), 1);\n }\n\n return {\n allowedDirs,\n allowCwd,\n port,\n readOnly,\n printConfig,\n json,\n httpHost,\n apiKey,\n };\n } catch (error: unknown) {\n if (error instanceof CliExitError) {\n throw error;\n }\n\n throw new CliExitError(normalizeCliExitMessage(error), 1);\n }\n}\n\n// ════════════════════════════════════════════════════════════\n// Effective config reporting — prints the resolved server config\n// ════════════════════════════════════════════════════════════\n\nexport interface EffectiveConfig {\n transport: string;\n readOnly: boolean;\n allowedRoots: string[];\n tools: string[];\n apiKey: string | null;\n limits: { maxFileSizeBytes: number };\n}\n\nexport interface PrintConfigOptions {\n allowedDirs: string[];\n allowCwd: boolean;\n readOnly: boolean;\n json: boolean;\n /** Resolved `--port`. Present means the launch this reports on is an HTTP bind. */\n port?: number;\n httpHost?: string;\n apiKey?: string;\n stdout?: (chunk: string) => void;\n}\n\nexport async function runPrintConfig(options: PrintConfigOptions): Promise<EffectiveConfig> {\n const write = options.stdout ?? ((s: string) => process.stdout.write(s));\n\n const pathGuard = new PathGuard({\n allowCwd: options.allowCwd,\n cliAllowedDirs: options.allowedDirs,\n });\n await pathGuard.recomputeAllowedDirectories();\n const allowedRoots = pathGuard.getAllowedDirectories();\n\n const tools = registeredTools(options.readOnly).map((t) => t.name);\n\n // Derived, never assumed: `--print-config --port 3000` reports the HTTP bind\n // that `--port` would actually have started, not the stdio default.\n const config: EffectiveConfig = {\n transport:\n options.port !== undefined\n ? `http://${options.httpHost ?? '127.0.0.1'}:${String(options.port)}`\n : 'stdio',\n readOnly: options.readOnly,\n allowedRoots,\n tools,\n apiKey: options.apiKey ? '***' : null,\n limits: { maxFileSizeBytes: getMaxTextFileSize() },\n };\n\n if (options.json) {\n write(JSON.stringify(config, null, 2));\n } else {\n const key = (k: string) => padEndVisible(cliFmt.cyan(k), 14);\n write(`${key('transport:')}${config.transport}\\n`);\n write(`${key('readOnly:')}${cliFmt.bool(config.readOnly)}\\n`);\n write(`${key('apiKey:')}${cliFmt.dim(config.apiKey ?? 'none')}\\n`);\n write(`${key('allowedRoots:')}${config.allowedRoots.join(', ') || cliFmt.dim('(none)')}\\n`);\n write(`${key('tools:')}${cliFmt.dim(config.tools.join(', '))}\\n`);\n write(`${key('maxFileSize:')}${cliFmt.yellow(String(config.limits.maxFileSizeBytes))}\\n`);\n }\n\n return config;\n}\n"]}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as z from 'zod/v4';
|
|
2
|
+
export type StoppedReason = 'maxResults' | 'maxFiles' | 'timeout';
|
|
3
|
+
export declare const StoppedReasonSchema: z.ZodOptional<z.ZodEnum<{
|
|
4
|
+
timeout: "timeout";
|
|
5
|
+
maxResults: "maxResults";
|
|
6
|
+
maxFiles: "maxFiles";
|
|
7
|
+
}>>;
|
|
8
|
+
/**
|
|
9
|
+
* The subset `search_text` and `find_files` can actually emit. Their scans call
|
|
10
|
+
* only `hitMaxResults` and `hitAbort` (search.ts), never `hitMaxFiles`, so the
|
|
11
|
+
* three-value enum published a value no response can carry and disagreed with
|
|
12
|
+
* both tools' own descriptions.
|
|
13
|
+
*/
|
|
14
|
+
export declare const SearchStoppedReasonSchema: z.ZodOptional<z.ZodEnum<{
|
|
15
|
+
timeout: "timeout";
|
|
16
|
+
maxResults: "maxResults";
|
|
17
|
+
}>>;
|
|
18
|
+
/**
|
|
19
|
+
* Accumulates why an enumeration stopped early. maxResults wins over maxFiles
|
|
20
|
+
* wins over timeout (the most specific cap is the definite cause even if the
|
|
21
|
+
* abort also fired on the same iteration). Call `resolve()` once at the end.
|
|
22
|
+
*/
|
|
23
|
+
export declare class StopReasonTracker {
|
|
24
|
+
#private;
|
|
25
|
+
hitMaxResults(): void;
|
|
26
|
+
hitMaxFiles(): void;
|
|
27
|
+
hitAbort(): void;
|
|
28
|
+
get truncated(): boolean;
|
|
29
|
+
resolve(): StoppedReason | undefined;
|
|
30
|
+
}
|
|
31
|
+
export interface ParallelResult<R> {
|
|
32
|
+
results: {
|
|
33
|
+
index: number;
|
|
34
|
+
value: R;
|
|
35
|
+
}[];
|
|
36
|
+
errors: {
|
|
37
|
+
index: number;
|
|
38
|
+
error: Error;
|
|
39
|
+
}[];
|
|
40
|
+
}
|
|
41
|
+
export declare function processInParallel<T, R>(items: readonly T[], processor: (item: T) => Promise<R>, concurrency?: number, signal?: AbortSignal): Promise<ParallelResult<R>>;
|
|
42
|
+
/**
|
|
43
|
+
* The streaming sibling of {@link processInParallel}: bounded-concurrency
|
|
44
|
+
* dispatch over an AsyncIterable that may be far larger than the caller wants
|
|
45
|
+
* to walk, so it stops early and reports why.
|
|
46
|
+
*
|
|
47
|
+
* `maxEntries` caps how many entries are dispatched (maxFiles); `shouldStop`
|
|
48
|
+
* lets the caller stop on its own accumulating result count (maxResults). Both
|
|
49
|
+
* are checked before dispatch, so the returned tracker names exactly one
|
|
50
|
+
* reason — the loop breaks on the first that fires.
|
|
51
|
+
*/
|
|
52
|
+
export declare function processEntriesConcurrently(entries: AsyncIterable<{
|
|
53
|
+
path: string;
|
|
54
|
+
}>, options: {
|
|
55
|
+
signal: AbortSignal | undefined;
|
|
56
|
+
concurrency: number;
|
|
57
|
+
maxEntries?: number;
|
|
58
|
+
shouldStop?: () => boolean;
|
|
59
|
+
onEntry: () => void;
|
|
60
|
+
onError?: (entryPath: string, err: unknown) => void;
|
|
61
|
+
runEntry: (entryPath: string) => Promise<void>;
|
|
62
|
+
}): Promise<StopReasonTracker>;
|
|
63
|
+
export declare function withAbort<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
64
|
+
/**
|
|
65
|
+
* `baseSignal` combined with a deadline. `AbortSignal.timeout`'s timer does not
|
|
66
|
+
* hold the event loop open and is collected with the signal, so there is
|
|
67
|
+
* nothing for callers to clean up.
|
|
68
|
+
*/
|
|
69
|
+
export declare function timedSignal(baseSignal: AbortSignal | undefined, timeoutMs: number): AbortSignal;
|
|
70
|
+
//# sourceMappingURL=concurrency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"concurrency.d.ts","sourceRoot":"","sources":["../../src/core/concurrency.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAK5B,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,UAAU,GAAG,SAAS,CAAC;AAElE,eAAO,MAAM,mBAAmB;;;;GAA2D,CAAC;AAE5F;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB;;;GAA+C,CAAC;AAEtF;;;;GAIG;AACH,qBAAa,iBAAiB;;IAG5B,aAAa,IAAI,IAAI;IAIrB,WAAW,IAAI,IAAI;IAInB,QAAQ,IAAI,IAAI;IAIhB,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,OAAO,IAAI,aAAa,GAAG,SAAS;CAGrC;AAED,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,CAAC,CAAA;KAAE,EAAE,CAAC;IACvC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,EAAE,CAAC;CAC3C;AAED,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAC1C,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EAClC,WAAW,GAAE,MAA6B,EAC1C,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAiD5B;AAED;;;;;;;;;GASG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,aAAa,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EACxC,OAAO,EAAE;IACP,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IACpD,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD,GACA,OAAO,CAAC,iBAAiB,CAAC,CA0D5B;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAmBlF;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,WAAW,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CAG/F"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import * as z from 'zod/v4';
|
|
2
|
+
import { normalizeUnknownError } from './errors.js';
|
|
3
|
+
import { PARALLEL_CONCURRENCY } from './util.js';
|
|
4
|
+
export const StoppedReasonSchema = z.enum(['maxResults', 'maxFiles', 'timeout']).optional();
|
|
5
|
+
/**
|
|
6
|
+
* The subset `search_text` and `find_files` can actually emit. Their scans call
|
|
7
|
+
* only `hitMaxResults` and `hitAbort` (search.ts), never `hitMaxFiles`, so the
|
|
8
|
+
* three-value enum published a value no response can carry and disagreed with
|
|
9
|
+
* both tools' own descriptions.
|
|
10
|
+
*/
|
|
11
|
+
export const SearchStoppedReasonSchema = z.enum(['maxResults', 'timeout']).optional();
|
|
12
|
+
/**
|
|
13
|
+
* Accumulates why an enumeration stopped early. maxResults wins over maxFiles
|
|
14
|
+
* wins over timeout (the most specific cap is the definite cause even if the
|
|
15
|
+
* abort also fired on the same iteration). Call `resolve()` once at the end.
|
|
16
|
+
*/
|
|
17
|
+
export class StopReasonTracker {
|
|
18
|
+
#reason;
|
|
19
|
+
hitMaxResults() {
|
|
20
|
+
this.#reason = 'maxResults';
|
|
21
|
+
}
|
|
22
|
+
hitMaxFiles() {
|
|
23
|
+
if (this.#reason !== 'maxResults')
|
|
24
|
+
this.#reason = 'maxFiles';
|
|
25
|
+
}
|
|
26
|
+
hitAbort() {
|
|
27
|
+
this.#reason ??= 'timeout';
|
|
28
|
+
}
|
|
29
|
+
get truncated() {
|
|
30
|
+
return this.#reason !== undefined;
|
|
31
|
+
}
|
|
32
|
+
resolve() {
|
|
33
|
+
return this.#reason;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export async function processInParallel(items, processor, concurrency = PARALLEL_CONCURRENCY, signal) {
|
|
37
|
+
const itemCount = items.length;
|
|
38
|
+
if (itemCount === 0)
|
|
39
|
+
return { results: [], errors: [] };
|
|
40
|
+
const results = [];
|
|
41
|
+
const errors = [];
|
|
42
|
+
signal?.throwIfAborted();
|
|
43
|
+
let nextIndex = 0;
|
|
44
|
+
const next = async () => {
|
|
45
|
+
while (nextIndex < itemCount) {
|
|
46
|
+
signal?.throwIfAborted();
|
|
47
|
+
const index = nextIndex;
|
|
48
|
+
nextIndex += 1;
|
|
49
|
+
const item = items[index];
|
|
50
|
+
if (item === undefined) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
const value = await processor(item);
|
|
55
|
+
signal?.throwIfAborted();
|
|
56
|
+
results.push({ index, value });
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
errors.push({
|
|
60
|
+
index,
|
|
61
|
+
error: normalizeUnknownError(error),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const workerCount = Math.min(itemCount, concurrency);
|
|
67
|
+
const workers = new Array(workerCount);
|
|
68
|
+
for (let index = 0; index < workerCount; index += 1) {
|
|
69
|
+
workers[index] = next();
|
|
70
|
+
}
|
|
71
|
+
await Promise.allSettled(workers);
|
|
72
|
+
// A deadline (timedSignal) hit during the run surfaces here as signal.reason
|
|
73
|
+
// — a TimeoutError — rather than a fresh AbortError, so callers see TIMEOUT,
|
|
74
|
+
// not CANCELLED. The per-item throws above are swallowed by allSettled.
|
|
75
|
+
signal?.throwIfAborted();
|
|
76
|
+
results.sort((left, right) => left.index - right.index);
|
|
77
|
+
return { results, errors };
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The streaming sibling of {@link processInParallel}: bounded-concurrency
|
|
81
|
+
* dispatch over an AsyncIterable that may be far larger than the caller wants
|
|
82
|
+
* to walk, so it stops early and reports why.
|
|
83
|
+
*
|
|
84
|
+
* `maxEntries` caps how many entries are dispatched (maxFiles); `shouldStop`
|
|
85
|
+
* lets the caller stop on its own accumulating result count (maxResults). Both
|
|
86
|
+
* are checked before dispatch, so the returned tracker names exactly one
|
|
87
|
+
* reason — the loop breaks on the first that fires.
|
|
88
|
+
*/
|
|
89
|
+
export async function processEntriesConcurrently(entries, options) {
|
|
90
|
+
const pending = new Set();
|
|
91
|
+
const { signal, concurrency, maxEntries, shouldStop, onEntry, onError, runEntry } = options;
|
|
92
|
+
const tracker = new StopReasonTracker();
|
|
93
|
+
let dispatched = 0;
|
|
94
|
+
const waitForSlot = async () => {
|
|
95
|
+
if (pending.size < concurrency)
|
|
96
|
+
return;
|
|
97
|
+
await Promise.race(pending);
|
|
98
|
+
};
|
|
99
|
+
for await (const entry of entries) {
|
|
100
|
+
// The signal is cancellation OR the caller's timeout: stop dispatching and
|
|
101
|
+
// let the caller report the run as incomplete rather than as a full sweep.
|
|
102
|
+
if (signal?.aborted) {
|
|
103
|
+
tracker.hitAbort();
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
if (maxEntries !== undefined && dispatched >= maxEntries) {
|
|
107
|
+
tracker.hitMaxFiles();
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
// Check the result cap before waiting for a slot so an in-flight task that
|
|
111
|
+
// already crossed the cap stops dispatch without an extra wait...
|
|
112
|
+
if (shouldStop?.()) {
|
|
113
|
+
tracker.hitMaxResults();
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
await waitForSlot();
|
|
117
|
+
// ...and again after the slot frees, since tasks settle concurrently. The
|
|
118
|
+
// cap can still be exceeded by at most `concurrency - 1` already-dispatched
|
|
119
|
+
// tasks that are mid-flight; that overrun is inherent to concurrent dispatch.
|
|
120
|
+
if (shouldStop?.()) {
|
|
121
|
+
tracker.hitMaxResults();
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
onEntry();
|
|
125
|
+
dispatched++;
|
|
126
|
+
// Track a non-rejecting wrapper so a rejected task can never propagate out of
|
|
127
|
+
// Promise.race(pending) in waitForSlot() and abort the loop before the final
|
|
128
|
+
// drain below (which would silently abandon other in-flight tasks).
|
|
129
|
+
// runEntry is expected to catch its own errors; if it unexpectedly throws,
|
|
130
|
+
// record it as a failure rather than silently dropping it.
|
|
131
|
+
const tracked = runEntry(entry.path).catch((err) => {
|
|
132
|
+
onError?.(entry.path, err);
|
|
133
|
+
});
|
|
134
|
+
pending.add(tracked);
|
|
135
|
+
void tracked.finally(() => {
|
|
136
|
+
pending.delete(tracked);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
if (pending.size > 0) {
|
|
140
|
+
await Promise.allSettled([...pending]);
|
|
141
|
+
}
|
|
142
|
+
return tracker;
|
|
143
|
+
}
|
|
144
|
+
export function withAbort(promise, signal) {
|
|
145
|
+
if (!signal) {
|
|
146
|
+
return promise;
|
|
147
|
+
}
|
|
148
|
+
signal.throwIfAborted();
|
|
149
|
+
let onAbort;
|
|
150
|
+
return Promise.race([
|
|
151
|
+
promise,
|
|
152
|
+
new Promise((_, reject) => {
|
|
153
|
+
onAbort = () => {
|
|
154
|
+
reject(signal.reason instanceof Error ? signal.reason : new Error('Operation aborted'));
|
|
155
|
+
};
|
|
156
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
157
|
+
}),
|
|
158
|
+
]).finally(() => {
|
|
159
|
+
if (onAbort) {
|
|
160
|
+
signal.removeEventListener('abort', onAbort);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* `baseSignal` combined with a deadline. `AbortSignal.timeout`'s timer does not
|
|
166
|
+
* hold the event loop open and is collected with the signal, so there is
|
|
167
|
+
* nothing for callers to clean up.
|
|
168
|
+
*/
|
|
169
|
+
export function timedSignal(baseSignal, timeoutMs) {
|
|
170
|
+
const deadline = AbortSignal.timeout(timeoutMs);
|
|
171
|
+
return baseSignal ? AbortSignal.any([baseSignal, deadline]) : deadline;
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=concurrency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"concurrency.js","sourceRoot":"","sources":["../../src/core/concurrency.ts"],"names":[],"mappings":"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","sourcesContent":["import * as z from 'zod/v4';\n\nimport { normalizeUnknownError } from './errors.js';\nimport { PARALLEL_CONCURRENCY } from './util.js';\n\nexport type StoppedReason = 'maxResults' | 'maxFiles' | 'timeout';\n\nexport const StoppedReasonSchema = z.enum(['maxResults', 'maxFiles', 'timeout']).optional();\n\n/**\n * The subset `search_text` and `find_files` can actually emit. Their scans call\n * only `hitMaxResults` and `hitAbort` (search.ts), never `hitMaxFiles`, so the\n * three-value enum published a value no response can carry and disagreed with\n * both tools' own descriptions.\n */\nexport const SearchStoppedReasonSchema = z.enum(['maxResults', 'timeout']).optional();\n\n/**\n * Accumulates why an enumeration stopped early. maxResults wins over maxFiles\n * wins over timeout (the most specific cap is the definite cause even if the\n * abort also fired on the same iteration). Call `resolve()` once at the end.\n */\nexport class StopReasonTracker {\n #reason?: StoppedReason;\n\n hitMaxResults(): void {\n this.#reason = 'maxResults';\n }\n\n hitMaxFiles(): void {\n if (this.#reason !== 'maxResults') this.#reason = 'maxFiles';\n }\n\n hitAbort(): void {\n this.#reason ??= 'timeout';\n }\n\n get truncated(): boolean {\n return this.#reason !== undefined;\n }\n\n resolve(): StoppedReason | undefined {\n return this.#reason;\n }\n}\n\nexport interface ParallelResult<R> {\n results: { index: number; value: R }[];\n errors: { index: number; error: Error }[];\n}\n\nexport async function processInParallel<T, R>(\n items: readonly T[],\n processor: (item: T) => Promise<R>,\n concurrency: number = PARALLEL_CONCURRENCY,\n signal?: AbortSignal,\n): Promise<ParallelResult<R>> {\n const itemCount = items.length;\n if (itemCount === 0) return { results: [], errors: [] };\n\n const results: { index: number; value: R }[] = [];\n const errors: { index: number; error: Error }[] = [];\n\n signal?.throwIfAborted();\n\n let nextIndex = 0;\n\n const next = async (): Promise<void> => {\n while (nextIndex < itemCount) {\n signal?.throwIfAborted();\n\n const index = nextIndex;\n nextIndex += 1;\n const item = items[index];\n if (item === undefined) {\n continue;\n }\n\n try {\n const value = await processor(item);\n signal?.throwIfAborted();\n results.push({ index, value });\n } catch (error) {\n errors.push({\n index,\n error: normalizeUnknownError(error),\n });\n }\n }\n };\n\n const workerCount = Math.min(itemCount, concurrency);\n const workers: Promise<void>[] = new Array<Promise<void>>(workerCount);\n for (let index = 0; index < workerCount; index += 1) {\n workers[index] = next();\n }\n\n await Promise.allSettled(workers);\n // A deadline (timedSignal) hit during the run surfaces here as signal.reason\n // — a TimeoutError — rather than a fresh AbortError, so callers see TIMEOUT,\n // not CANCELLED. The per-item throws above are swallowed by allSettled.\n signal?.throwIfAborted();\n\n results.sort((left, right) => left.index - right.index);\n return { results, errors };\n}\n\n/**\n * The streaming sibling of {@link processInParallel}: bounded-concurrency\n * dispatch over an AsyncIterable that may be far larger than the caller wants\n * to walk, so it stops early and reports why.\n *\n * `maxEntries` caps how many entries are dispatched (maxFiles); `shouldStop`\n * lets the caller stop on its own accumulating result count (maxResults). Both\n * are checked before dispatch, so the returned tracker names exactly one\n * reason — the loop breaks on the first that fires.\n */\nexport async function processEntriesConcurrently(\n entries: AsyncIterable<{ path: string }>,\n options: {\n signal: AbortSignal | undefined;\n concurrency: number;\n maxEntries?: number;\n shouldStop?: () => boolean;\n onEntry: () => void;\n onError?: (entryPath: string, err: unknown) => void;\n runEntry: (entryPath: string) => Promise<void>;\n },\n): Promise<StopReasonTracker> {\n const pending = new Set<Promise<void>>();\n const { signal, concurrency, maxEntries, shouldStop, onEntry, onError, runEntry } = options;\n const tracker = new StopReasonTracker();\n let dispatched = 0;\n\n const waitForSlot = async (): Promise<void> => {\n if (pending.size < concurrency) return;\n await Promise.race(pending);\n };\n\n for await (const entry of entries) {\n // The signal is cancellation OR the caller's timeout: stop dispatching and\n // let the caller report the run as incomplete rather than as a full sweep.\n if (signal?.aborted) {\n tracker.hitAbort();\n break;\n }\n if (maxEntries !== undefined && dispatched >= maxEntries) {\n tracker.hitMaxFiles();\n break;\n }\n // Check the result cap before waiting for a slot so an in-flight task that\n // already crossed the cap stops dispatch without an extra wait...\n if (shouldStop?.()) {\n tracker.hitMaxResults();\n break;\n }\n await waitForSlot();\n // ...and again after the slot frees, since tasks settle concurrently. The\n // cap can still be exceeded by at most `concurrency - 1` already-dispatched\n // tasks that are mid-flight; that overrun is inherent to concurrent dispatch.\n if (shouldStop?.()) {\n tracker.hitMaxResults();\n break;\n }\n onEntry();\n dispatched++;\n\n // Track a non-rejecting wrapper so a rejected task can never propagate out of\n // Promise.race(pending) in waitForSlot() and abort the loop before the final\n // drain below (which would silently abandon other in-flight tasks).\n // runEntry is expected to catch its own errors; if it unexpectedly throws,\n // record it as a failure rather than silently dropping it.\n const tracked = runEntry(entry.path).catch((err: unknown) => {\n onError?.(entry.path, err);\n });\n pending.add(tracked);\n void tracked.finally(() => {\n pending.delete(tracked);\n });\n }\n\n if (pending.size > 0) {\n await Promise.allSettled([...pending]);\n }\n\n return tracker;\n}\n\nexport function withAbort<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n if (!signal) {\n return promise;\n }\n signal.throwIfAborted();\n let onAbort: (() => void) | undefined;\n return Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n onAbort = () => {\n reject(signal.reason instanceof Error ? signal.reason : new Error('Operation aborted'));\n };\n signal.addEventListener('abort', onAbort, { once: true });\n }),\n ]).finally(() => {\n if (onAbort) {\n signal.removeEventListener('abort', onAbort);\n }\n });\n}\n\n/**\n * `baseSignal` combined with a deadline. `AbortSignal.timeout`'s timer does not\n * hold the event loop open and is collected with the signal, so there is\n * nothing for callers to clean up.\n */\nexport function timedSignal(baseSignal: AbortSignal | undefined, timeoutMs: number): AbortSignal {\n const deadline = AbortSignal.timeout(timeoutMs);\n return baseSignal ? AbortSignal.any([baseSignal, deadline]) : deadline;\n}\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface CliOverrides {
|
|
2
|
+
/** `--log-level` */
|
|
3
|
+
logLevel?: string;
|
|
4
|
+
/** `--max-file-size` (raw string; validated by the reader like the env var) */
|
|
5
|
+
maxFileSize?: string;
|
|
6
|
+
/** `--root-boundary` */
|
|
7
|
+
rootBoundary?: string;
|
|
8
|
+
/** `--allow-sensitive` */
|
|
9
|
+
allowSensitive?: boolean;
|
|
10
|
+
/** `--walk-cwd` */
|
|
11
|
+
allowCwdWalk?: boolean;
|
|
12
|
+
/** `--allow-missing-roots` */
|
|
13
|
+
allowMissingRoots?: boolean;
|
|
14
|
+
/** `--deny` entries (merged with DENYLIST by the reader) */
|
|
15
|
+
denyPatterns?: readonly string[];
|
|
16
|
+
}
|
|
17
|
+
/** Written once by cli.ts; an absent key means "not set on the command line". */
|
|
18
|
+
export declare const cli: CliOverrides;
|
|
19
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,YAAY;IAC3B,oBAAoB;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0BAA0B;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,mBAAmB;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,8BAA8B;IAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,4DAA4D;IAC5D,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED,iFAAiF;AACjF,eAAO,MAAM,GAAG,EAAE,YAAiB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Resolved CLI-flag overrides — the one owner of the flag-beats-env rule.
|
|
2
|
+
//
|
|
3
|
+
// `parseArgs` (cli.ts) used to write flag values back into `process.env` so
|
|
4
|
+
// deep core readers (path, sensitive, observability, util) would pick them up.
|
|
5
|
+
// That made the environment a hidden mutable config bus. Instead, cli.ts
|
|
6
|
+
// assigns onto `cli` once at startup and each reader consults it first, falling
|
|
7
|
+
// back to the operator's environment. This module deliberately has zero imports
|
|
8
|
+
// so any core module can read it without a cycle.
|
|
9
|
+
/** Written once by cli.ts; an absent key means "not set on the command line". */
|
|
10
|
+
export const cli = {};
|
|
11
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,EAAE;AACF,4EAA4E;AAC5E,+EAA+E;AAC/E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,kDAAkD;AAmBlD,iFAAiF;AACjF,MAAM,CAAC,MAAM,GAAG,GAAiB,EAAE,CAAC","sourcesContent":["// Resolved CLI-flag overrides — the one owner of the flag-beats-env rule.\n//\n// `parseArgs` (cli.ts) used to write flag values back into `process.env` so\n// deep core readers (path, sensitive, observability, util) would pick them up.\n// That made the environment a hidden mutable config bus. Instead, cli.ts\n// assigns onto `cli` once at startup and each reader consults it first, falling\n// back to the operator's environment. This module deliberately has zero imports\n// so any core module can read it without a cycle.\n\nexport interface CliOverrides {\n /** `--log-level` */\n logLevel?: string;\n /** `--max-file-size` (raw string; validated by the reader like the env var) */\n maxFileSize?: string;\n /** `--root-boundary` */\n rootBoundary?: string;\n /** `--allow-sensitive` */\n allowSensitive?: boolean;\n /** `--walk-cwd` */\n allowCwdWalk?: boolean;\n /** `--allow-missing-roots` */\n allowMissingRoots?: boolean;\n /** `--deny` entries (merged with DENYLIST by the reader) */\n denyPatterns?: readonly string[];\n}\n\n/** Written once by cli.ts; an absent key means \"not set on the command line\". */\nexport const cli: CliOverrides = {};\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { PageSnapshotStore } from './page-store.js';
|
|
2
|
+
export declare function createFirstPage<T, M>(params: {
|
|
3
|
+
store: PageSnapshotStore;
|
|
4
|
+
queryKey: string;
|
|
5
|
+
items: readonly T[];
|
|
6
|
+
metadata: M;
|
|
7
|
+
pageSize: number;
|
|
8
|
+
}): {
|
|
9
|
+
page: readonly T[];
|
|
10
|
+
metadata: M;
|
|
11
|
+
nextCursor: string | undefined;
|
|
12
|
+
};
|
|
13
|
+
export declare function readNextPage<T, M>(params: {
|
|
14
|
+
store: PageSnapshotStore;
|
|
15
|
+
queryKey: string;
|
|
16
|
+
cursor: string;
|
|
17
|
+
pageSize: number;
|
|
18
|
+
}): {
|
|
19
|
+
page: readonly T[];
|
|
20
|
+
metadata: M;
|
|
21
|
+
nextCursor: string | undefined;
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=cursor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/core/cursor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgB,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AA+BvE,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE;IAC5C,KAAK,EAAE,iBAAiB,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;IACpB,QAAQ,EAAE,CAAC,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;IAAC,QAAQ,EAAE,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAiBtE;AAGD,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE;IACzC,KAAK,EAAE,iBAAiB,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;IAAC,QAAQ,EAAE,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAItE"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ErrorCode, formatUnknownErrorMessage, FsError } from './errors.js';
|
|
2
|
+
import { invalidCursor } from './page-store.js';
|
|
3
|
+
function encodePageCursor(cursor) {
|
|
4
|
+
return Buffer.from(JSON.stringify(cursor)).toString('base64url');
|
|
5
|
+
}
|
|
6
|
+
function pageResult(snapshotId, offset, pageSize, snapshot) {
|
|
7
|
+
if (offset >= snapshot.items.length)
|
|
8
|
+
throw invalidCursor();
|
|
9
|
+
const page = snapshot.items.slice(offset, offset + pageSize);
|
|
10
|
+
const nextOffset = offset + page.length;
|
|
11
|
+
return {
|
|
12
|
+
page,
|
|
13
|
+
metadata: snapshot.metadata,
|
|
14
|
+
nextCursor: nextOffset < snapshot.items.length
|
|
15
|
+
? encodePageCursor({ snapshotId, offset: nextOffset })
|
|
16
|
+
: undefined,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function createFirstPage(params) {
|
|
20
|
+
if (params.items.length <= params.pageSize) {
|
|
21
|
+
return {
|
|
22
|
+
page: params.items,
|
|
23
|
+
metadata: params.metadata,
|
|
24
|
+
nextCursor: undefined,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const snapshotId = params.store.create({
|
|
28
|
+
queryKey: params.queryKey,
|
|
29
|
+
items: params.items,
|
|
30
|
+
metadata: params.metadata,
|
|
31
|
+
});
|
|
32
|
+
return pageResult(snapshotId, 0, params.pageSize, {
|
|
33
|
+
items: params.items,
|
|
34
|
+
metadata: params.metadata,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters -- the cursor carries no typed payload; the caller supplies the snapshot's original item and metadata types.
|
|
38
|
+
export function readNextPage(params) {
|
|
39
|
+
const decoded = decodePageCursor(params.cursor);
|
|
40
|
+
const snapshot = params.store.read(decoded.snapshotId, params.queryKey);
|
|
41
|
+
return pageResult(decoded.snapshotId, decoded.offset, params.pageSize, snapshot);
|
|
42
|
+
}
|
|
43
|
+
function decodePageCursor(cursor) {
|
|
44
|
+
try {
|
|
45
|
+
const text = Buffer.from(cursor, 'base64url').toString('utf-8');
|
|
46
|
+
const parsed = JSON.parse(text);
|
|
47
|
+
if (typeof parsed.snapshotId === 'string' &&
|
|
48
|
+
parsed.snapshotId.length > 0 &&
|
|
49
|
+
typeof parsed.offset === 'number' &&
|
|
50
|
+
Number.isInteger(parsed.offset) &&
|
|
51
|
+
parsed.offset >= 0) {
|
|
52
|
+
return { snapshotId: parsed.snapshotId, offset: parsed.offset };
|
|
53
|
+
}
|
|
54
|
+
throw new Error('Invalid page cursor');
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
if (error instanceof FsError)
|
|
58
|
+
throw error;
|
|
59
|
+
throw new FsError(ErrorCode.INVALID_INPUT, invalidCursor().message, undefined, { originalError: formatUnknownErrorMessage(error) }, error instanceof Error ? error : undefined);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/core/cursor.ts"],"names":[],"mappings":"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","sourcesContent":["import { ErrorCode, formatUnknownErrorMessage, FsError } from './errors.js';\nimport type { PageSnapshot, PageSnapshotStore } from './page-store.js';\nimport { invalidCursor } from './page-store.js';\n\ninterface PageCursor {\n readonly snapshotId: string;\n readonly offset: number;\n}\n\nfunction encodePageCursor(cursor: PageCursor): string {\n return Buffer.from(JSON.stringify(cursor)).toString('base64url');\n}\n\nfunction pageResult<T, M>(\n snapshotId: string,\n offset: number,\n pageSize: number,\n snapshot: PageSnapshot<T, M>,\n): { page: readonly T[]; metadata: M; nextCursor: string | undefined } {\n if (offset >= snapshot.items.length) throw invalidCursor();\n const page = snapshot.items.slice(offset, offset + pageSize);\n const nextOffset = offset + page.length;\n return {\n page,\n metadata: snapshot.metadata,\n nextCursor:\n nextOffset < snapshot.items.length\n ? encodePageCursor({ snapshotId, offset: nextOffset })\n : undefined,\n };\n}\n\nexport function createFirstPage<T, M>(params: {\n store: PageSnapshotStore;\n queryKey: string;\n items: readonly T[];\n metadata: M;\n pageSize: number;\n}): { page: readonly T[]; metadata: M; nextCursor: string | undefined } {\n if (params.items.length <= params.pageSize) {\n return {\n page: params.items,\n metadata: params.metadata,\n nextCursor: undefined,\n };\n }\n const snapshotId = params.store.create({\n queryKey: params.queryKey,\n items: params.items,\n metadata: params.metadata,\n });\n return pageResult(snapshotId, 0, params.pageSize, {\n items: params.items,\n metadata: params.metadata,\n });\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters -- the cursor carries no typed payload; the caller supplies the snapshot's original item and metadata types.\nexport function readNextPage<T, M>(params: {\n store: PageSnapshotStore;\n queryKey: string;\n cursor: string;\n pageSize: number;\n}): { page: readonly T[]; metadata: M; nextCursor: string | undefined } {\n const decoded = decodePageCursor(params.cursor);\n const snapshot = params.store.read<T, M>(decoded.snapshotId, params.queryKey);\n return pageResult(decoded.snapshotId, decoded.offset, params.pageSize, snapshot);\n}\n\nfunction decodePageCursor(cursor: string): PageCursor {\n try {\n const text = Buffer.from(cursor, 'base64url').toString('utf-8');\n const parsed = JSON.parse(text) as { snapshotId?: unknown; offset?: unknown };\n if (\n typeof parsed.snapshotId === 'string' &&\n parsed.snapshotId.length > 0 &&\n typeof parsed.offset === 'number' &&\n Number.isInteger(parsed.offset) &&\n parsed.offset >= 0\n ) {\n return { snapshotId: parsed.snapshotId, offset: parsed.offset };\n }\n throw new Error('Invalid page cursor');\n } catch (error) {\n if (error instanceof FsError) throw error;\n throw new FsError(\n ErrorCode.INVALID_INPUT,\n invalidCursor().message,\n undefined,\n { originalError: formatUnknownErrorMessage(error) },\n error instanceof Error ? error : undefined,\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { ProtocolErrorCode } from '@modelcontextprotocol/server';
|
|
2
|
+
export declare const ErrorCode: {
|
|
3
|
+
readonly ACCESS_DENIED: "ACCESS_DENIED";
|
|
4
|
+
readonly NOT_FOUND: "NOT_FOUND";
|
|
5
|
+
readonly NOT_FILE: "NOT_FILE";
|
|
6
|
+
readonly NOT_DIRECTORY: "NOT_DIRECTORY";
|
|
7
|
+
readonly TOO_LARGE: "TOO_LARGE";
|
|
8
|
+
readonly TIMEOUT: "TIMEOUT";
|
|
9
|
+
readonly CANCELLED: "CANCELLED";
|
|
10
|
+
readonly INVALID_PATTERN: "INVALID_PATTERN";
|
|
11
|
+
readonly INVALID_INPUT: "INVALID_INPUT";
|
|
12
|
+
readonly PERMISSION_DENIED: "PERMISSION_DENIED";
|
|
13
|
+
readonly SYMLINK_NOT_ALLOWED: "SYMLINK_NOT_ALLOWED";
|
|
14
|
+
readonly VALIDATION_FAILED: "VALIDATION_FAILED";
|
|
15
|
+
readonly IO_ERROR: "IO_ERROR";
|
|
16
|
+
readonly UNKNOWN: "UNKNOWN";
|
|
17
|
+
};
|
|
18
|
+
export type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];
|
|
19
|
+
interface PerFileError {
|
|
20
|
+
readonly code: ErrorCode;
|
|
21
|
+
readonly message: string;
|
|
22
|
+
readonly path?: string;
|
|
23
|
+
readonly suggestion?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface Problem {
|
|
26
|
+
readonly code: ErrorCode;
|
|
27
|
+
readonly message: string;
|
|
28
|
+
readonly path?: string;
|
|
29
|
+
readonly issues?: readonly ProblemIssue[];
|
|
30
|
+
readonly suggestion?: string;
|
|
31
|
+
readonly details?: ProblemDetails;
|
|
32
|
+
}
|
|
33
|
+
interface ProblemIssue {
|
|
34
|
+
readonly path: readonly (string | number)[];
|
|
35
|
+
readonly code: string;
|
|
36
|
+
readonly message: string;
|
|
37
|
+
readonly expected?: string;
|
|
38
|
+
readonly received?: string;
|
|
39
|
+
readonly params?: Readonly<Record<string, unknown>>;
|
|
40
|
+
}
|
|
41
|
+
interface ProblemDetails {
|
|
42
|
+
readonly errno?: string;
|
|
43
|
+
readonly syscall?: string;
|
|
44
|
+
readonly tool?: string;
|
|
45
|
+
readonly extra?: Readonly<Record<string, unknown>>;
|
|
46
|
+
}
|
|
47
|
+
interface ProblemFactoryOptions {
|
|
48
|
+
path?: string;
|
|
49
|
+
suggestion?: string;
|
|
50
|
+
details?: ProblemDetails;
|
|
51
|
+
issues?: readonly ProblemIssue[];
|
|
52
|
+
}
|
|
53
|
+
export declare const Problem: {
|
|
54
|
+
readonly invalidInput: (msg: string, o?: ProblemFactoryOptions) => Problem;
|
|
55
|
+
readonly accessDenied: (msg: string, o?: ProblemFactoryOptions) => Problem;
|
|
56
|
+
readonly timeout: (msg: string, o?: ProblemFactoryOptions) => Problem;
|
|
57
|
+
readonly cancelled: (msg: string, o?: ProblemFactoryOptions) => Problem;
|
|
58
|
+
readonly ioError: (msg: string, o?: ProblemFactoryOptions) => Problem;
|
|
59
|
+
readonly unknown: (msg: string, o?: ProblemFactoryOptions) => Problem;
|
|
60
|
+
readonly fromUnknown: (error: unknown, defaultCode: ErrorCode, path?: string) => Problem;
|
|
61
|
+
readonly toText: (error: unknown, defaultCode: ErrorCode) => {
|
|
62
|
+
code: ErrorCode;
|
|
63
|
+
text: string;
|
|
64
|
+
};
|
|
65
|
+
readonly toPerFileError: (error: unknown, defaultCode?: ErrorCode, path?: string) => PerFileError;
|
|
66
|
+
};
|
|
67
|
+
export declare const ERRNO_MAP: Readonly<Record<string, ErrorCode>>;
|
|
68
|
+
export declare const SKIPPABLE_FS_CODES: ReadonlySet<ErrorCode>;
|
|
69
|
+
export declare const SKIPPABLE_ERRNOS: ReadonlySet<string>;
|
|
70
|
+
export declare function isFsError(error: unknown): error is FsError;
|
|
71
|
+
/** FsError traces to a caller-supplied argument; anything else is server-side. */
|
|
72
|
+
export declare function fsErrorCode(error: unknown): ProtocolErrorCode;
|
|
73
|
+
/**
|
|
74
|
+
* Structural discriminator for SDK error classes (`ProtocolError`, `SdkError`).
|
|
75
|
+
* Checks `name` + `code` properties rather than `instanceof` so discrimination
|
|
76
|
+
* survives cross-realm / multi-SDK-copy conditions where the prototype chain
|
|
77
|
+
* breaks. Mirrors the isFsError pattern.
|
|
78
|
+
*/
|
|
79
|
+
export declare function hasErrorShape(error: unknown, name: string, code?: string | number): error is Error & {
|
|
80
|
+
code: string | number;
|
|
81
|
+
};
|
|
82
|
+
export declare function isNodeError(error: unknown): error is NodeJS.ErrnoException;
|
|
83
|
+
/** True when `error` is a Node errno error with code `ENOENT` (path not found). */
|
|
84
|
+
export declare function isNotFoundErrno(error: unknown): error is NodeJS.ErrnoException;
|
|
85
|
+
export declare function rethrowIfAborted(error: unknown): void;
|
|
86
|
+
export declare function formatUnknownErrorMessage(error: unknown): string;
|
|
87
|
+
export declare function normalizeUnknownError(error: unknown): Error;
|
|
88
|
+
export declare class FsError extends Error {
|
|
89
|
+
readonly problem: Problem;
|
|
90
|
+
constructor(code: ErrorCode, message: string, path?: string, details?: Record<string, unknown>, cause?: unknown);
|
|
91
|
+
get code(): ErrorCode;
|
|
92
|
+
get path(): string | undefined;
|
|
93
|
+
get details(): Record<string, unknown> | undefined;
|
|
94
|
+
}
|
|
95
|
+
export {};
|
|
96
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"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"}
|