feat(mcp): codegraph_explore as the sole primary tool + store coverage + overload disambiguation (#647)
## Summary
Completes the explore-overhaul arc: `codegraph_explore` becomes the single primary tool an agent reaches for, and its coverage + output shape are tuned so flow/architecture questions resolve with near-zero Read/Grep.
### What changed
- **explore is the sole primary tool** — removed `codegraph_context` (the fuzzy-input Read-trigger) and `codegraph_trace` (under-picked by agents); explore already surfaces the call flow among the symbols you name. A plain natural-language question now works as the query.
- **Store/handler coverage** — functions defined inside object literals (Zustand `create((set, get) => ({ … }))`, Redux/Pinia/MobX, exported handler/route maps) are indexed as real symbols, including calls through `useStore.getState().fn()` and destructured `const { fn } = useStore.getState()`. A general AST rule, not a per-lib hack.
- **Overload disambiguation** — explore leads with the *right* definition when a method name is overloaded across types (a PascalCase type token in the query biases to that type's own def); `codegraph_node` returns *every* overload's body in one call, with an optional `file`/`line` selector to pin one.
- **Method-atomic render** — explore never returns half a method; at the size budget it drops whole methods/files (and lists what it dropped) instead of truncating a body mid-method.
- **Native-read-shaped output** — per-call output is capped to ~24K with a 25K hard ceiling and concentrated into ~150–250-line flow windows, mirroring how the agent natively reads; repo size scales the *call* budget, not the per-call size (a larger response just gets externalized to a file the host Reads back).
- **Blast radius** folded into explore (dependents + covering tests, locations only).
### Benchmark (refreshed on this build)
Re-validated the 7-repo A/B on 2026-06-02 (Opus 4.8, effort=high, median of 4). WITH arm re-measured on this build, WITHOUT reused:
**~16% cheaper · 47% fewer tokens · 22% faster · 58% fewer tool calls** — 0 file reads on 6 of 7 repos (Gin ~1).
The arc trades larger, cache-heavy explore responses for guaranteed near-zero reads, so cost/token margins soften vs the prior build (Excalidraw and Tokio land at cost break-even) while time and tool-calls stay clear wins everywhere — consistent with the project's stated optimization target (latency + tool-calls, not token cost).
### Validation
- Full suite green: **1112 passed, 2 skipped**.
- 28/28 plain WITH runs across the 7 README repos completed clean; reads median 0 on 6/7.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
+1
-47
@@ -1073,52 +1073,6 @@ function printFileTree(
|
||||
renderNode(root, '', true, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* codegraph context <task>
|
||||
*/
|
||||
program
|
||||
.command('context <task>')
|
||||
.description('Build context for a task (outputs markdown)')
|
||||
.option('-p, --path <path>', 'Project path')
|
||||
.option('-n, --max-nodes <number>', 'Maximum nodes to include', '50')
|
||||
.option('-c, --max-code <number>', 'Maximum code blocks', '10')
|
||||
.option('--no-code', 'Exclude code blocks')
|
||||
.option('-f, --format <format>', 'Output format (markdown, json)', 'markdown')
|
||||
.action(async (task: string, options: {
|
||||
path?: string;
|
||||
maxNodes?: string;
|
||||
maxCode?: string;
|
||||
code?: boolean;
|
||||
format?: string;
|
||||
}) => {
|
||||
const projectPath = resolveProjectPath(options.path);
|
||||
|
||||
try {
|
||||
if (!isInitialized(projectPath)) {
|
||||
error(`CodeGraph not initialized in ${projectPath}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const { default: CodeGraph } = await loadCodeGraph();
|
||||
const cg = await CodeGraph.open(projectPath);
|
||||
|
||||
const context = await cg.buildContext(task, {
|
||||
maxNodes: parseInt(options.maxNodes || '50', 10),
|
||||
maxCodeBlocks: parseInt(options.maxCode || '10', 10),
|
||||
includeCode: options.code !== false,
|
||||
format: options.format as 'markdown' | 'json',
|
||||
});
|
||||
|
||||
// Output the context
|
||||
console.log(context);
|
||||
|
||||
cg.destroy();
|
||||
} catch (err) {
|
||||
error(`Failed to build context: ${err instanceof Error ? err.message : String(err)}`);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* codegraph serve
|
||||
*/
|
||||
@@ -1161,8 +1115,8 @@ program
|
||||
}
|
||||
`));
|
||||
console.error('Available tools:');
|
||||
console.error(chalk.cyan(' codegraph_explore') + ' - Primary: source of the relevant symbols for any question');
|
||||
console.error(chalk.cyan(' codegraph_search') + ' - Search for code symbols');
|
||||
console.error(chalk.cyan(' codegraph_context') + ' - Build context for a task');
|
||||
console.error(chalk.cyan(' codegraph_callers') + ' - Find callers of a symbol');
|
||||
console.error(chalk.cyan(' codegraph_callees') + ' - Find what a symbol calls');
|
||||
console.error(chalk.cyan(' codegraph_impact') + ' - Analyze impact of changes');
|
||||
|
||||
Reference in New Issue
Block a user