@dexto/tools-filesystem 1.6.25 → 1.6.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/directory-approval.cjs +6 -4
- package/dist/directory-approval.d.ts.map +1 -1
- package/dist/directory-approval.integration.test.cjs +235 -6
- package/dist/directory-approval.integration.test.js +236 -6
- package/dist/directory-approval.js +6 -4
- package/dist/filesystem-service.cjs +6 -2
- package/dist/filesystem-service.d.ts.map +1 -1
- package/dist/filesystem-service.js +6 -2
- package/dist/glob-files-tool.cjs +3 -13
- package/dist/glob-files-tool.d.ts.map +1 -1
- package/dist/glob-files-tool.js +3 -3
- package/dist/glob-files-tool.test.cjs +115 -0
- package/dist/glob-files-tool.test.d.ts +2 -0
- package/dist/glob-files-tool.test.d.ts.map +1 -0
- package/dist/glob-files-tool.test.js +92 -0
- package/dist/grep-content-tool.cjs +3 -13
- package/dist/grep-content-tool.d.ts.map +1 -1
- package/dist/grep-content-tool.js +3 -3
- package/dist/grep-content-tool.test.cjs +115 -0
- package/dist/grep-content-tool.test.d.ts +2 -0
- package/dist/grep-content-tool.test.d.ts.map +1 -0
- package/dist/grep-content-tool.test.js +92 -0
- package/dist/path-utils.cjs +55 -0
- package/dist/path-utils.d.ts +11 -0
- package/dist/path-utils.d.ts.map +1 -0
- package/dist/path-utils.js +20 -0
- package/dist/path-utils.test.cjs +52 -0
- package/dist/path-utils.test.d.ts +2 -0
- package/dist/path-utils.test.d.ts.map +1 -0
- package/dist/path-utils.test.js +29 -0
- package/dist/path-validator.cjs +23 -9
- package/dist/path-validator.d.ts.map +1 -1
- package/dist/path-validator.js +23 -9
- package/dist/path-validator.test.cjs +41 -0
- package/dist/path-validator.test.js +19 -0
- package/dist/tool-factory-config.d.ts +2 -2
- package/dist/tool-factory.cjs +29 -50
- package/dist/tool-factory.d.ts.map +1 -1
- package/dist/tool-factory.js +29 -50
- package/dist/write-file-tool.test.cjs +33 -0
- package/dist/write-file-tool.test.js +33 -0
- package/package.json +3 -3
|
@@ -39,6 +39,7 @@ var import_core = require("@dexto/core");
|
|
|
39
39
|
var import_path_validator = require("./path-validator.js");
|
|
40
40
|
var import_errors = require("./errors.js");
|
|
41
41
|
var import_mime_utils = require("./mime-utils.js");
|
|
42
|
+
var import_path_utils = require("./path-utils.js");
|
|
42
43
|
const DEFAULT_ENCODING = "utf-8";
|
|
43
44
|
const DEFAULT_MAX_RESULTS = 1e3;
|
|
44
45
|
const DEFAULT_MAX_SEARCH_RESULTS = 100;
|
|
@@ -68,7 +69,7 @@ class FileSystemService {
|
|
|
68
69
|
* TODO: Migrate to explicit configuration via CLI enrichment layer (per-agent paths)
|
|
69
70
|
*/
|
|
70
71
|
getBackupDir() {
|
|
71
|
-
return this.config.backupPath
|
|
72
|
+
return this.config.backupPath ? (0, import_path_utils.resolveUserPath)(this.getWorkingDirectory(), this.config.backupPath) : (0, import_core.getDextoPath)("backups");
|
|
72
73
|
}
|
|
73
74
|
/**
|
|
74
75
|
* Get the effective working directory for file operations.
|
|
@@ -313,7 +314,10 @@ class FileSystemService {
|
|
|
313
314
|
*/
|
|
314
315
|
async globFiles(pattern, options = {}) {
|
|
315
316
|
await this.ensureInitialized();
|
|
316
|
-
const cwd =
|
|
317
|
+
const cwd = (0, import_path_utils.resolveUserPath)(
|
|
318
|
+
this.config.workingDirectory || process.cwd(),
|
|
319
|
+
options.cwd || this.config.workingDirectory || process.cwd()
|
|
320
|
+
);
|
|
317
321
|
const maxResults = options.maxResults || DEFAULT_MAX_RESULTS;
|
|
318
322
|
try {
|
|
319
323
|
const files = await (0, import_glob.glob)(pattern, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filesystem-service.d.ts","sourceRoot":"","sources":["../src/filesystem-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAmC,MAAM,EAAqB,MAAM,aAAa,CAAC;AACzF,OAAO,EACH,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,UAAU,EACV,WAAW,EACX,YAAY,EAEZ,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,UAAU,EACV,aAAa,EAGb,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAEnB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"filesystem-service.d.ts","sourceRoot":"","sources":["../src/filesystem-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAmC,MAAM,EAAqB,MAAM,aAAa,CAAC;AACzF,OAAO,EACH,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,UAAU,EACV,WAAW,EACX,YAAY,EAEZ,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,UAAU,EACV,aAAa,EAGb,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAEnB,MAAM,YAAY,CAAC;AAYpB;;;;;;;;GAQG;AACH,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,wBAAwB,CAAC,CAAgC;IAEjE;;;;;;OAMG;gBACS,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM;IAQpD;;;OAGG;IACH,OAAO,CAAC,YAAY;IAOpB;;;OAGG;IACH,mBAAmB,IAAI,MAAM;IAI7B;;;OAGG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B;;OAEG;YACW,YAAY;IAuB1B;;;;OAIG;IACG,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAOxC;;;;;OAKG;IACH,2BAA2B,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI;IAKzE;;;OAGG;IACH,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI;IAanD;;;;;;OAMG;IACG,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YAIrD,gBAAgB;YAchB,kBAAkB;IA8FhC;;OAEG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;IAOrF;;OAEG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAsDhE;;;;;;OAMG;IACG,sBAAsB,CACxB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,eAAoB,GAC9B,OAAO,CAAC,WAAW,CAAC;IAOvB;;OAEG;IACG,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IAyEhF;;OAEG;IACG,aAAa,CACf,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,oBAAyB,GACnC,OAAO,CAAC,mBAAmB,CAAC;YAuJjB,kBAAkB;IA+BhC;;OAEG;IACG,eAAe,CACjB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,sBAA2B,GACrC,OAAO,CAAC,qBAAqB,CAAC;IAqCjC;;OAEG;IACG,UAAU,CACZ,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,iBAAsB,GAChC,OAAO,CAAC,gBAAgB,CAAC;IA4B5B;;OAEG;IACG,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA6D7E;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAyItF;;OAEG;IACG,SAAS,CACX,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,gBAAqB,GAC/B,OAAO,CAAC,WAAW,CAAC;IAwDvB;;OAEG;IACG,QAAQ,CACV,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,aAAa,EACxB,OAAO,GAAE,eAAoB,GAC9B,OAAO,CAAC,UAAU,CAAC;IAqEtB;;OAEG;YACW,YAAY;IA0B1B;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IA6D1C;;OAEG;IACH,SAAS,IAAI,QAAQ,CAAC,gBAAgB,CAAC;IAIvC;;OAEG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAI1D"}
|
|
@@ -6,6 +6,7 @@ import { DextoRuntimeError, getDextoPath, DextoLogComponent } from "@dexto/core"
|
|
|
6
6
|
import { PathValidator } from "./path-validator.js";
|
|
7
7
|
import { FileSystemError } from "./errors.js";
|
|
8
8
|
import { detectMimeType, getMediaFileKind, isLikelyBinary, isTextMimeType } from "./mime-utils.js";
|
|
9
|
+
import { resolveUserPath } from "./path-utils.js";
|
|
9
10
|
const DEFAULT_ENCODING = "utf-8";
|
|
10
11
|
const DEFAULT_MAX_RESULTS = 1e3;
|
|
11
12
|
const DEFAULT_MAX_SEARCH_RESULTS = 100;
|
|
@@ -35,7 +36,7 @@ class FileSystemService {
|
|
|
35
36
|
* TODO: Migrate to explicit configuration via CLI enrichment layer (per-agent paths)
|
|
36
37
|
*/
|
|
37
38
|
getBackupDir() {
|
|
38
|
-
return this.config.backupPath
|
|
39
|
+
return this.config.backupPath ? resolveUserPath(this.getWorkingDirectory(), this.config.backupPath) : getDextoPath("backups");
|
|
39
40
|
}
|
|
40
41
|
/**
|
|
41
42
|
* Get the effective working directory for file operations.
|
|
@@ -280,7 +281,10 @@ class FileSystemService {
|
|
|
280
281
|
*/
|
|
281
282
|
async globFiles(pattern, options = {}) {
|
|
282
283
|
await this.ensureInitialized();
|
|
283
|
-
const cwd =
|
|
284
|
+
const cwd = resolveUserPath(
|
|
285
|
+
this.config.workingDirectory || process.cwd(),
|
|
286
|
+
options.cwd || this.config.workingDirectory || process.cwd()
|
|
287
|
+
);
|
|
284
288
|
const maxResults = options.maxResults || DEFAULT_MAX_RESULTS;
|
|
285
289
|
try {
|
|
286
290
|
const files = await glob(pattern, {
|
package/dist/glob-files-tool.cjs
CHANGED
|
@@ -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,24 +15,16 @@ 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 glob_files_tool_exports = {};
|
|
30
20
|
__export(glob_files_tool_exports, {
|
|
31
21
|
createGlobFilesTool: () => createGlobFilesTool
|
|
32
22
|
});
|
|
33
23
|
module.exports = __toCommonJS(glob_files_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");
|
|
37
26
|
var import_directory_approval = require("./directory-approval.js");
|
|
27
|
+
var import_path_utils = require("./path-utils.js");
|
|
38
28
|
const GlobFilesInputSchema = import_zod.z.object({
|
|
39
29
|
pattern: import_zod.z.string().describe('Glob pattern to match files (e.g., "**/*.ts", "src/**/*.js")'),
|
|
40
30
|
path: import_zod.z.string().optional().describe("Base directory to search from (defaults to working directory)"),
|
|
@@ -64,7 +54,7 @@ function createGlobFilesTool(getFileSystemService) {
|
|
|
64
54
|
getFileSystemService,
|
|
65
55
|
resolvePaths: (input, fileSystemService) => {
|
|
66
56
|
const baseDir = fileSystemService.getWorkingDirectory();
|
|
67
|
-
const searchDir =
|
|
57
|
+
const searchDir = (0, import_path_utils.resolveUserPath)(baseDir, input.path || ".");
|
|
68
58
|
return { path: searchDir, parentDir: searchDir };
|
|
69
59
|
}
|
|
70
60
|
}),
|
|
@@ -72,7 +62,7 @@ function createGlobFilesTool(getFileSystemService) {
|
|
|
72
62
|
const resolvedFileSystemService = await getFileSystemService(context);
|
|
73
63
|
const { pattern, path: searchPath, max_results } = input;
|
|
74
64
|
const baseDir = resolvedFileSystemService.getWorkingDirectory();
|
|
75
|
-
const resolvedSearchPath =
|
|
65
|
+
const resolvedSearchPath = (0, import_path_utils.resolveUserPath)(baseDir, searchPath || ".");
|
|
76
66
|
const result = await resolvedFileSystemService.globFiles(pattern, {
|
|
77
67
|
cwd: resolvedSearchPath,
|
|
78
68
|
maxResults: max_results,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"glob-files-tool.d.ts","sourceRoot":"","sources":["../src/glob-files-tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"glob-files-tool.d.ts","sourceRoot":"","sources":["../src/glob-files-tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,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;AAIpE,QAAA,MAAM,oBAAoB;;;;;;;;;;;;EAiBb,CAAC;AAEd;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,oBAAoB,EAAE,uBAAuB,GAC9C,IAAI,CAAC,OAAO,oBAAoB,CAAC,CA2EnC"}
|
package/dist/glob-files-tool.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as path from "node:path";
|
|
2
1
|
import { z } from "zod";
|
|
3
2
|
import { createLocalToolCallHeader, defineTool, truncateForHeader } from "@dexto/core";
|
|
4
3
|
import { createDirectoryAccessApprovalHandlers } from "./directory-approval.js";
|
|
4
|
+
import { resolveUserPath } from "./path-utils.js";
|
|
5
5
|
const GlobFilesInputSchema = z.object({
|
|
6
6
|
pattern: z.string().describe('Glob pattern to match files (e.g., "**/*.ts", "src/**/*.js")'),
|
|
7
7
|
path: z.string().optional().describe("Base directory to search from (defaults to working directory)"),
|
|
@@ -31,7 +31,7 @@ function createGlobFilesTool(getFileSystemService) {
|
|
|
31
31
|
getFileSystemService,
|
|
32
32
|
resolvePaths: (input, fileSystemService) => {
|
|
33
33
|
const baseDir = fileSystemService.getWorkingDirectory();
|
|
34
|
-
const searchDir =
|
|
34
|
+
const searchDir = resolveUserPath(baseDir, input.path || ".");
|
|
35
35
|
return { path: searchDir, parentDir: searchDir };
|
|
36
36
|
}
|
|
37
37
|
}),
|
|
@@ -39,7 +39,7 @@ function createGlobFilesTool(getFileSystemService) {
|
|
|
39
39
|
const resolvedFileSystemService = await getFileSystemService(context);
|
|
40
40
|
const { pattern, path: searchPath, max_results } = input;
|
|
41
41
|
const baseDir = resolvedFileSystemService.getWorkingDirectory();
|
|
42
|
-
const resolvedSearchPath =
|
|
42
|
+
const resolvedSearchPath = resolveUserPath(baseDir, searchPath || ".");
|
|
43
43
|
const result = await resolvedFileSystemService.globFiles(pattern, {
|
|
44
44
|
cwd: resolvedSearchPath,
|
|
45
45
|
maxResults: max_results,
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (let key of __getOwnPropNames(from))
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
12
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
13
|
+
}
|
|
14
|
+
return to;
|
|
15
|
+
};
|
|
16
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
18
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
19
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
20
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
24
|
+
var import_vitest = require("vitest");
|
|
25
|
+
var path = __toESM(require("node:path"), 1);
|
|
26
|
+
var fs = __toESM(require("node:fs/promises"), 1);
|
|
27
|
+
var os = __toESM(require("node:os"), 1);
|
|
28
|
+
var import_filesystem_service = require("./filesystem-service.js");
|
|
29
|
+
var import_glob_files_tool = require("./glob-files-tool.js");
|
|
30
|
+
const createMockLogger = () => {
|
|
31
|
+
const logger = {
|
|
32
|
+
debug: import_vitest.vi.fn(),
|
|
33
|
+
silly: import_vitest.vi.fn(),
|
|
34
|
+
info: import_vitest.vi.fn(),
|
|
35
|
+
warn: import_vitest.vi.fn(),
|
|
36
|
+
error: import_vitest.vi.fn(),
|
|
37
|
+
trackException: import_vitest.vi.fn(),
|
|
38
|
+
createChild: import_vitest.vi.fn(() => logger),
|
|
39
|
+
createFileOnlyChild: import_vitest.vi.fn(() => logger),
|
|
40
|
+
setLevel: import_vitest.vi.fn(),
|
|
41
|
+
getLevel: import_vitest.vi.fn(() => "debug"),
|
|
42
|
+
getLogFilePath: import_vitest.vi.fn(() => null),
|
|
43
|
+
destroy: import_vitest.vi.fn(async () => void 0)
|
|
44
|
+
};
|
|
45
|
+
return logger;
|
|
46
|
+
};
|
|
47
|
+
function createToolContext(logger) {
|
|
48
|
+
return { logger };
|
|
49
|
+
}
|
|
50
|
+
(0, import_vitest.describe)("glob_files tool", () => {
|
|
51
|
+
let mockLogger;
|
|
52
|
+
let tempDir;
|
|
53
|
+
let fileSystemService;
|
|
54
|
+
(0, import_vitest.beforeEach)(async () => {
|
|
55
|
+
mockLogger = createMockLogger();
|
|
56
|
+
const rawTempDir = await fs.mkdtemp(path.join(os.tmpdir(), "dexto-glob-test-"));
|
|
57
|
+
tempDir = await fs.realpath(rawTempDir);
|
|
58
|
+
fileSystemService = new import_filesystem_service.FileSystemService(
|
|
59
|
+
{
|
|
60
|
+
allowedPaths: [tempDir],
|
|
61
|
+
blockedPaths: [],
|
|
62
|
+
blockedExtensions: [],
|
|
63
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
64
|
+
workingDirectory: tempDir,
|
|
65
|
+
enableBackups: false,
|
|
66
|
+
backupRetentionDays: 7
|
|
67
|
+
},
|
|
68
|
+
mockLogger
|
|
69
|
+
);
|
|
70
|
+
await fileSystemService.initialize();
|
|
71
|
+
});
|
|
72
|
+
(0, import_vitest.afterEach)(async () => {
|
|
73
|
+
import_vitest.vi.restoreAllMocks();
|
|
74
|
+
try {
|
|
75
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
76
|
+
} catch {
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
(0, import_vitest.it)("expands home-directory shorthand for glob base paths", async () => {
|
|
80
|
+
const homeTempDir = await fs.mkdtemp(path.join(os.homedir(), ".dexto-glob-home-test-"));
|
|
81
|
+
const fileSystemServiceForHome = new import_filesystem_service.FileSystemService(
|
|
82
|
+
{
|
|
83
|
+
allowedPaths: [homeTempDir],
|
|
84
|
+
blockedPaths: [],
|
|
85
|
+
blockedExtensions: [],
|
|
86
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
87
|
+
workingDirectory: tempDir,
|
|
88
|
+
enableBackups: false,
|
|
89
|
+
backupRetentionDays: 7
|
|
90
|
+
},
|
|
91
|
+
mockLogger
|
|
92
|
+
);
|
|
93
|
+
await fileSystemServiceForHome.initialize();
|
|
94
|
+
try {
|
|
95
|
+
const filePath = path.join(homeTempDir, "notes.txt");
|
|
96
|
+
await fs.writeFile(filePath, "hello");
|
|
97
|
+
const tool = (0, import_glob_files_tool.createGlobFilesTool)(async () => fileSystemServiceForHome);
|
|
98
|
+
const parsedInput = tool.inputSchema.parse({
|
|
99
|
+
pattern: "**/*.txt",
|
|
100
|
+
path: `~/${path.basename(homeTempDir)}`
|
|
101
|
+
});
|
|
102
|
+
const result = await tool.execute(parsedInput, createToolContext(mockLogger));
|
|
103
|
+
(0, import_vitest.expect)(result.total_found).toBe(1);
|
|
104
|
+
(0, import_vitest.expect)(result.files).toEqual([
|
|
105
|
+
{
|
|
106
|
+
path: filePath,
|
|
107
|
+
size: 5,
|
|
108
|
+
modified: import_vitest.expect.any(String)
|
|
109
|
+
}
|
|
110
|
+
]);
|
|
111
|
+
} finally {
|
|
112
|
+
await fs.rm(homeTempDir, { recursive: true, force: true });
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glob-files-tool.test.d.ts","sourceRoot":"","sources":["../src/glob-files-tool.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import * as fs from "node:fs/promises";
|
|
4
|
+
import * as os from "node:os";
|
|
5
|
+
import { FileSystemService } from "./filesystem-service.js";
|
|
6
|
+
import { createGlobFilesTool } from "./glob-files-tool.js";
|
|
7
|
+
const createMockLogger = () => {
|
|
8
|
+
const logger = {
|
|
9
|
+
debug: vi.fn(),
|
|
10
|
+
silly: vi.fn(),
|
|
11
|
+
info: vi.fn(),
|
|
12
|
+
warn: vi.fn(),
|
|
13
|
+
error: vi.fn(),
|
|
14
|
+
trackException: vi.fn(),
|
|
15
|
+
createChild: vi.fn(() => logger),
|
|
16
|
+
createFileOnlyChild: vi.fn(() => logger),
|
|
17
|
+
setLevel: vi.fn(),
|
|
18
|
+
getLevel: vi.fn(() => "debug"),
|
|
19
|
+
getLogFilePath: vi.fn(() => null),
|
|
20
|
+
destroy: vi.fn(async () => void 0)
|
|
21
|
+
};
|
|
22
|
+
return logger;
|
|
23
|
+
};
|
|
24
|
+
function createToolContext(logger) {
|
|
25
|
+
return { logger };
|
|
26
|
+
}
|
|
27
|
+
describe("glob_files tool", () => {
|
|
28
|
+
let mockLogger;
|
|
29
|
+
let tempDir;
|
|
30
|
+
let fileSystemService;
|
|
31
|
+
beforeEach(async () => {
|
|
32
|
+
mockLogger = createMockLogger();
|
|
33
|
+
const rawTempDir = await fs.mkdtemp(path.join(os.tmpdir(), "dexto-glob-test-"));
|
|
34
|
+
tempDir = await fs.realpath(rawTempDir);
|
|
35
|
+
fileSystemService = new FileSystemService(
|
|
36
|
+
{
|
|
37
|
+
allowedPaths: [tempDir],
|
|
38
|
+
blockedPaths: [],
|
|
39
|
+
blockedExtensions: [],
|
|
40
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
41
|
+
workingDirectory: tempDir,
|
|
42
|
+
enableBackups: false,
|
|
43
|
+
backupRetentionDays: 7
|
|
44
|
+
},
|
|
45
|
+
mockLogger
|
|
46
|
+
);
|
|
47
|
+
await fileSystemService.initialize();
|
|
48
|
+
});
|
|
49
|
+
afterEach(async () => {
|
|
50
|
+
vi.restoreAllMocks();
|
|
51
|
+
try {
|
|
52
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
53
|
+
} catch {
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
it("expands home-directory shorthand for glob base paths", async () => {
|
|
57
|
+
const homeTempDir = await fs.mkdtemp(path.join(os.homedir(), ".dexto-glob-home-test-"));
|
|
58
|
+
const fileSystemServiceForHome = new FileSystemService(
|
|
59
|
+
{
|
|
60
|
+
allowedPaths: [homeTempDir],
|
|
61
|
+
blockedPaths: [],
|
|
62
|
+
blockedExtensions: [],
|
|
63
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
64
|
+
workingDirectory: tempDir,
|
|
65
|
+
enableBackups: false,
|
|
66
|
+
backupRetentionDays: 7
|
|
67
|
+
},
|
|
68
|
+
mockLogger
|
|
69
|
+
);
|
|
70
|
+
await fileSystemServiceForHome.initialize();
|
|
71
|
+
try {
|
|
72
|
+
const filePath = path.join(homeTempDir, "notes.txt");
|
|
73
|
+
await fs.writeFile(filePath, "hello");
|
|
74
|
+
const tool = createGlobFilesTool(async () => fileSystemServiceForHome);
|
|
75
|
+
const parsedInput = tool.inputSchema.parse({
|
|
76
|
+
pattern: "**/*.txt",
|
|
77
|
+
path: `~/${path.basename(homeTempDir)}`
|
|
78
|
+
});
|
|
79
|
+
const result = await tool.execute(parsedInput, createToolContext(mockLogger));
|
|
80
|
+
expect(result.total_found).toBe(1);
|
|
81
|
+
expect(result.files).toEqual([
|
|
82
|
+
{
|
|
83
|
+
path: filePath,
|
|
84
|
+
size: 5,
|
|
85
|
+
modified: expect.any(String)
|
|
86
|
+
}
|
|
87
|
+
]);
|
|
88
|
+
} finally {
|
|
89
|
+
await fs.rm(homeTempDir, { recursive: true, force: true });
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
});
|
|
@@ -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,24 +15,16 @@ 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 grep_content_tool_exports = {};
|
|
30
20
|
__export(grep_content_tool_exports, {
|
|
31
21
|
createGrepContentTool: () => createGrepContentTool
|
|
32
22
|
});
|
|
33
23
|
module.exports = __toCommonJS(grep_content_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");
|
|
37
26
|
var import_directory_approval = require("./directory-approval.js");
|
|
27
|
+
var import_path_utils = require("./path-utils.js");
|
|
38
28
|
const GrepContentInputSchema = import_zod.z.object({
|
|
39
29
|
pattern: import_zod.z.string().describe("Regular expression pattern to search for"),
|
|
40
30
|
path: import_zod.z.string().optional().describe("Directory to search in (defaults to working directory)"),
|
|
@@ -70,7 +60,7 @@ function createGrepContentTool(getFileSystemService) {
|
|
|
70
60
|
getFileSystemService,
|
|
71
61
|
resolvePaths: (input, fileSystemService) => {
|
|
72
62
|
const baseDir = fileSystemService.getWorkingDirectory();
|
|
73
|
-
const searchDir =
|
|
63
|
+
const searchDir = (0, import_path_utils.resolveUserPath)(baseDir, input.path || ".");
|
|
74
64
|
return { path: searchDir, parentDir: searchDir };
|
|
75
65
|
}
|
|
76
66
|
}),
|
|
@@ -85,7 +75,7 @@ function createGrepContentTool(getFileSystemService) {
|
|
|
85
75
|
max_results
|
|
86
76
|
} = input;
|
|
87
77
|
const baseDir = resolvedFileSystemService.getWorkingDirectory();
|
|
88
|
-
const resolvedSearchPath =
|
|
78
|
+
const resolvedSearchPath = (0, import_path_utils.resolveUserPath)(baseDir, searchPath || ".");
|
|
89
79
|
const result = await resolvedFileSystemService.searchContent(pattern, {
|
|
90
80
|
path: resolvedSearchPath,
|
|
91
81
|
glob,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grep-content-tool.d.ts","sourceRoot":"","sources":["../src/grep-content-tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"grep-content-tool.d.ts","sourceRoot":"","sources":["../src/grep-content-tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,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;AAIpE,QAAA,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;EAiCf,CAAC;AAEd;;GAEG;AACH,wBAAgB,qBAAqB,CACjC,oBAAoB,EAAE,uBAAuB,GAC9C,IAAI,CAAC,OAAO,sBAAsB,CAAC,CA6FrC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as path from "node:path";
|
|
2
1
|
import { z } from "zod";
|
|
3
2
|
import { createLocalToolCallHeader, defineTool, truncateForHeader } from "@dexto/core";
|
|
4
3
|
import { createDirectoryAccessApprovalHandlers } from "./directory-approval.js";
|
|
4
|
+
import { resolveUserPath } from "./path-utils.js";
|
|
5
5
|
const GrepContentInputSchema = z.object({
|
|
6
6
|
pattern: z.string().describe("Regular expression pattern to search for"),
|
|
7
7
|
path: z.string().optional().describe("Directory to search in (defaults to working directory)"),
|
|
@@ -37,7 +37,7 @@ function createGrepContentTool(getFileSystemService) {
|
|
|
37
37
|
getFileSystemService,
|
|
38
38
|
resolvePaths: (input, fileSystemService) => {
|
|
39
39
|
const baseDir = fileSystemService.getWorkingDirectory();
|
|
40
|
-
const searchDir =
|
|
40
|
+
const searchDir = resolveUserPath(baseDir, input.path || ".");
|
|
41
41
|
return { path: searchDir, parentDir: searchDir };
|
|
42
42
|
}
|
|
43
43
|
}),
|
|
@@ -52,7 +52,7 @@ function createGrepContentTool(getFileSystemService) {
|
|
|
52
52
|
max_results
|
|
53
53
|
} = input;
|
|
54
54
|
const baseDir = resolvedFileSystemService.getWorkingDirectory();
|
|
55
|
-
const resolvedSearchPath =
|
|
55
|
+
const resolvedSearchPath = resolveUserPath(baseDir, searchPath || ".");
|
|
56
56
|
const result = await resolvedFileSystemService.searchContent(pattern, {
|
|
57
57
|
path: resolvedSearchPath,
|
|
58
58
|
glob,
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (let key of __getOwnPropNames(from))
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
12
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
13
|
+
}
|
|
14
|
+
return to;
|
|
15
|
+
};
|
|
16
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
18
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
19
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
20
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
24
|
+
var import_vitest = require("vitest");
|
|
25
|
+
var path = __toESM(require("node:path"), 1);
|
|
26
|
+
var fs = __toESM(require("node:fs/promises"), 1);
|
|
27
|
+
var os = __toESM(require("node:os"), 1);
|
|
28
|
+
var import_filesystem_service = require("./filesystem-service.js");
|
|
29
|
+
var import_grep_content_tool = require("./grep-content-tool.js");
|
|
30
|
+
const createMockLogger = () => {
|
|
31
|
+
const logger = {
|
|
32
|
+
debug: import_vitest.vi.fn(),
|
|
33
|
+
silly: import_vitest.vi.fn(),
|
|
34
|
+
info: import_vitest.vi.fn(),
|
|
35
|
+
warn: import_vitest.vi.fn(),
|
|
36
|
+
error: import_vitest.vi.fn(),
|
|
37
|
+
trackException: import_vitest.vi.fn(),
|
|
38
|
+
createChild: import_vitest.vi.fn(() => logger),
|
|
39
|
+
createFileOnlyChild: import_vitest.vi.fn(() => logger),
|
|
40
|
+
setLevel: import_vitest.vi.fn(),
|
|
41
|
+
getLevel: import_vitest.vi.fn(() => "debug"),
|
|
42
|
+
getLogFilePath: import_vitest.vi.fn(() => null),
|
|
43
|
+
destroy: import_vitest.vi.fn(async () => void 0)
|
|
44
|
+
};
|
|
45
|
+
return logger;
|
|
46
|
+
};
|
|
47
|
+
function createToolContext(logger) {
|
|
48
|
+
return { logger };
|
|
49
|
+
}
|
|
50
|
+
(0, import_vitest.describe)("grep_content tool", () => {
|
|
51
|
+
let mockLogger;
|
|
52
|
+
let tempDir;
|
|
53
|
+
let fileSystemService;
|
|
54
|
+
(0, import_vitest.beforeEach)(async () => {
|
|
55
|
+
mockLogger = createMockLogger();
|
|
56
|
+
const rawTempDir = await fs.mkdtemp(path.join(os.tmpdir(), "dexto-grep-test-"));
|
|
57
|
+
tempDir = await fs.realpath(rawTempDir);
|
|
58
|
+
fileSystemService = new import_filesystem_service.FileSystemService(
|
|
59
|
+
{
|
|
60
|
+
allowedPaths: [tempDir],
|
|
61
|
+
blockedPaths: [],
|
|
62
|
+
blockedExtensions: [],
|
|
63
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
64
|
+
workingDirectory: tempDir,
|
|
65
|
+
enableBackups: false,
|
|
66
|
+
backupRetentionDays: 7
|
|
67
|
+
},
|
|
68
|
+
mockLogger
|
|
69
|
+
);
|
|
70
|
+
await fileSystemService.initialize();
|
|
71
|
+
});
|
|
72
|
+
(0, import_vitest.afterEach)(async () => {
|
|
73
|
+
import_vitest.vi.restoreAllMocks();
|
|
74
|
+
try {
|
|
75
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
76
|
+
} catch {
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
(0, import_vitest.it)("expands home-directory shorthand for search paths", async () => {
|
|
80
|
+
const homeTempDir = await fs.mkdtemp(path.join(os.homedir(), ".dexto-grep-home-test-"));
|
|
81
|
+
const fileSystemServiceForHome = new import_filesystem_service.FileSystemService(
|
|
82
|
+
{
|
|
83
|
+
allowedPaths: [homeTempDir],
|
|
84
|
+
blockedPaths: [],
|
|
85
|
+
blockedExtensions: [],
|
|
86
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
87
|
+
workingDirectory: tempDir,
|
|
88
|
+
enableBackups: false,
|
|
89
|
+
backupRetentionDays: 7
|
|
90
|
+
},
|
|
91
|
+
mockLogger
|
|
92
|
+
);
|
|
93
|
+
await fileSystemServiceForHome.initialize();
|
|
94
|
+
try {
|
|
95
|
+
const filePath = path.join(homeTempDir, "notes.txt");
|
|
96
|
+
await fs.writeFile(filePath, "alpha\nneedle\nomega\n");
|
|
97
|
+
const tool = (0, import_grep_content_tool.createGrepContentTool)(async () => fileSystemServiceForHome);
|
|
98
|
+
const parsedInput = tool.inputSchema.parse({
|
|
99
|
+
pattern: "needle",
|
|
100
|
+
path: `~/${path.basename(homeTempDir)}`
|
|
101
|
+
});
|
|
102
|
+
const result = await tool.execute(parsedInput, createToolContext(mockLogger));
|
|
103
|
+
(0, import_vitest.expect)(result.files_searched).toBe(1);
|
|
104
|
+
(0, import_vitest.expect)(result.matches).toEqual([
|
|
105
|
+
{
|
|
106
|
+
file: filePath,
|
|
107
|
+
line_number: 2,
|
|
108
|
+
line: "needle"
|
|
109
|
+
}
|
|
110
|
+
]);
|
|
111
|
+
} finally {
|
|
112
|
+
await fs.rm(homeTempDir, { recursive: true, force: true });
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grep-content-tool.test.d.ts","sourceRoot":"","sources":["../src/grep-content-tool.test.ts"],"names":[],"mappings":""}
|