MCPcopy Index your code
hub / github.com/PatrickSys/codebase-context / buildRelationshipHints

Function buildRelationshipHints

src/tools/search-codebase.ts:517–592  ·  view source on GitHub ↗
(result: SearchResult)

Source from the content-addressed store, hash-verified

515 }
516
517 function buildRelationshipHints(result: SearchResult): RelationshipHints {
518 const rPath = result.filePath;
519 // Graph keys are relative paths with forward slashes; normalize for comparison
520 const rPathNorm =
521 path.relative(ctx.rootPath, rPath).replace(/\\/g, '/') || rPath.replace(/\\/g, '/');
522
523 // importedBy: files that import this result (reverse lookup), collect with counts
524 const importedByMap = new Map<string, number>();
525 for (const [dep, importers] of reverseImports) {
526 if (dep === rPathNorm || dep.endsWith(rPathNorm) || rPathNorm.endsWith(dep)) {
527 for (const importer of importers) {
528 importedByMap.set(importer, (importedByMap.get(importer) || 0) + 1);
529 }
530 }
531 }
532
533 // testedIn: heuristic — same basename with .spec/.test extension
534 const testedIn: string[] = [];
535 const baseName = path.basename(rPathNorm).replace(/\.[^.]+$/, '');
536 const localImportsGraph = getImportsGraph();
537 if (localImportsGraph) {
538 for (const file of Object.keys(localImportsGraph)) {
539 const fileBase = path.basename(file);
540 if (
541 (fileBase.includes('.spec.') || fileBase.includes('.test.')) &&
542 fileBase.startsWith(baseName)
543 ) {
544 testedIn.push(file);
545 }
546 }
547 }
548
549 // Build condensed relationships
550 const condensedRel: Record<string, number | boolean> = {};
551 if (importedByMap.size > 0) {
552 condensedRel.importedByCount = importedByMap.size;
553 }
554 if (testedIn.length > 0) {
555 condensedRel.hasTests = true;
556 }
557
558 // Build hints object with capped arrays
559 const hintsObj: Record<string, string[]> = {};
560
561 // Rank importers by count descending, cap at 3
562 if (importedByMap.size > 0) {
563 const sortedCallers = Array.from(importedByMap.entries())
564 .sort((a, b) => b[1] - a[1])
565 .slice(0, 3)
566 .map(([file]) => file);
567 hintsObj.callers = sortedCallers;
568 // NOTE: consumers removed — it was identical to callers (pure token waste)
569 }
570
571 // Cap tests at 3
572 if (testedIn.length > 0) {
573 hintsObj.tests = testedIn.slice(0, 3);
574 }

Callers 1

handleFunction · 0.85

Calls 3

getImportsGraphFunction · 0.85
setMethod · 0.80
getMethod · 0.45

Tested by

no test coverage detected