mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-03-01 15:03:57 +08:00
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:
@@ -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));
|
||||
|
||||
104
ccw/src/tools/read-outline.ts
Normal file
104
ccw/src/tools/read-outline.ts
Normal 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}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user