@j0hanz/filesystem-mcp 1.19.1 → 2.1.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 +26 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +18 -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 +37 -0
- package/dist/core/fmt.d.ts.map +1 -0
- package/dist/core/fmt.js +93 -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 +348 -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 +24 -0
- package/dist/core/util.d.ts.map +1 -0
- package/dist/core/util.js +65 -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 +11 -0
- package/dist/instructions.d.ts.map +1 -0
- package/dist/instructions.js +70 -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 +124 -0
- package/dist/tools/create.js.map +1 -0
- package/dist/tools/define.d.ts +102 -0
- package/dist/tools/define.d.ts.map +1 -0
- package/dist/tools/define.js +404 -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 +327 -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 +440 -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 +301 -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 +423 -150
- 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 +432 -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 +45 -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 +189 -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 -585
- 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 -473
- 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
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/server';
|
|
2
|
+
import type { PageSnapshotStore } from '../core/page-store.js';
|
|
3
|
+
import type { PathGuard } from '../core/path.js';
|
|
4
|
+
import type { ResourceStore } from '../core/store.js';
|
|
5
|
+
import type { DefinedTool } from './define.js';
|
|
6
|
+
import { LIST } from './list.js';
|
|
7
|
+
import { READ_FILE } from './read.js';
|
|
8
|
+
import { LIST_ALLOWED_DIRECTORIES } from './roots.js';
|
|
9
|
+
import { SEARCH_CONTENT } from './search-content.js';
|
|
10
|
+
import { SEARCH_FILES } from './search-files.js';
|
|
11
|
+
import { GET_FILE_INFO } from './stat.js';
|
|
12
|
+
export declare const ALL_TOOLS: readonly [DefinedTool, DefinedTool, DefinedTool, DefinedTool, DefinedTool, DefinedTool, DefinedTool, DefinedTool, DefinedTool, DefinedTool, DefinedTool, DefinedTool, DefinedTool];
|
|
13
|
+
export declare const MUTATING_TOOL_NAMES: Set<string>;
|
|
14
|
+
export declare const ALL_REGISTERED_TOOL_NAMES: readonly string[];
|
|
15
|
+
/** The tools a server registers at this setting — the one owner of the `--read-only` gate. */
|
|
16
|
+
export declare function registeredTools(readOnly: boolean): readonly DefinedTool[];
|
|
17
|
+
export { LIST, LIST_ALLOWED_DIRECTORIES, READ_FILE, SEARCH_CONTENT, SEARCH_FILES, GET_FILE_INFO };
|
|
18
|
+
interface ToolRegistrarDeps {
|
|
19
|
+
readonly server: McpServer;
|
|
20
|
+
readonly pathGuard: PathGuard;
|
|
21
|
+
readonly pageStore: PageSnapshotStore;
|
|
22
|
+
readonly resourceStore: ResourceStore;
|
|
23
|
+
readonly readOnly?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare function registerTools(deps: ToolRegistrarDeps): void;
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,eAAO,MAAM,SAAS,oLAcZ,CAAC;AAEX,eAAO,MAAM,mBAAmB,aAE/B,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAAiC,CAAC;AAEzF,8FAA8F;AAC9F,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,WAAW,EAAE,CAEzE;AAOD,OAAO,EAAE,IAAI,EAAE,wBAAwB,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;AAElG,UAAU,iBAAiB;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC;IACtC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAU3D"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { CREATE } from './create.js';
|
|
2
|
+
import { DELETE_FILE } from './delete-file.js';
|
|
3
|
+
import { DIFF } from './diff.js';
|
|
4
|
+
import { EDIT } from './edit.js';
|
|
5
|
+
import { LIST } from './list.js';
|
|
6
|
+
import { MOVE } from './move.js';
|
|
7
|
+
import { PATCH } from './patch.js';
|
|
8
|
+
import { READ_FILE } from './read.js';
|
|
9
|
+
import { SEARCH_AND_REPLACE } from './replace-in-files.js';
|
|
10
|
+
import { LIST_ALLOWED_DIRECTORIES } from './roots.js';
|
|
11
|
+
import { SEARCH_CONTENT } from './search-content.js';
|
|
12
|
+
import { SEARCH_FILES } from './search-files.js';
|
|
13
|
+
import { GET_FILE_INFO } from './stat.js';
|
|
14
|
+
export const ALL_TOOLS = [
|
|
15
|
+
CREATE,
|
|
16
|
+
DELETE_FILE,
|
|
17
|
+
DIFF,
|
|
18
|
+
EDIT,
|
|
19
|
+
LIST,
|
|
20
|
+
MOVE,
|
|
21
|
+
PATCH,
|
|
22
|
+
READ_FILE,
|
|
23
|
+
SEARCH_AND_REPLACE,
|
|
24
|
+
LIST_ALLOWED_DIRECTORIES,
|
|
25
|
+
SEARCH_CONTENT,
|
|
26
|
+
SEARCH_FILES,
|
|
27
|
+
GET_FILE_INFO,
|
|
28
|
+
];
|
|
29
|
+
export const MUTATING_TOOL_NAMES = new Set(ALL_TOOLS.filter((t) => !t.annotations.readOnlyHint).map((t) => t.name));
|
|
30
|
+
export const ALL_REGISTERED_TOOL_NAMES = ALL_TOOLS.map((t) => t.name);
|
|
31
|
+
/** The tools a server registers at this setting — the one owner of the `--read-only` gate. */
|
|
32
|
+
export function registeredTools(readOnly) {
|
|
33
|
+
return readOnly ? ALL_TOOLS.filter((t) => !MUTATING_TOOL_NAMES.has(t.name)) : ALL_TOOLS;
|
|
34
|
+
}
|
|
35
|
+
// Re-exported so documentation surfaces quote `.name` off the definition rather
|
|
36
|
+
// than repeating the string. This module is the only owner of the inventory.
|
|
37
|
+
// Only the read-only tools are named individually: the mutating six are no
|
|
38
|
+
// longer listed by hand anywhere, so their names reach callers through
|
|
39
|
+
// MUTATING_TOOL_NAMES and ALL_TOOLS instead.
|
|
40
|
+
export { LIST, LIST_ALLOWED_DIRECTORIES, READ_FILE, SEARCH_CONTENT, SEARCH_FILES, GET_FILE_INFO };
|
|
41
|
+
export function registerTools(deps) {
|
|
42
|
+
const toolDeps = {
|
|
43
|
+
server: deps.server,
|
|
44
|
+
pathGuard: deps.pathGuard,
|
|
45
|
+
pageStore: deps.pageStore,
|
|
46
|
+
resourceStore: deps.resourceStore,
|
|
47
|
+
};
|
|
48
|
+
for (const tool of registeredTools(deps.readOnly ?? false)) {
|
|
49
|
+
tool.register(toolDeps);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,MAAM;IACN,WAAW;IACX,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,KAAK;IACL,SAAS;IACT,kBAAkB;IAClB,wBAAwB;IACxB,cAAc;IACd,YAAY;IACZ,aAAa;CACL,CAAC;AAEX,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,GAAG,CACxC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CACxE,CAAC;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAAsB,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAEzF,8FAA8F;AAC9F,MAAM,UAAU,eAAe,CAAC,QAAiB;IAC/C,OAAO,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1F,CAAC;AAED,gFAAgF;AAChF,6EAA6E;AAC7E,2EAA2E;AAC3E,uEAAuE;AACvE,6CAA6C;AAC7C,OAAO,EAAE,IAAI,EAAE,wBAAwB,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;AAUlG,MAAM,UAAU,aAAa,CAAC,IAAuB;IACnD,MAAM,QAAQ,GAAG;QACf,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,aAAa,EAAE,IAAI,CAAC,aAAa;KAClC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,eAAe,CAAC,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,EAAE,CAAC;QAC3D,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC;AACH,CAAC","sourcesContent":["import type { McpServer } from '@modelcontextprotocol/server';\n\nimport type { PageSnapshotStore } from '../core/page-store.js';\nimport type { PathGuard } from '../core/path.js';\nimport type { ResourceStore } from '../core/store.js';\nimport { CREATE } from './create.js';\nimport type { DefinedTool } from './define.js';\nimport { DELETE_FILE } from './delete-file.js';\nimport { DIFF } from './diff.js';\nimport { EDIT } from './edit.js';\nimport { LIST } from './list.js';\nimport { MOVE } from './move.js';\nimport { PATCH } from './patch.js';\nimport { READ_FILE } from './read.js';\nimport { SEARCH_AND_REPLACE } from './replace-in-files.js';\nimport { LIST_ALLOWED_DIRECTORIES } from './roots.js';\nimport { SEARCH_CONTENT } from './search-content.js';\nimport { SEARCH_FILES } from './search-files.js';\nimport { GET_FILE_INFO } from './stat.js';\n\nexport const ALL_TOOLS = [\n CREATE,\n DELETE_FILE,\n DIFF,\n EDIT,\n LIST,\n MOVE,\n PATCH,\n READ_FILE,\n SEARCH_AND_REPLACE,\n LIST_ALLOWED_DIRECTORIES,\n SEARCH_CONTENT,\n SEARCH_FILES,\n GET_FILE_INFO,\n] as const;\n\nexport const MUTATING_TOOL_NAMES = new Set(\n ALL_TOOLS.filter((t) => !t.annotations.readOnlyHint).map((t) => t.name),\n);\n\nexport const ALL_REGISTERED_TOOL_NAMES: readonly string[] = ALL_TOOLS.map((t) => t.name);\n\n/** The tools a server registers at this setting — the one owner of the `--read-only` gate. */\nexport function registeredTools(readOnly: boolean): readonly DefinedTool[] {\n return readOnly ? ALL_TOOLS.filter((t) => !MUTATING_TOOL_NAMES.has(t.name)) : ALL_TOOLS;\n}\n\n// Re-exported so documentation surfaces quote `.name` off the definition rather\n// than repeating the string. This module is the only owner of the inventory.\n// Only the read-only tools are named individually: the mutating six are no\n// longer listed by hand anywhere, so their names reach callers through\n// MUTATING_TOOL_NAMES and ALL_TOOLS instead.\nexport { LIST, LIST_ALLOWED_DIRECTORIES, READ_FILE, SEARCH_CONTENT, SEARCH_FILES, GET_FILE_INFO };\n\ninterface ToolRegistrarDeps {\n readonly server: McpServer;\n readonly pathGuard: PathGuard;\n readonly pageStore: PageSnapshotStore;\n readonly resourceStore: ResourceStore;\n readonly readOnly?: boolean;\n}\n\nexport function registerTools(deps: ToolRegistrarDeps): void {\n const toolDeps = {\n server: deps.server,\n pathGuard: deps.pathGuard,\n pageStore: deps.pageStore,\n resourceStore: deps.resourceStore,\n };\n for (const tool of registeredTools(deps.readOnly ?? false)) {\n tool.register(toolDeps);\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/tools/list.ts"],"names":[],"mappings":"AAuWA,eAAO,MAAM,IAAI,mCA6Cf,CAAC"}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { basename } from 'node:path';
|
|
2
|
+
import * as z from 'zod/v4';
|
|
3
|
+
import { timedSignal } from '../core/concurrency.js';
|
|
4
|
+
import { createFirstPage, readNextPage } from '../core/cursor.js';
|
|
5
|
+
import { ErrorCode } from '../core/errors.js';
|
|
6
|
+
import { DEFAULT_EXCLUDE_PATTERNS, globEntries, isIgnoredByGitignore, loadRootGitignore, resolveEntryType, } from '../core/glob.js';
|
|
7
|
+
import { toPosixRelative } from '../core/path.js';
|
|
8
|
+
import { CursorSchema, FileType as FileTypeEnum, includeHiddenField, includeIgnoredField, NextCursorSchema, NonNegInt, OptionalPath, PositiveInt, } from '../core/schema.js';
|
|
9
|
+
import { putJsonResource } from '../core/store.js';
|
|
10
|
+
import { DEFAULT_SEARCH_TIMEOUT_MS, DEFAULT_TREE_ENTRIES, MAX_LIST_ENTRIES, MAX_TREE_DEPTH, } from '../core/util.js';
|
|
11
|
+
import { defineTool } from './define.js';
|
|
12
|
+
function entryTypeRank(type) {
|
|
13
|
+
if (type === 'directory')
|
|
14
|
+
return 0;
|
|
15
|
+
return 1;
|
|
16
|
+
}
|
|
17
|
+
function compareEntries(a, b) {
|
|
18
|
+
// Compare by parent directory first (depth-level grouping)
|
|
19
|
+
const slashA = a.relativePath.lastIndexOf('/');
|
|
20
|
+
const slashB = b.relativePath.lastIndexOf('/');
|
|
21
|
+
const parentA = slashA === -1 ? '' : a.relativePath.slice(0, slashA);
|
|
22
|
+
const parentB = slashB === -1 ? '' : b.relativePath.slice(0, slashB);
|
|
23
|
+
if (parentA !== parentB)
|
|
24
|
+
return parentA.localeCompare(parentB);
|
|
25
|
+
// Within same parent: dirs first, then alphabetical
|
|
26
|
+
const rankDiff = entryTypeRank(a.type) - entryTypeRank(b.type);
|
|
27
|
+
if (rankDiff !== 0)
|
|
28
|
+
return rankDiff;
|
|
29
|
+
return a.name.localeCompare(b.name);
|
|
30
|
+
}
|
|
31
|
+
async function collect(rootPath, options) {
|
|
32
|
+
const gitignoreMatcher = options.includeIgnored
|
|
33
|
+
? null
|
|
34
|
+
: await loadRootGitignore(rootPath, options.signal);
|
|
35
|
+
const entries = [];
|
|
36
|
+
let scanned = 0;
|
|
37
|
+
let totalEntries = 0;
|
|
38
|
+
let totalFiles = 0;
|
|
39
|
+
let totalDirectories = 0;
|
|
40
|
+
for await (const entry of globEntries({
|
|
41
|
+
cwd: rootPath,
|
|
42
|
+
pattern: '**/*',
|
|
43
|
+
excludePatterns: options.includeIgnored ? [] : DEFAULT_EXCLUDE_PATTERNS,
|
|
44
|
+
includeHidden: options.includeHidden,
|
|
45
|
+
baseNameMatch: false,
|
|
46
|
+
// ListInputSchema.maxDepth is 1-based (1 = top-level only); the shared
|
|
47
|
+
// globEntries primitive is now 0-based, so subtract one here. options.maxDepth
|
|
48
|
+
// is guaranteed >= 1 by its PositiveInt schema, so this never underflows.
|
|
49
|
+
maxDepth: options.maxDepth - 1,
|
|
50
|
+
onlyFiles: false,
|
|
51
|
+
})) {
|
|
52
|
+
options.signal.throwIfAborted();
|
|
53
|
+
scanned++;
|
|
54
|
+
options.onProgress?.({ current: scanned });
|
|
55
|
+
const entryType = resolveEntryType(entry.dirent);
|
|
56
|
+
const isDir = entryType === 'directory';
|
|
57
|
+
const relPath = toPosixRelative(rootPath, entry.path);
|
|
58
|
+
const name = basename(relPath);
|
|
59
|
+
if (gitignoreMatcher &&
|
|
60
|
+
isIgnoredByGitignore(gitignoreMatcher, rootPath, entry.path, {
|
|
61
|
+
isDirectory: isDir,
|
|
62
|
+
})) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const accessible = await options.pathGuard.isEntryAccessible(entry.path, entryType, [rootPath]);
|
|
66
|
+
if (!accessible)
|
|
67
|
+
continue;
|
|
68
|
+
totalEntries++;
|
|
69
|
+
if (entryType === 'directory') {
|
|
70
|
+
totalDirectories++;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
totalFiles++;
|
|
74
|
+
}
|
|
75
|
+
const collectedEntry = {
|
|
76
|
+
name,
|
|
77
|
+
relativePath: relPath,
|
|
78
|
+
type: entryType,
|
|
79
|
+
};
|
|
80
|
+
if (entries.length < options.entryCap) {
|
|
81
|
+
entries.push(collectedEntry);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
options.signal.throwIfAborted();
|
|
85
|
+
entries.sort(compareEntries);
|
|
86
|
+
return {
|
|
87
|
+
entries,
|
|
88
|
+
totalEntries,
|
|
89
|
+
totalFiles,
|
|
90
|
+
totalDirectories,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const TEE = '├── ';
|
|
94
|
+
const ELBOW = '└── ';
|
|
95
|
+
const PIPE = '│ ';
|
|
96
|
+
const INDENT = ' ';
|
|
97
|
+
function renderMarkdown(rootName, entries) {
|
|
98
|
+
if (entries.length === 0)
|
|
99
|
+
return rootName;
|
|
100
|
+
// Group entries by parent path
|
|
101
|
+
const childrenOf = new Map();
|
|
102
|
+
for (const entry of entries) {
|
|
103
|
+
const slash = entry.relativePath.lastIndexOf('/');
|
|
104
|
+
const parentKey = slash === -1 ? '' : entry.relativePath.slice(0, slash);
|
|
105
|
+
if (!childrenOf.has(parentKey))
|
|
106
|
+
childrenOf.set(parentKey, []);
|
|
107
|
+
const children = childrenOf.get(parentKey);
|
|
108
|
+
if (children)
|
|
109
|
+
children.push(entry);
|
|
110
|
+
}
|
|
111
|
+
const lines = [rootName];
|
|
112
|
+
function renderChildren(parentKey, prefix) {
|
|
113
|
+
const children = childrenOf.get(parentKey);
|
|
114
|
+
if (!children)
|
|
115
|
+
return;
|
|
116
|
+
for (let i = 0; i < children.length; i++) {
|
|
117
|
+
const child = children[i];
|
|
118
|
+
if (!child)
|
|
119
|
+
continue;
|
|
120
|
+
const isLast = i === children.length - 1;
|
|
121
|
+
const connector = isLast ? ELBOW : TEE;
|
|
122
|
+
lines.push(prefix + connector + child.name);
|
|
123
|
+
const childKey = child.relativePath;
|
|
124
|
+
const nextPrefix = prefix + (isLast ? INDENT : PIPE);
|
|
125
|
+
renderChildren(childKey, nextPrefix);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
renderChildren('', '');
|
|
129
|
+
return lines.join('\n');
|
|
130
|
+
}
|
|
131
|
+
const DEFAULT_LIST_DEPTH = 1;
|
|
132
|
+
const DEFAULT_LIST_ENTRIES = DEFAULT_TREE_ENTRIES;
|
|
133
|
+
const ListInputSchema = z.strictObject({
|
|
134
|
+
path: OptionalPath.describe('Directory to list (default: first allowed root)'),
|
|
135
|
+
maxDepth: PositiveInt.max(MAX_TREE_DEPTH)
|
|
136
|
+
.default(DEFAULT_LIST_DEPTH)
|
|
137
|
+
.describe(`Max directory depth to traverse (default: ${String(DEFAULT_LIST_DEPTH)} = top-level only; increase to recurse deeper)`),
|
|
138
|
+
maxEntries: PositiveInt.max(MAX_LIST_ENTRIES)
|
|
139
|
+
.default(DEFAULT_LIST_ENTRIES)
|
|
140
|
+
.describe(`Page size (default: ${String(DEFAULT_LIST_ENTRIES)}). Continue with nextCursor; resourceUri is only for hard-cap overflow.`),
|
|
141
|
+
includeHidden: includeHiddenField(),
|
|
142
|
+
includeIgnored: includeIgnoredField(),
|
|
143
|
+
cursor: CursorSchema,
|
|
144
|
+
});
|
|
145
|
+
const ListOutputSchema = z.strictObject({
|
|
146
|
+
path: z.string().optional().describe('Resolved absolute path of the listed directory'),
|
|
147
|
+
entries: z
|
|
148
|
+
.array(z.strictObject({
|
|
149
|
+
name: z.string().describe('Entry basename'),
|
|
150
|
+
relativePath: z.string().describe('POSIX path relative to the listed directory'),
|
|
151
|
+
type: FileTypeEnum.describe('Entry type: file, directory, symlink, or other'),
|
|
152
|
+
}))
|
|
153
|
+
.describe('Inline directory entries sorted directories-first then alphabetically by name'),
|
|
154
|
+
// No `markdown` field: the ASCII tree is the call's text content already, and
|
|
155
|
+
// carrying it here too doubled every list response for a string the client
|
|
156
|
+
// has in hand. The stored full-tree resource still holds its own copy — that
|
|
157
|
+
// one is a *different* (uncapped) tree and is never sent inline.
|
|
158
|
+
entryCount: NonNegInt.describe('Number of entries included in this response'),
|
|
159
|
+
totalEntries: NonNegInt.describe('Total entries found before the maxEntries cap was applied'),
|
|
160
|
+
totalFiles: NonNegInt.describe('Total number of files found'),
|
|
161
|
+
totalDirectories: NonNegInt.describe('Total number of directories found'),
|
|
162
|
+
resourceUri: z
|
|
163
|
+
.string()
|
|
164
|
+
.optional()
|
|
165
|
+
.describe('URI to the full entry list in the resource store; first page only, when total entries exceed the ' +
|
|
166
|
+
'hard cap (the same cap that bounds pagination; page via nextCursor below it). The stored list is ' +
|
|
167
|
+
'itself capped at that limit and marked truncated if exceeded.'),
|
|
168
|
+
nextCursor: NextCursorSchema,
|
|
169
|
+
});
|
|
170
|
+
function listQueryKey(args, path) {
|
|
171
|
+
return JSON.stringify({
|
|
172
|
+
method: 'list',
|
|
173
|
+
path,
|
|
174
|
+
maxDepth: args.maxDepth,
|
|
175
|
+
includeHidden: args.includeHidden,
|
|
176
|
+
includeIgnored: args.includeIgnored,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
function listOutput(entries, metadata, nextCursor) {
|
|
180
|
+
return {
|
|
181
|
+
path: metadata.path,
|
|
182
|
+
entries: [...entries],
|
|
183
|
+
entryCount: entries.length,
|
|
184
|
+
totalEntries: metadata.totalEntries,
|
|
185
|
+
totalFiles: metadata.totalFiles,
|
|
186
|
+
totalDirectories: metadata.totalDirectories,
|
|
187
|
+
...(metadata.resourceUri ? { resourceUri: metadata.resourceUri } : {}),
|
|
188
|
+
...(nextCursor !== undefined ? { nextCursor } : {}),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
async function handleList(args, ctx) {
|
|
192
|
+
const path = args.path;
|
|
193
|
+
const resolvedPath = ctx.fs.pathGuard.resolvePathOrRoot(path);
|
|
194
|
+
const queryKey = listQueryKey(args, resolvedPath);
|
|
195
|
+
if (args.cursor !== undefined) {
|
|
196
|
+
const paged = readNextPage({
|
|
197
|
+
store: ctx.pageStore,
|
|
198
|
+
queryKey,
|
|
199
|
+
cursor: args.cursor,
|
|
200
|
+
pageSize: args.maxEntries,
|
|
201
|
+
});
|
|
202
|
+
// First page only: the overflow entry runs on ResourceStore's own TTL and
|
|
203
|
+
// LRU, not this snapshot's, so replaying it hands back a dead pointer.
|
|
204
|
+
const { resourceUri: _firstPageOnly, ...pageMetadata } = paged.metadata;
|
|
205
|
+
return {
|
|
206
|
+
structured: listOutput(paged.page, pageMetadata, paged.nextCursor),
|
|
207
|
+
markdown: renderMarkdown(basename(paged.metadata.path), [...paged.page]),
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
const validDir = await ctx.fs.pathGuard.validateExistingDirectory(resolvedPath);
|
|
211
|
+
const result = await collect(validDir, {
|
|
212
|
+
maxDepth: args.maxDepth,
|
|
213
|
+
includeHidden: args.includeHidden,
|
|
214
|
+
includeIgnored: args.includeIgnored,
|
|
215
|
+
signal: timedSignal(ctx.signal, DEFAULT_SEARCH_TIMEOUT_MS),
|
|
216
|
+
pathGuard: ctx.fs.pathGuard,
|
|
217
|
+
entryCap: MAX_LIST_ENTRIES,
|
|
218
|
+
...(ctx.onProgress ? { onProgress: ctx.onProgress } : {}),
|
|
219
|
+
});
|
|
220
|
+
let resourceUri;
|
|
221
|
+
let link;
|
|
222
|
+
if (result.totalEntries > result.entries.length && ctx.resourceStore) {
|
|
223
|
+
const fullMarkdown = renderMarkdown(basename(validDir), result.entries);
|
|
224
|
+
const fullTruncated = result.totalEntries > result.entries.length;
|
|
225
|
+
const fullOutput = {
|
|
226
|
+
entries: result.entries,
|
|
227
|
+
markdown: fullMarkdown,
|
|
228
|
+
totalEntries: result.totalEntries,
|
|
229
|
+
totalFiles: result.totalFiles,
|
|
230
|
+
totalDirectories: result.totalDirectories,
|
|
231
|
+
...(fullTruncated ? { truncated: true } : {}),
|
|
232
|
+
};
|
|
233
|
+
const res = putJsonResource(ctx.resourceStore, `${basename(validDir)} tree`, fullOutput);
|
|
234
|
+
resourceUri = res.entry.uri;
|
|
235
|
+
link = res.link;
|
|
236
|
+
}
|
|
237
|
+
const metadata = {
|
|
238
|
+
path: validDir,
|
|
239
|
+
totalEntries: result.totalEntries,
|
|
240
|
+
totalFiles: result.totalFiles,
|
|
241
|
+
totalDirectories: result.totalDirectories,
|
|
242
|
+
...(resourceUri ? { resourceUri } : {}),
|
|
243
|
+
};
|
|
244
|
+
const paged = createFirstPage({
|
|
245
|
+
store: ctx.pageStore,
|
|
246
|
+
queryKey,
|
|
247
|
+
items: result.entries,
|
|
248
|
+
metadata,
|
|
249
|
+
pageSize: args.maxEntries,
|
|
250
|
+
});
|
|
251
|
+
const output = listOutput(paged.page, metadata, paged.nextCursor);
|
|
252
|
+
return {
|
|
253
|
+
structured: output,
|
|
254
|
+
markdown: renderMarkdown(basename(validDir), [...paged.page]),
|
|
255
|
+
...(link ? { link } : {}),
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
export const LIST = defineTool({
|
|
259
|
+
name: 'list',
|
|
260
|
+
title: 'List',
|
|
261
|
+
description: 'List sorted directory entries and an ASCII tree. maxDepth=1 is top-level. ' +
|
|
262
|
+
'maxEntries sets page size; continue with nextCursor. resourceUri is only for hard-cap overflow.',
|
|
263
|
+
input: ListInputSchema,
|
|
264
|
+
output: ListOutputSchema,
|
|
265
|
+
// Not published: every field is a plainly-named scalar (`entryCount`,
|
|
266
|
+
// `totalFiles`, `nextCursor`) that one sample response teaches, and the
|
|
267
|
+
// schema costs 1599 chars of every session start. Publishing is reserved for
|
|
268
|
+
// the value-XOR-error union shape a sample cannot convey.
|
|
269
|
+
annotations: {
|
|
270
|
+
readOnlyHint: true,
|
|
271
|
+
idempotentHint: true,
|
|
272
|
+
destructiveHint: false,
|
|
273
|
+
openWorldHint: false,
|
|
274
|
+
},
|
|
275
|
+
timeoutMs: DEFAULT_SEARCH_TIMEOUT_MS,
|
|
276
|
+
defaultErrorCode: ErrorCode.NOT_DIRECTORY,
|
|
277
|
+
progress: (args) => ({
|
|
278
|
+
label: 'List',
|
|
279
|
+
subject: args.path ? basename(args.path) : '.',
|
|
280
|
+
}),
|
|
281
|
+
accessPaths: (args) => (args.path ? [args.path] : []),
|
|
282
|
+
run: async (args, ctx) => {
|
|
283
|
+
const { structured, markdown, link } = await handleList(args, ctx);
|
|
284
|
+
// The tree is what the model reads; nextCursor and the overflow notice used
|
|
285
|
+
// to reach it only through the structured half, which now ships as _meta.
|
|
286
|
+
// Both ride the text so paging needs no second lookup.
|
|
287
|
+
const trailer = [];
|
|
288
|
+
if (structured.nextCursor !== undefined) {
|
|
289
|
+
trailer.push(`nextCursor: ${structured.nextCursor}`);
|
|
290
|
+
}
|
|
291
|
+
if (structured.resourceUri !== undefined) {
|
|
292
|
+
trailer.push(`truncated: ${String(structured.entryCount)} of ${String(structured.totalEntries)} entries shown; full tree at ${structured.resourceUri}`);
|
|
293
|
+
}
|
|
294
|
+
return {
|
|
295
|
+
structured,
|
|
296
|
+
text: trailer.length > 0 ? `${markdown}\n\n${trailer.join('\n')}` : markdown,
|
|
297
|
+
...(link ? { resources: [link] } : {}),
|
|
298
|
+
};
|
|
299
|
+
},
|
|
300
|
+
});
|
|
301
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/tools/list.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContentBlock } from '@modelcontextprotocol/server';\n\nimport { basename } from 'node:path';\n\nimport * as z from 'zod/v4';\n\nimport { timedSignal } from '../core/concurrency.js';\nimport { createFirstPage, readNextPage } from '../core/cursor.js';\nimport { ErrorCode } from '../core/errors.js';\nimport type { EntryType } from '../core/glob.js';\nimport {\n DEFAULT_EXCLUDE_PATTERNS,\n globEntries,\n isIgnoredByGitignore,\n loadRootGitignore,\n resolveEntryType,\n} from '../core/glob.js';\nimport type { PathGuard } from '../core/path.js';\nimport { toPosixRelative } from '../core/path.js';\nimport {\n CursorSchema,\n FileType as FileTypeEnum,\n includeHiddenField,\n includeIgnoredField,\n NextCursorSchema,\n NonNegInt,\n OptionalPath,\n PositiveInt,\n} from '../core/schema.js';\nimport { putJsonResource } from '../core/store.js';\nimport {\n DEFAULT_SEARCH_TIMEOUT_MS,\n DEFAULT_TREE_ENTRIES,\n MAX_LIST_ENTRIES,\n MAX_TREE_DEPTH,\n} from '../core/util.js';\nimport { defineTool, type ToolCtx } from './define.js';\n\ninterface CollectedEntry {\n name: string;\n relativePath: string; // POSIX\n type: EntryType;\n}\n\ninterface CollectOptions {\n maxDepth: number;\n includeHidden: boolean;\n includeIgnored: boolean;\n signal: AbortSignal;\n pathGuard: PathGuard;\n /** Upper bound on the stored, paginable entry array. */\n entryCap: number;\n onProgress?: (progress: { current: number; total?: number }) => void;\n}\n\ninterface CollectResult {\n entries: CollectedEntry[];\n totalEntries: number;\n totalFiles: number;\n totalDirectories: number;\n}\n\nfunction entryTypeRank(type: EntryType): number {\n if (type === 'directory') return 0;\n return 1;\n}\n\nfunction compareEntries(a: CollectedEntry, b: CollectedEntry): number {\n // Compare by parent directory first (depth-level grouping)\n const slashA = a.relativePath.lastIndexOf('/');\n const slashB = b.relativePath.lastIndexOf('/');\n const parentA = slashA === -1 ? '' : a.relativePath.slice(0, slashA);\n const parentB = slashB === -1 ? '' : b.relativePath.slice(0, slashB);\n\n if (parentA !== parentB) return parentA.localeCompare(parentB);\n\n // Within same parent: dirs first, then alphabetical\n const rankDiff = entryTypeRank(a.type) - entryTypeRank(b.type);\n if (rankDiff !== 0) return rankDiff;\n return a.name.localeCompare(b.name);\n}\n\nasync function collect(rootPath: string, options: CollectOptions): Promise<CollectResult> {\n const gitignoreMatcher = options.includeIgnored\n ? null\n : await loadRootGitignore(rootPath, options.signal);\n\n const entries: CollectedEntry[] = [];\n let scanned = 0;\n let totalEntries = 0;\n let totalFiles = 0;\n let totalDirectories = 0;\n\n for await (const entry of globEntries({\n cwd: rootPath,\n pattern: '**/*',\n excludePatterns: options.includeIgnored ? [] : DEFAULT_EXCLUDE_PATTERNS,\n includeHidden: options.includeHidden,\n baseNameMatch: false,\n // ListInputSchema.maxDepth is 1-based (1 = top-level only); the shared\n // globEntries primitive is now 0-based, so subtract one here. options.maxDepth\n // is guaranteed >= 1 by its PositiveInt schema, so this never underflows.\n maxDepth: options.maxDepth - 1,\n onlyFiles: false,\n })) {\n options.signal.throwIfAborted();\n scanned++;\n options.onProgress?.({ current: scanned });\n\n const entryType: EntryType = resolveEntryType(entry.dirent);\n const isDir = entryType === 'directory';\n const relPath = toPosixRelative(rootPath, entry.path);\n const name = basename(relPath);\n\n if (\n gitignoreMatcher &&\n isIgnoredByGitignore(gitignoreMatcher, rootPath, entry.path, {\n isDirectory: isDir,\n })\n ) {\n continue;\n }\n const accessible = await options.pathGuard.isEntryAccessible(entry.path, entryType, [rootPath]);\n if (!accessible) continue;\n\n totalEntries++;\n if (entryType === 'directory') {\n totalDirectories++;\n } else {\n totalFiles++;\n }\n\n const collectedEntry: CollectedEntry = {\n name,\n relativePath: relPath,\n type: entryType,\n };\n\n if (entries.length < options.entryCap) {\n entries.push(collectedEntry);\n }\n }\n\n options.signal.throwIfAborted();\n entries.sort(compareEntries);\n\n return {\n entries,\n totalEntries,\n totalFiles,\n totalDirectories,\n };\n}\n\nconst TEE = '├── ';\nconst ELBOW = '└── ';\nconst PIPE = '│ ';\nconst INDENT = ' ';\n\nfunction renderMarkdown(rootName: string, entries: CollectedEntry[]): string {\n if (entries.length === 0) return rootName;\n\n // Group entries by parent path\n const childrenOf = new Map<string, CollectedEntry[]>();\n for (const entry of entries) {\n const slash = entry.relativePath.lastIndexOf('/');\n const parentKey = slash === -1 ? '' : entry.relativePath.slice(0, slash);\n if (!childrenOf.has(parentKey)) childrenOf.set(parentKey, []);\n const children = childrenOf.get(parentKey);\n if (children) children.push(entry);\n }\n\n const lines: string[] = [rootName];\n\n function renderChildren(parentKey: string, prefix: string): void {\n const children = childrenOf.get(parentKey);\n if (!children) return;\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (!child) continue;\n const isLast = i === children.length - 1;\n const connector = isLast ? ELBOW : TEE;\n lines.push(prefix + connector + child.name);\n\n const childKey = child.relativePath;\n const nextPrefix = prefix + (isLast ? INDENT : PIPE);\n renderChildren(childKey, nextPrefix);\n }\n }\n\n renderChildren('', '');\n return lines.join('\\n');\n}\n\nconst DEFAULT_LIST_DEPTH = 1;\nconst DEFAULT_LIST_ENTRIES = DEFAULT_TREE_ENTRIES;\n\nconst ListInputSchema = z.strictObject({\n path: OptionalPath.describe('Directory to list (default: first allowed root)'),\n maxDepth: PositiveInt.max(MAX_TREE_DEPTH)\n .default(DEFAULT_LIST_DEPTH)\n .describe(\n `Max directory depth to traverse (default: ${String(DEFAULT_LIST_DEPTH)} = top-level only; increase to recurse deeper)`,\n ),\n maxEntries: PositiveInt.max(MAX_LIST_ENTRIES)\n .default(DEFAULT_LIST_ENTRIES)\n .describe(\n `Page size (default: ${String(DEFAULT_LIST_ENTRIES)}). Continue with nextCursor; resourceUri is only for hard-cap overflow.`,\n ),\n includeHidden: includeHiddenField(),\n includeIgnored: includeIgnoredField(),\n cursor: CursorSchema,\n});\n\nconst ListOutputSchema = z.strictObject({\n path: z.string().optional().describe('Resolved absolute path of the listed directory'),\n entries: z\n .array(\n z.strictObject({\n name: z.string().describe('Entry basename'),\n relativePath: z.string().describe('POSIX path relative to the listed directory'),\n type: FileTypeEnum.describe('Entry type: file, directory, symlink, or other'),\n }),\n )\n .describe('Inline directory entries sorted directories-first then alphabetically by name'),\n // No `markdown` field: the ASCII tree is the call's text content already, and\n // carrying it here too doubled every list response for a string the client\n // has in hand. The stored full-tree resource still holds its own copy — that\n // one is a *different* (uncapped) tree and is never sent inline.\n entryCount: NonNegInt.describe('Number of entries included in this response'),\n totalEntries: NonNegInt.describe('Total entries found before the maxEntries cap was applied'),\n totalFiles: NonNegInt.describe('Total number of files found'),\n totalDirectories: NonNegInt.describe('Total number of directories found'),\n resourceUri: z\n .string()\n .optional()\n .describe(\n 'URI to the full entry list in the resource store; first page only, when total entries exceed the ' +\n 'hard cap (the same cap that bounds pagination; page via nextCursor below it). The stored list is ' +\n 'itself capped at that limit and marked truncated if exceeded.',\n ),\n nextCursor: NextCursorSchema,\n});\n\ninterface ListPageMetadata {\n readonly path: string;\n readonly totalEntries: number;\n readonly totalFiles: number;\n readonly totalDirectories: number;\n readonly resourceUri?: string;\n}\n\nfunction listQueryKey(args: z.infer<typeof ListInputSchema>, path: string): string {\n return JSON.stringify({\n method: 'list',\n path,\n maxDepth: args.maxDepth,\n includeHidden: args.includeHidden,\n includeIgnored: args.includeIgnored,\n });\n}\n\nfunction listOutput(\n entries: readonly CollectedEntry[],\n metadata: ListPageMetadata,\n nextCursor: string | undefined,\n): z.infer<typeof ListOutputSchema> {\n return {\n path: metadata.path,\n entries: [...entries],\n entryCount: entries.length,\n totalEntries: metadata.totalEntries,\n totalFiles: metadata.totalFiles,\n totalDirectories: metadata.totalDirectories,\n ...(metadata.resourceUri ? { resourceUri: metadata.resourceUri } : {}),\n ...(nextCursor !== undefined ? { nextCursor } : {}),\n };\n}\n\nasync function handleList(\n args: z.infer<typeof ListInputSchema>,\n ctx: ToolCtx,\n): Promise<{\n structured: z.infer<typeof ListOutputSchema>;\n markdown: string;\n link?: ContentBlock;\n}> {\n const path = args.path;\n const resolvedPath = ctx.fs.pathGuard.resolvePathOrRoot(path);\n const queryKey = listQueryKey(args, resolvedPath);\n\n if (args.cursor !== undefined) {\n const paged = readNextPage<CollectedEntry, ListPageMetadata>({\n store: ctx.pageStore,\n queryKey,\n cursor: args.cursor,\n pageSize: args.maxEntries,\n });\n // First page only: the overflow entry runs on ResourceStore's own TTL and\n // LRU, not this snapshot's, so replaying it hands back a dead pointer.\n const { resourceUri: _firstPageOnly, ...pageMetadata } = paged.metadata;\n return {\n structured: listOutput(paged.page, pageMetadata, paged.nextCursor),\n markdown: renderMarkdown(basename(paged.metadata.path), [...paged.page]),\n };\n }\n\n const validDir = await ctx.fs.pathGuard.validateExistingDirectory(resolvedPath);\n const result = await collect(validDir, {\n maxDepth: args.maxDepth,\n includeHidden: args.includeHidden,\n includeIgnored: args.includeIgnored,\n signal: timedSignal(ctx.signal, DEFAULT_SEARCH_TIMEOUT_MS),\n pathGuard: ctx.fs.pathGuard,\n entryCap: MAX_LIST_ENTRIES,\n ...(ctx.onProgress ? { onProgress: ctx.onProgress } : {}),\n });\n let resourceUri: string | undefined;\n let link: ContentBlock | undefined;\n if (result.totalEntries > result.entries.length && ctx.resourceStore) {\n const fullMarkdown = renderMarkdown(basename(validDir), result.entries);\n const fullTruncated = result.totalEntries > result.entries.length;\n const fullOutput = {\n entries: result.entries,\n markdown: fullMarkdown,\n totalEntries: result.totalEntries,\n totalFiles: result.totalFiles,\n totalDirectories: result.totalDirectories,\n ...(fullTruncated ? { truncated: true } : {}),\n };\n const res = putJsonResource(ctx.resourceStore, `${basename(validDir)} tree`, fullOutput);\n resourceUri = res.entry.uri;\n link = res.link;\n }\n\n const metadata: ListPageMetadata = {\n path: validDir,\n totalEntries: result.totalEntries,\n totalFiles: result.totalFiles,\n totalDirectories: result.totalDirectories,\n ...(resourceUri ? { resourceUri } : {}),\n };\n const paged = createFirstPage<CollectedEntry, ListPageMetadata>({\n store: ctx.pageStore,\n queryKey,\n items: result.entries,\n metadata,\n pageSize: args.maxEntries,\n });\n const output = listOutput(paged.page, metadata, paged.nextCursor);\n\n return {\n structured: output,\n markdown: renderMarkdown(basename(validDir), [...paged.page]),\n ...(link ? { link } : {}),\n };\n}\n\nexport const LIST = defineTool({\n name: 'list',\n title: 'List',\n description:\n 'List sorted directory entries and an ASCII tree. maxDepth=1 is top-level. ' +\n 'maxEntries sets page size; continue with nextCursor. resourceUri is only for hard-cap overflow.',\n input: ListInputSchema,\n output: ListOutputSchema,\n // Not published: every field is a plainly-named scalar (`entryCount`,\n // `totalFiles`, `nextCursor`) that one sample response teaches, and the\n // schema costs 1599 chars of every session start. Publishing is reserved for\n // the value-XOR-error union shape a sample cannot convey.\n annotations: {\n readOnlyHint: true,\n idempotentHint: true,\n destructiveHint: false,\n openWorldHint: false,\n },\n timeoutMs: DEFAULT_SEARCH_TIMEOUT_MS,\n defaultErrorCode: ErrorCode.NOT_DIRECTORY,\n progress: (args) => ({\n label: 'List',\n subject: args.path ? basename(args.path) : '.',\n }),\n accessPaths: (args) => (args.path ? [args.path] : []),\n run: async (args, ctx) => {\n const { structured, markdown, link } = await handleList(args, ctx);\n // The tree is what the model reads; nextCursor and the overflow notice used\n // to reach it only through the structured half, which now ships as _meta.\n // Both ride the text so paging needs no second lookup.\n const trailer: string[] = [];\n if (structured.nextCursor !== undefined) {\n trailer.push(`nextCursor: ${structured.nextCursor}`);\n }\n if (structured.resourceUri !== undefined) {\n trailer.push(\n `truncated: ${String(structured.entryCount)} of ${String(structured.totalEntries)} entries shown; full tree at ${structured.resourceUri}`,\n );\n }\n return {\n structured,\n text: trailer.length > 0 ? `${markdown}\\n\\n${trailer.join('\\n')}` : markdown,\n ...(link ? { resources: [link] } : {}),\n };\n },\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"move.d.ts","sourceRoot":"","sources":["../../src/tools/move.ts"],"names":[],"mappings":"AAsaA,eAAO,MAAM,IAAI,mCA8Cf,CAAC"}
|