Add evaluation framework and fix call graph extraction

- Add evaluation test suite with TypeScript and Python fixtures
- Fix MCP server to defer CodeGraph init until rootUri received
- Fix call edge extraction by calling resolveReferences() after indexAll/sync
- Fix glob matching for root-level files (e.g., **/*.py now matches auth.py)
- Fix duplicate node extraction for methods inside classes
- Update context tests to use buildContext for semantic search + graph traversal
- Export unused formatter functions to fix build

Evaluation results:
- TypeScript: 96% precision, 79% recall, 85% F1
- Python: 99% precision, 80% recall, 85% F1

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Colby McHenry
2026-01-18 18:48:22 -06:00
co-authored by Claude Opus 4.5
parent e306114607
commit 6b672f9152
30 changed files with 2600 additions and 129 deletions
+18 -7
View File
@@ -65,13 +65,24 @@ export function hashContent(content: string): string {
* Check if a path matches any glob pattern (simplified)
*/
function matchesGlob(filePath: string, pattern: string): boolean {
// Convert glob to regex (simplified)
const regexStr = pattern
.replace(/\./g, '\\.')
.replace(/\*\*/g, '<<<GLOBSTAR>>>')
.replace(/\*/g, '[^/]*')
.replace(/<<<GLOBSTAR>>>/g, '.*')
.replace(/\?/g, '.');
// Convert glob to regex using placeholders to avoid conflicts
let regexStr = pattern;
// Replace glob patterns with placeholders first
regexStr = regexStr.replace(/\*\*\//g, '\x00GLOBSTAR_SLASH\x00');
regexStr = regexStr.replace(/\*\*/g, '\x00GLOBSTAR\x00');
regexStr = regexStr.replace(/\*/g, '\x00STAR\x00');
regexStr = regexStr.replace(/\?/g, '\x00QUESTION\x00');
// Escape regex special characters
regexStr = regexStr.replace(/[.+^${}()|[\]\\]/g, '\\$&');
// Replace placeholders with regex equivalents
regexStr = regexStr.replace(/\x00GLOBSTAR_SLASH\x00/g, '(?:.*/)?'); // **/ = zero or more dirs
regexStr = regexStr.replace(/\x00GLOBSTAR\x00/g, '.*'); // ** = anything
regexStr = regexStr.replace(/\x00STAR\x00/g, '[^/]*'); // * = anything except /
regexStr = regexStr.replace(/\x00QUESTION\x00/g, '.'); // ? = single char
const regex = new RegExp(`^${regexStr}$`);
return regex.test(filePath);
}