@skroyc/librarian 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -16
- package/dist/agents/context-schema.d.ts +1 -1
- package/dist/agents/context-schema.d.ts.map +1 -1
- package/dist/agents/context-schema.js +5 -2
- package/dist/agents/context-schema.js.map +1 -1
- package/dist/agents/react-agent.d.ts.map +1 -1
- package/dist/agents/react-agent.js +36 -27
- package/dist/agents/react-agent.js.map +1 -1
- package/dist/agents/tool-runtime.d.ts.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +53 -49
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +115 -69
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +246 -150
- package/dist/index.js.map +1 -1
- package/dist/tools/file-finding.tool.d.ts +1 -1
- package/dist/tools/file-finding.tool.d.ts.map +1 -1
- package/dist/tools/file-finding.tool.js +70 -130
- package/dist/tools/file-finding.tool.js.map +1 -1
- package/dist/tools/file-listing.tool.d.ts +7 -1
- package/dist/tools/file-listing.tool.d.ts.map +1 -1
- package/dist/tools/file-listing.tool.js +96 -80
- package/dist/tools/file-listing.tool.js.map +1 -1
- package/dist/tools/file-reading.tool.d.ts +4 -1
- package/dist/tools/file-reading.tool.d.ts.map +1 -1
- package/dist/tools/file-reading.tool.js +107 -45
- package/dist/tools/file-reading.tool.js.map +1 -1
- package/dist/tools/grep-content.tool.d.ts +13 -1
- package/dist/tools/grep-content.tool.d.ts.map +1 -1
- package/dist/tools/grep-content.tool.js +186 -144
- package/dist/tools/grep-content.tool.js.map +1 -1
- package/dist/utils/error-utils.d.ts +9 -0
- package/dist/utils/error-utils.d.ts.map +1 -0
- package/dist/utils/error-utils.js +61 -0
- package/dist/utils/error-utils.js.map +1 -0
- package/dist/utils/file-utils.d.ts +1 -0
- package/dist/utils/file-utils.d.ts.map +1 -1
- package/dist/utils/file-utils.js +81 -9
- package/dist/utils/file-utils.js.map +1 -1
- package/dist/utils/format-utils.d.ts +25 -0
- package/dist/utils/format-utils.d.ts.map +1 -0
- package/dist/utils/format-utils.js +111 -0
- package/dist/utils/format-utils.js.map +1 -0
- package/dist/utils/gitignore-service.d.ts +10 -0
- package/dist/utils/gitignore-service.d.ts.map +1 -0
- package/dist/utils/gitignore-service.js +91 -0
- package/dist/utils/gitignore-service.js.map +1 -0
- package/dist/utils/logger.d.ts +2 -2
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +35 -34
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/path-utils.js +3 -3
- package/dist/utils/path-utils.js.map +1 -1
- package/package.json +1 -1
- package/src/agents/context-schema.ts +5 -2
- package/src/agents/react-agent.ts +667 -641
- package/src/agents/tool-runtime.ts +4 -4
- package/src/cli.ts +95 -57
- package/src/config.ts +192 -90
- package/src/index.ts +402 -180
- package/src/tools/file-finding.tool.ts +198 -310
- package/src/tools/file-listing.tool.ts +245 -202
- package/src/tools/file-reading.tool.ts +225 -138
- package/src/tools/grep-content.tool.ts +387 -307
- package/src/utils/error-utils.ts +95 -0
- package/src/utils/file-utils.ts +104 -19
- package/src/utils/format-utils.ts +190 -0
- package/src/utils/gitignore-service.ts +123 -0
- package/src/utils/logger.ts +112 -77
- package/src/utils/path-utils.ts +3 -3
|
@@ -1,277 +1,167 @@
|
|
|
1
|
-
import { tool } from "langchain";
|
|
2
|
-
import { z } from "zod";
|
|
3
1
|
import fs from "node:fs/promises";
|
|
4
|
-
import type { Dirent } from "node:fs";
|
|
5
2
|
import path from "node:path";
|
|
3
|
+
import { Glob } from "bun";
|
|
4
|
+
import { tool } from "langchain";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { formatToolError, getToolSuggestion } from "../utils/error-utils.js";
|
|
7
|
+
import { GitIgnoreService } from "../utils/gitignore-service.js";
|
|
6
8
|
import { logger } from "../utils/logger.js";
|
|
7
9
|
|
|
8
|
-
// Find files matching glob patterns in a directory
|
|
9
|
-
async function findFiles(
|
|
10
|
-
searchPath: string,
|
|
11
|
-
patterns: string[],
|
|
12
|
-
options: {
|
|
13
|
-
exclude?: string[];
|
|
14
|
-
recursive?: boolean;
|
|
15
|
-
maxResults?: number;
|
|
16
|
-
includeHidden?: boolean;
|
|
17
|
-
} = {},
|
|
18
|
-
): Promise<string[]> {
|
|
19
|
-
const {
|
|
20
|
-
exclude = [],
|
|
21
|
-
recursive = true,
|
|
22
|
-
maxResults = 1000,
|
|
23
|
-
includeHidden = false,
|
|
24
|
-
} = options;
|
|
25
|
-
|
|
26
|
-
const foundFiles: string[] = [];
|
|
27
|
-
const processedPaths = new Set<string>();
|
|
28
|
-
|
|
29
|
-
// Process each pattern
|
|
30
|
-
for (const pattern of patterns) {
|
|
31
|
-
// Only add **/ prefix if recursive and pattern doesn't already contain path separators
|
|
32
|
-
const effectivePattern =
|
|
33
|
-
recursive && !pattern.includes("**") && !pattern.includes("/")
|
|
34
|
-
? `**/${pattern}`
|
|
35
|
-
: pattern;
|
|
36
|
-
|
|
37
|
-
// Simple glob matching implementation
|
|
38
|
-
const matchingFiles = await simpleGlobSearch(searchPath, effectivePattern, {
|
|
39
|
-
recursive,
|
|
40
|
-
includeHidden,
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
for (const file of matchingFiles) {
|
|
44
|
-
if (foundFiles.length >= maxResults) {
|
|
45
|
-
break;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (processedPaths.has(file)) {
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
processedPaths.add(file);
|
|
53
|
-
|
|
54
|
-
// Check if file should be excluded
|
|
55
|
-
const relativePath = path.relative(searchPath, file);
|
|
56
|
-
if (exclude.some((excl) => simpleMatch(relativePath, excl))) {
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
foundFiles.push(file);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (foundFiles.length >= maxResults) {
|
|
64
|
-
break;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return foundFiles.slice(0, maxResults);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
async function handleDirectoryEntry(
|
|
72
|
-
entry: Dirent,
|
|
73
|
-
basePath: string,
|
|
74
|
-
pattern: string,
|
|
75
|
-
options: { recursive: boolean; includeHidden: boolean },
|
|
76
|
-
results: string[],
|
|
77
|
-
): Promise<void> {
|
|
78
|
-
const fullPath = path.join(basePath, entry.name);
|
|
79
|
-
|
|
80
|
-
if (pattern === "**" || pattern.includes("**") || options.recursive) {
|
|
81
|
-
const basePattern = pattern.split("/")[0] || pattern;
|
|
82
|
-
if (simpleMatch(entry.name, basePattern)) {
|
|
83
|
-
results.push(fullPath);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (options.recursive) {
|
|
87
|
-
const subDirResults = await simpleGlobSearch(
|
|
88
|
-
fullPath,
|
|
89
|
-
pattern,
|
|
90
|
-
options,
|
|
91
|
-
);
|
|
92
|
-
results.push(...subDirResults);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function handleFileEntry(
|
|
98
|
-
entry: Dirent,
|
|
99
|
-
basePath: string,
|
|
100
|
-
pattern: string,
|
|
101
|
-
results: string[],
|
|
102
|
-
): void {
|
|
103
|
-
const fullPath = path.join(basePath, entry.name);
|
|
104
|
-
const relativePath = path.relative(basePath, fullPath);
|
|
105
|
-
const basePattern = pattern.includes("**/")
|
|
106
|
-
? pattern.split("**/")[1] || ""
|
|
107
|
-
: pattern;
|
|
108
|
-
if (
|
|
109
|
-
simpleMatch(entry.name, basePattern) ||
|
|
110
|
-
simpleMatch(relativePath, basePattern)
|
|
111
|
-
) {
|
|
112
|
-
results.push(fullPath);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Simple glob search implementation (basic pattern matching)
|
|
117
|
-
async function simpleGlobSearch(
|
|
118
|
-
basePath: string,
|
|
119
|
-
pattern: string,
|
|
120
|
-
options: {
|
|
121
|
-
recursive: boolean;
|
|
122
|
-
includeHidden: boolean;
|
|
123
|
-
},
|
|
124
|
-
): Promise<string[]> {
|
|
125
|
-
const results: string[] = [];
|
|
126
|
-
|
|
127
|
-
try {
|
|
128
|
-
const entries = await fs.readdir(basePath, { withFileTypes: true });
|
|
129
|
-
|
|
130
|
-
for (const entry of entries) {
|
|
131
|
-
if (!options.includeHidden && entry.name.startsWith(".")) {
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (entry.isDirectory()) {
|
|
136
|
-
await handleDirectoryEntry(entry, basePath, pattern, options, results);
|
|
137
|
-
} else if (entry.isFile()) {
|
|
138
|
-
handleFileEntry(entry, basePath, pattern, results);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
} catch {
|
|
142
|
-
return [];
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return results;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Simple pattern matching (supports * and ? wildcards)
|
|
149
|
-
function simpleMatch(str: string, pattern: string): boolean {
|
|
150
|
-
// Handle exact match first
|
|
151
|
-
if (pattern === str) {
|
|
152
|
-
return true;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Convert glob pattern to regex
|
|
156
|
-
const regexPattern = pattern
|
|
157
|
-
.replace(/\./g, "\\.") // Escape dots
|
|
158
|
-
.replace(/\*/g, ".*") // Replace * with .*
|
|
159
|
-
.replace(/\?/g, "."); // Replace ? with .
|
|
160
|
-
|
|
161
|
-
const regex = new RegExp(`^${regexPattern}$`);
|
|
162
|
-
return regex.test(str);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
10
|
// Create the modernized tool using the tool() function
|
|
166
|
-
export const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
11
|
+
export const findTool = tool(
|
|
12
|
+
async (
|
|
13
|
+
{
|
|
14
|
+
searchPath = ".",
|
|
15
|
+
patterns,
|
|
16
|
+
exclude = [],
|
|
17
|
+
recursive = true,
|
|
18
|
+
maxResults = 100,
|
|
19
|
+
includeHidden = false,
|
|
20
|
+
},
|
|
21
|
+
config
|
|
22
|
+
) => {
|
|
23
|
+
const timingId = logger.timingStart("find");
|
|
24
|
+
|
|
25
|
+
logger.info("TOOL", "find called", {
|
|
26
|
+
searchPath,
|
|
27
|
+
patterns,
|
|
28
|
+
exclude,
|
|
29
|
+
recursive,
|
|
30
|
+
maxResults,
|
|
31
|
+
includeHidden,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
// Get working directory from config context - required for security
|
|
36
|
+
const workingDir = config?.context?.workingDir;
|
|
37
|
+
if (!workingDir) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
"Context with workingDir is required for file operations"
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Validate the path to prevent directory traversal
|
|
44
|
+
const resolvedPath = path.resolve(workingDir, searchPath);
|
|
45
|
+
const resolvedWorkingDir = path.resolve(workingDir);
|
|
46
|
+
const relativePath = path.relative(resolvedWorkingDir, resolvedPath);
|
|
47
|
+
|
|
48
|
+
if (relativePath.startsWith("..")) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
`Search path "${searchPath}" attempts to escape the working directory sandbox`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Validate that the search path exists and is a directory
|
|
55
|
+
let stats: import("node:fs").Stats;
|
|
56
|
+
try {
|
|
57
|
+
stats = await fs.stat(resolvedPath);
|
|
58
|
+
} catch (error) {
|
|
59
|
+
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
|
60
|
+
throw new Error(`Search path "${searchPath}" does not exist`);
|
|
61
|
+
}
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (!stats.isDirectory()) {
|
|
66
|
+
throw new Error(`Search path "${searchPath}" is not a directory`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Validate that patterns array is not empty
|
|
70
|
+
if (!patterns || patterns.length === 0) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
'The "patterns" parameter must contain at least one glob pattern'
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Initialize GitIgnoreService
|
|
77
|
+
const gitignore = new GitIgnoreService(workingDir);
|
|
78
|
+
await gitignore.initialize();
|
|
79
|
+
|
|
80
|
+
const foundFiles: string[] = [];
|
|
81
|
+
const excludeGlobs = exclude.map((pattern) => new Glob(pattern));
|
|
82
|
+
|
|
83
|
+
// Process each pattern using Bun's native Glob for accuracy and performance
|
|
84
|
+
for (const pattern of patterns) {
|
|
85
|
+
if (foundFiles.length >= maxResults) {
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// If recursive and no directory component in pattern, prepend **/
|
|
90
|
+
const effectivePattern =
|
|
91
|
+
recursive && !pattern.includes("/") && !pattern.includes("**")
|
|
92
|
+
? `**/${pattern}`
|
|
93
|
+
: pattern;
|
|
94
|
+
|
|
95
|
+
const glob = new Glob(effectivePattern);
|
|
96
|
+
|
|
97
|
+
// Scan using resolvedPath as cwd
|
|
98
|
+
for await (const file of glob.scan({
|
|
99
|
+
cwd: resolvedPath,
|
|
100
|
+
onlyFiles: true,
|
|
101
|
+
dot: includeHidden,
|
|
102
|
+
})) {
|
|
103
|
+
if (foundFiles.length >= maxResults) {
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// file is relative to resolvedPath
|
|
108
|
+
const fullPath = path.resolve(resolvedPath, file);
|
|
109
|
+
const relativeToWorkingDir = path.relative(
|
|
110
|
+
resolvedWorkingDir,
|
|
111
|
+
fullPath
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
// 1. Check if file should be ignored by .gitignore
|
|
115
|
+
if (gitignore.shouldIgnore(fullPath, false)) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// 2. Check if file should be excluded by manual exclude patterns
|
|
120
|
+
const isExcluded = excludeGlobs.some((eg) =>
|
|
121
|
+
eg.match(relativeToWorkingDir)
|
|
122
|
+
);
|
|
123
|
+
if (isExcluded) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (!foundFiles.includes(relativeToWorkingDir)) {
|
|
128
|
+
foundFiles.push(relativeToWorkingDir);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
logger.timingEnd(timingId, "TOOL", "find completed");
|
|
134
|
+
|
|
135
|
+
if (foundFiles.length === 0) {
|
|
136
|
+
return `No files found matching patterns: ${patterns.join(", ")}`;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
foundFiles.sort();
|
|
140
|
+
|
|
141
|
+
// Format results relative to working directory
|
|
142
|
+
let output = `Found ${foundFiles.length} files matching patterns [${patterns.join(", ")}]:\n\n`;
|
|
143
|
+
output += foundFiles.join("\n");
|
|
144
|
+
|
|
145
|
+
return output;
|
|
146
|
+
} catch (error) {
|
|
147
|
+
logger.error(
|
|
148
|
+
"TOOL",
|
|
149
|
+
"find failed",
|
|
150
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
151
|
+
{ searchPath, patterns }
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
return formatToolError({
|
|
155
|
+
operation: "find",
|
|
156
|
+
path: searchPath,
|
|
157
|
+
cause: error,
|
|
158
|
+
suggestion: getToolSuggestion("find", searchPath),
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
name: "find",
|
|
164
|
+
description: `Discovers files using glob patterns. Respects .gitignore.
|
|
275
165
|
Usage
|
|
276
166
|
- Fast file pattern matching command that works with any codebase size
|
|
277
167
|
- Supports glob patterns like "**/*.js" or "src/**/*.ts"
|
|
@@ -280,45 +170,43 @@ Usage
|
|
|
280
170
|
- When you are doing an open ended search that may require multiple rounds of globbing and grepping, use the Task tool instead
|
|
281
171
|
- You can call multiple commands in a single response. It is always better to speculatively perform multiple searches in parallel if they are potentially useful.
|
|
282
172
|
`,
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
}),
|
|
323
|
-
},
|
|
173
|
+
schema: z.object({
|
|
174
|
+
searchPath: z
|
|
175
|
+
.string()
|
|
176
|
+
.describe(
|
|
177
|
+
"The directory path to search in, relative to the working directory"
|
|
178
|
+
),
|
|
179
|
+
patterns: z
|
|
180
|
+
.array(z.string())
|
|
181
|
+
.describe(
|
|
182
|
+
"Array of glob patterns to match files (e.g., ['*.js', '*.ts'])"
|
|
183
|
+
),
|
|
184
|
+
exclude: z
|
|
185
|
+
.array(z.string())
|
|
186
|
+
.optional()
|
|
187
|
+
.default([])
|
|
188
|
+
.describe(
|
|
189
|
+
"Array of glob patterns to exclude from results. Use full glob patterns for exclusions (e.g., '**/node_modules/**' to exclude a directory and its contents recursively). Defaults to none"
|
|
190
|
+
),
|
|
191
|
+
recursive: z
|
|
192
|
+
.boolean()
|
|
193
|
+
.optional()
|
|
194
|
+
.default(true)
|
|
195
|
+
.describe(
|
|
196
|
+
"Whether to search recursively in subdirectories. Defaults to `true`"
|
|
197
|
+
),
|
|
198
|
+
maxResults: z
|
|
199
|
+
.number()
|
|
200
|
+
.optional()
|
|
201
|
+
.default(100)
|
|
202
|
+
.describe("Maximum number of files to return. Defaults to 100"),
|
|
203
|
+
includeHidden: z
|
|
204
|
+
.boolean()
|
|
205
|
+
.optional()
|
|
206
|
+
.default(false)
|
|
207
|
+
.describe(
|
|
208
|
+
"Whether to include hidden files and directories. Defaults to `false`"
|
|
209
|
+
),
|
|
210
|
+
}),
|
|
211
|
+
}
|
|
324
212
|
);
|