@j0hanz/filesystem-mcp 2.1.4 → 2.1.6
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/dist/cli.d.ts +2 -14
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -22
- package/dist/cli.js.map +1 -1
- package/dist/core/cursor.d.ts +2 -14
- package/dist/core/cursor.d.ts.map +1 -1
- package/dist/core/cursor.js +25 -39
- package/dist/core/cursor.js.map +1 -1
- package/dist/core/diff.d.ts +6 -0
- package/dist/core/diff.d.ts.map +1 -0
- package/dist/core/diff.js +21 -0
- package/dist/core/diff.js.map +1 -0
- package/dist/core/errors.d.ts +2 -31
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +15 -86
- package/dist/core/errors.js.map +1 -1
- package/dist/core/file-uri.d.ts +18 -2
- package/dist/core/file-uri.d.ts.map +1 -1
- package/dist/core/file-uri.js +34 -6
- package/dist/core/file-uri.js.map +1 -1
- package/dist/core/fmt.js +5 -5
- package/dist/core/fmt.js.map +1 -1
- package/dist/core/fs.d.ts +4 -13
- package/dist/core/fs.d.ts.map +1 -1
- package/dist/core/fs.js +4 -41
- package/dist/core/fs.js.map +1 -1
- package/dist/core/glob.d.ts +1 -7
- package/dist/core/glob.d.ts.map +1 -1
- package/dist/core/glob.js +1 -11
- package/dist/core/glob.js.map +1 -1
- package/dist/core/input-required.d.ts +2 -10
- package/dist/core/input-required.d.ts.map +1 -1
- package/dist/core/input-required.js +3 -12
- package/dist/core/input-required.js.map +1 -1
- package/dist/core/path-completer.d.ts.map +1 -1
- package/dist/core/path-completer.js +3 -7
- package/dist/core/path-completer.js.map +1 -1
- package/dist/core/path-discovery.js +2 -2
- package/dist/core/path-discovery.js.map +1 -1
- package/dist/core/path.d.ts +10 -25
- package/dist/core/path.d.ts.map +1 -1
- package/dist/core/path.js +28 -66
- package/dist/core/path.js.map +1 -1
- package/dist/core/primitives.d.ts +8 -3
- package/dist/core/primitives.d.ts.map +1 -1
- package/dist/core/primitives.js +10 -5
- package/dist/core/primitives.js.map +1 -1
- package/dist/core/read.d.ts +0 -16
- package/dist/core/read.d.ts.map +1 -1
- package/dist/core/read.js +19 -56
- package/dist/core/read.js.map +1 -1
- package/dist/core/schema.d.ts +1 -32
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +7 -66
- package/dist/core/schema.js.map +1 -1
- package/dist/core/search.d.ts +16 -5
- package/dist/core/search.d.ts.map +1 -1
- package/dist/core/search.js +118 -108
- package/dist/core/search.js.map +1 -1
- package/dist/core/sensitive.d.ts.map +1 -1
- package/dist/core/sensitive.js +7 -15
- package/dist/core/sensitive.js.map +1 -1
- package/dist/core/store.d.ts +1 -3
- package/dist/core/store.d.ts.map +1 -1
- package/dist/core/store.js +1 -5
- package/dist/core/store.js.map +1 -1
- package/dist/core/watcher-registry.d.ts +1 -8
- package/dist/core/watcher-registry.d.ts.map +1 -1
- package/dist/core/watcher-registry.js +3 -12
- package/dist/core/watcher-registry.js.map +1 -1
- package/dist/index.js +1 -8
- package/dist/index.js.map +1 -1
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +7 -33
- package/dist/prompts.js.map +1 -1
- package/dist/resources.d.ts +1 -1
- package/dist/resources.d.ts.map +1 -1
- package/dist/resources.js +3 -9
- package/dist/resources.js.map +1 -1
- package/dist/server.d.ts +0 -3
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -5
- package/dist/server.js.map +1 -1
- package/dist/tools/batch.d.ts +5 -69
- package/dist/tools/batch.d.ts.map +1 -1
- package/dist/tools/batch.js +7 -117
- package/dist/tools/batch.js.map +1 -1
- package/dist/tools/create.d.ts.map +1 -1
- package/dist/tools/create.js +8 -18
- package/dist/tools/create.js.map +1 -1
- package/dist/tools/define.d.ts +1 -4
- package/dist/tools/define.d.ts.map +1 -1
- package/dist/tools/define.js +6 -24
- package/dist/tools/define.js.map +1 -1
- package/dist/tools/delete-file.d.ts.map +1 -1
- package/dist/tools/delete-file.js +6 -6
- package/dist/tools/delete-file.js.map +1 -1
- package/dist/tools/diff.d.ts.map +1 -1
- package/dist/tools/diff.js +3 -10
- package/dist/tools/diff.js.map +1 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +43 -87
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/index.d.ts +0 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +0 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/list.js +3 -2
- package/dist/tools/list.js.map +1 -1
- package/dist/tools/move.d.ts.map +1 -1
- package/dist/tools/move.js +169 -119
- package/dist/tools/move.js.map +1 -1
- package/dist/tools/patch.d.ts.map +1 -1
- package/dist/tools/patch.js +5 -23
- package/dist/tools/patch.js.map +1 -1
- package/dist/tools/progress.d.ts +0 -1
- package/dist/tools/progress.d.ts.map +1 -1
- package/dist/tools/progress.js +2 -8
- package/dist/tools/progress.js.map +1 -1
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +21 -25
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/replace-in-files.d.ts.map +1 -1
- package/dist/tools/replace-in-files.js +25 -44
- package/dist/tools/replace-in-files.js.map +1 -1
- package/dist/tools/search-content.d.ts.map +1 -1
- package/dist/tools/search-content.js +17 -49
- package/dist/tools/search-content.js.map +1 -1
- package/dist/tools/search-files.d.ts.map +1 -1
- package/dist/tools/search-files.js +1 -2
- package/dist/tools/search-files.js.map +1 -1
- package/dist/tools/stat.d.ts.map +1 -1
- package/dist/tools/stat.js +5 -6
- package/dist/tools/stat.js.map +1 -1
- package/dist/transport/http-policy.d.ts +6 -0
- package/dist/transport/http-policy.d.ts.map +1 -1
- package/dist/transport/http-policy.js +2 -2
- package/dist/transport/http-policy.js.map +1 -1
- package/dist/transport/http.d.ts.map +1 -1
- package/dist/transport/http.js +4 -11
- package/dist/transport/http.js.map +1 -1
- package/dist/transport/stdio.js +1 -1
- package/dist/transport/stdio.js.map +1 -1
- package/dist/transport.d.ts +1 -3
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +5 -2
- package/dist/transport.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.d.ts
CHANGED
|
@@ -12,17 +12,7 @@ export declare function parseArgs(): Promise<{
|
|
|
12
12
|
httpHost: string | undefined;
|
|
13
13
|
apiKey: string | undefined;
|
|
14
14
|
}>;
|
|
15
|
-
export
|
|
16
|
-
transport: string;
|
|
17
|
-
readOnly: boolean;
|
|
18
|
-
allowedRoots: string[];
|
|
19
|
-
tools: string[];
|
|
20
|
-
apiKey: string | null;
|
|
21
|
-
limits: {
|
|
22
|
-
maxFileSizeBytes: number;
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
export interface PrintConfigOptions {
|
|
15
|
+
export declare function runPrintConfig(options: {
|
|
26
16
|
allowedDirs: string[];
|
|
27
17
|
allowCwd: boolean;
|
|
28
18
|
readOnly: boolean;
|
|
@@ -31,7 +21,5 @@ export interface PrintConfigOptions {
|
|
|
31
21
|
port?: number;
|
|
32
22
|
httpHost?: string;
|
|
33
23
|
apiKey?: string;
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
export declare function runPrintConfig(options: PrintConfigOptions): Promise<EffectiveConfig>;
|
|
24
|
+
}): Promise<void>;
|
|
37
25
|
//# sourceMappingURL=cli.d.ts.map
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAsBA,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAK9C;AAsGD,wBAAsB,SAAS,IAAI,OAAO,CAAC;IACzC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B,CAAC,CAgFD;AAMD,wBAAsB,cAAc,CAAC,OAAO,EAAE;IAC5C,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqChB"}
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { stat } from 'node:fs/promises';
|
|
2
2
|
import { parseArgs as utilParseArgs } from 'node:util';
|
|
3
3
|
import { printHelpAndExit, printVersionAndExit } from './cli-help.js';
|
|
4
|
-
import { processInParallel } from './core/concurrency.js';
|
|
5
4
|
import { cli } from './core/config.js';
|
|
6
5
|
import { formatUnknownErrorMessage } from './core/errors.js';
|
|
7
6
|
import { cliFmt, padEndVisible } from './core/fmt.js';
|
|
@@ -10,7 +9,6 @@ import { PathGuard } from './core/path.js';
|
|
|
10
9
|
import { IS_WINDOWS, parseTrueEnvFlag } from './core/primitives.js';
|
|
11
10
|
import { getMaxTextFileSize } from './core/util.js';
|
|
12
11
|
import { registeredTools } from './tools/index.js';
|
|
13
|
-
const CLI_VALIDATE_CONCURRENCY = 8;
|
|
14
12
|
// ════════════════════════════════════════════════════════════
|
|
15
13
|
// Path & Config Utilities — pure functions and error types
|
|
16
14
|
// ════════════════════════════════════════════════════════════
|
|
@@ -34,38 +32,30 @@ function validateCliPath(inputPath) {
|
|
|
34
32
|
throw new CliExitError(`Windows reserved device name not allowed: ${reserved}.`, 1);
|
|
35
33
|
}
|
|
36
34
|
}
|
|
37
|
-
function assertDirectory(stats, inputPath) {
|
|
38
|
-
if (stats.isDirectory())
|
|
39
|
-
return;
|
|
40
|
-
throw new Error(`${inputPath} is not a directory`);
|
|
41
|
-
}
|
|
42
35
|
async function validateDirectoryPath(inputPath, allowMissing = false) {
|
|
43
36
|
const normalized = normalizePath(inputPath);
|
|
37
|
+
let stats;
|
|
44
38
|
try {
|
|
45
|
-
|
|
46
|
-
assertDirectory(stats, inputPath);
|
|
47
|
-
return normalized;
|
|
39
|
+
stats = await stat(normalized);
|
|
48
40
|
}
|
|
49
41
|
catch (error) {
|
|
50
|
-
if (allowMissing)
|
|
51
|
-
if (error instanceof Error && error.message.includes('is not a directory')) {
|
|
52
|
-
throw error;
|
|
53
|
-
}
|
|
42
|
+
if (allowMissing)
|
|
54
43
|
return normalized;
|
|
55
|
-
}
|
|
56
44
|
// Node's own message already names the syscall and the errno.
|
|
57
45
|
throw new Error(`Cannot access directory ${inputPath}: ${formatUnknownErrorMessage(error)}`, {
|
|
58
46
|
cause: error,
|
|
59
47
|
});
|
|
60
48
|
}
|
|
49
|
+
if (!stats.isDirectory())
|
|
50
|
+
throw new Error(`${inputPath} is not a directory`);
|
|
51
|
+
return normalized;
|
|
61
52
|
}
|
|
62
53
|
async function normalizeAndValidateDirs(paths, allowMissing = false) {
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
54
|
+
const normalized = [];
|
|
55
|
+
for (const p of paths) {
|
|
56
|
+
normalized.push(await validateDirectoryPath(p, allowMissing));
|
|
66
57
|
}
|
|
67
|
-
|
|
68
|
-
throw first.error;
|
|
58
|
+
return deduplicateAllowedDirectories(normalized);
|
|
69
59
|
}
|
|
70
60
|
function normalizeCliExitMessage(error) {
|
|
71
61
|
const rawMessage = formatUnknownErrorMessage(error);
|
|
@@ -193,8 +183,11 @@ export async function parseArgs() {
|
|
|
193
183
|
throw new CliExitError(normalizeCliExitMessage(error), 1);
|
|
194
184
|
}
|
|
195
185
|
}
|
|
186
|
+
// ════════════════════════════════════════════════════════════
|
|
187
|
+
// Effective config reporting — prints the resolved server config
|
|
188
|
+
// ════════════════════════════════════════════════════════════
|
|
196
189
|
export async function runPrintConfig(options) {
|
|
197
|
-
const write =
|
|
190
|
+
const write = (s) => process.stdout.write(s);
|
|
198
191
|
const pathGuard = new PathGuard({
|
|
199
192
|
allowCwd: options.allowCwd,
|
|
200
193
|
cliAllowedDirs: options.allowedDirs,
|
|
@@ -226,6 +219,5 @@ export async function runPrintConfig(options) {
|
|
|
226
219
|
write(`${key('tools:')}${cliFmt.dim(config.tools.join(', '))}\n`);
|
|
227
220
|
write(`${key('maxFileSize:')}${cliFmt.yellow(String(config.limits.maxFileSizeBytes))}\n`);
|
|
228
221
|
}
|
|
229
|
-
return config;
|
|
230
222
|
}
|
|
231
223
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +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 { 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, 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 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 // Node's own message already names the syscall and the errno.\n throw new Error(`Cannot access directory ${inputPath}: ${formatUnknownErrorMessage(error)}`, {\n cause: error,\n });\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"]}
|
|
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 { parseArgs as utilParseArgs } from 'node:util';\n\nimport { printHelpAndExit, printVersionAndExit } from './cli-help.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, parseTrueEnvFlag } from './core/primitives.js';\nimport { getMaxTextFileSize } from './core/util.js';\nimport { registeredTools } from './tools/index.js';\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\nasync function validateDirectoryPath(inputPath: string, allowMissing = false): Promise<string> {\n const normalized = normalizePath(inputPath);\n\n let stats: Stats;\n try {\n stats = await stat(normalized);\n } catch (error) {\n if (allowMissing) return normalized;\n // Node's own message already names the syscall and the errno.\n throw new Error(`Cannot access directory ${inputPath}: ${formatUnknownErrorMessage(error)}`, {\n cause: error,\n });\n }\n\n if (!stats.isDirectory()) throw new Error(`${inputPath} is not a directory`);\n return normalized;\n}\n\nasync function normalizeAndValidateDirs(\n paths: readonly string[],\n allowMissing = false,\n): Promise<string[]> {\n const normalized: string[] = [];\n for (const p of paths) {\n normalized.push(await validateDirectoryPath(p, allowMissing));\n }\n return deduplicateAllowedDirectories(normalized);\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 async function runPrintConfig(options: {\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}): Promise<void> {\n const write = (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 = {\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"]}
|
package/dist/core/cursor.d.ts
CHANGED
|
@@ -1,11 +1,4 @@
|
|
|
1
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
|
-
}): Page<T, M>;
|
|
9
2
|
/**
|
|
10
3
|
* The full result set a paged tool produced, before slicing. `truncated` is the
|
|
11
4
|
* engine's own stop state — the hard result cap or a timeout cut the set — and
|
|
@@ -16,7 +9,7 @@ export interface ProducedPage<T, M> {
|
|
|
16
9
|
readonly metadata: M;
|
|
17
10
|
readonly truncated: boolean;
|
|
18
11
|
}
|
|
19
|
-
|
|
12
|
+
interface Page<T, M> {
|
|
20
13
|
readonly page: readonly T[];
|
|
21
14
|
readonly metadata: M;
|
|
22
15
|
readonly nextCursor: string | undefined;
|
|
@@ -51,10 +44,5 @@ export declare function paginate<T, M, R>(params: {
|
|
|
51
44
|
produce: () => Promise<ProducedPage<T, M>>;
|
|
52
45
|
externalize?: ((items: readonly T[], metadata: M) => R) | undefined;
|
|
53
46
|
}): Promise<PaginatedPage<T, M, R>>;
|
|
54
|
-
export
|
|
55
|
-
store: PageSnapshotStore;
|
|
56
|
-
queryKey: string;
|
|
57
|
-
cursor: string;
|
|
58
|
-
pageSize: number;
|
|
59
|
-
}): Page<T, M>;
|
|
47
|
+
export {};
|
|
60
48
|
//# sourceMappingURL=cursor.d.ts.map
|
|
@@ -1 +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;AAgCvE
|
|
1
|
+
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/core/cursor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgB,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAgCvE;;;;GAIG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC,EAAE,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,UAAU,IAAI,CAAC,CAAC,EAAE,CAAC;IACjB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAE,SAAQ,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;IACxD,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE;IAC9C,KAAK,EAAE,iBAAiB,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3C,WAAW,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,SAAS,CAAC;CACrE,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CA6BlC"}
|
package/dist/core/cursor.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ErrorCode,
|
|
1
|
+
import { ErrorCode, FsError } from './errors.js';
|
|
2
2
|
import { invalidCursor } from './page-store.js';
|
|
3
3
|
function encodePageCursor(cursor) {
|
|
4
4
|
return Buffer.from(JSON.stringify(cursor)).toString('base64url');
|
|
@@ -17,25 +17,6 @@ function pageResult(snapshotId, offset, pageSize, snapshot) {
|
|
|
17
17
|
: undefined,
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
|
-
export function createFirstPage(params) {
|
|
21
|
-
if (params.items.length <= params.pageSize) {
|
|
22
|
-
return {
|
|
23
|
-
page: params.items,
|
|
24
|
-
metadata: params.metadata,
|
|
25
|
-
nextCursor: undefined,
|
|
26
|
-
offset: 0,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
const snapshotId = params.store.create({
|
|
30
|
-
queryKey: params.queryKey,
|
|
31
|
-
items: params.items,
|
|
32
|
-
metadata: params.metadata,
|
|
33
|
-
});
|
|
34
|
-
return pageResult(snapshotId, 0, params.pageSize, {
|
|
35
|
-
items: params.items,
|
|
36
|
-
metadata: params.metadata,
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
20
|
/**
|
|
40
21
|
* The one replay-or-produce branch every paged tool runs. A cursor replays a
|
|
41
22
|
* stored snapshot; without one, `produce` runs the query and its result is
|
|
@@ -50,31 +31,36 @@ export function createFirstPage(params) {
|
|
|
50
31
|
*/
|
|
51
32
|
export async function paginate(params) {
|
|
52
33
|
if (params.cursor !== undefined) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
cursor: params.cursor,
|
|
57
|
-
pageSize: params.pageSize,
|
|
58
|
-
});
|
|
34
|
+
const decoded = decodePageCursor(params.cursor);
|
|
35
|
+
const snapshot = params.store.read(decoded.snapshotId, params.queryKey);
|
|
36
|
+
return pageResult(decoded.snapshotId, decoded.offset, params.pageSize, snapshot);
|
|
59
37
|
}
|
|
60
38
|
const produced = await params.produce();
|
|
61
39
|
const incomplete = produced.items.length > params.pageSize || produced.truncated;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
40
|
+
let first;
|
|
41
|
+
if (produced.items.length <= params.pageSize) {
|
|
42
|
+
first = {
|
|
43
|
+
page: produced.items,
|
|
44
|
+
metadata: produced.metadata,
|
|
45
|
+
nextCursor: undefined,
|
|
46
|
+
offset: 0,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const snapshotId = params.store.create({
|
|
51
|
+
queryKey: params.queryKey,
|
|
52
|
+
items: produced.items,
|
|
53
|
+
metadata: produced.metadata,
|
|
54
|
+
});
|
|
55
|
+
first = pageResult(snapshotId, 0, params.pageSize, {
|
|
56
|
+
items: produced.items,
|
|
57
|
+
metadata: produced.metadata,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
69
60
|
if (!incomplete || params.externalize === undefined)
|
|
70
61
|
return first;
|
|
71
62
|
return { ...first, resource: params.externalize(produced.items, produced.metadata) };
|
|
72
63
|
}
|
|
73
|
-
export function readNextPage(params) {
|
|
74
|
-
const decoded = decodePageCursor(params.cursor);
|
|
75
|
-
const snapshot = params.store.read(decoded.snapshotId, params.queryKey);
|
|
76
|
-
return pageResult(decoded.snapshotId, decoded.offset, params.pageSize, snapshot);
|
|
77
|
-
}
|
|
78
64
|
function decodePageCursor(cursor) {
|
|
79
65
|
try {
|
|
80
66
|
const text = Buffer.from(cursor, 'base64url').toString('utf-8');
|
|
@@ -91,7 +77,7 @@ function decodePageCursor(cursor) {
|
|
|
91
77
|
catch (error) {
|
|
92
78
|
if (error instanceof FsError)
|
|
93
79
|
throw error;
|
|
94
|
-
throw new FsError(ErrorCode.INVALID_INPUT, invalidCursor().message, undefined,
|
|
80
|
+
throw new FsError(ErrorCode.INVALID_INPUT, invalidCursor().message, undefined, error instanceof Error ? error : undefined);
|
|
95
81
|
}
|
|
96
82
|
}
|
|
97
83
|
//# sourceMappingURL=cursor.js.map
|
package/dist/core/cursor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/core/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/core/cursor.ts"],"names":[],"mappings":"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","sourcesContent":["import { ErrorCode, 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<T, M> {\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 offset,\n nextCursor:\n nextOffset < snapshot.items.length\n ? encodePageCursor({ snapshotId, offset: nextOffset })\n : undefined,\n };\n}\n\n/**\n * The full result set a paged tool produced, before slicing. `truncated` is the\n * engine's own stop state — the hard result cap or a timeout cut the set — and\n * says nothing about page size.\n */\nexport interface ProducedPage<T, M> {\n readonly items: readonly T[];\n readonly metadata: M;\n readonly truncated: boolean;\n}\n\ninterface Page<T, M> {\n readonly page: readonly T[];\n readonly metadata: M;\n readonly nextCursor: string | undefined;\n /**\n * Index of this page's first item in the full set. A tool that reports\n * progress in its text needs it: without it every page can only say how many\n * rows it holds, which is the same number on page 1 and page 9.\n */\n readonly offset: number;\n}\n\nexport interface PaginatedPage<T, M, R> extends Page<T, M> {\n /** The externalized full set. First page only, and only when incomplete. */\n readonly resource?: R;\n}\n\n/**\n * The one replay-or-produce branch every paged tool runs. A cursor replays a\n * stored snapshot; without one, `produce` runs the query and its result is\n * snapshotted for later pages.\n *\n * The response is incomplete when the set spans more than one page or the\n * engine truncated it. Then — and only on the first page — `externalize`\n * stores the full set and its handle rides back as `resource`. Replayed pages\n * never carry it: the stored entry expires on the resource store's own TTL and\n * LRU, not this snapshot's, so replaying its URI would hand back a dead\n * pointer. Nor do they mint a new one; the set was already stored whole.\n */\nexport async function paginate<T, M, R>(params: {\n store: PageSnapshotStore;\n queryKey: string;\n cursor: string | undefined;\n pageSize: number;\n produce: () => Promise<ProducedPage<T, M>>;\n externalize?: ((items: readonly T[], metadata: M) => R) | undefined;\n}): Promise<PaginatedPage<T, M, R>> {\n if (params.cursor !== 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 const produced = await params.produce();\n const incomplete = produced.items.length > params.pageSize || produced.truncated;\n let first: Page<T, M>;\n if (produced.items.length <= params.pageSize) {\n first = {\n page: produced.items,\n metadata: produced.metadata,\n nextCursor: undefined,\n offset: 0,\n };\n } else {\n const snapshotId = params.store.create({\n queryKey: params.queryKey,\n items: produced.items,\n metadata: produced.metadata,\n });\n first = pageResult(snapshotId, 0, params.pageSize, {\n items: produced.items,\n metadata: produced.metadata,\n });\n }\n if (!incomplete || params.externalize === undefined) return first;\n return { ...first, resource: params.externalize(produced.items, produced.metadata) };\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 error instanceof Error ? error : undefined,\n );\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/core/diff.ts"],"names":[],"mappings":"AAKA,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAS9C;AAID,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEtF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createTwoFilesPatch, diffLines } from 'diff';
|
|
2
|
+
// Unified-diff computation over two text buffers. Kept out of `fmt.ts`, which
|
|
3
|
+
// formats terminal output and has no business pulling in the `diff` package.
|
|
4
|
+
export function computeDiffStats(original, modified) {
|
|
5
|
+
// diffLines returns the change list synchronously on diff v9.
|
|
6
|
+
let linesAdded = 0;
|
|
7
|
+
let linesRemoved = 0;
|
|
8
|
+
for (const part of diffLines(original, modified)) {
|
|
9
|
+
if (part.added)
|
|
10
|
+
linesAdded += part.count;
|
|
11
|
+
else if (part.removed)
|
|
12
|
+
linesRemoved += part.count;
|
|
13
|
+
}
|
|
14
|
+
return { linesAdded, linesRemoved };
|
|
15
|
+
}
|
|
16
|
+
// createTwoFilesPatch returns the unified diff string synchronously on diff v9
|
|
17
|
+
// (the { callback } option fires via setTimeout and returns undefined).
|
|
18
|
+
export function unifiedPatch(label, original, modified) {
|
|
19
|
+
return createTwoFilesPatch(label, label, original, modified, 'Original', 'Modified');
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/core/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEtD,8EAA8E;AAC9E,6EAA6E;AAE7E,MAAM,UAAU,gBAAgB,CAC9B,QAAgB,EAChB,QAAgB;IAEhB,8DAA8D;IAC9D,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC;QACjD,IAAI,IAAI,CAAC,KAAK;YAAE,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC;aACpC,IAAI,IAAI,CAAC,OAAO;YAAE,YAAY,IAAI,IAAI,CAAC,KAAK,CAAC;IACpD,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;AACtC,CAAC;AAED,+EAA+E;AAC/E,wEAAwE;AACxE,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,QAAgB,EAAE,QAAgB;IAC5E,OAAO,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AACvF,CAAC","sourcesContent":["import { createTwoFilesPatch, diffLines } from 'diff';\n\n// Unified-diff computation over two text buffers. Kept out of `fmt.ts`, which\n// formats terminal output and has no business pulling in the `diff` package.\n\nexport function computeDiffStats(\n original: string,\n modified: string,\n): { linesAdded: number; linesRemoved: number } {\n // diffLines returns the change list synchronously on diff v9.\n let linesAdded = 0;\n let linesRemoved = 0;\n for (const part of diffLines(original, modified)) {\n if (part.added) linesAdded += part.count;\n else if (part.removed) linesRemoved += part.count;\n }\n return { linesAdded, linesRemoved };\n}\n\n// createTwoFilesPatch returns the unified diff string synchronously on diff v9\n// (the { callback } option fires via setTimeout and returns undefined).\nexport function unifiedPatch(label: string, original: string, modified: string): string {\n return createTwoFilesPatch(label, label, original, modified, 'Original', 'Modified');\n}\n"]}
|
package/dist/core/errors.d.ts
CHANGED
|
@@ -11,58 +11,31 @@ export declare const ErrorCode: {
|
|
|
11
11
|
readonly INVALID_INPUT: "INVALID_INPUT";
|
|
12
12
|
readonly PERMISSION_DENIED: "PERMISSION_DENIED";
|
|
13
13
|
readonly SYMLINK_NOT_ALLOWED: "SYMLINK_NOT_ALLOWED";
|
|
14
|
-
readonly VALIDATION_FAILED: "VALIDATION_FAILED";
|
|
15
14
|
readonly IO_ERROR: "IO_ERROR";
|
|
16
15
|
readonly UNKNOWN: "UNKNOWN";
|
|
17
16
|
};
|
|
18
17
|
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
18
|
export interface Problem {
|
|
26
19
|
readonly code: ErrorCode;
|
|
27
20
|
readonly message: string;
|
|
28
21
|
readonly path?: string;
|
|
29
|
-
readonly issues?: readonly ProblemIssue[];
|
|
30
22
|
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
23
|
}
|
|
47
24
|
interface ProblemFactoryOptions {
|
|
48
25
|
path?: string;
|
|
49
26
|
suggestion?: string;
|
|
50
|
-
details?: ProblemDetails;
|
|
51
|
-
issues?: readonly ProblemIssue[];
|
|
52
27
|
}
|
|
53
28
|
export declare const Problem: {
|
|
54
29
|
readonly invalidInput: (msg: string, o?: ProblemFactoryOptions) => Problem;
|
|
55
30
|
readonly accessDenied: (msg: string, o?: ProblemFactoryOptions) => Problem;
|
|
56
31
|
readonly timeout: (msg: string, o?: ProblemFactoryOptions) => Problem;
|
|
57
32
|
readonly cancelled: (msg: string, o?: ProblemFactoryOptions) => Problem;
|
|
58
|
-
readonly ioError: (msg: string, o?: ProblemFactoryOptions) => Problem;
|
|
59
33
|
readonly unknown: (msg: string, o?: ProblemFactoryOptions) => Problem;
|
|
60
34
|
readonly fromUnknown: (error: unknown, defaultCode: ErrorCode, path?: string) => Problem;
|
|
61
35
|
readonly toText: (error: unknown, defaultCode: ErrorCode) => {
|
|
62
36
|
code: ErrorCode;
|
|
63
37
|
text: string;
|
|
64
38
|
};
|
|
65
|
-
readonly toPerFileError: (error: unknown, defaultCode?: ErrorCode, path?: string) => PerFileError;
|
|
66
39
|
};
|
|
67
40
|
export declare const ERRNO_MAP: Readonly<Record<string, ErrorCode>>;
|
|
68
41
|
export declare const SKIPPABLE_FS_CODES: ReadonlySet<ErrorCode>;
|
|
@@ -76,7 +49,7 @@ export declare function fsErrorCode(error: unknown): ProtocolErrorCode;
|
|
|
76
49
|
* survives cross-realm / multi-SDK-copy conditions where the prototype chain
|
|
77
50
|
* breaks. Mirrors the isFsError pattern.
|
|
78
51
|
*/
|
|
79
|
-
export declare function hasErrorShape(error: unknown, name: string
|
|
52
|
+
export declare function hasErrorShape(error: unknown, name: string): error is Error & {
|
|
80
53
|
code: string | number;
|
|
81
54
|
};
|
|
82
55
|
export declare function isNodeError(error: unknown): error is NodeJS.ErrnoException;
|
|
@@ -87,10 +60,8 @@ export declare function formatUnknownErrorMessage(error: unknown): string;
|
|
|
87
60
|
export declare function normalizeUnknownError(error: unknown): Error;
|
|
88
61
|
export declare class FsError extends Error {
|
|
89
62
|
readonly problem: Problem;
|
|
90
|
-
constructor(code: ErrorCode, message: string, path?: string,
|
|
63
|
+
constructor(code: ErrorCode, message: string, path?: string, cause?: unknown);
|
|
91
64
|
get code(): ErrorCode;
|
|
92
|
-
get path(): string | undefined;
|
|
93
|
-
get details(): Record<string, unknown> | undefined;
|
|
94
65
|
}
|
|
95
66
|
export {};
|
|
96
67
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,eAAO,MAAM,SAAS;;;;;;;;;;;;;;CAcZ,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAEnE,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,UAAU,qBAAqB;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAWD,eAAO,MAAM,OAAO;iCACE,MAAM,MAAM,qBAAqB,KAAG,OAAO;iCAE3C,MAAM,MAAM,qBAAqB,KAAG,OAAO;4BAEhD,MAAM,MAAM,qBAAqB,KAAG,OAAO;8BACzC,MAAM,MAAM,qBAAqB,KAAG,OAAO;4BAE7C,MAAM,MAAM,qBAAqB,KAAG,OAAO;kCACvC,OAAO,eAAe,SAAS,SAAS,MAAM,KAAG,OAAO;6BAe7D,OAAO,eAAe,SAAS,KAAG;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;CAIzE,CAAC;AAcX,eAAO,MAAM,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAezD,CAAC;AAOF,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,SAAS,CAOpD,CAAC;AAEH,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAA0C,CAAC;AA4F5F,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAO1D;AAED,kFAAkF;AAClF,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB,CAE7D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,GACX,KAAK,IAAI,KAAK,GAAG;IAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAI5C;AAoBD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,cAAc,CAK1E;AAED,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,cAAc,CAE9E;AAMD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAErD;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQhE;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CAE3D;AAeD,qBAAa,OAAQ,SAAQ,KAAK;IAChC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;gBAEd,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;IAa5E,IAAI,IAAI,IAAI,SAAS,CAEpB;CACF"}
|