MCPcopy Create free account
hub / github.com/QodeXcli/QodeX / execute

Method execute

src/tools/filesystem/read.ts:22–133  ·  view source on GitHub ↗
(args: z.infer<typeof ArgsSchema>, ctx: ToolContext)

Source from the content-addressed store, hash-verified

20 argsSchema = ArgsSchema;
21
22 async execute(args: z.infer<typeof ArgsSchema>, ctx: ToolContext): Promise<ToolResult> {
23 const abs = path.isAbsolute(args.path) ? args.path : path.resolve(ctx.cwd, args.path);
24
25 let buf: Buffer;
26 try {
27 const stat = await fs.stat(abs);
28 if (stat.isDirectory()) {
29 return { content: `[ERROR] ${args.path} is a directory. Use ls to list its contents.`, isError: true };
30 }
31 if (stat.size > 5 * 1024 * 1024) {
32 return {
33 content: `[ERROR] File ${args.path} is ${(stat.size / 1024 / 1024).toFixed(1)}MB which is too large. Use offset/limit to read in chunks, or use grep to find specific content.`,
34 isError: true,
35 };
36 }
37 // Fast-path reject for known binary extensions
38 if (hasBinaryExtension(abs)) {
39 return {
40 content: `[BINARY_FILE] ${args.path} is a binary file by extension (${(stat.size / 1024).toFixed(1)}KB). I cannot read binary content as text. If you need metadata, use shell with: file '${path.basename(abs)}' or stat. If you need byte-level inspection, use: hexdump -C '${path.basename(abs)}' | head.`,
41 isError: true,
42 };
43 }
44 buf = await fs.readFile(abs);
45 } catch (e: any) {
46 if (e.code === 'ENOENT') {
47 const { notFoundWithSuggestions } = await import('./suggest-paths.js');
48 const msg = await notFoundWithSuggestions(
49 ctx.cwd, args.path,
50 `[FILE_NOT_FOUND] ${args.path} does not exist.${outsideCwdHint(args.path, abs, ctx.cwd)}`,
51 );
52 return { content: msg, isError: true };
53 }
54 return { content: `[ERROR] Failed to read ${args.path}: ${e.message}`, isError: true };
55 }
56
57 // Content-sniff for binary
58 if (isBinaryBuffer(buf)) {
59 return {
60 content: `[BINARY_FILE] ${args.path} appears to be binary content (${(buf.length / 1024).toFixed(1)}KB, contains null bytes or non-printable bytes). I cannot read it as text. Use shell with hexdump/file/strings for binary inspection.`,
61 isError: true,
62 };
63 }
64
65 const content = buf.toString('utf-8');
66
67 const allLines = content.split('\n');
68
69 // Symbol-targeted read: resolve a declaration by name via the outline and
70 // return exactly that range. Lets the model say symbol="HomePage" instead of
71 // guessing line numbers on a big file.
72 if (args.symbol) {
73 const { fileOutline } = await import('../../context/file-outline.js');
74 const rel = path.relative(ctx.cwd, abs) || path.basename(abs);
75 const outline = await fileOutline(rel, content);
76 const want = args.symbol.toLowerCase();
77 const hit = outline.find(e => e.symbol.toLowerCase() === want)
78 ?? outline.find(e => e.symbol.toLowerCase().endsWith('.' + want))
79 ?? outline.find(e => e.symbol.toLowerCase().includes(want));

Callers

nothing calls this directly

Calls 7

hasBinaryExtensionFunction · 0.85
notFoundWithSuggestionsFunction · 0.85
outsideCwdHintFunction · 0.85
isBinaryBufferFunction · 0.85
fileOutlineFunction · 0.85
renderLargeFileMapFunction · 0.85
resolveMethod · 0.80

Tested by

no test coverage detected