Add benchmark results and tests for LSP graph builder and staged search

- Introduced a new benchmark results file for performance comparison on 2026-02-09.
- Added a test for LspGraphBuilder to ensure it does not expand nodes at maximum depth.
- Created a test for the staged search pipeline to validate fallback behavior when stage 1 returns empty results.
This commit is contained in:
catlog22
2026-02-09 21:43:13 +08:00
parent 4344e79e68
commit 362f354f1c
25 changed files with 2613 additions and 51 deletions

View File

@@ -24,6 +24,7 @@ import * as codexLensLspMod from './codex-lens-lsp.js';
import * as vscodeLspMod from './vscode-lsp.js';
import * as readFileMod from './read-file.js';
import * as readManyFilesMod from './read-many-files.js';
import * as readOutlineMod from './read-outline.js';
import * as coreMemoryMod from './core-memory.js';
import * as contextCacheMod from './context-cache.js';
import * as skillContextLoaderMod from './skill-context-loader.js';
@@ -367,6 +368,7 @@ registerTool(toLegacyTool(codexLensLspMod));
registerTool(toLegacyTool(vscodeLspMod));
registerTool(toLegacyTool(readFileMod));
registerTool(toLegacyTool(readManyFilesMod));
registerTool(toLegacyTool(readOutlineMod));
registerTool(toLegacyTool(coreMemoryMod));
registerTool(toLegacyTool(contextCacheMod));
registerTool(toLegacyTool(skillContextLoaderMod));

View File

@@ -0,0 +1,104 @@
/**
* Read Outline Tool - Parse code files into structured symbol outlines.
*
* Uses web-tree-sitter for AST-level parsing. Returns function/class/method
* signatures with line offsets directly usable by read_file(offset, limit).
*
* Supported: TypeScript, TSX, JavaScript, Python, Go, Rust, Java, C#, C, C++
*/
import { z } from 'zod';
import type { ToolSchema, ToolResult } from '../types/tool.js';
import { existsSync, statSync, readFileSync } from 'fs';
import { relative } from 'path';
import { validatePath, getProjectRoot } from '../utils/path-validator.js';
import { BINARY_EXTENSIONS } from '../utils/file-reader.js';
import { detectLanguage } from '../utils/outline-queries.js';
import { parseOutline } from '../utils/outline-parser.js';
import type { OutlineResult } from '../utils/outline-parser.js';
import { extname } from 'path';
const ParamsSchema = z.object({
path: z.string().describe('File path to parse for outline'),
language: z.string().optional().describe('Language hint (e.g. "typescript", "python"). Auto-detected from extension if omitted.'),
});
type Params = z.infer<typeof ParamsSchema>;
export const schema: ToolSchema = {
name: 'read_outline',
description: `Parse a code file into a structured outline of symbols (functions, classes, methods, interfaces, types, enums).
Returns symbol names, signatures, docstrings, and 0-based line offsets that work directly with read_file(offset, limit).
Usage:
read_outline(path="src/server.ts")
read_outline(path="main.py", language="python")
Workflow: discover symbols → use line/endLine with read_file to jump to implementations.
Supported languages: TypeScript, TSX, JavaScript, Python, Go, Rust, Java, C#, C, C++`,
inputSchema: {
type: 'object',
properties: {
path: { type: 'string', description: 'File path to parse for outline' },
language: { type: 'string', description: 'Language hint (e.g. "typescript", "python"). Auto-detected from extension if omitted.' },
},
required: ['path'],
},
};
export async function handler(params: Record<string, unknown>): Promise<ToolResult<OutlineResult>> {
const parsed = ParamsSchema.safeParse(params);
if (!parsed.success) {
return { success: false, error: `Invalid params: ${parsed.error.message}` };
}
const { path: filePath, language: langHint } = parsed.data;
const cwd = getProjectRoot();
const resolvedPath = await validatePath(filePath);
if (!existsSync(resolvedPath)) {
return { success: false, error: `File not found: ${filePath}` };
}
const stat = statSync(resolvedPath);
if (!stat.isFile()) {
return { success: false, error: `Not a file: ${filePath}` };
}
// Check for binary files
const ext = extname(resolvedPath).toLowerCase();
if (BINARY_EXTENSIONS.has(ext)) {
return { success: false, error: `Binary file not supported: ${filePath}` };
}
// Detect language
const config = detectLanguage(resolvedPath, langHint);
if (!config) {
const supported = 'TypeScript, TSX, JavaScript, Python, Go, Rust, Java, C#, C, C++';
return {
success: false,
error: `Unsupported language for "${ext}" extension. Supported: ${supported}`,
};
}
// Read file content
const content = readFileSync(resolvedPath, 'utf-8');
// Parse outline
try {
const result = await parseOutline(
relative(cwd, resolvedPath) || filePath,
content,
config
);
return { success: true, result };
} catch (err) {
return {
success: false,
error: `Outline parsing failed: ${(err as Error).message}`,
};
}
}