diff --git a/CLAUDE.md b/CLAUDE.md index f76eb2dc..31a3a361 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -119,7 +119,7 @@ Codegraph is **our own tool**. Use it to analyze this repository before making c node src/cli.js build . # Build/update the graph (incremental) node src/cli.js map --limit 20 # Module overview & most-connected nodes node src/cli.js stats # Graph health and quality score -node src/cli.js fn -T # Function call chain (callers + callees) +node src/cli.js query -T # Function call chain (callers + callees) node src/cli.js deps src/.js # File-level imports and importers node src/cli.js diff-impact main # Impact of current branch vs main node src/cli.js complexity -T # Per-function complexity metrics diff --git a/FOUNDATION.md b/FOUNDATION.md index 44458aea..3158f388 100644 --- a/FOUNDATION.md +++ b/FOUNDATION.md @@ -62,7 +62,7 @@ LLM-powered features (richer embeddings, semantic search, AI-enhanced analysis) This dual-mode approach is unique in the competitive landscape. Competitors either require cloud APIs for core functionality (code-graph-rag, autodev-codebase) or offer no AI enhancement at all (CKB, axon, arbor). Nobody else offers both modes in one tool. -*Test: does every core command (`build`, `query`, `fn`, `deps`, `impact`, `diff-impact`, `cycles`, `map`) work with zero API keys? Are LLM features additive, never blocking?* +*Test: does every core command (`build`, `query`, `deps`, `impact`, `diff-impact`, `cycles`, `map`) work with zero API keys? Are LLM features additive, never blocking?* ### 5. Embeddable first, CLI second diff --git a/README.md b/README.md index c0b8866d..656924cc 100644 --- a/README.md +++ b/README.md @@ -217,8 +217,8 @@ codegraph explain # Function summary: signature, calls, callers, te ```bash codegraph impact # Transitive reverse dependency trace -codegraph fn # Function-level: callers, callees, call chain -codegraph fn --no-tests --depth 5 +codegraph query --no-tests # Function-level: callers, callees, call chain +codegraph query --no-tests --depth 5 codegraph fn-impact # What functions break if this one changes codegraph path # Shortest path between two symbols (A calls...calls B) codegraph path --reverse # Follow edges backward @@ -287,7 +287,7 @@ codegraph embed # Build embeddings (default: nomic-v1.5) codegraph embed --model nomic # Use a different model codegraph search "handle authentication" codegraph search "parse config" --min-score 0.4 -n 10 -codegraph models # List available models +codegraph embed --models # List available models ``` #### Multi-query search @@ -336,13 +336,13 @@ codegraph registry remove # Unregister | Flag | Description | |---|---| | `-d, --db ` | Custom path to `graph.db` | -| `-T, --no-tests` | Exclude `.test.`, `.spec.`, `__test__` files (available on `fn`, `fn-impact`, `path`, `context`, `explain`, `where`, `diff-impact`, `search`, `map`, `hotspots`, `roles`, `co-change`, `deps`, `impact`, `complexity`, `communities`, `manifesto`) | +| `-T, --no-tests` | Exclude `.test.`, `.spec.`, `__test__` files (available on `query`, `fn-impact`, `path`, `context`, `explain`, `where`, `diff-impact`, `search`, `map`, `hotspots`, `roles`, `co-change`, `deps`, `impact`, `complexity`, `communities`, `manifesto`) | | `--depth ` | Transitive trace depth (default varies by command) | | `-j, --json` | Output as JSON | | `-v, --verbose` | Enable debug output | | `--engine ` | Parser engine: `native`, `wasm`, or `auto` (default: `auto`) | -| `-k, --kind ` | Filter by kind: `function`, `method`, `class`, `struct`, `enum`, `trait`, `record`, `module` (`fn`, `context`, `search`) | -| `-f, --file ` | Scope to a specific file (`fn`, `context`, `where`) | +| `-k, --kind ` | Filter by kind: `function`, `method`, `class`, `struct`, `enum`, `trait`, `record`, `module` (`query`, `context`, `search`) | +| `-f, --file ` | Scope to a specific file (`query`, `context`, `where`) | | `--rrf-k ` | RRF smoothing constant for multi-query search (default 60) | ## 🌐 Language Support @@ -485,7 +485,7 @@ This project uses codegraph. The database is at `.codegraph/graph.db`. ### Other useful commands - `codegraph build .` — rebuild the graph (incremental by default) - `codegraph map` — module overview -- `codegraph fn -T` — function call chain +- `codegraph query -T` — function call chain - `codegraph path -T` — shortest call path between two symbols - `codegraph deps ` — file-level dependencies - `codegraph roles --role dead -T` — find dead code (unreferenced symbols) diff --git a/scripts/lib/bench-config.js b/scripts/lib/bench-config.js index 804a6b3f..241a6254 100644 --- a/scripts/lib/bench-config.js +++ b/scripts/lib/bench-config.js @@ -70,7 +70,6 @@ export async function resolveBenchmarkSource() { cwd: tmpDir, stdio: 'pipe', timeout: 120_000, - shell: true, }); break; } catch (err) { diff --git a/src/cli.js b/src/cli.js index 1c77ab83..ec3e9ce4 100644 --- a/src/cli.js +++ b/src/cli.js @@ -26,7 +26,6 @@ import { fnImpact, impactAnalysis, moduleMap, - queryName, roles, stats, symbolPath, @@ -95,8 +94,11 @@ program program .command('query ') - .description('Find a function/class, show callers and callees') + .description('Find a function/class — callers, callees, and transitive call chain') .option('-d, --db ', 'Path to graph.db') + .option('--depth ', 'Transitive caller depth', '3') + .option('-f, --file ', 'Scope search to functions in this file (partial match)') + .option('-k, --kind ', 'Filter to a specific symbol kind') .option('-T, --no-tests', 'Exclude test/spec files from results') .option('--include-tests', 'Include test/spec files (overrides excludeTests config)') .option('-j, --json', 'Output as JSON') @@ -104,7 +106,14 @@ program .option('--offset ', 'Skip N results (default: 0)') .option('--ndjson', 'Newline-delimited JSON output') .action((name, opts) => { - queryName(name, opts.db, { + if (opts.kind && !ALL_SYMBOL_KINDS.includes(opts.kind)) { + console.error(`Invalid kind "${opts.kind}". Valid: ${ALL_SYMBOL_KINDS.join(', ')}`); + process.exit(1); + } + fnDeps(name, opts.db, { + depth: parseInt(opts.depth, 10), + file: opts.file, + kind: opts.kind, noTests: resolveNoTests(opts), json: opts.json, limit: opts.limit ? parseInt(opts.limit, 10) : undefined, @@ -161,30 +170,6 @@ program fileDeps(file, opts.db, { noTests: resolveNoTests(opts), json: opts.json }); }); -program - .command('fn ') - .description('Function-level dependencies: callers, callees, and transitive call chain') - .option('-d, --db ', 'Path to graph.db') - .option('--depth ', 'Transitive caller depth', '3') - .option('-f, --file ', 'Scope search to functions in this file (partial match)') - .option('-k, --kind ', 'Filter to a specific symbol kind') - .option('-T, --no-tests', 'Exclude test/spec files from results') - .option('--include-tests', 'Include test/spec files (overrides excludeTests config)') - .option('-j, --json', 'Output as JSON') - .action((name, opts) => { - if (opts.kind && !ALL_SYMBOL_KINDS.includes(opts.kind)) { - console.error(`Invalid kind "${opts.kind}". Valid: ${ALL_SYMBOL_KINDS.join(', ')}`); - process.exit(1); - } - fnDeps(name, opts.db, { - depth: parseInt(opts.depth, 10), - file: opts.file, - kind: opts.kind, - noTests: resolveNoTests(opts), - json: opts.json, - }); - }); - program .command('fn-impact ') .description('Function-level impact: what functions break if this one changes') @@ -489,23 +474,6 @@ registry // ─── Embedding commands ───────────────────────────────────────────────── -program - .command('models') - .description('List available embedding models') - .action(() => { - const defaultModel = config.embeddings?.model || DEFAULT_MODEL; - console.log('\nAvailable embedding models:\n'); - for (const [key, cfg] of Object.entries(MODELS)) { - const def = key === defaultModel ? ' (default)' : ''; - const ctx = cfg.contextWindow ? `${cfg.contextWindow} ctx` : ''; - console.log( - ` ${key.padEnd(12)} ${String(cfg.dim).padStart(4)}d ${ctx.padEnd(9)} ${cfg.desc}${def}`, - ); - } - console.log('\nUsage: codegraph embed --model --strategy '); - console.log(' codegraph search "query" --model \n'); - }); - program .command('embed [dir]') .description( @@ -513,15 +481,30 @@ program ) .option( '-m, --model ', - 'Embedding model (default from config or minilm). Run `codegraph models` for details', + 'Embedding model (default from config or minilm). Use `--models` to list available models', ) .option( '-s, --strategy ', `Embedding strategy: ${EMBEDDING_STRATEGIES.join(', ')}. "structured" uses graph context (callers/callees), "source" embeds raw code`, 'structured', ) + .option('--models', 'List available embedding models and exit') .option('-d, --db ', 'Path to graph.db') .action(async (dir, opts) => { + if (opts.models) { + const defaultModel = config.embeddings?.model || DEFAULT_MODEL; + console.log('\nAvailable embedding models:\n'); + for (const [key, cfg] of Object.entries(MODELS)) { + const def = key === defaultModel ? ' (default)' : ''; + const ctx = cfg.contextWindow ? `${cfg.contextWindow} ctx` : ''; + console.log( + ` ${key.padEnd(12)} ${String(cfg.dim).padStart(4)}d ${ctx.padEnd(9)} ${cfg.desc}${def}`, + ); + } + console.log('\nUsage: codegraph embed --model --strategy '); + console.log(' codegraph search "query" --model \n'); + return; + } if (!EMBEDDING_STRATEGIES.includes(opts.strategy)) { console.error( `Unknown strategy: ${opts.strategy}. Available: ${EMBEDDING_STRATEGIES.join(', ')}`, diff --git a/tests/integration/cli.test.js b/tests/integration/cli.test.js index 10eac6d2..45f82c03 100644 --- a/tests/integration/cli.test.js +++ b/tests/integration/cli.test.js @@ -101,9 +101,9 @@ describe('CLI smoke tests', () => { expect(data).toHaveProperty('results'); }); - // ─── Fn ────────────────────────────────────────────────────────────── - test('fn --json returns valid JSON with results', () => { - const out = run('fn', 'add', '--db', dbPath, '--json'); + // ─── Query (fn-level) ─────────────────────────────────────────────── + test('query --json returns fn-level results with depth', () => { + const out = run('query', 'add', '--db', dbPath, '--json'); const data = JSON.parse(out); expect(data).toHaveProperty('results'); });