purecontext-mcp 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/docs/dev/API_STABILITY.md +0 -319
- package/docs/dev/DECISIONS.md +0 -22
- package/docs/dev/DOCUMENTATION_PLAN.md +0 -113
- package/docs/dev/PHASE10_TASKS.md +0 -476
- package/docs/dev/PHASE11_TASKS.md +0 -385
- package/docs/dev/PHASE12_TASKS.md +0 -335
- package/docs/dev/PHASE13_TASKS.md +0 -381
- package/docs/dev/PHASE14_TASKS.md +0 -371
- package/docs/dev/PHASE15_TASKS.md +0 -256
- package/docs/dev/PHASE16_TASKS.md +0 -314
- package/docs/dev/PHASE17_TASKS.md +0 -321
- package/docs/dev/PHASE18_TASKS.md +0 -345
- package/docs/dev/PHASE19_TASKS.md +0 -261
- package/docs/dev/PHASE1_TASKS.md +0 -443
- package/docs/dev/PHASE20_TASKS.md +0 -280
- package/docs/dev/PHASE21_TASKS.md +0 -355
- package/docs/dev/PHASE22_TASKS.md +0 -371
- package/docs/dev/PHASE23_TASKS.md +0 -274
- package/docs/dev/PHASE24_TASKS.md +0 -326
- package/docs/dev/PHASE25_TASKS.md +0 -452
- package/docs/dev/PHASE26_TASKS.md +0 -253
- package/docs/dev/PHASE27_TASKS.md +0 -410
- package/docs/dev/PHASE2_TASKS.md +0 -328
- package/docs/dev/PHASE3_TASKS.md +0 -571
- package/docs/dev/PHASE4_TASKS.md +0 -531
- package/docs/dev/PHASE5_TASKS.md +0 -835
- package/docs/dev/PHASE6_TASKS.md +0 -347
- package/docs/dev/PHASE7_TASKS.md +0 -257
- package/docs/dev/PHASE8_TASKS.md +0 -299
- package/docs/dev/PHASE9_TASKS.md +0 -320
- package/docs/dev/PureContext_MCP_PRD_v1.0.docx +0 -0
- package/docs/dev/SELF_HOSTING.md +0 -142
- package/docs/dev/TEAM_SETUP.md +0 -316
- package/docs/dev/TELEMETRY.md +0 -99
- package/docs/dev/feature-analysis.md +0 -305
- package/docs/dev/phase-1-notes.md +0 -3
|
@@ -1,452 +0,0 @@
|
|
|
1
|
-
# Phase 25 — AI-Powered Architecture Analysis
|
|
2
|
-
|
|
3
|
-
**Goal**: Turn PureContext into a code intelligence platform — not just retrieval, but diagnosis and guidance. Detect anti-patterns, calculate complexity, generate architecture docs, find refactoring opportunities, and bundle the right context for any task description.
|
|
4
|
-
|
|
5
|
-
**Scope rationale**: jCodeMunch is a retrieval tool. PureContext already has the dependency graph, symbol index, semantic embeddings, and AI summarization pipeline — the ingredients for analysis. This phase combines them into tools that reason about code quality, risk, and structure. No other MCP tool does this.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Task 158: Code Quality Metrics
|
|
10
|
-
|
|
11
|
-
Calculate and store per-symbol code quality metrics (complexity, size, coupling) during indexing, and expose them via a query tool.
|
|
12
|
-
|
|
13
|
-
**Current state**: Symbols store source code, signatures, and summaries. No quality metrics are calculated. Agents assessing risk must read source code manually.
|
|
14
|
-
|
|
15
|
-
**Deliverables**:
|
|
16
|
-
|
|
17
|
-
- `src/core/db/schema.ts` — extend `symbols` table:
|
|
18
|
-
```sql
|
|
19
|
-
ALTER TABLE symbols ADD COLUMN line_count INTEGER;
|
|
20
|
-
ALTER TABLE symbols ADD COLUMN cyclomatic_complexity INTEGER;
|
|
21
|
-
ALTER TABLE symbols ADD COLUMN cognitive_complexity INTEGER;
|
|
22
|
-
ALTER TABLE symbols ADD COLUMN param_count INTEGER;
|
|
23
|
-
ALTER TABLE symbols ADD COLUMN return_count INTEGER; -- Number of return statements
|
|
24
|
-
ALTER TABLE symbols ADD COLUMN nesting_depth INTEGER; -- Max nesting level
|
|
25
|
-
```
|
|
26
|
-
- `src/core/metrics/complexity-calculator.ts`:
|
|
27
|
-
```typescript
|
|
28
|
-
interface ComplexityMetrics {
|
|
29
|
-
lineCount: number;
|
|
30
|
-
cyclomaticComplexity: number; // Decision points + 1
|
|
31
|
-
cognitiveComplexity: number; // SonarSource cognitive complexity score
|
|
32
|
-
paramCount: number;
|
|
33
|
-
returnCount: number;
|
|
34
|
-
nestingDepth: number;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function calculateComplexity(
|
|
38
|
-
source: string,
|
|
39
|
-
language: 'typescript' | 'javascript' | 'python' | ...
|
|
40
|
-
): ComplexityMetrics
|
|
41
|
-
```
|
|
42
|
-
- Cyclomatic complexity: count `if`, `else if`, `for`, `while`, `case`, `catch`, `&&`, `||`, `?` → +1 each, start at 1
|
|
43
|
-
- Cognitive complexity: weight nested structures higher (SonarSource algorithm — nesting adds to the increment)
|
|
44
|
-
- `src/core/parse-dispatcher.ts` — after extracting symbols, run `calculateComplexity` on each symbol's source and store metrics
|
|
45
|
-
- `src/server/tools/get-quality-metrics.ts` — new MCP tool:
|
|
46
|
-
```typescript
|
|
47
|
-
interface GetQualityMetricsInput {
|
|
48
|
-
repoId: string;
|
|
49
|
-
scope?: string; // Directory filter
|
|
50
|
-
kind?: SymbolKind;
|
|
51
|
-
sortBy?: 'complexity' | 'size' | 'nesting' | 'params';
|
|
52
|
-
threshold?: {
|
|
53
|
-
cyclomaticComplexity?: number; // Only return symbols above threshold
|
|
54
|
-
lineCount?: number;
|
|
55
|
-
nestingDepth?: number;
|
|
56
|
-
};
|
|
57
|
-
limit?: number; // Default 20
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
interface SymbolQualityRecord {
|
|
61
|
-
symbolId: string;
|
|
62
|
-
name: string;
|
|
63
|
-
kind: SymbolKind;
|
|
64
|
-
filePath: string;
|
|
65
|
-
lineCount: number;
|
|
66
|
-
cyclomaticComplexity: number;
|
|
67
|
-
cognitiveComplexity: number;
|
|
68
|
-
paramCount: number;
|
|
69
|
-
nestingDepth: number;
|
|
70
|
-
qualityScore: number; // 0–100 composite (higher = worse)
|
|
71
|
-
riskLevel: 'good' | 'moderate' | 'high' | 'critical';
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
interface GetQualityMetricsOutput {
|
|
75
|
-
reposId: string;
|
|
76
|
-
symbolsAnalyzed: number;
|
|
77
|
-
worstOffenders: SymbolQualityRecord[];
|
|
78
|
-
summary: {
|
|
79
|
-
avgComplexity: number;
|
|
80
|
-
avgLineCount: number;
|
|
81
|
-
criticalCount: number;
|
|
82
|
-
goodCount: number;
|
|
83
|
-
};
|
|
84
|
-
_meta: ResponseMeta;
|
|
85
|
-
}
|
|
86
|
-
```
|
|
87
|
-
- `qualityScore` composite: weighted average of normalized complexity, size, nesting, params
|
|
88
|
-
- `riskLevel`: `good` (score < 25), `moderate` (25–50), `high` (50–75), `critical` (> 75)
|
|
89
|
-
|
|
90
|
-
**Key technical notes**:
|
|
91
|
-
- Complexity calculation is pure text/token analysis — no tree-sitter traversal needed for basic cyclomatic complexity (token counting). For cognitive complexity, nesting detection benefits from AST traversal
|
|
92
|
-
- Start with token-based heuristics; tree-sitter traversal can be added incrementally per language handler
|
|
93
|
-
- Metrics are calculated at index time — zero overhead at query time
|
|
94
|
-
- Do not calculate metrics for `kind: 'const'` or `kind: 'type'` — only for functions, methods, and classes
|
|
95
|
-
|
|
96
|
-
**Tests**: `test/core/complexity-calculator.test.ts`
|
|
97
|
-
- Simple function → complexity 1
|
|
98
|
-
- Function with 3 if-branches → complexity 4
|
|
99
|
-
- Nested loops → higher cognitive complexity than equivalent non-nested code
|
|
100
|
-
- `get_quality_metrics` returns sorted results
|
|
101
|
-
- Threshold filter works
|
|
102
|
-
|
|
103
|
-
**Verify**:
|
|
104
|
-
```bash
|
|
105
|
-
# get_quality_metrics { repoId: "...", threshold: { cyclomaticComplexity: 10 }, sortBy: "complexity" }
|
|
106
|
-
# Returns functions with CC > 10, sorted descending
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
---
|
|
110
|
-
|
|
111
|
-
## Task 159: Anti-Pattern Detection Tool
|
|
112
|
-
|
|
113
|
-
New `detect_antipatterns` tool — scan the indexed repo for structural anti-patterns: circular dependencies, god classes, high-coupling modules, and overly deep inheritance.
|
|
114
|
-
|
|
115
|
-
**Current state**: `get_layer_violations` detects one specific class of violations (layered architecture breaks). There is no general-purpose anti-pattern scanner.
|
|
116
|
-
|
|
117
|
-
**Deliverables**:
|
|
118
|
-
|
|
119
|
-
- `src/server/tools/detect-antipatterns.ts` — new MCP tool:
|
|
120
|
-
```typescript
|
|
121
|
-
interface DetectAntipatternsInput {
|
|
122
|
-
repoId: string;
|
|
123
|
-
checks?: AntipatternCheck[]; // Omit to run all checks
|
|
124
|
-
severity?: 'all' | 'warning' | 'error';
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
type AntipatternCheck =
|
|
128
|
-
| 'circular_dependencies'
|
|
129
|
-
| 'god_class'
|
|
130
|
-
| 'high_coupling'
|
|
131
|
-
| 'dead_code'
|
|
132
|
-
| 'deep_nesting'
|
|
133
|
-
| 'long_parameter_list'
|
|
134
|
-
| 'duplicate_code';
|
|
135
|
-
|
|
136
|
-
interface AntipatternFinding {
|
|
137
|
-
check: AntipatternCheck;
|
|
138
|
-
severity: 'warning' | 'error';
|
|
139
|
-
filePath: string;
|
|
140
|
-
symbolId?: string;
|
|
141
|
-
symbolName?: string;
|
|
142
|
-
description: string; // Human-readable explanation
|
|
143
|
-
evidence: string; // Specific data supporting the finding
|
|
144
|
-
suggestion: string; // Actionable remediation hint
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
interface DetectAntipatternsOutput {
|
|
148
|
-
repoId: string;
|
|
149
|
-
findingsCount: number;
|
|
150
|
-
errorCount: number;
|
|
151
|
-
warningCount: number;
|
|
152
|
-
findings: AntipatternFinding[];
|
|
153
|
-
healthScore: number; // 0–100 (100 = no findings)
|
|
154
|
-
_meta: ResponseMeta;
|
|
155
|
-
}
|
|
156
|
-
```
|
|
157
|
-
- Individual checks:
|
|
158
|
-
- **`circular_dependencies`**: traverse `dep_edges` with DFS cycle detection — any cycle is an error
|
|
159
|
-
- **`god_class`**: classes with `line_count > 500` OR `method_count > 20` — error
|
|
160
|
-
- **`high_coupling`**: files imported by > 10 other files (efferent coupling) — warning; > 20 — error
|
|
161
|
-
- **`dead_code`**: reuse `find_dead_code` tool logic — exported symbols with zero importers — warning
|
|
162
|
-
- **`deep_nesting`**: symbols with `nesting_depth > 5` (from Task 158 metrics) — error
|
|
163
|
-
- **`long_parameter_list`**: functions/methods with `param_count > 7` — warning; > 10 — error
|
|
164
|
-
- **`duplicate_code`**: symbols with cosine similarity > 0.95 to another symbol of the same kind (uses HNSW index) — warning
|
|
165
|
-
- `healthScore`: `100 - (errors × 10 + warnings × 2)` clamped to 0
|
|
166
|
-
|
|
167
|
-
**Key technical notes**:
|
|
168
|
-
- `duplicate_code` check requires HNSW semantic index — skip gracefully if not available and note in response
|
|
169
|
-
- Cycle detection: existing `graph-traversal.ts` has DFS infrastructure — extend with cycle tracking
|
|
170
|
-
- `god_class` method count: query `COUNT(*)` from `symbols` where `file_path = class_file AND kind = 'method'`
|
|
171
|
-
- This tool is intended to be run periodically (e.g. in CI) and the output consumed by humans or AI reviewers
|
|
172
|
-
|
|
173
|
-
**Tests**: `test/server/detect-antipatterns.test.ts`
|
|
174
|
-
- Circular dependency detected in fixture with cycle
|
|
175
|
-
- God class detected when method count > 20
|
|
176
|
-
- High coupling detected for widely-imported file
|
|
177
|
-
- Dead code reuses find_dead_code logic
|
|
178
|
-
- `healthScore` calculation correct
|
|
179
|
-
- `checks` filter runs only specified checks
|
|
180
|
-
|
|
181
|
-
**Verify**:
|
|
182
|
-
```bash
|
|
183
|
-
# detect_antipatterns { repoId: "...", checks: ["circular_dependencies", "god_class"] }
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
---
|
|
187
|
-
|
|
188
|
-
## Task 160: Architecture Documentation Generator
|
|
189
|
-
|
|
190
|
-
New `generate_docs` tool — produce a structured markdown architecture document for a repo (or a directory within it) from the indexed symbols, dependency graph, and AI summaries.
|
|
191
|
-
|
|
192
|
-
**Current state**: Repos are indexed with AI-generated summaries per symbol. There is no tool that assembles these into a coherent architecture document. Teams spend significant time writing and maintaining architecture docs manually.
|
|
193
|
-
|
|
194
|
-
**Deliverables**:
|
|
195
|
-
|
|
196
|
-
- `src/server/tools/generate-docs.ts` — new MCP tool:
|
|
197
|
-
```typescript
|
|
198
|
-
interface GenerateDocsInput {
|
|
199
|
-
repoId: string;
|
|
200
|
-
scope?: string; // Directory prefix (e.g. "src/core/")
|
|
201
|
-
format?: 'markdown' | 'json';
|
|
202
|
-
includeSymbols?: boolean; // Default true — list key symbols per module
|
|
203
|
-
includeDependencies?: boolean; // Default true — show import relationships
|
|
204
|
-
includeMetrics?: boolean; // Default false — append quality metrics
|
|
205
|
-
aiEnhance?: boolean; // Default true — use AI to write module descriptions
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
interface ModuleDoc {
|
|
209
|
-
path: string;
|
|
210
|
-
title: string;
|
|
211
|
-
description: string; // AI-generated or from top docstring
|
|
212
|
-
publicSymbols: {
|
|
213
|
-
name: string;
|
|
214
|
-
kind: SymbolKind;
|
|
215
|
-
signature: string;
|
|
216
|
-
summary: string;
|
|
217
|
-
}[];
|
|
218
|
-
dependsOn: string[]; // Modules this one imports from
|
|
219
|
-
importedBy: string[]; // Modules that import this one
|
|
220
|
-
metrics?: {
|
|
221
|
-
symbolCount: number;
|
|
222
|
-
avgComplexity: number;
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
interface GenerateDocsOutput {
|
|
227
|
-
repoId: string;
|
|
228
|
-
title: string;
|
|
229
|
-
generatedAt: string;
|
|
230
|
-
moduleCount: number;
|
|
231
|
-
document: string; // Full markdown or JSON
|
|
232
|
-
_meta: ResponseMeta;
|
|
233
|
-
}
|
|
234
|
-
```
|
|
235
|
-
- Document structure (markdown):
|
|
236
|
-
```markdown
|
|
237
|
-
# {Repo Name} — Architecture Overview
|
|
238
|
-
_Generated by PureContext on {date}_
|
|
239
|
-
|
|
240
|
-
## Modules
|
|
241
|
-
|
|
242
|
-
### src/core/index-manager.ts
|
|
243
|
-
{AI-generated description of what this module does}
|
|
244
|
-
|
|
245
|
-
**Public API:**
|
|
246
|
-
- `indexFolder(path, options)` — Orchestrates full indexing pipeline
|
|
247
|
-
- `reindexFiles(repoId, paths)` — Incremental re-index for changed files
|
|
248
|
-
|
|
249
|
-
**Depends on:** `file-discovery`, `parse-dispatcher`, `symbol-store`
|
|
250
|
-
**Imported by:** `mcp-server`, `index-folder tool`
|
|
251
|
-
|
|
252
|
-
---
|
|
253
|
-
```
|
|
254
|
-
- AI enhancement (`aiEnhance: true`): for modules without a top-level docstring, call the configured AI summarizer with a prompt: "Given these exported symbols from {filePath}, write a 2-sentence description of what this module does and its role in the codebase."
|
|
255
|
-
- Batch AI calls: group up to 10 modules per API call (same batch infrastructure as `ai-summarizer.ts`)
|
|
256
|
-
- Non-AI fallback: assemble description from the first docstring found in the file, or from the summary of the most-imported symbol
|
|
257
|
-
|
|
258
|
-
**Key technical notes**:
|
|
259
|
-
- This tool is intentionally token-heavy (it generates a document, not retrieves one) — do not include it in `_meta` token savings calculations
|
|
260
|
-
- `aiEnhance` requires a configured AI provider — check config and warn clearly if none is set
|
|
261
|
-
- Output is useful both for humans (review the markdown) and for AI agents (pass the doc to another LLM for higher-level analysis)
|
|
262
|
-
- The `json` format produces structured data for downstream tooling (CI pipelines, wikis, etc.)
|
|
263
|
-
|
|
264
|
-
**Tests**: `test/server/generate-docs.test.ts`
|
|
265
|
-
- Markdown output contains all modules in scope
|
|
266
|
-
- Each module has public symbols listed
|
|
267
|
-
- Dependencies listed correctly from dep_edges
|
|
268
|
-
- `aiEnhance: false` — no AI calls made
|
|
269
|
-
- `scope` filter narrows to directory
|
|
270
|
-
- `format: 'json'` returns parseable JSON
|
|
271
|
-
|
|
272
|
-
**Verify**:
|
|
273
|
-
```bash
|
|
274
|
-
# generate_docs { repoId: "...", scope: "src/core/", aiEnhance: false }
|
|
275
|
-
# Should produce a markdown architecture doc for the core module
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
---
|
|
279
|
-
|
|
280
|
-
## Task 161: Smart Context Bundling
|
|
281
|
-
|
|
282
|
-
New `get_task_context` tool — given a natural language task description, determine and return the minimal but complete set of symbols and files an agent needs to complete that task.
|
|
283
|
-
|
|
284
|
-
**Current state**: `get_context_bundle` returns a fixed symbol + its imports. Agents must still iterate — run multiple searches, read multiple symbols, discover what they need through trial and error. There is no tool that reasons about "what do I need to understand to accomplish X?"
|
|
285
|
-
|
|
286
|
-
**Deliverables**:
|
|
287
|
-
|
|
288
|
-
- `src/server/tools/get-task-context.ts` — new MCP tool:
|
|
289
|
-
```typescript
|
|
290
|
-
interface GetTaskContextInput {
|
|
291
|
-
repoId: string;
|
|
292
|
-
task: string; // Natural language: "add OAuth login to the user service"
|
|
293
|
-
maxSymbols?: number; // Default 15, max 50
|
|
294
|
-
includeSource?: boolean; // Default false — return source or just metadata
|
|
295
|
-
model?: string; // AI model for context planning (default: configured summarizer)
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
interface ContextItem {
|
|
299
|
-
symbolId: string;
|
|
300
|
-
name: string;
|
|
301
|
-
kind: SymbolKind;
|
|
302
|
-
filePath: string;
|
|
303
|
-
signature: string;
|
|
304
|
-
summary: string;
|
|
305
|
-
relevanceReason: string; // Why this symbol is needed for the task
|
|
306
|
-
source?: string; // Only when includeSource: true
|
|
307
|
-
role: 'primary' | 'dependency' | 'test' | 'config';
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
interface GetTaskContextOutput {
|
|
311
|
-
task: string;
|
|
312
|
-
plan: string; // AI-generated brief plan: what files/areas to touch
|
|
313
|
-
contextItems: ContextItem[];
|
|
314
|
-
estimatedFiles: string[]; // Files the agent will likely need to modify
|
|
315
|
-
totalTokens: number; // Estimated tokens for all context items
|
|
316
|
-
_meta: ResponseMeta;
|
|
317
|
-
}
|
|
318
|
-
```
|
|
319
|
-
- Two-stage pipeline:
|
|
320
|
-
1. **Discovery**: run `search_semantic` (hybrid mode) with the task description to find the top 30 candidate symbols
|
|
321
|
-
2. **Ranking**: call the AI with: task description + top 30 candidate symbol summaries + dependency graph context → ask the AI to select the most relevant 15 and explain each one's role
|
|
322
|
-
- AI prompt template (in `src/server/tools/get-task-context.ts`):
|
|
323
|
-
```
|
|
324
|
-
Task: {task}
|
|
325
|
-
|
|
326
|
-
Available symbols (name, kind, file, summary):
|
|
327
|
-
{candidates}
|
|
328
|
-
|
|
329
|
-
Select the most relevant symbols for completing this task. For each selected symbol, state:
|
|
330
|
-
- Why it's needed (relevanceReason)
|
|
331
|
-
- Its role: primary (directly implements the feature), dependency (needed to understand/call), test (test file to update), config (configuration to modify)
|
|
332
|
-
|
|
333
|
-
Also provide: a brief plan (2-3 sentences) and which files are likely to be modified.
|
|
334
|
-
```
|
|
335
|
-
- Fall back to pure semantic search ranking (no AI call) if no AI provider configured
|
|
336
|
-
- `includeSource: true` fetches full source for each symbol using batch retrieval (`get_symbols` logic from Task 133)
|
|
337
|
-
|
|
338
|
-
**Key technical notes**:
|
|
339
|
-
- This tool's value is in reducing agent iteration loops — instead of 10 search-and-read cycles, one call delivers everything needed
|
|
340
|
-
- The AI stage is optional but dramatically improves relevance — without it, the tool degrades to a ranked semantic search
|
|
341
|
-
- Cost: one embedding call (task description) + one AI completion call (selection + planning) + N symbol source reads
|
|
342
|
-
- The AI model used for planning need not be the same as the summarization model — configure separately if needed
|
|
343
|
-
|
|
344
|
-
**Tests**: `test/server/get-task-context.test.ts`
|
|
345
|
-
- Semantic discovery returns candidates
|
|
346
|
-
- AI selection narrows to `maxSymbols`
|
|
347
|
-
- `relevanceReason` populated for each item
|
|
348
|
-
- `includeSource: true` returns symbol source
|
|
349
|
-
- No AI provider → falls back to semantic ranking
|
|
350
|
-
- `_meta` does not double-count token savings
|
|
351
|
-
|
|
352
|
-
**Verify**:
|
|
353
|
-
```bash
|
|
354
|
-
# get_task_context { repoId: "...", task: "add rate limiting to the API endpoints", maxSymbols: 10 }
|
|
355
|
-
# Should return relevant symbols with roles and a brief plan
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
---
|
|
359
|
-
|
|
360
|
-
## Task 162: Refactoring Opportunity Detector
|
|
361
|
-
|
|
362
|
-
New `find_refactoring_opportunities` tool — identify functions that are too large, parameters that should be objects, duplicated logic, and classes that could be extracted.
|
|
363
|
-
|
|
364
|
-
**Current state**: Code quality metrics (Task 158) flag individual symbols. There is no tool that connects these signals into actionable refactoring recommendations with specific suggestions.
|
|
365
|
-
|
|
366
|
-
**Deliverables**:
|
|
367
|
-
|
|
368
|
-
- `src/server/tools/find-refactoring-opportunities.ts` — new MCP tool:
|
|
369
|
-
```typescript
|
|
370
|
-
interface FindRefactoringOpportunitiesInput {
|
|
371
|
-
repoId: string;
|
|
372
|
-
scope?: string;
|
|
373
|
-
types?: RefactoringType[]; // Omit for all
|
|
374
|
-
minImpact?: 'low' | 'medium' | 'high';
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
type RefactoringType =
|
|
378
|
-
| 'extract_function' // Function too long → split it
|
|
379
|
-
| 'introduce_parameter_object' // Too many params → group them
|
|
380
|
-
| 'extract_class' // File too large, too many responsibilities
|
|
381
|
-
| 'inline_function' // Trivial wrapper with one callsite
|
|
382
|
-
| 'consolidate_duplicates' // Near-duplicate functions → merge
|
|
383
|
-
| 'simplify_conditional' // Deep nesting → early returns
|
|
384
|
-
|
|
385
|
-
interface RefactoringOpportunity {
|
|
386
|
-
type: RefactoringType;
|
|
387
|
-
impact: 'low' | 'medium' | 'high';
|
|
388
|
-
symbolId: string;
|
|
389
|
-
symbolName: string;
|
|
390
|
-
filePath: string;
|
|
391
|
-
description: string; // "Function has 120 lines and complexity 24"
|
|
392
|
-
suggestion: string; // "Extract lines 45-80 into a separate validateInput() function"
|
|
393
|
-
effort: 'trivial' | 'small' | 'medium' | 'large';
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
interface FindRefactoringOpportunitiesOutput {
|
|
397
|
-
repoId: string;
|
|
398
|
-
totalOpportunities: number;
|
|
399
|
-
opportunities: RefactoringOpportunity[];
|
|
400
|
-
estimatedImpact: string; // "Reducing complexity by ~30% across 8 symbols"
|
|
401
|
-
_meta: ResponseMeta;
|
|
402
|
-
}
|
|
403
|
-
```
|
|
404
|
-
- Detection logic per type:
|
|
405
|
-
- **`extract_function`**: `line_count > 50 AND cyclomatic_complexity > 10`
|
|
406
|
-
- **`introduce_parameter_object`**: `param_count > 5`
|
|
407
|
-
- **`extract_class`**: file with `symbol_count > 15` of mixed kinds — multiple responsibilities
|
|
408
|
-
- **`inline_function`**: function with `line_count <= 3` AND imported by exactly 1 file
|
|
409
|
-
- **`consolidate_duplicates`**: HNSW similarity > 0.92 between two functions of the same kind
|
|
410
|
-
- **`simplify_conditional`**: `nesting_depth > 4 AND return_count > 3` — candidate for early-return refactor
|
|
411
|
-
- Suggestions are templated per type — not AI-generated (deterministic, fast)
|
|
412
|
-
- `effort` heuristic: based on line count and blast radius of the symbol
|
|
413
|
-
|
|
414
|
-
**Key technical notes**:
|
|
415
|
-
- All detection uses stored metrics (Task 158) + dep_edges — no additional parsing at query time
|
|
416
|
-
- `consolidate_duplicates` requires HNSW — skip if not available
|
|
417
|
-
- Sort by `impact` descending, then `effort` ascending (highest value, lowest effort first)
|
|
418
|
-
- Results are actionable: each opportunity points to a specific symbol with a specific suggestion
|
|
419
|
-
|
|
420
|
-
**Tests**: `test/server/find-refactoring-opportunities.test.ts`
|
|
421
|
-
- Long complex function → `extract_function` opportunity
|
|
422
|
-
- Many-param function → `introduce_parameter_object`
|
|
423
|
-
- Trivial single-callsite function → `inline_function`
|
|
424
|
-
- Deep nesting → `simplify_conditional`
|
|
425
|
-
- `types` filter limits to specified types
|
|
426
|
-
- `minImpact` filter excludes low-impact findings
|
|
427
|
-
|
|
428
|
-
**Verify**:
|
|
429
|
-
```bash
|
|
430
|
-
# find_refactoring_opportunities { repoId: "...", types: ["extract_function", "simplify_conditional"] }
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
---
|
|
434
|
-
|
|
435
|
-
## Order of Execution
|
|
436
|
-
|
|
437
|
-
```
|
|
438
|
-
158 (quality metrics) ──▶ 159 (antipatterns — uses metrics)
|
|
439
|
-
──▶ 162 (refactoring — uses metrics)
|
|
440
|
-
160 (generate docs) ── independent (uses AI summarizer)
|
|
441
|
-
161 (smart context bundling) ── independent (uses semantic search + AI)
|
|
442
|
-
```
|
|
443
|
-
|
|
444
|
-
Recommended sequence: 158 → 159 → 162 → 161 → 160
|
|
445
|
-
|
|
446
|
-
---
|
|
447
|
-
|
|
448
|
-
## Phase 25 Completion
|
|
449
|
-
|
|
450
|
-
**Before**: PureContext retrieves code. Quality, risk, and architecture are invisible without reading source manually.
|
|
451
|
-
|
|
452
|
-
**After**: Every symbol carries a quality score. Anti-patterns are detected automatically. Architecture docs are generated on demand. Smart context bundling eliminates the multi-step "what do I need?" discovery loop. Refactoring opportunities are served on a plate with specific suggestions. This is a fundamentally different product category from jCodeMunch — not a retrieval tool but a code intelligence platform.
|