@dexto/tools-filesystem 1.5.8 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/directory-approval.cjs +98 -0
  2. package/dist/directory-approval.d.ts +24 -0
  3. package/dist/directory-approval.d.ts.map +1 -0
  4. package/dist/directory-approval.integration.test.cjs +175 -390
  5. package/dist/directory-approval.integration.test.d.ts +14 -2
  6. package/dist/directory-approval.integration.test.d.ts.map +1 -0
  7. package/dist/directory-approval.integration.test.js +178 -390
  8. package/dist/directory-approval.js +63 -0
  9. package/dist/edit-file-tool.cjs +109 -120
  10. package/dist/edit-file-tool.d.ts +22 -9
  11. package/dist/edit-file-tool.d.ts.map +1 -0
  12. package/dist/edit-file-tool.js +116 -110
  13. package/dist/edit-file-tool.test.cjs +109 -29
  14. package/dist/edit-file-tool.test.d.ts +7 -2
  15. package/dist/edit-file-tool.test.d.ts.map +1 -0
  16. package/dist/edit-file-tool.test.js +109 -29
  17. package/dist/error-codes.cjs +4 -0
  18. package/dist/error-codes.d.ts +6 -3
  19. package/dist/error-codes.d.ts.map +1 -0
  20. package/dist/error-codes.js +4 -0
  21. package/dist/errors.cjs +48 -0
  22. package/dist/errors.d.ts +20 -7
  23. package/dist/errors.d.ts.map +1 -0
  24. package/dist/errors.js +48 -0
  25. package/dist/file-tool-types.d.ts +8 -40
  26. package/dist/file-tool-types.d.ts.map +1 -0
  27. package/dist/filesystem-service.cjs +325 -10
  28. package/dist/filesystem-service.d.ts +41 -12
  29. package/dist/filesystem-service.d.ts.map +1 -0
  30. package/dist/filesystem-service.js +326 -11
  31. package/dist/filesystem-service.test.cjs +10 -2
  32. package/dist/filesystem-service.test.d.ts +7 -2
  33. package/dist/filesystem-service.test.d.ts.map +1 -0
  34. package/dist/filesystem-service.test.js +10 -2
  35. package/dist/glob-files-tool.cjs +32 -46
  36. package/dist/glob-files-tool.d.ts +19 -9
  37. package/dist/glob-files-tool.d.ts.map +1 -0
  38. package/dist/glob-files-tool.js +33 -47
  39. package/dist/grep-content-tool.cjs +40 -45
  40. package/dist/grep-content-tool.d.ts +28 -9
  41. package/dist/grep-content-tool.d.ts.map +1 -0
  42. package/dist/grep-content-tool.js +41 -46
  43. package/dist/index.cjs +6 -3
  44. package/dist/index.d.cts +852 -14
  45. package/dist/index.d.ts +11 -5
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +4 -2
  48. package/dist/path-validator.cjs +28 -2
  49. package/dist/path-validator.d.ts +20 -9
  50. package/dist/path-validator.d.ts.map +1 -0
  51. package/dist/path-validator.js +28 -2
  52. package/dist/path-validator.test.d.ts +7 -2
  53. package/dist/path-validator.test.d.ts.map +1 -0
  54. package/dist/read-file-tool.cjs +26 -59
  55. package/dist/read-file-tool.d.ts +19 -9
  56. package/dist/read-file-tool.d.ts.map +1 -0
  57. package/dist/read-file-tool.js +27 -50
  58. package/dist/tool-factory-config.cjs +61 -0
  59. package/dist/{tool-provider.d.ts → tool-factory-config.d.ts} +13 -30
  60. package/dist/tool-factory-config.d.ts.map +1 -0
  61. package/dist/tool-factory-config.js +36 -0
  62. package/dist/tool-factory.cjs +123 -0
  63. package/dist/tool-factory.d.ts +4 -0
  64. package/dist/tool-factory.d.ts.map +1 -0
  65. package/dist/tool-factory.js +102 -0
  66. package/dist/types.d.ts +82 -18
  67. package/dist/types.d.ts.map +1 -0
  68. package/dist/write-file-tool.cjs +93 -99
  69. package/dist/write-file-tool.d.ts +22 -9
  70. package/dist/write-file-tool.d.ts.map +1 -0
  71. package/dist/write-file-tool.js +97 -91
  72. package/dist/write-file-tool.test.cjs +139 -33
  73. package/dist/write-file-tool.test.d.ts +7 -2
  74. package/dist/write-file-tool.test.d.ts.map +1 -0
  75. package/dist/write-file-tool.test.js +139 -33
  76. package/package.json +5 -4
  77. package/dist/directory-approval.integration.test.d.cts +0 -2
  78. package/dist/edit-file-tool.d.cts +0 -17
  79. package/dist/edit-file-tool.test.d.cts +0 -2
  80. package/dist/error-codes.d.cts +0 -32
  81. package/dist/errors.d.cts +0 -112
  82. package/dist/file-tool-types.d.cts +0 -46
  83. package/dist/filesystem-service.d.cts +0 -112
  84. package/dist/filesystem-service.test.d.cts +0 -2
  85. package/dist/glob-files-tool.d.cts +0 -17
  86. package/dist/grep-content-tool.d.cts +0 -17
  87. package/dist/path-validator.d.cts +0 -97
  88. package/dist/path-validator.test.d.cts +0 -2
  89. package/dist/read-file-tool.d.cts +0 -17
  90. package/dist/tool-provider.cjs +0 -123
  91. package/dist/tool-provider.d.cts +0 -77
  92. package/dist/tool-provider.js +0 -99
  93. package/dist/types.d.cts +0 -178
  94. package/dist/write-file-tool.d.cts +0 -17
  95. package/dist/write-file-tool.test.d.cts +0 -2
@@ -34,61 +34,47 @@ module.exports = __toCommonJS(glob_files_tool_exports);
34
34
  var path = __toESM(require("node:path"), 1);
35
35
  var import_zod = require("zod");
36
36
  var import_core = require("@dexto/core");
37
+ var import_directory_approval = require("./directory-approval.js");
37
38
  const GlobFilesInputSchema = import_zod.z.object({
38
39
  pattern: import_zod.z.string().describe('Glob pattern to match files (e.g., "**/*.ts", "src/**/*.js")'),
39
40
  path: import_zod.z.string().optional().describe("Base directory to search from (defaults to working directory)"),
40
41
  max_results: import_zod.z.number().int().positive().optional().default(1e3).describe("Maximum number of results to return (default: 1000)")
41
42
  }).strict();
42
- function createGlobFilesTool(options) {
43
- const { fileSystemService, directoryApproval } = options;
44
- let pendingApprovalSearchDir;
45
- return {
43
+ function createGlobFilesTool(getFileSystemService) {
44
+ return (0, import_core.defineTool)({
46
45
  id: "glob_files",
46
+ aliases: ["glob"],
47
47
  description: "Find files matching a glob pattern. Supports standard glob syntax like **/*.js for recursive matches, *.ts for files in current directory, and src/**/*.tsx for nested paths. Returns array of file paths with metadata (size, modified date). Results are limited to allowed paths only.",
48
48
  inputSchema: GlobFilesInputSchema,
49
- /**
50
- * Check if this glob operation needs directory access approval.
51
- * Returns custom approval request if the search directory is outside allowed paths.
52
- */
53
- getApprovalOverride: async (args) => {
54
- const { path: searchPath } = args;
55
- const baseDir = fileSystemService.getWorkingDirectory();
56
- const searchDir = path.resolve(baseDir, searchPath || ".");
57
- const isAllowed = await fileSystemService.isPathWithinConfigAllowed(searchDir);
58
- if (isAllowed) {
59
- return null;
49
+ presentation: {
50
+ describeHeader: (input) => {
51
+ const bits = [`pattern=${input.pattern}`];
52
+ if (input.path) bits.push(`path=${input.path}`);
53
+ if (typeof input.max_results === "number") bits.push(`max=${input.max_results}`);
54
+ return (0, import_core.createLocalToolCallHeader)({
55
+ title: "Find Files",
56
+ argsText: (0, import_core.truncateForHeader)(bits.join(", "), 140)
57
+ });
60
58
  }
61
- if (directoryApproval?.isSessionApproved(searchDir)) {
62
- return null;
63
- }
64
- pendingApprovalSearchDir = searchDir;
65
- return {
66
- type: import_core.ApprovalType.DIRECTORY_ACCESS,
67
- metadata: {
68
- path: searchDir,
69
- parentDir: searchDir,
70
- operation: "search",
71
- toolName: "glob_files"
72
- }
73
- };
74
59
  },
75
- /**
76
- * Handle approved directory access - remember the directory for session
77
- */
78
- onApprovalGranted: (response) => {
79
- if (!directoryApproval || !pendingApprovalSearchDir) return;
80
- const data = response.data;
81
- const rememberDirectory = data?.rememberDirectory ?? false;
82
- directoryApproval.addApproved(
83
- pendingApprovalSearchDir,
84
- rememberDirectory ? "session" : "once"
85
- );
86
- pendingApprovalSearchDir = void 0;
87
- },
88
- execute: async (input, _context) => {
89
- const { pattern, path: path2, max_results } = input;
90
- const result = await fileSystemService.globFiles(pattern, {
91
- cwd: path2,
60
+ ...(0, import_directory_approval.createDirectoryAccessApprovalHandlers)({
61
+ toolName: "glob_files",
62
+ operation: "read",
63
+ inputSchema: GlobFilesInputSchema,
64
+ getFileSystemService,
65
+ resolvePaths: (input, fileSystemService) => {
66
+ const baseDir = fileSystemService.getWorkingDirectory();
67
+ const searchDir = path.resolve(baseDir, input.path || ".");
68
+ return { path: searchDir, parentDir: searchDir };
69
+ }
70
+ }),
71
+ async execute(input, context) {
72
+ const resolvedFileSystemService = await getFileSystemService(context);
73
+ const { pattern, path: searchPath, max_results } = input;
74
+ const baseDir = resolvedFileSystemService.getWorkingDirectory();
75
+ const resolvedSearchPath = path.resolve(baseDir, searchPath || ".");
76
+ const result = await resolvedFileSystemService.globFiles(pattern, {
77
+ cwd: resolvedSearchPath,
92
78
  maxResults: max_results,
93
79
  includeMetadata: true
94
80
  });
@@ -115,7 +101,7 @@ function createGlobFilesTool(options) {
115
101
  _display
116
102
  };
117
103
  }
118
- };
104
+ });
119
105
  }
120
106
  // Annotate the CommonJS export names for ESM import in node:
121
107
  0 && (module.exports = {
@@ -1,17 +1,27 @@
1
- import { InternalTool } from '@dexto/core';
2
- import { FileToolOptions } from './file-tool-types.js';
3
- import './filesystem-service.js';
4
- import './types.js';
5
-
6
1
  /**
7
2
  * Glob Files Tool
8
3
  *
9
4
  * Internal tool for finding files using glob patterns
10
5
  */
11
-
6
+ import { z } from 'zod';
7
+ import type { Tool } from '@dexto/core';
8
+ import type { FileSystemServiceGetter } from './file-tool-types.js';
9
+ declare const GlobFilesInputSchema: z.ZodObject<{
10
+ pattern: z.ZodString;
11
+ path: z.ZodOptional<z.ZodString>;
12
+ max_results: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
13
+ }, "strict", z.ZodTypeAny, {
14
+ pattern: string;
15
+ max_results: number;
16
+ path?: string | undefined;
17
+ }, {
18
+ pattern: string;
19
+ path?: string | undefined;
20
+ max_results?: number | undefined;
21
+ }>;
12
22
  /**
13
23
  * Create the glob_files internal tool with directory approval support
14
24
  */
15
- declare function createGlobFilesTool(options: FileToolOptions): InternalTool;
16
-
17
- export { createGlobFilesTool };
25
+ export declare function createGlobFilesTool(getFileSystemService: FileSystemServiceGetter): Tool<typeof GlobFilesInputSchema>;
26
+ export {};
27
+ //# sourceMappingURL=glob-files-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob-files-tool.d.ts","sourceRoot":"","sources":["../src/glob-files-tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,IAAI,EAAwB,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAGpE,QAAA,MAAM,oBAAoB;;;;;;;;;;;;EAiBb,CAAC;AAEd;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,oBAAoB,EAAE,uBAAuB,GAC9C,IAAI,CAAC,OAAO,oBAAoB,CAAC,CA2EnC"}
@@ -1,61 +1,47 @@
1
1
  import * as path from "node:path";
2
2
  import { z } from "zod";
3
- import { ApprovalType } from "@dexto/core";
3
+ import { createLocalToolCallHeader, defineTool, truncateForHeader } from "@dexto/core";
4
+ import { createDirectoryAccessApprovalHandlers } from "./directory-approval.js";
4
5
  const GlobFilesInputSchema = z.object({
5
6
  pattern: z.string().describe('Glob pattern to match files (e.g., "**/*.ts", "src/**/*.js")'),
6
7
  path: z.string().optional().describe("Base directory to search from (defaults to working directory)"),
7
8
  max_results: z.number().int().positive().optional().default(1e3).describe("Maximum number of results to return (default: 1000)")
8
9
  }).strict();
9
- function createGlobFilesTool(options) {
10
- const { fileSystemService, directoryApproval } = options;
11
- let pendingApprovalSearchDir;
12
- return {
10
+ function createGlobFilesTool(getFileSystemService) {
11
+ return defineTool({
13
12
  id: "glob_files",
13
+ aliases: ["glob"],
14
14
  description: "Find files matching a glob pattern. Supports standard glob syntax like **/*.js for recursive matches, *.ts for files in current directory, and src/**/*.tsx for nested paths. Returns array of file paths with metadata (size, modified date). Results are limited to allowed paths only.",
15
15
  inputSchema: GlobFilesInputSchema,
16
- /**
17
- * Check if this glob operation needs directory access approval.
18
- * Returns custom approval request if the search directory is outside allowed paths.
19
- */
20
- getApprovalOverride: async (args) => {
21
- const { path: searchPath } = args;
22
- const baseDir = fileSystemService.getWorkingDirectory();
23
- const searchDir = path.resolve(baseDir, searchPath || ".");
24
- const isAllowed = await fileSystemService.isPathWithinConfigAllowed(searchDir);
25
- if (isAllowed) {
26
- return null;
16
+ presentation: {
17
+ describeHeader: (input) => {
18
+ const bits = [`pattern=${input.pattern}`];
19
+ if (input.path) bits.push(`path=${input.path}`);
20
+ if (typeof input.max_results === "number") bits.push(`max=${input.max_results}`);
21
+ return createLocalToolCallHeader({
22
+ title: "Find Files",
23
+ argsText: truncateForHeader(bits.join(", "), 140)
24
+ });
27
25
  }
28
- if (directoryApproval?.isSessionApproved(searchDir)) {
29
- return null;
30
- }
31
- pendingApprovalSearchDir = searchDir;
32
- return {
33
- type: ApprovalType.DIRECTORY_ACCESS,
34
- metadata: {
35
- path: searchDir,
36
- parentDir: searchDir,
37
- operation: "search",
38
- toolName: "glob_files"
39
- }
40
- };
41
26
  },
42
- /**
43
- * Handle approved directory access - remember the directory for session
44
- */
45
- onApprovalGranted: (response) => {
46
- if (!directoryApproval || !pendingApprovalSearchDir) return;
47
- const data = response.data;
48
- const rememberDirectory = data?.rememberDirectory ?? false;
49
- directoryApproval.addApproved(
50
- pendingApprovalSearchDir,
51
- rememberDirectory ? "session" : "once"
52
- );
53
- pendingApprovalSearchDir = void 0;
54
- },
55
- execute: async (input, _context) => {
56
- const { pattern, path: path2, max_results } = input;
57
- const result = await fileSystemService.globFiles(pattern, {
58
- cwd: path2,
27
+ ...createDirectoryAccessApprovalHandlers({
28
+ toolName: "glob_files",
29
+ operation: "read",
30
+ inputSchema: GlobFilesInputSchema,
31
+ getFileSystemService,
32
+ resolvePaths: (input, fileSystemService) => {
33
+ const baseDir = fileSystemService.getWorkingDirectory();
34
+ const searchDir = path.resolve(baseDir, input.path || ".");
35
+ return { path: searchDir, parentDir: searchDir };
36
+ }
37
+ }),
38
+ async execute(input, context) {
39
+ const resolvedFileSystemService = await getFileSystemService(context);
40
+ const { pattern, path: searchPath, max_results } = input;
41
+ const baseDir = resolvedFileSystemService.getWorkingDirectory();
42
+ const resolvedSearchPath = path.resolve(baseDir, searchPath || ".");
43
+ const result = await resolvedFileSystemService.globFiles(pattern, {
44
+ cwd: resolvedSearchPath,
59
45
  maxResults: max_results,
60
46
  includeMetadata: true
61
47
  });
@@ -82,7 +68,7 @@ function createGlobFilesTool(options) {
82
68
  _display
83
69
  };
84
70
  }
85
- };
71
+ });
86
72
  }
87
73
  export {
88
74
  createGlobFilesTool
@@ -34,6 +34,7 @@ module.exports = __toCommonJS(grep_content_tool_exports);
34
34
  var path = __toESM(require("node:path"), 1);
35
35
  var import_zod = require("zod");
36
36
  var import_core = require("@dexto/core");
37
+ var import_directory_approval = require("./directory-approval.js");
37
38
  const GrepContentInputSchema = import_zod.z.object({
38
39
  pattern: import_zod.z.string().describe("Regular expression pattern to search for"),
39
40
  path: import_zod.z.string().optional().describe("Directory to search in (defaults to working directory)"),
@@ -44,55 +45,49 @@ const GrepContentInputSchema = import_zod.z.object({
44
45
  case_insensitive: import_zod.z.boolean().optional().default(false).describe("Perform case-insensitive search (default: false)"),
45
46
  max_results: import_zod.z.number().int().positive().optional().default(100).describe("Maximum number of results to return (default: 100)")
46
47
  }).strict();
47
- function createGrepContentTool(options) {
48
- const { fileSystemService, directoryApproval } = options;
49
- let pendingApprovalSearchDir;
50
- return {
48
+ function createGrepContentTool(getFileSystemService) {
49
+ return (0, import_core.defineTool)({
51
50
  id: "grep_content",
51
+ aliases: ["grep"],
52
52
  description: 'Search for text patterns in files using regular expressions. Returns matching lines with file path, line number, and optional context lines. Use glob parameter to filter specific file types (e.g., "*.ts"). Supports case-insensitive search. Great for finding code patterns, function definitions, or specific text across multiple files.',
53
53
  inputSchema: GrepContentInputSchema,
54
- /**
55
- * Check if this grep operation needs directory access approval.
56
- * Returns custom approval request if the search directory is outside allowed paths.
57
- */
58
- getApprovalOverride: async (args) => {
59
- const { path: searchPath } = args;
60
- const searchDir = path.resolve(searchPath || process.cwd());
61
- const isAllowed = await fileSystemService.isPathWithinConfigAllowed(searchDir);
62
- if (isAllowed) {
63
- return null;
54
+ presentation: {
55
+ describeHeader: (input) => {
56
+ const bits = [`pattern=${input.pattern}`];
57
+ if (input.glob) bits.push(`glob=${input.glob}`);
58
+ if (input.path) bits.push(`path=${input.path}`);
59
+ if (typeof input.max_results === "number") bits.push(`max=${input.max_results}`);
60
+ return (0, import_core.createLocalToolCallHeader)({
61
+ title: "Search Files",
62
+ argsText: (0, import_core.truncateForHeader)(bits.join(", "), 140)
63
+ });
64
64
  }
65
- if (directoryApproval?.isSessionApproved(searchDir)) {
66
- return null;
67
- }
68
- pendingApprovalSearchDir = searchDir;
69
- return {
70
- type: import_core.ApprovalType.DIRECTORY_ACCESS,
71
- metadata: {
72
- path: searchDir,
73
- parentDir: searchDir,
74
- operation: "search",
75
- toolName: "grep_content"
76
- }
77
- };
78
- },
79
- /**
80
- * Handle approved directory access - remember the directory for session
81
- */
82
- onApprovalGranted: (response) => {
83
- if (!directoryApproval || !pendingApprovalSearchDir) return;
84
- const data = response.data;
85
- const rememberDirectory = data?.rememberDirectory ?? false;
86
- directoryApproval.addApproved(
87
- pendingApprovalSearchDir,
88
- rememberDirectory ? "session" : "once"
89
- );
90
- pendingApprovalSearchDir = void 0;
91
65
  },
92
- execute: async (input, _context) => {
93
- const { pattern, path: path2, glob, context_lines, case_insensitive, max_results } = input;
94
- const result = await fileSystemService.searchContent(pattern, {
95
- path: path2,
66
+ ...(0, import_directory_approval.createDirectoryAccessApprovalHandlers)({
67
+ toolName: "grep_content",
68
+ operation: "read",
69
+ inputSchema: GrepContentInputSchema,
70
+ getFileSystemService,
71
+ resolvePaths: (input, fileSystemService) => {
72
+ const baseDir = fileSystemService.getWorkingDirectory();
73
+ const searchDir = path.resolve(baseDir, input.path || ".");
74
+ return { path: searchDir, parentDir: searchDir };
75
+ }
76
+ }),
77
+ async execute(input, context) {
78
+ const resolvedFileSystemService = await getFileSystemService(context);
79
+ const {
80
+ pattern,
81
+ path: searchPath,
82
+ glob,
83
+ context_lines,
84
+ case_insensitive,
85
+ max_results
86
+ } = input;
87
+ const baseDir = resolvedFileSystemService.getWorkingDirectory();
88
+ const resolvedSearchPath = path.resolve(baseDir, searchPath || ".");
89
+ const result = await resolvedFileSystemService.searchContent(pattern, {
90
+ path: resolvedSearchPath,
96
91
  glob,
97
92
  contextLines: context_lines,
98
93
  caseInsensitive: case_insensitive,
@@ -130,7 +125,7 @@ function createGrepContentTool(options) {
130
125
  _display
131
126
  };
132
127
  }
133
- };
128
+ });
134
129
  }
135
130
  // Annotate the CommonJS export names for ESM import in node:
136
131
  0 && (module.exports = {
@@ -1,17 +1,36 @@
1
- import { InternalTool } from '@dexto/core';
2
- import { FileToolOptions } from './file-tool-types.js';
3
- import './filesystem-service.js';
4
- import './types.js';
5
-
6
1
  /**
7
2
  * Grep Content Tool
8
3
  *
9
4
  * Internal tool for searching file contents using regex patterns
10
5
  */
11
-
6
+ import { z } from 'zod';
7
+ import type { Tool } from '@dexto/core';
8
+ import type { FileSystemServiceGetter } from './file-tool-types.js';
9
+ declare const GrepContentInputSchema: z.ZodObject<{
10
+ pattern: z.ZodString;
11
+ path: z.ZodOptional<z.ZodString>;
12
+ glob: z.ZodOptional<z.ZodString>;
13
+ context_lines: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
14
+ case_insensitive: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
15
+ max_results: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
16
+ }, "strict", z.ZodTypeAny, {
17
+ pattern: string;
18
+ max_results: number;
19
+ context_lines: number;
20
+ case_insensitive: boolean;
21
+ path?: string | undefined;
22
+ glob?: string | undefined;
23
+ }, {
24
+ pattern: string;
25
+ path?: string | undefined;
26
+ max_results?: number | undefined;
27
+ glob?: string | undefined;
28
+ context_lines?: number | undefined;
29
+ case_insensitive?: boolean | undefined;
30
+ }>;
12
31
  /**
13
32
  * Create the grep_content internal tool with directory approval support
14
33
  */
15
- declare function createGrepContentTool(options: FileToolOptions): InternalTool;
16
-
17
- export { createGrepContentTool };
34
+ export declare function createGrepContentTool(getFileSystemService: FileSystemServiceGetter): Tool<typeof GrepContentInputSchema>;
35
+ export {};
36
+ //# sourceMappingURL=grep-content-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grep-content-tool.d.ts","sourceRoot":"","sources":["../src/grep-content-tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,IAAI,EAAwB,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAGpE,QAAA,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;EAiCf,CAAC;AAEd;;GAEG;AACH,wBAAgB,qBAAqB,CACjC,oBAAoB,EAAE,uBAAuB,GAC9C,IAAI,CAAC,OAAO,sBAAsB,CAAC,CA6FrC"}
@@ -1,6 +1,7 @@
1
1
  import * as path from "node:path";
2
2
  import { z } from "zod";
3
- import { ApprovalType } from "@dexto/core";
3
+ import { createLocalToolCallHeader, defineTool, truncateForHeader } from "@dexto/core";
4
+ import { createDirectoryAccessApprovalHandlers } from "./directory-approval.js";
4
5
  const GrepContentInputSchema = z.object({
5
6
  pattern: z.string().describe("Regular expression pattern to search for"),
6
7
  path: z.string().optional().describe("Directory to search in (defaults to working directory)"),
@@ -11,55 +12,49 @@ const GrepContentInputSchema = z.object({
11
12
  case_insensitive: z.boolean().optional().default(false).describe("Perform case-insensitive search (default: false)"),
12
13
  max_results: z.number().int().positive().optional().default(100).describe("Maximum number of results to return (default: 100)")
13
14
  }).strict();
14
- function createGrepContentTool(options) {
15
- const { fileSystemService, directoryApproval } = options;
16
- let pendingApprovalSearchDir;
17
- return {
15
+ function createGrepContentTool(getFileSystemService) {
16
+ return defineTool({
18
17
  id: "grep_content",
18
+ aliases: ["grep"],
19
19
  description: 'Search for text patterns in files using regular expressions. Returns matching lines with file path, line number, and optional context lines. Use glob parameter to filter specific file types (e.g., "*.ts"). Supports case-insensitive search. Great for finding code patterns, function definitions, or specific text across multiple files.',
20
20
  inputSchema: GrepContentInputSchema,
21
- /**
22
- * Check if this grep operation needs directory access approval.
23
- * Returns custom approval request if the search directory is outside allowed paths.
24
- */
25
- getApprovalOverride: async (args) => {
26
- const { path: searchPath } = args;
27
- const searchDir = path.resolve(searchPath || process.cwd());
28
- const isAllowed = await fileSystemService.isPathWithinConfigAllowed(searchDir);
29
- if (isAllowed) {
30
- return null;
21
+ presentation: {
22
+ describeHeader: (input) => {
23
+ const bits = [`pattern=${input.pattern}`];
24
+ if (input.glob) bits.push(`glob=${input.glob}`);
25
+ if (input.path) bits.push(`path=${input.path}`);
26
+ if (typeof input.max_results === "number") bits.push(`max=${input.max_results}`);
27
+ return createLocalToolCallHeader({
28
+ title: "Search Files",
29
+ argsText: truncateForHeader(bits.join(", "), 140)
30
+ });
31
31
  }
32
- if (directoryApproval?.isSessionApproved(searchDir)) {
33
- return null;
34
- }
35
- pendingApprovalSearchDir = searchDir;
36
- return {
37
- type: ApprovalType.DIRECTORY_ACCESS,
38
- metadata: {
39
- path: searchDir,
40
- parentDir: searchDir,
41
- operation: "search",
42
- toolName: "grep_content"
43
- }
44
- };
45
- },
46
- /**
47
- * Handle approved directory access - remember the directory for session
48
- */
49
- onApprovalGranted: (response) => {
50
- if (!directoryApproval || !pendingApprovalSearchDir) return;
51
- const data = response.data;
52
- const rememberDirectory = data?.rememberDirectory ?? false;
53
- directoryApproval.addApproved(
54
- pendingApprovalSearchDir,
55
- rememberDirectory ? "session" : "once"
56
- );
57
- pendingApprovalSearchDir = void 0;
58
32
  },
59
- execute: async (input, _context) => {
60
- const { pattern, path: path2, glob, context_lines, case_insensitive, max_results } = input;
61
- const result = await fileSystemService.searchContent(pattern, {
62
- path: path2,
33
+ ...createDirectoryAccessApprovalHandlers({
34
+ toolName: "grep_content",
35
+ operation: "read",
36
+ inputSchema: GrepContentInputSchema,
37
+ getFileSystemService,
38
+ resolvePaths: (input, fileSystemService) => {
39
+ const baseDir = fileSystemService.getWorkingDirectory();
40
+ const searchDir = path.resolve(baseDir, input.path || ".");
41
+ return { path: searchDir, parentDir: searchDir };
42
+ }
43
+ }),
44
+ async execute(input, context) {
45
+ const resolvedFileSystemService = await getFileSystemService(context);
46
+ const {
47
+ pattern,
48
+ path: searchPath,
49
+ glob,
50
+ context_lines,
51
+ case_insensitive,
52
+ max_results
53
+ } = input;
54
+ const baseDir = resolvedFileSystemService.getWorkingDirectory();
55
+ const resolvedSearchPath = path.resolve(baseDir, searchPath || ".");
56
+ const result = await resolvedFileSystemService.searchContent(pattern, {
57
+ path: resolvedSearchPath,
63
58
  glob,
64
59
  contextLines: context_lines,
65
60
  caseInsensitive: case_insensitive,
@@ -97,7 +92,7 @@ function createGrepContentTool(options) {
97
92
  _display
98
93
  };
99
94
  }
100
- };
95
+ });
101
96
  }
102
97
  export {
103
98
  createGrepContentTool
package/dist/index.cjs CHANGED
@@ -21,16 +21,18 @@ __export(index_exports, {
21
21
  FileSystemError: () => import_errors.FileSystemError,
22
22
  FileSystemErrorCode: () => import_error_codes.FileSystemErrorCode,
23
23
  FileSystemService: () => import_filesystem_service.FileSystemService,
24
+ FileSystemToolsConfigSchema: () => import_tool_factory_config.FileSystemToolsConfigSchema,
24
25
  PathValidator: () => import_path_validator.PathValidator,
25
26
  createEditFileTool: () => import_edit_file_tool.createEditFileTool,
26
27
  createGlobFilesTool: () => import_glob_files_tool.createGlobFilesTool,
27
28
  createGrepContentTool: () => import_grep_content_tool.createGrepContentTool,
28
29
  createReadFileTool: () => import_read_file_tool.createReadFileTool,
29
30
  createWriteFileTool: () => import_write_file_tool.createWriteFileTool,
30
- fileSystemToolsProvider: () => import_tool_provider.fileSystemToolsProvider
31
+ fileSystemToolsFactory: () => import_tool_factory.fileSystemToolsFactory
31
32
  });
32
33
  module.exports = __toCommonJS(index_exports);
33
- var import_tool_provider = require("./tool-provider.js");
34
+ var import_tool_factory = require("./tool-factory.js");
35
+ var import_tool_factory_config = require("./tool-factory-config.js");
34
36
  var import_filesystem_service = require("./filesystem-service.js");
35
37
  var import_path_validator = require("./path-validator.js");
36
38
  var import_errors = require("./errors.js");
@@ -45,11 +47,12 @@ var import_grep_content_tool = require("./grep-content-tool.js");
45
47
  FileSystemError,
46
48
  FileSystemErrorCode,
47
49
  FileSystemService,
50
+ FileSystemToolsConfigSchema,
48
51
  PathValidator,
49
52
  createEditFileTool,
50
53
  createGlobFilesTool,
51
54
  createGrepContentTool,
52
55
  createReadFileTool,
53
56
  createWriteFileTool,
54
- fileSystemToolsProvider
57
+ fileSystemToolsFactory
55
58
  });