@dexto/tools-filesystem 1.5.7 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/directory-approval.cjs +94 -0
  2. package/dist/directory-approval.d.cts +22 -0
  3. package/dist/directory-approval.d.ts +20 -0
  4. package/dist/directory-approval.d.ts.map +1 -0
  5. package/dist/directory-approval.integration.test.cjs +303 -269
  6. package/dist/directory-approval.integration.test.d.ts +14 -2
  7. package/dist/directory-approval.integration.test.d.ts.map +1 -0
  8. package/dist/directory-approval.integration.test.js +309 -270
  9. package/dist/directory-approval.js +59 -0
  10. package/dist/edit-file-tool.cjs +57 -90
  11. package/dist/edit-file-tool.d.cts +20 -3
  12. package/dist/edit-file-tool.d.ts +22 -9
  13. package/dist/edit-file-tool.d.ts.map +1 -0
  14. package/dist/edit-file-tool.js +53 -76
  15. package/dist/edit-file-tool.test.cjs +66 -29
  16. package/dist/edit-file-tool.test.d.ts +7 -2
  17. package/dist/edit-file-tool.test.d.ts.map +1 -0
  18. package/dist/edit-file-tool.test.js +66 -29
  19. package/dist/error-codes.d.ts +2 -3
  20. package/dist/error-codes.d.ts.map +1 -0
  21. package/dist/errors.d.ts +4 -7
  22. package/dist/errors.d.ts.map +1 -0
  23. package/dist/file-tool-types.d.cts +7 -35
  24. package/dist/file-tool-types.d.ts +8 -40
  25. package/dist/file-tool-types.d.ts.map +1 -0
  26. package/dist/filesystem-service.cjs +18 -1
  27. package/dist/filesystem-service.d.cts +11 -6
  28. package/dist/filesystem-service.d.ts +14 -12
  29. package/dist/filesystem-service.d.ts.map +1 -0
  30. package/dist/filesystem-service.js +18 -1
  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 +22 -47
  36. package/dist/glob-files-tool.d.cts +17 -3
  37. package/dist/glob-files-tool.d.ts +19 -9
  38. package/dist/glob-files-tool.d.ts.map +1 -0
  39. package/dist/glob-files-tool.js +23 -48
  40. package/dist/grep-content-tool.cjs +29 -46
  41. package/dist/grep-content-tool.d.cts +26 -3
  42. package/dist/grep-content-tool.d.ts +28 -9
  43. package/dist/grep-content-tool.d.ts.map +1 -0
  44. package/dist/grep-content-tool.js +30 -47
  45. package/dist/index.cjs +3 -3
  46. package/dist/index.d.cts +4 -2
  47. package/dist/index.d.ts +10 -5
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +2 -2
  50. package/dist/path-validator.d.cts +2 -2
  51. package/dist/path-validator.d.ts +6 -9
  52. package/dist/path-validator.d.ts.map +1 -0
  53. package/dist/path-validator.test.d.ts +7 -2
  54. package/dist/path-validator.test.d.ts.map +1 -0
  55. package/dist/read-file-tool.cjs +21 -60
  56. package/dist/read-file-tool.d.cts +17 -3
  57. package/dist/read-file-tool.d.ts +19 -9
  58. package/dist/read-file-tool.d.ts.map +1 -0
  59. package/dist/read-file-tool.js +22 -51
  60. package/dist/tool-factory-config.cjs +61 -0
  61. package/dist/{tool-provider.d.ts → tool-factory-config.d.cts} +9 -23
  62. package/dist/{tool-provider.d.cts → tool-factory-config.d.ts} +13 -30
  63. package/dist/tool-factory-config.d.ts.map +1 -0
  64. package/dist/tool-factory-config.js +36 -0
  65. package/dist/tool-factory.cjs +102 -0
  66. package/dist/tool-factory.d.cts +7 -0
  67. package/dist/tool-factory.d.ts +4 -0
  68. package/dist/tool-factory.d.ts.map +1 -0
  69. package/dist/tool-factory.js +81 -0
  70. package/dist/types.d.ts +17 -18
  71. package/dist/types.d.ts.map +1 -0
  72. package/dist/write-file-tool.cjs +45 -73
  73. package/dist/write-file-tool.d.cts +20 -3
  74. package/dist/write-file-tool.d.ts +22 -9
  75. package/dist/write-file-tool.d.ts.map +1 -0
  76. package/dist/write-file-tool.js +46 -68
  77. package/dist/write-file-tool.test.cjs +76 -32
  78. package/dist/write-file-tool.test.d.ts +7 -2
  79. package/dist/write-file-tool.test.d.ts.map +1 -0
  80. package/dist/write-file-tool.test.js +76 -32
  81. package/package.json +4 -3
  82. package/dist/tool-provider.cjs +0 -123
  83. package/dist/tool-provider.js +0 -99
@@ -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,37 @@ 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
+ displayName: "Search Files",
52
+ aliases: ["grep"],
52
53
  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
54
  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;
55
+ ...(0, import_directory_approval.createDirectoryAccessApprovalHandlers)({
56
+ toolName: "grep_content",
57
+ operation: "read",
58
+ getFileSystemService,
59
+ resolvePaths: (input, fileSystemService) => {
60
+ const baseDir = fileSystemService.getWorkingDirectory();
61
+ const searchDir = path.resolve(baseDir, input.path || ".");
62
+ return { path: searchDir, parentDir: searchDir };
64
63
  }
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
- },
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,
64
+ }),
65
+ async execute(input, context) {
66
+ const resolvedFileSystemService = await getFileSystemService(context);
67
+ const {
68
+ pattern,
69
+ path: searchPath,
70
+ glob,
71
+ context_lines,
72
+ case_insensitive,
73
+ max_results
74
+ } = input;
75
+ const baseDir = resolvedFileSystemService.getWorkingDirectory();
76
+ const resolvedSearchPath = path.resolve(baseDir, searchPath || ".");
77
+ const result = await resolvedFileSystemService.searchContent(pattern, {
78
+ path: resolvedSearchPath,
96
79
  glob,
97
80
  contextLines: context_lines,
98
81
  caseInsensitive: case_insensitive,
@@ -130,7 +113,7 @@ function createGrepContentTool(options) {
130
113
  _display
131
114
  };
132
115
  }
133
- };
116
+ });
134
117
  }
135
118
  // Annotate the CommonJS export names for ESM import in node:
136
119
  0 && (module.exports = {
@@ -1,5 +1,6 @@
1
- import { InternalTool } from '@dexto/core';
2
- import { FileToolOptions } from './file-tool-types.cjs';
1
+ import { z } from 'zod';
2
+ import { Tool } from '@dexto/core';
3
+ import { FileSystemServiceGetter } from './file-tool-types.cjs';
3
4
  import './filesystem-service.cjs';
4
5
  import './types.cjs';
5
6
 
@@ -9,9 +10,31 @@ import './types.cjs';
9
10
  * Internal tool for searching file contents using regex patterns
10
11
  */
11
12
 
13
+ declare const GrepContentInputSchema: z.ZodObject<{
14
+ pattern: z.ZodString;
15
+ path: z.ZodOptional<z.ZodString>;
16
+ glob: z.ZodOptional<z.ZodString>;
17
+ context_lines: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
18
+ case_insensitive: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
19
+ max_results: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
20
+ }, "strict", z.ZodTypeAny, {
21
+ pattern: string;
22
+ max_results: number;
23
+ context_lines: number;
24
+ case_insensitive: boolean;
25
+ path?: string | undefined;
26
+ glob?: string | undefined;
27
+ }, {
28
+ pattern: string;
29
+ path?: string | undefined;
30
+ max_results?: number | undefined;
31
+ glob?: string | undefined;
32
+ context_lines?: number | undefined;
33
+ case_insensitive?: boolean | undefined;
34
+ }>;
12
35
  /**
13
36
  * Create the grep_content internal tool with directory approval support
14
37
  */
15
- declare function createGrepContentTool(options: FileToolOptions): InternalTool;
38
+ declare function createGrepContentTool(getFileSystemService: FileSystemServiceGetter): Tool<typeof GrepContentInputSchema>;
16
39
 
17
40
  export { createGrepContentTool };
@@ -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,CA+ErC"}
@@ -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 { defineTool } 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,37 @@ 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
+ displayName: "Search Files",
19
+ aliases: ["grep"],
19
20
  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
21
  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;
22
+ ...createDirectoryAccessApprovalHandlers({
23
+ toolName: "grep_content",
24
+ operation: "read",
25
+ getFileSystemService,
26
+ resolvePaths: (input, fileSystemService) => {
27
+ const baseDir = fileSystemService.getWorkingDirectory();
28
+ const searchDir = path.resolve(baseDir, input.path || ".");
29
+ return { path: searchDir, parentDir: searchDir };
31
30
  }
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
- },
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,
31
+ }),
32
+ async execute(input, context) {
33
+ const resolvedFileSystemService = await getFileSystemService(context);
34
+ const {
35
+ pattern,
36
+ path: searchPath,
37
+ glob,
38
+ context_lines,
39
+ case_insensitive,
40
+ max_results
41
+ } = input;
42
+ const baseDir = resolvedFileSystemService.getWorkingDirectory();
43
+ const resolvedSearchPath = path.resolve(baseDir, searchPath || ".");
44
+ const result = await resolvedFileSystemService.searchContent(pattern, {
45
+ path: resolvedSearchPath,
63
46
  glob,
64
47
  contextLines: context_lines,
65
48
  caseInsensitive: case_insensitive,
@@ -97,7 +80,7 @@ function createGrepContentTool(options) {
97
80
  _display
98
81
  };
99
82
  }
100
- };
83
+ });
101
84
  }
102
85
  export {
103
86
  createGrepContentTool
package/dist/index.cjs CHANGED
@@ -27,10 +27,10 @@ __export(index_exports, {
27
27
  createGrepContentTool: () => import_grep_content_tool.createGrepContentTool,
28
28
  createReadFileTool: () => import_read_file_tool.createReadFileTool,
29
29
  createWriteFileTool: () => import_write_file_tool.createWriteFileTool,
30
- fileSystemToolsProvider: () => import_tool_provider.fileSystemToolsProvider
30
+ fileSystemToolsFactory: () => import_tool_factory.fileSystemToolsFactory
31
31
  });
32
32
  module.exports = __toCommonJS(index_exports);
33
- var import_tool_provider = require("./tool-provider.js");
33
+ var import_tool_factory = require("./tool-factory.js");
34
34
  var import_filesystem_service = require("./filesystem-service.js");
35
35
  var import_path_validator = require("./path-validator.js");
36
36
  var import_errors = require("./errors.js");
@@ -51,5 +51,5 @@ var import_grep_content_tool = require("./grep-content-tool.js");
51
51
  createGrepContentTool,
52
52
  createReadFileTool,
53
53
  createWriteFileTool,
54
- fileSystemToolsProvider
54
+ fileSystemToolsFactory
55
55
  });
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- export { fileSystemToolsProvider } from './tool-provider.cjs';
2
- export { DirectoryApprovalCallbacks, FileToolOptions } from './file-tool-types.cjs';
1
+ export { fileSystemToolsFactory } from './tool-factory.cjs';
2
+ export { FileSystemServiceGetter } from './file-tool-types.cjs';
3
3
  export { FileSystemService } from './filesystem-service.cjs';
4
4
  export { PathValidator } from './path-validator.cjs';
5
5
  export { FileSystemError } from './errors.cjs';
@@ -10,5 +10,7 @@ export { createWriteFileTool } from './write-file-tool.cjs';
10
10
  export { createEditFileTool } from './edit-file-tool.cjs';
11
11
  export { createGlobFilesTool } from './glob-files-tool.cjs';
12
12
  export { createGrepContentTool } from './grep-content-tool.cjs';
13
+ import '@dexto/agent-config';
14
+ import './tool-factory-config.cjs';
13
15
  import 'zod';
14
16
  import '@dexto/core';
package/dist/index.d.ts CHANGED
@@ -1,14 +1,19 @@
1
- export { fileSystemToolsProvider } from './tool-provider.js';
2
- export { DirectoryApprovalCallbacks, FileToolOptions } from './file-tool-types.js';
1
+ /**
2
+ * @dexto/tools-filesystem
3
+ *
4
+ * FileSystem tools factory for Dexto agents.
5
+ * Provides file operation tools: read, write, edit, glob, grep.
6
+ */
7
+ export { fileSystemToolsFactory } from './tool-factory.js';
8
+ export type { FileSystemServiceGetter } from './file-tool-types.js';
3
9
  export { FileSystemService } from './filesystem-service.js';
4
10
  export { PathValidator } from './path-validator.js';
5
11
  export { FileSystemError } from './errors.js';
6
12
  export { FileSystemErrorCode } from './error-codes.js';
7
- export { BufferEncoding, EditFileOptions, EditOperation, EditResult, FileContent, FileMetadata, FileSystemConfig, GlobOptions, GlobResult, GrepOptions, PathValidation, ReadFileOptions, SearchMatch, SearchResult, WriteFileOptions, WriteResult } from './types.js';
13
+ export type { FileSystemConfig, FileContent, ReadFileOptions, GlobOptions, GlobResult, GrepOptions, SearchResult, SearchMatch, WriteFileOptions, WriteResult, EditFileOptions, EditResult, EditOperation, FileMetadata, PathValidation, BufferEncoding, } from './types.js';
8
14
  export { createReadFileTool } from './read-file-tool.js';
9
15
  export { createWriteFileTool } from './write-file-tool.js';
10
16
  export { createEditFileTool } from './edit-file-tool.js';
11
17
  export { createGlobFilesTool } from './glob-files-tool.js';
12
18
  export { createGrepContentTool } from './grep-content-tool.js';
13
- import 'zod';
14
- import '@dexto/core';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAGpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAGvD,YAAY,EACR,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,WAAW,EACX,UAAU,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,UAAU,EACV,aAAa,EACb,YAAY,EACZ,cAAc,EACd,cAAc,GACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { fileSystemToolsProvider } from "./tool-provider.js";
1
+ import { fileSystemToolsFactory } from "./tool-factory.js";
2
2
  import { FileSystemService } from "./filesystem-service.js";
3
3
  import { PathValidator } from "./path-validator.js";
4
4
  import { FileSystemError } from "./errors.js";
@@ -18,5 +18,5 @@ export {
18
18
  createGrepContentTool,
19
19
  createReadFileTool,
20
20
  createWriteFileTool,
21
- fileSystemToolsProvider
21
+ fileSystemToolsFactory
22
22
  };
@@ -1,5 +1,5 @@
1
1
  import { FileSystemConfig, PathValidation } from './types.cjs';
2
- import { IDextoLogger } from '@dexto/core';
2
+ import { Logger } from '@dexto/core';
3
3
 
4
4
  /**
5
5
  * Path Validator
@@ -32,7 +32,7 @@ declare class PathValidator {
32
32
  private normalizedBlockedExtensions;
33
33
  private logger;
34
34
  private directoryApprovalChecker;
35
- constructor(config: FileSystemConfig, logger: IDextoLogger);
35
+ constructor(config: FileSystemConfig, logger: Logger);
36
36
  /**
37
37
  * Set a callback to check if a path is in an approved directory.
38
38
  * This allows PathValidator to consult ApprovalManager without a direct dependency.
@@ -1,17 +1,15 @@
1
- import { FileSystemConfig, PathValidation } from './types.js';
2
- import { IDextoLogger } from '@dexto/core';
3
-
4
1
  /**
5
2
  * Path Validator
6
3
  *
7
4
  * Security-focused path validation for file system operations
8
5
  */
9
-
6
+ import { FileSystemConfig, PathValidation } from './types.js';
7
+ import type { Logger } from '@dexto/core';
10
8
  /**
11
9
  * Callback type for checking if a path is in an approved directory.
12
10
  * Used to consult ApprovalManager without creating a direct dependency.
13
11
  */
14
- type DirectoryApprovalChecker = (filePath: string) => boolean;
12
+ export type DirectoryApprovalChecker = (filePath: string) => boolean;
15
13
  /**
16
14
  * PathValidator - Validates file paths for security and policy compliance
17
15
  *
@@ -25,14 +23,14 @@ type DirectoryApprovalChecker = (filePath: string) => boolean;
25
23
  * PathValidator can optionally consult an external approval checker (e.g., ApprovalManager)
26
24
  * to determine if paths outside the config's allowed paths are accessible.
27
25
  */
28
- declare class PathValidator {
26
+ export declare class PathValidator {
29
27
  private config;
30
28
  private normalizedAllowedPaths;
31
29
  private normalizedBlockedPaths;
32
30
  private normalizedBlockedExtensions;
33
31
  private logger;
34
32
  private directoryApprovalChecker;
35
- constructor(config: FileSystemConfig, logger: IDextoLogger);
33
+ constructor(config: FileSystemConfig, logger: Logger);
36
34
  /**
37
35
  * Set a callback to check if a path is in an approved directory.
38
36
  * This allows PathValidator to consult ApprovalManager without a direct dependency.
@@ -93,5 +91,4 @@ declare class PathValidator {
93
91
  */
94
92
  getBlockedPaths(): string[];
95
93
  }
96
-
97
- export { type DirectoryApprovalChecker, PathValidator };
94
+ //# sourceMappingURL=path-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-validator.d.ts","sourceRoot":"","sources":["../src/path-validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;AAErE;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAa;IACtB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,sBAAsB,CAAW;IACzC,OAAO,CAAC,sBAAsB,CAAW;IACzC,OAAO,CAAC,2BAA2B,CAAW;IAC9C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,wBAAwB,CAAuC;gBAE3D,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM;IAsBpD;;;;;OAKG;IACH,2BAA2B,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI;IAKpE;;OAEG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAyE7D;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAIrB;;OAEG;IACH,OAAO,CAAC,aAAa;IAyBrB;;;OAGG;IACH,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO;IAInD;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAyBzB;;;;;;;;;OASG;IACG,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA8B7D;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAY9B;;OAEG;IACH,eAAe,IAAI,MAAM,EAAE;IAI3B;;OAEG;IACH,eAAe,IAAI,MAAM,EAAE;CAG9B"}
@@ -1,2 +1,7 @@
1
-
2
- export { }
1
+ /**
2
+ * PathValidator Unit Tests
3
+ *
4
+ * Tests for path validation, security checks, and allowed path logic.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=path-validator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-validator.test.d.ts","sourceRoot":"","sources":["../src/path-validator.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,84 +15,47 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
  var read_file_tool_exports = {};
30
20
  __export(read_file_tool_exports, {
31
21
  createReadFileTool: () => createReadFileTool
32
22
  });
33
23
  module.exports = __toCommonJS(read_file_tool_exports);
34
- var path = __toESM(require("node:path"), 1);
35
24
  var import_zod = require("zod");
36
25
  var import_core = require("@dexto/core");
26
+ var import_directory_approval = require("./directory-approval.js");
37
27
  const ReadFileInputSchema = import_zod.z.object({
38
- file_path: import_zod.z.string().describe("Absolute path to the file to read"),
28
+ file_path: import_zod.z.string().min(1).describe("Absolute path to the file to read"),
39
29
  limit: import_zod.z.number().int().positive().optional().describe("Maximum number of lines to read (optional)"),
40
30
  offset: import_zod.z.number().int().min(1).optional().describe("Starting line number (1-based, optional)")
41
31
  }).strict();
42
- function createReadFileTool(options) {
43
- const { fileSystemService, directoryApproval } = options;
44
- let pendingApprovalParentDir;
45
- return {
32
+ function createReadFileTool(getFileSystemService) {
33
+ return (0, import_core.defineTool)({
46
34
  id: "read_file",
35
+ displayName: "Read",
36
+ aliases: ["read"],
47
37
  description: "Read the contents of a file with optional pagination. Returns file content, line count, encoding, and whether the output was truncated. Use limit and offset parameters for large files to read specific sections. This tool is for reading files within allowed paths only.",
48
38
  inputSchema: ReadFileInputSchema,
49
- /**
50
- * Check if this read operation needs directory access approval.
51
- * Returns custom approval request if the file is outside allowed paths.
52
- */
53
- getApprovalOverride: async (args) => {
54
- const { file_path } = args;
55
- if (!file_path) return null;
56
- const isAllowed = await fileSystemService.isPathWithinConfigAllowed(file_path);
57
- if (isAllowed) {
58
- return null;
59
- }
60
- if (directoryApproval?.isSessionApproved(file_path)) {
61
- return null;
62
- }
63
- const absolutePath = path.resolve(file_path);
64
- const parentDir = path.dirname(absolutePath);
65
- pendingApprovalParentDir = parentDir;
66
- return {
67
- type: import_core.ApprovalType.DIRECTORY_ACCESS,
68
- metadata: {
69
- path: absolutePath,
70
- parentDir,
71
- operation: "read",
72
- toolName: "read_file"
73
- }
74
- };
75
- },
76
- /**
77
- * Handle approved directory access - remember the directory for session
78
- */
79
- onApprovalGranted: (response) => {
80
- if (!directoryApproval || !pendingApprovalParentDir) return;
81
- const data = response.data;
82
- const rememberDirectory = data?.rememberDirectory ?? false;
83
- directoryApproval.addApproved(
84
- pendingApprovalParentDir,
85
- rememberDirectory ? "session" : "once"
86
- );
87
- pendingApprovalParentDir = void 0;
88
- },
89
- execute: async (input, _context) => {
39
+ ...(0, import_directory_approval.createDirectoryAccessApprovalHandlers)({
40
+ toolName: "read_file",
41
+ operation: "read",
42
+ getFileSystemService,
43
+ resolvePaths: (input, fileSystemService) => (0, import_directory_approval.resolveFilePath)(fileSystemService.getWorkingDirectory(), input.file_path)
44
+ }),
45
+ async execute(input, context) {
46
+ const resolvedFileSystemService = await getFileSystemService(context);
90
47
  const { file_path, limit, offset } = input;
91
- const result = await fileSystemService.readFile(file_path, {
48
+ const { path: resolvedPath } = (0, import_directory_approval.resolveFilePath)(
49
+ resolvedFileSystemService.getWorkingDirectory(),
50
+ file_path
51
+ );
52
+ const result = await resolvedFileSystemService.readFile(resolvedPath, {
92
53
  limit,
93
54
  offset
94
55
  });
95
56
  const _display = {
96
57
  type: "file",
97
- path: file_path,
58
+ path: resolvedPath,
98
59
  operation: "read",
99
60
  size: result.size,
100
61
  lineCount: result.lines
@@ -109,7 +70,7 @@ function createReadFileTool(options) {
109
70
  _display
110
71
  };
111
72
  }
112
- };
73
+ });
113
74
  }
114
75
  // Annotate the CommonJS export names for ESM import in node:
115
76
  0 && (module.exports = {
@@ -1,5 +1,6 @@
1
- import { InternalTool } from '@dexto/core';
2
- import { FileToolOptions } from './file-tool-types.cjs';
1
+ import { z } from 'zod';
2
+ import { Tool } from '@dexto/core';
3
+ import { FileSystemServiceGetter } from './file-tool-types.cjs';
3
4
  import './filesystem-service.cjs';
4
5
  import './types.cjs';
5
6
 
@@ -9,9 +10,22 @@ import './types.cjs';
9
10
  * Internal tool for reading file contents with size limits and pagination
10
11
  */
11
12
 
13
+ declare const ReadFileInputSchema: z.ZodObject<{
14
+ file_path: z.ZodString;
15
+ limit: z.ZodOptional<z.ZodNumber>;
16
+ offset: z.ZodOptional<z.ZodNumber>;
17
+ }, "strict", z.ZodTypeAny, {
18
+ file_path: string;
19
+ limit?: number | undefined;
20
+ offset?: number | undefined;
21
+ }, {
22
+ file_path: string;
23
+ limit?: number | undefined;
24
+ offset?: number | undefined;
25
+ }>;
12
26
  /**
13
27
  * Create the read_file internal tool with directory approval support
14
28
  */
15
- declare function createReadFileTool(options: FileToolOptions): InternalTool;
29
+ declare function createReadFileTool(getFileSystemService: FileSystemServiceGetter): Tool<typeof ReadFileInputSchema>;
16
30
 
17
31
  export { createReadFileTool };
@@ -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
  * Read File Tool
8
3
  *
9
4
  * Internal tool for reading file contents with size limits and pagination
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 ReadFileInputSchema: z.ZodObject<{
10
+ file_path: z.ZodString;
11
+ limit: z.ZodOptional<z.ZodNumber>;
12
+ offset: z.ZodOptional<z.ZodNumber>;
13
+ }, "strict", z.ZodTypeAny, {
14
+ file_path: string;
15
+ limit?: number | undefined;
16
+ offset?: number | undefined;
17
+ }, {
18
+ file_path: string;
19
+ limit?: number | undefined;
20
+ offset?: number | undefined;
21
+ }>;
12
22
  /**
13
23
  * Create the read_file internal tool with directory approval support
14
24
  */
15
- declare function createReadFileTool(options: FileToolOptions): InternalTool;
16
-
17
- export { createReadFileTool };
25
+ export declare function createReadFileTool(getFileSystemService: FileSystemServiceGetter): Tool<typeof ReadFileInputSchema>;
26
+ export {};
27
+ //# sourceMappingURL=read-file-tool.d.ts.map