@amodalai/runtime 0.3.33 → 0.3.35

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.
@@ -0,0 +1,603 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * File tools — sandboxed filesystem access for agent repo directories.
8
+ *
9
+ * Provides 8 tools: read_repo_file, write_repo_file, edit_repo_file,
10
+ * delete_repo_file, list_repo_files, glob_repo_files, grep_repo_files,
11
+ * and read_many_repo_files. All paths are validated against an allowlist
12
+ * of directories and a blocklist of sensitive filenames.
13
+ *
14
+ * When `studioUrl` is set, writes go to Studio's draft API instead of
15
+ * disk, and reads check drafts first (draft overlay).
16
+ */
17
+ import { readFile, readdir, writeFile, mkdir, unlink } from 'node:fs/promises';
18
+ import * as path from 'node:path';
19
+ import { z } from 'zod';
20
+ // ---------------------------------------------------------------------------
21
+ // Sandbox path resolution (inlined from @amodalai/workspace-tools to avoid
22
+ // making the private workspace-tools package a published dependency)
23
+ // ---------------------------------------------------------------------------
24
+ function resolveSandboxPath(sandboxRoot, requestedPath) {
25
+ if (path.isAbsolute(requestedPath)) {
26
+ throw new FileToolError(`Absolute paths are not allowed: ${requestedPath}`);
27
+ }
28
+ if (requestedPath.includes('\0')) {
29
+ throw new FileToolError('Path contains null bytes');
30
+ }
31
+ const segments = requestedPath.split(/[/\\]/);
32
+ if (segments.includes('..')) {
33
+ throw new FileToolError(`Path traversal is not allowed: ${requestedPath}`);
34
+ }
35
+ const resolved = path.resolve(sandboxRoot, requestedPath);
36
+ if (resolved !== sandboxRoot && !resolved.startsWith(sandboxRoot + path.sep)) {
37
+ throw new FileToolError(`Path escapes sandbox: ${requestedPath}`);
38
+ }
39
+ return resolved;
40
+ }
41
+ // ---------------------------------------------------------------------------
42
+ // Constants
43
+ // ---------------------------------------------------------------------------
44
+ export const DEFAULT_ALLOWED_DIRS = [
45
+ 'skills',
46
+ 'knowledge',
47
+ 'connections',
48
+ 'stores',
49
+ 'pages',
50
+ 'automations',
51
+ 'evals',
52
+ 'agents',
53
+ 'tools',
54
+ ];
55
+ export const DEFAULT_BLOCKED_FILES = [
56
+ '.env',
57
+ 'amodal.json',
58
+ 'package.json',
59
+ 'pnpm-lock.yaml',
60
+ 'tsconfig.json',
61
+ ];
62
+ /** Maximum number of grep results returned. */
63
+ const GREP_MAX_RESULTS = 100;
64
+ /** Maximum number of files for read_many_repo_files. */
65
+ const READ_MANY_MAX_FILES = 20;
66
+ // ---------------------------------------------------------------------------
67
+ // Error class
68
+ // ---------------------------------------------------------------------------
69
+ export class FileToolError extends Error {
70
+ constructor(message) {
71
+ super(message);
72
+ this.name = 'FileToolError';
73
+ }
74
+ }
75
+ // ---------------------------------------------------------------------------
76
+ // Path validation
77
+ // ---------------------------------------------------------------------------
78
+ function validatePath(repoRoot, filePath, allowedDirs, blockedFiles) {
79
+ const abs = resolveSandboxPath(repoRoot, filePath);
80
+ const rel = path.relative(repoRoot, abs);
81
+ const topDir = rel.split(path.sep)[0];
82
+ if (!allowedDirs.includes(topDir)) {
83
+ throw new FileToolError(`Path "${filePath}" is not in an allowed directory. Allowed: ${allowedDirs.join(', ')}`);
84
+ }
85
+ const basename = path.basename(abs);
86
+ if (blockedFiles.includes(basename)) {
87
+ throw new FileToolError(`File "${basename}" cannot be accessed`);
88
+ }
89
+ return abs;
90
+ }
91
+ /**
92
+ * Validate that a directory path is within allowed dirs.
93
+ * If dir is omitted, returns null (meaning "all allowed dirs").
94
+ */
95
+ function validateDirPath(repoRoot, dir, allowedDirs) {
96
+ if (!dir)
97
+ return null;
98
+ // The dir itself must be an allowed top-level dir or a subdirectory of one
99
+ const abs = resolveSandboxPath(repoRoot, dir);
100
+ const rel = path.relative(repoRoot, abs);
101
+ const topDir = rel.split(path.sep)[0];
102
+ if (!allowedDirs.includes(topDir)) {
103
+ throw new FileToolError(`Directory "${dir}" is not in an allowed directory. Allowed: ${allowedDirs.join(', ')}`);
104
+ }
105
+ return abs;
106
+ }
107
+ // ---------------------------------------------------------------------------
108
+ // Draft API helpers
109
+ // ---------------------------------------------------------------------------
110
+ async function readFromDraft(studioUrl, filePath, logger) {
111
+ try {
112
+ const res = await fetch(`${studioUrl}/api/drafts/${encodeURIComponent(filePath)}`, {
113
+ signal: AbortSignal.timeout(5000),
114
+ });
115
+ if (res.ok) {
116
+ const raw = await res.json();
117
+ if (raw && typeof raw === 'object' && 'content' in raw) {
118
+ const val = raw['content'];
119
+ if (typeof val === 'string')
120
+ return val;
121
+ }
122
+ }
123
+ }
124
+ catch (err) {
125
+ logger.debug('draft_read_fallback', { path: filePath, error: err instanceof Error ? err.message : String(err) });
126
+ }
127
+ return null;
128
+ }
129
+ async function writeToDraft(studioUrl, filePath, content) {
130
+ const res = await fetch(`${studioUrl}/api/drafts/${encodeURIComponent(filePath)}`, {
131
+ method: 'PUT',
132
+ headers: { 'Content-Type': 'application/json' },
133
+ body: JSON.stringify({ content }),
134
+ signal: AbortSignal.timeout(10000),
135
+ });
136
+ if (!res.ok) {
137
+ throw new FileToolError(`Failed to save draft: ${res.status} ${res.statusText}`);
138
+ }
139
+ }
140
+ async function deleteFromDraft(studioUrl, filePath) {
141
+ const res = await fetch(`${studioUrl}/api/drafts/${encodeURIComponent(filePath)}`, {
142
+ method: 'DELETE',
143
+ signal: AbortSignal.timeout(5000),
144
+ });
145
+ if (!res.ok) {
146
+ throw new FileToolError(`Failed to delete draft: ${res.status} ${res.statusText}`);
147
+ }
148
+ }
149
+ // ---------------------------------------------------------------------------
150
+ // Read helper (with draft overlay)
151
+ // ---------------------------------------------------------------------------
152
+ async function readFileContent(abs, relPath, studioUrl, logger) {
153
+ // Try draft overlay first
154
+ if (studioUrl) {
155
+ const draftContent = await readFromDraft(studioUrl, relPath, logger);
156
+ if (draftContent !== null)
157
+ return draftContent;
158
+ }
159
+ // Fall back to disk
160
+ return readFile(abs, 'utf-8');
161
+ }
162
+ // ---------------------------------------------------------------------------
163
+ // Write helper (draft or disk)
164
+ // ---------------------------------------------------------------------------
165
+ async function writeFileContent(abs, relPath, content, studioUrl) {
166
+ if (studioUrl) {
167
+ await writeToDraft(studioUrl, relPath, content);
168
+ }
169
+ else {
170
+ await mkdir(path.dirname(abs), { recursive: true });
171
+ await writeFile(abs, content, 'utf-8');
172
+ }
173
+ }
174
+ // ---------------------------------------------------------------------------
175
+ // Glob pattern helper
176
+ // ---------------------------------------------------------------------------
177
+ /**
178
+ * Convert a simple glob pattern to a RegExp.
179
+ * Supports *, **, and ? wildcards.
180
+ */
181
+ function globToRegex(pattern) {
182
+ let regexStr = '';
183
+ let i = 0;
184
+ while (i < pattern.length) {
185
+ const char = pattern[i];
186
+ if (char === '*') {
187
+ if (pattern[i + 1] === '*') {
188
+ // ** matches any path segments
189
+ regexStr += '.*';
190
+ i += 2;
191
+ // Skip trailing separator after **
192
+ if (pattern[i] === '/' || pattern[i] === path.sep) {
193
+ i += 1;
194
+ }
195
+ }
196
+ else {
197
+ // * matches anything except path separator
198
+ regexStr += '[^/]*';
199
+ i += 1;
200
+ }
201
+ }
202
+ else if (char === '?') {
203
+ regexStr += '[^/]';
204
+ i += 1;
205
+ }
206
+ else if (char === '.') {
207
+ regexStr += '\\.';
208
+ i += 1;
209
+ }
210
+ else {
211
+ regexStr += char;
212
+ i += 1;
213
+ }
214
+ }
215
+ return new RegExp(`^${regexStr}$`);
216
+ }
217
+ // ---------------------------------------------------------------------------
218
+ // Recursive directory listing
219
+ // ---------------------------------------------------------------------------
220
+ async function listFilesRecursive(dirPath, basePath, logger) {
221
+ const results = [];
222
+ try {
223
+ const entries = await readdir(dirPath, { withFileTypes: true });
224
+ for (const entry of entries) {
225
+ const fullPath = path.join(dirPath, entry.name);
226
+ const relPath = path.relative(basePath, fullPath);
227
+ if (entry.isDirectory()) {
228
+ const subFiles = await listFilesRecursive(fullPath, basePath, logger);
229
+ results.push(...subFiles);
230
+ }
231
+ else {
232
+ results.push(relPath);
233
+ }
234
+ }
235
+ }
236
+ catch (err) {
237
+ logger.debug('file_tool_readdir_skipped', { dir: dirPath, error: err instanceof Error ? err.message : String(err) });
238
+ }
239
+ return results;
240
+ }
241
+ // ---------------------------------------------------------------------------
242
+ // Tool registration
243
+ // ---------------------------------------------------------------------------
244
+ export function registerFileTools(registry, opts) {
245
+ const { repoRoot, allowedDirs, blockedFiles, studioUrl, logger } = opts;
246
+ // -------------------------------------------------------------------------
247
+ // read_repo_file
248
+ // -------------------------------------------------------------------------
249
+ registry.register('read_repo_file', {
250
+ description: 'Read a file from the agent repository. Supports optional line-based offset and limit for large files.',
251
+ parameters: z.object({
252
+ path: z.string().describe('Relative path to the file within the repo'),
253
+ offset: z.number().optional().describe('Line number to start reading from (0-based)'),
254
+ limit: z.number().optional().describe('Maximum number of lines to return'),
255
+ }),
256
+ readOnly: true,
257
+ metadata: { category: 'system' },
258
+ async execute(params, _ctx) {
259
+ const startMs = Date.now();
260
+ try {
261
+ const abs = validatePath(repoRoot, params.path, allowedDirs, blockedFiles);
262
+ const relPath = path.relative(repoRoot, abs);
263
+ logger.debug('file_tool_call', { tool: 'read_repo_file', path: params.path });
264
+ let content = await readFileContent(abs, relPath, studioUrl, logger);
265
+ // Apply line-based offset/limit
266
+ if (params.offset !== undefined || params.limit !== undefined) {
267
+ const lines = content.split('\n');
268
+ const start = params.offset ?? 0;
269
+ const end = params.limit !== undefined ? start + params.limit : lines.length;
270
+ content = lines.slice(start, end).join('\n');
271
+ }
272
+ const durationMs = Date.now() - startMs;
273
+ logger.debug('file_tool_complete', { tool: 'read_repo_file', path: params.path, durationMs });
274
+ return content;
275
+ }
276
+ catch (err) {
277
+ const durationMs = Date.now() - startMs;
278
+ const message = err instanceof Error ? err.message : String(err);
279
+ logger.debug('file_tool_error', { tool: 'read_repo_file', path: params.path, error: message, durationMs });
280
+ return { error: message };
281
+ }
282
+ },
283
+ });
284
+ // -------------------------------------------------------------------------
285
+ // write_repo_file
286
+ // -------------------------------------------------------------------------
287
+ registry.register('write_repo_file', {
288
+ description: 'Write content to a file in the agent repository. Creates parent directories as needed.',
289
+ parameters: z.object({
290
+ path: z.string().describe('Relative path to the file within the repo'),
291
+ content: z.string().describe('The content to write to the file'),
292
+ }),
293
+ readOnly: false,
294
+ metadata: { category: 'system' },
295
+ async execute(params, _ctx) {
296
+ const startMs = Date.now();
297
+ try {
298
+ const abs = validatePath(repoRoot, params.path, allowedDirs, blockedFiles);
299
+ const relPath = path.relative(repoRoot, abs);
300
+ logger.debug('file_tool_call', { tool: 'write_repo_file', path: params.path });
301
+ await writeFileContent(abs, relPath, params.content, studioUrl);
302
+ const durationMs = Date.now() - startMs;
303
+ logger.debug('file_tool_complete', { tool: 'write_repo_file', path: params.path, durationMs });
304
+ return { success: true, path: params.path };
305
+ }
306
+ catch (err) {
307
+ const durationMs = Date.now() - startMs;
308
+ const message = err instanceof Error ? err.message : String(err);
309
+ logger.debug('file_tool_error', { tool: 'write_repo_file', path: params.path, error: message, durationMs });
310
+ return { error: message };
311
+ }
312
+ },
313
+ });
314
+ // -------------------------------------------------------------------------
315
+ // edit_repo_file
316
+ // -------------------------------------------------------------------------
317
+ registry.register('edit_repo_file', {
318
+ description: 'Edit a file by replacing a string. Reads the current content, finds old_string, and replaces it with new_string. ' +
319
+ 'If multiple matches are found and allow_multiple is not set, returns an error.',
320
+ parameters: z.object({
321
+ path: z.string().describe('Relative path to the file within the repo'),
322
+ old_string: z.string().describe('The exact string to find and replace'),
323
+ new_string: z.string().describe('The replacement string'),
324
+ allow_multiple: z.boolean().optional().describe('Allow replacing all occurrences if multiple matches found'),
325
+ }),
326
+ readOnly: false,
327
+ metadata: { category: 'system' },
328
+ async execute(params, _ctx) {
329
+ const startMs = Date.now();
330
+ try {
331
+ const abs = validatePath(repoRoot, params.path, allowedDirs, blockedFiles);
332
+ const relPath = path.relative(repoRoot, abs);
333
+ logger.debug('file_tool_call', { tool: 'edit_repo_file', path: params.path });
334
+ const content = await readFileContent(abs, relPath, studioUrl, logger);
335
+ // Count occurrences
336
+ let count = 0;
337
+ let idx = 0;
338
+ while (true) {
339
+ idx = content.indexOf(params.old_string, idx);
340
+ if (idx === -1)
341
+ break;
342
+ count += 1;
343
+ idx += params.old_string.length;
344
+ }
345
+ if (count === 0) {
346
+ return { error: `String not found in ${params.path}` };
347
+ }
348
+ if (count > 1 && !params.allow_multiple) {
349
+ return { error: `Multiple matches found (${String(count)}), set allow_multiple: true to replace all` };
350
+ }
351
+ // Replace
352
+ let newContent;
353
+ if (params.allow_multiple) {
354
+ newContent = content.split(params.old_string).join(params.new_string);
355
+ }
356
+ else {
357
+ newContent = content.replace(params.old_string, params.new_string);
358
+ }
359
+ await writeFileContent(abs, relPath, newContent, studioUrl);
360
+ const durationMs = Date.now() - startMs;
361
+ logger.debug('file_tool_complete', { tool: 'edit_repo_file', path: params.path, replacements: count, durationMs });
362
+ return { success: true, path: params.path, replacements: count };
363
+ }
364
+ catch (err) {
365
+ const durationMs = Date.now() - startMs;
366
+ const message = err instanceof Error ? err.message : String(err);
367
+ logger.debug('file_tool_error', { tool: 'edit_repo_file', path: params.path, error: message, durationMs });
368
+ return { error: message };
369
+ }
370
+ },
371
+ });
372
+ // -------------------------------------------------------------------------
373
+ // delete_repo_file
374
+ // -------------------------------------------------------------------------
375
+ registry.register('delete_repo_file', {
376
+ description: 'Delete a file from the agent repository.',
377
+ parameters: z.object({
378
+ path: z.string().describe('Relative path to the file within the repo'),
379
+ }),
380
+ readOnly: false,
381
+ metadata: { category: 'system' },
382
+ async execute(params, _ctx) {
383
+ const startMs = Date.now();
384
+ try {
385
+ const abs = validatePath(repoRoot, params.path, allowedDirs, blockedFiles);
386
+ const relPath = path.relative(repoRoot, abs);
387
+ logger.debug('file_tool_call', { tool: 'delete_repo_file', path: params.path });
388
+ if (studioUrl) {
389
+ await deleteFromDraft(studioUrl, relPath);
390
+ }
391
+ else {
392
+ await unlink(abs);
393
+ }
394
+ const durationMs = Date.now() - startMs;
395
+ logger.debug('file_tool_complete', { tool: 'delete_repo_file', path: params.path, durationMs });
396
+ return { success: true, path: params.path };
397
+ }
398
+ catch (err) {
399
+ const durationMs = Date.now() - startMs;
400
+ const message = err instanceof Error ? err.message : String(err);
401
+ logger.debug('file_tool_error', { tool: 'delete_repo_file', path: params.path, error: message, durationMs });
402
+ return { error: message };
403
+ }
404
+ },
405
+ });
406
+ // -------------------------------------------------------------------------
407
+ // list_repo_files
408
+ // -------------------------------------------------------------------------
409
+ registry.register('list_repo_files', {
410
+ description: 'List files in the agent repository. If dir is provided, lists that directory. ' +
411
+ 'If omitted, lists all allowed directories.',
412
+ parameters: z.object({
413
+ dir: z.string().optional().describe('Directory to list (relative path). If omitted, lists all allowed directories.'),
414
+ }),
415
+ readOnly: true,
416
+ metadata: { category: 'system' },
417
+ async execute(params, _ctx) {
418
+ const startMs = Date.now();
419
+ try {
420
+ logger.debug('file_tool_call', { tool: 'list_repo_files', dir: params.dir });
421
+ let files;
422
+ if (params.dir) {
423
+ const absDir = validateDirPath(repoRoot, params.dir, allowedDirs);
424
+ if (!absDir) {
425
+ return { error: 'Invalid directory' };
426
+ }
427
+ files = await listFilesRecursive(absDir, repoRoot, logger);
428
+ }
429
+ else {
430
+ // List all allowed directories
431
+ files = [];
432
+ for (const dir of allowedDirs) {
433
+ const absDir = path.join(repoRoot, dir);
434
+ const dirFiles = await listFilesRecursive(absDir, repoRoot, logger);
435
+ files.push(...dirFiles);
436
+ }
437
+ }
438
+ const durationMs = Date.now() - startMs;
439
+ logger.debug('file_tool_complete', { tool: 'list_repo_files', fileCount: files.length, durationMs });
440
+ return { files };
441
+ }
442
+ catch (err) {
443
+ const durationMs = Date.now() - startMs;
444
+ const message = err instanceof Error ? err.message : String(err);
445
+ logger.debug('file_tool_error', { tool: 'list_repo_files', error: message, durationMs });
446
+ return { error: message };
447
+ }
448
+ },
449
+ });
450
+ // -------------------------------------------------------------------------
451
+ // glob_repo_files
452
+ // -------------------------------------------------------------------------
453
+ registry.register('glob_repo_files', {
454
+ description: 'Find files matching a glob pattern in the agent repository. ' +
455
+ 'Supports *, **, and ? wildcards. Only searches allowed directories.',
456
+ parameters: z.object({
457
+ pattern: z.string().describe('Glob pattern to match files against (e.g., "**/*.yaml", "skills/*.md")'),
458
+ }),
459
+ readOnly: true,
460
+ metadata: { category: 'system' },
461
+ async execute(params, _ctx) {
462
+ const startMs = Date.now();
463
+ try {
464
+ logger.debug('file_tool_call', { tool: 'glob_repo_files', pattern: params.pattern });
465
+ const regex = globToRegex(params.pattern);
466
+ const matches = [];
467
+ for (const dir of allowedDirs) {
468
+ const absDir = path.join(repoRoot, dir);
469
+ const files = await listFilesRecursive(absDir, repoRoot, logger);
470
+ for (const file of files) {
471
+ if (regex.test(file)) {
472
+ matches.push(file);
473
+ }
474
+ }
475
+ }
476
+ const durationMs = Date.now() - startMs;
477
+ logger.debug('file_tool_complete', { tool: 'glob_repo_files', matchCount: matches.length, durationMs });
478
+ return { files: matches };
479
+ }
480
+ catch (err) {
481
+ const durationMs = Date.now() - startMs;
482
+ const message = err instanceof Error ? err.message : String(err);
483
+ logger.debug('file_tool_error', { tool: 'glob_repo_files', error: message, durationMs });
484
+ return { error: message };
485
+ }
486
+ },
487
+ });
488
+ // -------------------------------------------------------------------------
489
+ // grep_repo_files
490
+ // -------------------------------------------------------------------------
491
+ registry.register('grep_repo_files', {
492
+ description: 'Search file contents with a regex pattern. Returns matching lines with file path and line number. ' +
493
+ 'Capped at 100 results. Only searches allowed directories.',
494
+ parameters: z.object({
495
+ pattern: z.string().describe('Regex pattern to search for in file contents'),
496
+ dir: z.string().optional().describe('Directory to search in (relative path). If omitted, searches all allowed directories.'),
497
+ }),
498
+ readOnly: true,
499
+ metadata: { category: 'system' },
500
+ async execute(params, _ctx) {
501
+ const startMs = Date.now();
502
+ try {
503
+ logger.debug('file_tool_call', { tool: 'grep_repo_files', pattern: params.pattern, dir: params.dir });
504
+ let regex;
505
+ try {
506
+ regex = new RegExp(params.pattern);
507
+ }
508
+ catch {
509
+ return { error: `Invalid regex pattern: ${params.pattern}` };
510
+ }
511
+ const results = [];
512
+ // Determine which directories to search
513
+ const dirsToSearch = [];
514
+ if (params.dir) {
515
+ const absDir = validateDirPath(repoRoot, params.dir, allowedDirs);
516
+ if (!absDir) {
517
+ return { error: 'Invalid directory' };
518
+ }
519
+ dirsToSearch.push(params.dir);
520
+ }
521
+ else {
522
+ dirsToSearch.push(...allowedDirs);
523
+ }
524
+ for (const dir of dirsToSearch) {
525
+ if (results.length >= GREP_MAX_RESULTS)
526
+ break;
527
+ const absDir = path.join(repoRoot, dir);
528
+ const files = await listFilesRecursive(absDir, repoRoot, logger);
529
+ for (const file of files) {
530
+ if (results.length >= GREP_MAX_RESULTS)
531
+ break;
532
+ const absFile = path.join(repoRoot, file);
533
+ try {
534
+ const content = await readFile(absFile, 'utf-8');
535
+ const lines = content.split('\n');
536
+ for (let i = 0; i < lines.length; i++) {
537
+ if (results.length >= GREP_MAX_RESULTS)
538
+ break;
539
+ if (regex.test(lines[i])) {
540
+ results.push({ file, line: i + 1, content: lines[i] });
541
+ }
542
+ }
543
+ }
544
+ catch (err) {
545
+ logger.debug('file_tool_grep_skip', { file, error: err instanceof Error ? err.message : String(err) });
546
+ }
547
+ }
548
+ }
549
+ const durationMs = Date.now() - startMs;
550
+ logger.debug('file_tool_complete', { tool: 'grep_repo_files', resultCount: results.length, durationMs });
551
+ return { results, truncated: results.length >= GREP_MAX_RESULTS };
552
+ }
553
+ catch (err) {
554
+ const durationMs = Date.now() - startMs;
555
+ const message = err instanceof Error ? err.message : String(err);
556
+ logger.debug('file_tool_error', { tool: 'grep_repo_files', error: message, durationMs });
557
+ return { error: message };
558
+ }
559
+ },
560
+ });
561
+ // -------------------------------------------------------------------------
562
+ // read_many_repo_files
563
+ // -------------------------------------------------------------------------
564
+ registry.register('read_many_repo_files', {
565
+ description: 'Read multiple files at once. Returns an object mapping each path to its content. ' +
566
+ `Maximum ${String(READ_MANY_MAX_FILES)} files per call.`,
567
+ parameters: z.object({
568
+ paths: z.array(z.string()).max(READ_MANY_MAX_FILES).describe(`Array of relative file paths to read (max ${String(READ_MANY_MAX_FILES)})`),
569
+ }),
570
+ readOnly: true,
571
+ metadata: { category: 'system' },
572
+ async execute(params, _ctx) {
573
+ const startMs = Date.now();
574
+ try {
575
+ logger.debug('file_tool_call', { tool: 'read_many_repo_files', fileCount: params.paths.length });
576
+ if (params.paths.length > READ_MANY_MAX_FILES) {
577
+ return { error: `Too many files requested. Maximum is ${String(READ_MANY_MAX_FILES)}.` };
578
+ }
579
+ const results = {};
580
+ for (const filePath of params.paths) {
581
+ try {
582
+ const abs = validatePath(repoRoot, filePath, allowedDirs, blockedFiles);
583
+ const relPath = path.relative(repoRoot, abs);
584
+ results[filePath] = await readFileContent(abs, relPath, studioUrl, logger);
585
+ }
586
+ catch (err) {
587
+ results[filePath] = { error: err instanceof Error ? err.message : String(err) };
588
+ }
589
+ }
590
+ const durationMs = Date.now() - startMs;
591
+ logger.debug('file_tool_complete', { tool: 'read_many_repo_files', fileCount: params.paths.length, durationMs });
592
+ return results;
593
+ }
594
+ catch (err) {
595
+ const durationMs = Date.now() - startMs;
596
+ const message = err instanceof Error ? err.message : String(err);
597
+ logger.debug('file_tool_error', { tool: 'read_many_repo_files', error: message, durationMs });
598
+ return { error: message };
599
+ }
600
+ },
601
+ });
602
+ }
603
+ //# sourceMappingURL=file-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-tools.js","sourceRoot":"","sources":["../../../src/tools/file-tools.ts"],"names":[],"mappings":"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"}