(args: z.infer<typeof Args>, ctx: ToolContext)
| 26 | argsSchema = Args; |
| 27 | |
| 28 | async execute(args: z.infer<typeof Args>, ctx: ToolContext): Promise<ToolResult> { |
| 29 | const abs = path.isAbsolute(args.path) ? args.path : path.resolve(ctx.cwd, args.path); |
| 30 | const rel = path.relative(ctx.cwd, abs); |
| 31 | let content: string; |
| 32 | try { |
| 33 | content = await fs.readFile(abs, 'utf-8'); |
| 34 | } catch (e: any) { |
| 35 | return { content: `[FILE_NOT_FOUND] ${args.path}: ${e.message}`, isError: true }; |
| 36 | } |
| 37 | |
| 38 | const { analyzeDataFlow } = await import('../../context/data-flow.js'); |
| 39 | const flows = await analyzeDataFlow(rel, content); |
| 40 | if (flows.length === 0) { |
| 41 | return { content: `No functions found in ${rel} (or language not supported for data-flow analysis).` }; |
| 42 | } |
| 43 | |
| 44 | const filtered = args.function_name |
| 45 | ? flows.filter(f => f.name === args.function_name || f.name.toLowerCase() === args.function_name!.toLowerCase()) |
| 46 | : flows; |
| 47 | |
| 48 | if (filtered.length === 0) { |
| 49 | return { content: `No function named "${args.function_name}" in ${rel}. Found: ${flows.map(f => f.name).join(', ')}` }; |
| 50 | } |
| 51 | |
| 52 | const lines = [`# Data-flow dependencies — ${rel}`, '']; |
| 53 | for (const f of filtered) { |
| 54 | lines.push(`## ${f.name} (lines ${f.startLine}-${f.endLine})`); |
| 55 | if (f.freeVars.length === 0) { |
| 56 | lines.push(' (self-contained — no external dependencies)'); |
| 57 | } else { |
| 58 | lines.push(' External symbols used (most-referenced first):'); |
| 59 | for (const v of f.freeVars) { |
| 60 | lines.push(` - ${v.name}${v.count > 1 ? ` (×${v.count})` : ''}`); |
| 61 | } |
| 62 | } |
| 63 | lines.push(''); |
| 64 | } |
| 65 | lines.push('Tip: cross-reference these symbols with `find_symbol` / the import graph to locate which files define them.'); |
| 66 | return { content: lines.join('\n'), metadata: { functionCount: filtered.length } }; |
| 67 | } |
| 68 | } |
nothing calls this directly
no test coverage detected