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

Method execute

src/codegraph/tools.ts:182–242  ·  view source on GitHub ↗
(args: z.infer<typeof FindCallersArgs>, ctx: ToolContext)

Source from the content-addressed store, hash-verified

180 argsSchema = FindCallersArgs;
181
182 async execute(args: z.infer<typeof FindCallersArgs>, ctx: ToolContext): Promise<ToolResult> {
183 const db = requireDB();
184 if ('error' in db) return { content: db.error, isError: true };
185
186 // Build a set of definition locations to filter out from ripgrep results
187 const defs = db.findSymbolsByName(args.name);
188 const defKeys = new Set(defs.map(d => `${d.file_path}:${d.start_line}`));
189
190 const escaped = args.name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
191 const pattern = `\\b${escaped}\\s*\\(`;
192 const limit = args.limit ?? 100;
193
194 const rgArgs = ['-n', '--no-heading', '--max-count', String(limit + defs.length), '-e', pattern];
195 if (args.language) rgArgs.push('--type', args.language);
196 rgArgs.push(ctx.cwd);
197
198 const search = await runLineSearch(ctx.cwd, {
199 rgArgs,
200 regex: new RegExp(pattern),
201 language: args.language,
202 maxCount: limit + defs.length,
203 signal: ctx.signal,
204 });
205 if ('error' in search) return { content: search.error, isError: true };
206
207 const lines = search.stdout.split('\n').filter(Boolean);
208 // Format: file:line:content
209 const callers: Array<{ file: string; line: number; preview: string }> = [];
210 for (const raw of lines) {
211 const firstColon = raw.indexOf(':');
212 const secondColon = raw.indexOf(':', firstColon + 1);
213 if (firstColon === -1 || secondColon === -1) continue;
214 const file = raw.slice(0, firstColon);
215 const lineNum = parseInt(raw.slice(firstColon + 1, secondColon), 10);
216 if (!Number.isFinite(lineNum)) continue;
217 const preview = raw.slice(secondColon + 1).trim();
218 // Filter out definition lines
219 if (defKeys.has(`${file}:${lineNum}`)) continue;
220 callers.push({ file, line: lineNum, preview: preview.slice(0, 200) });
221 if (callers.length >= limit) break;
222 }
223 if (callers.length === 0) {
224 return { content: `[NO_CALLERS] No call sites found for "${args.name}". Either it's only defined (never called from the indexed paths), or the project hasn't been indexed yet (try /index).` };
225 }
226 // Group by file
227 const byFile = new Map<string, typeof callers>();
228 for (const c of callers) {
229 const rel = path.relative(ctx.cwd, c.file);
230 if (!byFile.has(rel)) byFile.set(rel, []);
231 byFile.get(rel)!.push(c);
232 }
233 const out: string[] = [`Found ${callers.length} call site${callers.length > 1 ? 's' : ''} for "${args.name}":`];
234 for (const [rel, items] of byFile) {
235 out.push(`\n ${rel}`);
236 for (const it of items) {
237 out.push(` :${it.line} ${it.preview}`);
238 }
239 }

Callers

nothing calls this directly

Calls 7

requireDBFunction · 0.85
runLineSearchFunction · 0.85
findSymbolsByNameMethod · 0.80
pushMethod · 0.45
hasMethod · 0.45
setMethod · 0.45
getMethod · 0.45

Tested by

no test coverage detected