Skip to content

Commit 90cb2bd

Browse files
prosdevclaude
andcommitted
refactor(core,mcp): remove dead code and stale GitHub references
- Rewrite analyzeFileWithDocs to use pure extractors directly - Delete 3 now-redundant private wrapper methods - Remove githubStatePath, checkGitHubIndex, githubIndex from health adapter - Clean up health adapter tests (remove 5 GitHub-specific tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 37c86b7 commit 90cb2bd

3 files changed

Lines changed: 18 additions & 217 deletions

File tree

packages/core/src/services/pattern-analysis-service.ts

Lines changed: 15 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -238,46 +238,37 @@ export class PatternAnalysisService {
238238
}
239239

240240
/**
241-
* Analyze file patterns using pre-scanned documents (faster)
242-
*
243-
* @param filePath - Relative path from repository root
244-
* @param documents - Pre-scanned documents for this file
245-
* @returns Pattern analysis results
241+
* Analyze file patterns using pre-scanned documents (fallback path).
246242
*/
247243
private async analyzeFileWithDocs(
248244
filePath: string,
249245
documents: Document[]
250246
): Promise<FilePatterns> {
251-
// Step 1: Get file stats and content
252247
const fullPath = path.join(this.config.repositoryPath, filePath);
253-
const [stat, content] = await Promise.all([fs.stat(fullPath), fs.readFile(fullPath, 'utf-8')]);
248+
const [content, stat, testing] = await Promise.all([
249+
fs.readFile(fullPath, 'utf-8'),
250+
fs.stat(fullPath),
251+
this.analyzeTesting(filePath),
252+
]);
254253

255-
const lines = content.split('\n').length;
254+
const signatures = documents
255+
.filter((d) => d.type === 'function' || d.type === 'method')
256+
.map((d) => d.metadata.signature || '')
257+
.filter(Boolean);
256258

257-
// Step 2: Extract all patterns (using cached documents)
258259
return {
259-
fileSize: {
260-
lines,
261-
bytes: stat.size,
262-
},
263-
testing: await this.analyzeTesting(filePath),
264-
importStyle: await this.analyzeImportsFromFile(filePath, documents),
265-
errorHandling: this.analyzeErrorHandling(content),
266-
typeAnnotations: this.analyzeTypes(documents),
260+
fileSize: { lines: content.split('\n').length, bytes: stat.size },
261+
testing,
262+
importStyle: extractImportStyleFromContent(content),
263+
errorHandling: extractErrorHandlingFromContent(content),
264+
typeAnnotations: extractTypeCoverageFromSignatures(signatures),
267265
};
268266
}
269267

270-
// ========================================================================
271-
// Pattern Extractors (MVP: 5 core patterns)
272-
// ========================================================================
273-
274268
/**
275269
* Analyze test coverage for a file
276-
*
277-
* Checks for co-located test files (*.test.*, *.spec.*)
278270
*/
279271
private async analyzeTesting(filePath: string): Promise<TestingPattern> {
280-
// Skip if already a test file
281272
if (isTestFile(filePath)) {
282273
return { hasTest: false };
283274
}
@@ -289,37 +280,6 @@ export class PatternAnalysisService {
289280
};
290281
}
291282

292-
/**
293-
* Analyze import style from documents
294-
*
295-
* Always uses content analysis for reliability (scanner may not extract imports from all files).
296-
*/
297-
private async analyzeImportsFromFile(
298-
filePath: string,
299-
_documents: Document[]
300-
): Promise<ImportStylePattern> {
301-
const fullPath = path.join(this.config.repositoryPath, filePath);
302-
const content = await fs.readFile(fullPath, 'utf-8');
303-
return extractImportStyleFromContent(content);
304-
}
305-
306-
/**
307-
* Analyze error handling patterns in file content
308-
*/
309-
private analyzeErrorHandling(content: string): ErrorHandlingPattern {
310-
return extractErrorHandlingFromContent(content);
311-
}
312-
313-
/**
314-
* Analyze type annotation coverage from documents
315-
*/
316-
private analyzeTypes(documents: Document[]): TypeAnnotationPattern {
317-
const signatures = documents
318-
.filter((d) => d.type === 'function' || d.type === 'method')
319-
.map((d) => d.metadata.signature || '');
320-
return extractTypeCoverageFromSignatures(signatures);
321-
}
322-
323283
// ========================================================================
324284
// Pattern Comparisons
325285
// ========================================================================

packages/mcp-server/src/adapters/__tests__/health-adapter.test.ts

Lines changed: 0 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ describe('HealthAdapter', () => {
99
let testDir: string;
1010
let vectorStorePath: string;
1111
let repositoryPath: string;
12-
let githubStatePath: string;
1312
let adapter: HealthAdapter;
1413
let context: AdapterContext;
1514
let execContext: ToolExecutionContext;
@@ -19,16 +18,13 @@ describe('HealthAdapter', () => {
1918
testDir = path.join(os.tmpdir(), `health-adapter-test-${Date.now()}`);
2019
vectorStorePath = path.join(testDir, 'vectors');
2120
repositoryPath = path.join(testDir, 'repo');
22-
githubStatePath = path.join(testDir, 'github-state.json');
23-
2421
await fs.mkdir(testDir, { recursive: true });
2522
await fs.mkdir(vectorStorePath, { recursive: true });
2623
await fs.mkdir(repositoryPath, { recursive: true });
2724

2825
adapter = new HealthAdapter({
2926
repositoryPath,
3027
vectorStorePath,
31-
githubStatePath,
3228
});
3329

3430
context = {
@@ -75,16 +71,6 @@ describe('HealthAdapter', () => {
7571
// Setup: Create git repository
7672
await fs.mkdir(path.join(repositoryPath, '.git'));
7773

78-
// Setup: Create GitHub index
79-
await fs.writeFile(
80-
githubStatePath,
81-
JSON.stringify({
82-
version: '1.0.0',
83-
lastIndexed: new Date().toISOString(),
84-
items: [{ id: 1 }, { id: 2 }],
85-
})
86-
);
87-
8874
const result = await adapter.execute({}, execContext);
8975

9076
expect(result.success).toBe(true);
@@ -95,13 +81,11 @@ describe('HealthAdapter', () => {
9581
expect(result.data).toContain('HEALTHY');
9682
expect(result.data).toContain('Vector Storage');
9783
expect(result.data).toContain('Repository');
98-
expect(result.data).toContain('Github Index');
9984
});
10085

10186
it('should report degraded when components have warnings', async () => {
10287
// Vector storage is empty (warning)
10388
// Repository exists but no .git (warning)
104-
// No GitHub index
10589

10690
const result = await adapter.execute({}, execContext);
10791

@@ -188,67 +172,6 @@ describe('HealthAdapter', () => {
188172
});
189173
});
190174

191-
describe('GitHub Index Check', () => {
192-
it('should pass when index is recent', async () => {
193-
await fs.writeFile(
194-
githubStatePath,
195-
JSON.stringify({
196-
version: '1.0.0',
197-
lastIndexed: new Date().toISOString(),
198-
items: [{ id: 1 }, { id: 2 }, { id: 3 }],
199-
})
200-
);
201-
202-
const result = await adapter.execute({}, execContext);
203-
204-
expect(result.success).toBe(true);
205-
expect(result.data).toContain('Github Index');
206-
expect(result.data).toContain('3 items');
207-
});
208-
209-
it('should warn when index is stale (>24 hours)', async () => {
210-
const yesterday = new Date(Date.now() - 25 * 60 * 60 * 1000);
211-
await fs.writeFile(
212-
githubStatePath,
213-
JSON.stringify({
214-
version: '1.0.0',
215-
lastIndexed: yesterday.toISOString(),
216-
items: [{ id: 1 }],
217-
})
218-
);
219-
220-
const result = await adapter.execute({}, execContext);
221-
222-
expect(result.success).toBe(true);
223-
expect(result.data).toContain('Github Index');
224-
expect(result.data).toContain('old');
225-
});
226-
227-
it('should warn when index file does not exist', async () => {
228-
const result = await adapter.execute({}, execContext);
229-
230-
expect(result.success).toBe(true);
231-
expect(result.data).toContain('not accessible');
232-
});
233-
234-
it('should not check GitHub index when not configured', async () => {
235-
const adapterWithoutGithub = new HealthAdapter({
236-
repositoryPath,
237-
vectorStorePath,
238-
});
239-
240-
await adapterWithoutGithub.initialize(context);
241-
242-
const result = await adapterWithoutGithub.execute({}, execContext);
243-
244-
expect(result.success).toBe(true);
245-
// Github Index section should not appear when not configured
246-
expect(result.data).not.toContain('Github Index');
247-
248-
await adapterWithoutGithub.shutdown();
249-
});
250-
});
251-
252175
describe('Output Formatting', () => {
253176
it('should format uptime correctly', async () => {
254177
// Wait a moment to accumulate uptime
@@ -309,16 +232,6 @@ describe('HealthAdapter', () => {
309232
await fs.writeFile(path.join(vectorStorePath, 'data.db'), 'test');
310233
await fs.mkdir(path.join(repositoryPath, '.git'));
311234

312-
// Add GitHub index to make it fully healthy
313-
await fs.writeFile(
314-
githubStatePath,
315-
JSON.stringify({
316-
version: '1.0.0',
317-
lastIndexed: new Date().toISOString(),
318-
items: [{ id: 1 }],
319-
})
320-
);
321-
322235
const healthy = await adapter.healthCheck();
323236

324237
expect(healthy).toBe(true);
@@ -334,15 +247,6 @@ describe('HealthAdapter', () => {
334247
});
335248

336249
describe('Error Handling', () => {
337-
it('should handle invalid GitHub state JSON', async () => {
338-
await fs.writeFile(githubStatePath, 'invalid json');
339-
340-
const result = await adapter.execute({}, execContext);
341-
342-
expect(result.success).toBe(true);
343-
expect(result.data).toContain('⚠️');
344-
});
345-
346250
it('should handle permission errors gracefully', async () => {
347251
// This test is platform-dependent, so we'll skip it if we can't set permissions
348252
if (process.platform !== 'win32') {

packages/mcp-server/src/adapters/built-in/health-adapter.ts

Lines changed: 3 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,13 @@ import { validateArgs } from '../validation.js';
1313
export interface HealthCheckConfig {
1414
repositoryPath: string;
1515
vectorStorePath: string;
16-
githubStatePath?: string;
1716
}
1817

1918
export interface HealthStatus {
2019
status: 'healthy' | 'degraded' | 'unhealthy';
2120
checks: {
2221
vectorStorage: CheckResult;
2322
repository: CheckResult;
24-
githubIndex?: CheckResult;
2523
};
2624
timestamp: string;
2725
uptime: number; // milliseconds
@@ -61,7 +59,7 @@ export class HealthAdapter extends ToolAdapter {
6159
return {
6260
name: 'dev_health',
6361
description:
64-
'Check the health status of the dev-agent MCP server and its dependencies (vector storage, repository, GitHub index)',
62+
'Check the health status of the dev-agent MCP server and its dependencies (Antfly vector storage, repository access)',
6563
inputSchema: {
6664
type: 'object',
6765
properties: {
@@ -114,20 +112,12 @@ export class HealthAdapter extends ToolAdapter {
114112
}
115113

116114
private async performHealthChecks(verbose: boolean): Promise<HealthStatus> {
117-
const [vectorStorage, repository, githubIndex] = await Promise.all([
115+
const [vectorStorage, repository] = await Promise.all([
118116
this.checkVectorStorage(verbose),
119117
this.checkRepository(verbose),
120-
this.config.githubStatePath ? this.checkGitHubIndex(verbose) : Promise.resolve(undefined),
121118
]);
122119

123-
const checks: HealthStatus['checks'] = {
124-
vectorStorage,
125-
repository,
126-
};
127-
128-
if (githubIndex) {
129-
checks.githubIndex = githubIndex;
130-
}
120+
const checks: HealthStatus['checks'] = { vectorStorage, repository };
131121

132122
return {
133123
status: this.getOverallStatus({ checks } as HealthStatus),
@@ -211,59 +201,6 @@ export class HealthAdapter extends ToolAdapter {
211201
}
212202
}
213203

214-
private async checkGitHubIndex(verbose: boolean): Promise<CheckResult> {
215-
if (!this.config.githubStatePath) {
216-
return {
217-
status: 'warn',
218-
message: 'GitHub index not configured',
219-
};
220-
}
221-
222-
try {
223-
const content = await fs.readFile(this.config.githubStatePath, 'utf-8');
224-
const state = JSON.parse(content);
225-
226-
const lastIndexed = state.lastIndexed ? new Date(state.lastIndexed) : null;
227-
const itemCount = state.items?.length ?? 0;
228-
229-
if (!lastIndexed) {
230-
return {
231-
status: 'warn',
232-
message: 'GitHub index exists but has no lastIndexed timestamp',
233-
details: verbose ? { path: this.config.githubStatePath } : undefined,
234-
};
235-
}
236-
237-
const ageMs = Date.now() - lastIndexed.getTime();
238-
const ageHours = Math.floor(ageMs / (1000 * 60 * 60));
239-
240-
// Warn if index is older than 24 hours
241-
if (ageHours > 24) {
242-
return {
243-
status: 'warn',
244-
message: `GitHub index is ${ageHours}h old (${itemCount} items) - consider re-indexing`,
245-
details: verbose
246-
? { path: this.config.githubStatePath, lastIndexed: lastIndexed.toISOString() }
247-
: undefined,
248-
};
249-
}
250-
251-
return {
252-
status: 'pass',
253-
message: `GitHub index operational (${itemCount} items, indexed ${ageHours}h ago)`,
254-
details: verbose
255-
? { path: this.config.githubStatePath, lastIndexed: lastIndexed.toISOString() }
256-
: undefined,
257-
};
258-
} catch (error) {
259-
return {
260-
status: 'warn',
261-
message: `GitHub index not accessible: ${error instanceof Error ? error.message : String(error)}`,
262-
details: verbose ? { path: this.config.githubStatePath } : undefined,
263-
};
264-
}
265-
}
266-
267204
private getOverallStatus(health: HealthStatus): 'healthy' | 'degraded' | 'unhealthy' {
268205
const checks = Object.values(health.checks).filter(
269206
(check): check is CheckResult => check !== undefined

0 commit comments

Comments
 (0)