Skip to content

Commit f893bb8

Browse files
authored
feat(core): improve real-repo analysis resilience
Merge validated real-repo analysis resilience improvements from PR #50.
1 parent d8e0929 commit f893bb8

26 files changed

Lines changed: 2027 additions & 128 deletions

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Common workflows:
2626

2727
```bash
2828
npx codebase-intelligence hotspots ./src --metric complexity --limit 10
29+
npx codebase-intelligence opportunities ./src --limit 10
2930
npx codebase-intelligence impact ./src parseCodebase
3031
npx codebase-intelligence dead-exports ./src --limit 20
3132
npx codebase-intelligence changes ./src --json
@@ -55,7 +56,7 @@ claude mcp add -s user -t stdio codebase-intelligence -- npx -y codebase-intelli
5556

5657
## Features
5758

58-
- **17 CLI commands** for architecture analysis, dependency impact, dead code detection, search, CI rules, and agent setup
59+
- **18 CLI commands** for architecture analysis, dependency impact, improvement opportunities, dead code detection, search, CI rules, and agent setup
5960
- **Machine-readable JSON output** (`--json`) for automation and CI pipelines
6061
- **Auto-cached index** in `.code-visualizer/` for fast repeat queries
6162
- **11 architectural metrics** — PageRank, betweenness, coupling, cohesion, tension, churn, complexity, blast radius, dead exports, test coverage, escape velocity
@@ -64,7 +65,7 @@ claude mcp add -s user -t stdio codebase-intelligence -- npx -y codebase-intelli
6465
- **Process tracing** — detect entry points and execution flows through the call graph
6566
- **Community detection** — Louvain clustering for natural file groupings
6667
- **Agent adoption**`init` writes per-agent instruction files + installs a skill so AI agents query CI before grep/read
67-
- **MCP parity (secondary)** — same analysis and rules gate available as 16 MCP tools, 2 prompts, and 3 resources
68+
- **MCP parity (secondary)** — same analysis and rules gate available as 17 MCP tools, 2 prompts, and 3 resources
6869

6970
## Installation
7071

@@ -100,6 +101,7 @@ codebase-intelligence <command> <path> [options]
100101
| `modules` | Module architecture + cross-dependencies |
101102
| `forces` | Cohesion/tension/escape-velocity analysis |
102103
| `dead-exports` | Unused export detection |
104+
| `opportunities` | Ranked code-quality and refactoring opportunities |
103105
| `groups` | Top-level directory groups + aggregate metrics |
104106
| `symbol` | Callers/callees and symbol metrics |
105107
| `impact` | Symbol-level blast radius |
@@ -119,6 +121,8 @@ codebase-intelligence <command> <path> [options]
119121
| `--metric <m>` | Select ranking metric for `hotspots` |
120122
| `--scope <s>` | Select git diff scope for `changes`: `staged`, `unstaged`, `all` |
121123

124+
The scanner always excludes common generated and agent-workspace directories such as `.code-visualizer/`, `.next/`, `dist/`, `coverage/`, `.worktrees/`, and `.claude/worktrees/`.
125+
122126
For full command details, see [docs/cli-reference.md](docs/cli-reference.md).
123127

124128
## Agent Adoption
@@ -304,6 +308,8 @@ pnpm test # vitest
304308
pnpm lint # eslint
305309
pnpm typecheck # tsc --noEmit
306310
pnpm build # production build
311+
pnpm verify:cli-real # default real-repo CLI matrix
312+
pnpm verify:cli-real:heavy # large /home/ubuntu repo matrix
307313
```
308314

309315
## License

docs/architecture.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ Core (shared computation)
2222
| result builders used by both MCP and CLI
2323
v
2424
MCP (stdio) CLI (terminal/CI)
25-
| 16 tools, 2 prompts, | 5 commands: overview, hotspots,
26-
| 3 resources for LLMs | file, search, changes + --json
25+
| 17 tools, 2 prompts, | 18 commands with text + JSON
26+
| 3 resources for LLMs | output for humans and CI
2727
```
2828

2929
## Module Map
@@ -37,13 +37,14 @@ src/
3737
core/index.ts <- Shared result computation (MCP + CLI)
3838
config/index.ts <- Config discovery + zod validation
3939
rules/index.ts <- Rules engine + registry (check command + MCP check tool)
40-
mcp/index.ts <- 16 MCP tools for LLM integration
40+
mcp/index.ts <- 17 MCP tools for LLM integration
4141
mcp/hints.ts <- Next-step hints for MCP tool responses
4242
impact/index.ts <- Symbol-level impact analysis + rename planning
4343
search/index.ts <- BM25 search engine
4444
process/index.ts <- Entry point detection + call chain tracing
4545
community/index.ts <- Louvain clustering
4646
persistence/index.ts <- Graph export/import to .code-visualizer/
47+
persistence/cache-key.ts <- Cache signature from HEAD, worktree content, CLI version, parser settings
4748
install/index.ts <- Agent adoption: managed-block engine + per-agent file targets + skill
4849
server/graph-store.ts <- Global graph state (shared by CLI + MCP)
4950
cli.ts <- Entry point, CLI commands + MCP fallback
@@ -66,17 +67,20 @@ analyzeGraph(builtGraph, parsedFiles)
6667
}
6768
6869
startMcpServer(codebaseGraph)
69-
-> stdio MCP server with 16 tools, 2 prompts, 3 resources
70+
-> stdio MCP server with 17 tools, 2 prompts, 3 resources
7071
```
7172

7273
## Key Design Decisions
7374

7475
- **Dual interface**: MCP stdio for LLM agents, CLI subcommands for humans/CI. Both consume `src/core/`.
7576
- **graphology**: In-memory graph with O(1) neighbor lookup. PageRank and betweenness computed via graphology-metrics.
7677
- **Batch git churn**: Single `git log --all --name-only` call, parsed for all files. Avoids O(n) subprocess spawning.
78+
- **Monorepo import resolution**: Root `tsconfig.json` path aliases and local `package.json` package names resolve to source files before graph construction.
79+
- **Large repo fallback**: Above 1500 TypeScript files, the parser uses AST-only extraction to keep file/import/export analysis available without TypeScript program OOM.
7780
- **Dead export detection**: Cross-references parsed exports against edge symbol lists. May miss `import *` or re-exports (known limitation).
7881
- **Graceful degradation**: Non-git dirs get churn=0, no-test codebases get coverage=false. Never crashes.
79-
- **Graph persistence**: CLI commands always cache the graph index to `.code-visualizer/`. MCP mode (`codebase-intelligence <path>`) requires `--index` to persist the cache.
82+
- **Built-in scanner excludes**: Generated indexes, build outputs, coverage, framework caches, and agent worktrees are skipped before TypeScript program creation.
83+
- **Graph persistence**: CLI commands always cache the graph index to `.code-visualizer/`. Cache reuse requires matching HEAD, dirty/untracked file-content fingerprint, CLI version, and parser cache settings. MCP mode (`codebase-intelligence <path>`) requires `--index` to persist the cache.
8084

8185
## Adding a New Metric
8286

docs/cli-reference.md

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# CLI Reference
22

3-
17 commands for terminal and CI use. The 15 analysis commands have full parity with MCP tools and auto-cache the index to `.code-visualizer/`; `check` runs the rules gate; `init` sets up agent adoption.
3+
18 commands for terminal and CI use. The 16 analysis commands have full parity with MCP tools and auto-cache the index to `.code-visualizer/`; `check` runs the rules gate; `init` sets up agent adoption.
44

55
## Commands
66

@@ -12,7 +12,7 @@ High-level codebase snapshot.
1212
codebase-intelligence overview <path> [--json] [--force]
1313
```
1414

15-
**Output:** file count, function count, dependency count, modules (path, files, LOC, coupling, cohesion), top 5 depended files, avg LOC, max depth, circular dep count.
15+
**Output:** file count, function count, dependency count, analysis mode/call graph precision, modules (path, files, LOC, coupling, cohesion), top 5 depended files, avg LOC, max depth, circular dep count.
1616

1717
### hotspots
1818

@@ -94,7 +94,17 @@ Find unused exports across the codebase.
9494
codebase-intelligence dead-exports <path> [--module <module>] [--limit <n>] [--json] [--force]
9595
```
9696

97-
**Output:** dead export count, files with unused exports, summary.
97+
**Output:** dead export count, files with unused exports, confidence, package-entrypoint evidence, summary.
98+
99+
### opportunities
100+
101+
Rank code quality and refactoring opportunities for AI agents.
102+
103+
```bash
104+
codebase-intelligence opportunities <path> [--limit <n>] [--json] [--force]
105+
```
106+
107+
**Output:** ranked opportunities with kind, priority, confidence, score, target, evidence, and suggested follow-up commands.
98108

99109
### groups
100110

@@ -198,7 +208,7 @@ codebase-intelligence init [path] [--agents <list>] [--all] [--skill] [--yes] [-
198208
| `--json` | All commands | Output stable JSON to stdout |
199209
| `--force` | All commands | Re-parse even if cached index matches HEAD |
200210
| `--metric <m>` | hotspots | Metric to rank by (default: coupling) |
201-
| `--limit <n>` | hotspots, search, dead-exports, processes | Max results |
211+
| `--limit <n>` | hotspots, search, dead-exports, opportunities, processes | Max results |
202212
| `--scope <s>` | changes | Git diff scope: staged, unstaged, all |
203213
| `--depth <n>` | dependents | Max traversal depth (default: 2) |
204214
| `--cohesion <n>` | forces | Min cohesion threshold (default: 0.6) |
@@ -221,7 +231,11 @@ codebase-intelligence init [path] [--agents <list>] [--all] [--skill] [--yes] [-
221231

222232
## Behavior
223233

224-
**Auto-caching:** First CLI invocation parses the codebase and saves the index to `.code-visualizer/`. Subsequent commands use the cache if `git HEAD` hasn't changed. Add `.code-visualizer/` to `.gitignore`.
234+
**Auto-caching:** First CLI invocation parses the codebase and saves the index to `.code-visualizer/`. Subsequent commands use the cache only when `git HEAD`, dirty/untracked file contents under the analyzed path, the CLI version, and parser cache settings match. Add `.code-visualizer/` to `.gitignore`.
235+
236+
**Default scanner excludes:** The parser always skips `.git`, `node_modules`, `.code-visualizer`, `.next`, `dist`, `coverage`, `.turbo`, `.cache`, `.worktrees`, and `.claude/worktrees`, even if the target repo has no matching `.gitignore` entry.
237+
238+
**Large repo mode:** Repos above 1500 TypeScript files use a lightweight AST parser by default to avoid TypeScript program OOM. File/import/export/dependency metrics remain available; type-resolved call graph details are reduced. Set `CBI_FULL_PROGRAM_FILE_LIMIT=<n>` to tune the cutoff.
225239

226240
**stdout/stderr:** Results go to stdout. Progress messages go to stderr. Safe for piping (`| jq`, `> file.json`).
227241

@@ -234,4 +248,4 @@ codebase-intelligence init [path] [--agents <list>] [--all] [--skill] [--yes] [-
234248
- `--index` — persist graph index to `.code-visualizer/` (CLI auto-caches, MCP requires this flag)
235249
- `--status` — print index status and exit
236250
- `--clean` — remove `.code-visualizer/` index and exit
237-
- `--force` — re-index even if HEAD unchanged
251+
- `--force` — re-index even if the cache signature matches

docs/data-model.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ FileMetrics {
7676
cyclomaticComplexity: number // Avg complexity of exports
7777
blastRadius: number // Transitive dependent count
7878
deadExports: string[] // Unused export names
79+
totalExports: number // Named export count used as dead-export denominator
80+
isPackageEntrypoint: boolean // package.json exports/main/types/bin point here
81+
packageEntrypointReason: string // package.json field/path evidence
7982
isTestFile: boolean // Whether this file is a test file
8083
}
8184

@@ -107,6 +110,9 @@ CodebaseGraph {
107110
totalFunctions: number
108111
totalDependencies: number
109112
circularDeps: string[][] // Each cycle = array of file paths
113+
analysisMode: "full-program" | "ast-only"
114+
callGraphPrecision: "type-resolved" | "syntax-only"
115+
fullProgramFileLimit: number
110116
}
111117
}
112118
```

docs/mcp-tools.md

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# MCP Tools Reference
22

3-
16 tools available via MCP stdio.
3+
17 tools available via MCP stdio.
44

55
## 1. codebase_overview
66

77
High-level summary of the entire codebase.
88

99
**Input:** `{ depth?: number }`
10-
**Returns:** totalFiles, totalFunctions, totalDependencies, modules (sorted by size), topDependedFiles (top 5 by fanIn), globalMetrics (avgLOC, maxDepth, circularDepCount)
10+
**Returns:** totalFiles, totalFunctions, totalDependencies, modules (sorted by size), topDependedFiles (top 5 by fanIn), metrics (avgLOC, maxDepth, circularDeps), analysis (mode, callGraphPrecision, fullProgramFileLimit)
1111

1212
**Use when:** First exploring a codebase. "What does this project look like?"
1313
**Not for:** Module details (use get_module_structure) or data flow (use analyze_forces).
@@ -17,7 +17,7 @@ High-level summary of the entire codebase.
1717
Detailed context for a single file.
1818

1919
**Input:** `{ filePath: string }` (relative path)
20-
**Returns:** path, loc, exports, imports (with symbols, isTypeOnly, weight), dependents (with symbols, isTypeOnly, weight), metrics (all FileMetrics including churn, complexity, blastRadius, deadExports, hasTests, testFile)
20+
**Returns:** path, loc, exports, imports (with symbols, isTypeOnly, weight), dependents (with symbols, isTypeOnly, weight), metrics (all FileMetrics including churn, complexity, blastRadius, deadExports, totalExports, package-entrypoint metadata, hasTests, testFile)
2121

2222
**Path normalization:** Backslashes are normalized to forward slashes. The exact graph path is tried first; if not found, common prefixes (`src/`, `lib/`, `app/`) are stripped once from the leading position and retried. If the file is not found, the error includes up to 3 suggested similar paths.
2323

@@ -70,12 +70,24 @@ Architectural force analysis — module health, misplaced files, bridge files.
7070
Find unused exports across the codebase.
7171

7272
**Input:** `{ module?: string, limit?: number }` (default limit: 20)
73-
**Returns:** totalDeadExports, files (with path, module, deadExports[], totalExports), summary
73+
**Returns:** totalDeadExports, files (with path, module, deadExports[], totalExports, confidence, package-entrypoint metadata), summary
74+
75+
Package public entrypoints from `exports`, `main`, `types`, and `bin` are reported as low confidence because external consumers may use them.
7476

7577
**Use when:** Cleaning up dead code, reducing API surface.
7678
**Not for:** Finding used exports (use file_context).
7779

78-
## 8. get_groups
80+
## 8. find_opportunities
81+
82+
Rank code quality and refactoring opportunities for AI agents.
83+
84+
**Input:** `{ limit?: number }` (default limit: 20)
85+
**Returns:** totalOpportunities, opportunities[] (rank, kind, target, title, priority, score, confidence, why, evidence[], suggestedCommands[]), summary
86+
87+
**Use when:** "What should I improve?" "Find refactoring opportunities." "Which files need tests?"
88+
**Not for:** Raw metric lists only (use find_hotspots or analyze_forces).
89+
90+
## 9. get_groups
7991

8092
Top-level directory groups with aggregate metrics.
8193

@@ -85,7 +97,7 @@ Top-level directory groups with aggregate metrics.
8597
**Use when:** "What are the main areas of this codebase?" High-level grouping overview.
8698
**Not for:** Detailed module metrics (use get_module_structure).
8799

88-
## 9. symbol_context
100+
## 10. symbol_context
89101

90102
Callers, callees, and importance metrics for a function, class, or method.
91103

@@ -95,7 +107,7 @@ Callers, callees, and importance metrics for a function, class, or method.
95107
**Use when:** "Who calls X?" "Trace this function." "What depends on this symbol?"
96108
**Not for:** Text search (use search) or file-level dependencies (use get_dependents).
97109

98-
## 10. search
110+
## 11. search
99111

100112
Search files and symbols by keyword.
101113

@@ -105,7 +117,7 @@ Search files and symbols by keyword.
105117
**Use when:** "Find files related to auth." "Where is getUserById defined?"
106118
**Not for:** Structured call graph queries (use symbol_context).
107119

108-
## 11. detect_changes
120+
## 12. detect_changes
109121

110122
Detect changed files from git diff with risk metrics.
111123

@@ -115,7 +127,7 @@ Detect changed files from git diff with risk metrics.
115127
**Use when:** Starting a review, triaging changes, "what changed?"
116128
**Not for:** Symbol-level impact (use impact_analysis).
117129

118-
## 12. impact_analysis
130+
## 13. impact_analysis
119131

120132
Symbol-level blast radius with depth-grouped risk labels.
121133

@@ -125,7 +137,7 @@ Symbol-level blast radius with depth-grouped risk labels.
125137
**Use when:** "What breaks if I change getUserById?" Symbol-level impact assessment.
126138
**Not for:** File-level dependencies (use get_dependents).
127139

128-
## 13. rename_symbol
140+
## 14. rename_symbol
129141

130142
Read-only reference finder for rename planning.
131143

@@ -135,7 +147,7 @@ Read-only reference finder for rename planning.
135147
**Use when:** Planning a rename, finding all usages of a symbol.
136148
**Not for:** Call graph analysis (use symbol_context).
137149

138-
## 14. get_processes
150+
## 15. get_processes
139151

140152
Trace execution flows from entry points through the call graph.
141153

@@ -145,7 +157,7 @@ Trace execution flows from entry points through the call graph.
145157
**Use when:** "How does this app start?" "Trace request flow." "What are the entry points?"
146158
**Not for:** Static file dependencies (use get_dependents).
147159

148-
## 15. get_clusters
160+
## 16. get_clusters
149161

150162
Community-detected clusters of related files.
151163

@@ -155,7 +167,7 @@ Community-detected clusters of related files.
155167
**Use when:** "What files are related?" "Find natural groupings." Discovering emergent groupings that differ from directory structure.
156168
**Not for:** Directory-based modules (use get_module_structure).
157169

158-
## 16. check
170+
## 17. check
159171

160172
Run the configurable rules engine and gate on findings.
161173

@@ -192,6 +204,8 @@ Rules: `no-comments` (off by default), `no-circular-deps` (error), `no-dead-expo
192204
| "What breaks if I change function X?" | `impact_analysis` |
193205
| "What are the riskiest files?" | `find_hotspots` (coupling, churn, or blast_radius) |
194206
| "Which files need tests?" | `find_hotspots` (coverage) |
207+
| "What should I improve first?" | `find_opportunities` |
208+
| "Find refactoring opportunities." | `find_opportunities` |
195209
| "What can I safely delete?" | `find_dead_exports` |
196210
| "How are modules organized?" | `get_module_structure` |
197211
| "What's architecturally wrong?" | `analyze_forces` |

0 commit comments

Comments
 (0)