Skip to content

Commit 33831e1

Browse files
authored
Merge pull request #4 from haasonsaas/fix/validation-length-mismatch
fix: address validation length mismatch and directory verification
2 parents 4ceeb44 + 7e51531 commit 33831e1

11 files changed

+126
-115
lines changed

src/analyzers/DeepCodeReasonerV2.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ export class DeepCodeReasonerV2 {
236236
private createErrorResult(error: Error, context: ClaudeCodeContext): DeepAnalysisResult {
237237
// Extract structured error information
238238
const errorDetails = this.extractErrorDetails(error);
239-
239+
240240
return {
241241
status: 'partial',
242242
findings: {
@@ -261,7 +261,7 @@ export class DeepCodeReasonerV2 {
261261
newInsights: [{
262262
type: 'error',
263263
description: errorDetails.insight,
264-
supporting_evidence: [error.stack || error.message]
264+
supporting_evidence: [error.stack || error.message],
265265
}],
266266
validatedHypotheses: [],
267267
ruledOutApproaches: context.attemptedApproaches,
@@ -270,7 +270,7 @@ export class DeepCodeReasonerV2 {
270270
errorType: error.name,
271271
errorCode: errorDetails.code,
272272
errorSource: errorDetails.source,
273-
}
273+
},
274274
};
275275
}
276276

@@ -285,71 +285,71 @@ export class DeepCodeReasonerV2 {
285285
const classification = ErrorClassifier.classify(error);
286286
const nextSteps = ErrorClassifier.getNextSteps(classification);
287287
const message = error.message;
288-
288+
289289
// Map classification to detailed error structure
290290
switch (classification.category) {
291291
case 'api':
292292
return {
293293
description: classification.description,
294294
rootCauses: [{
295295
type: classification.code === 'RATE_LIMIT_ERROR' ? 'performance' : 'configuration',
296-
description: classification.code === 'RATE_LIMIT_ERROR'
296+
description: classification.code === 'RATE_LIMIT_ERROR'
297297
? 'API rate limit or quota exceeded'
298298
: 'Gemini API authentication or configuration issue',
299299
location: { file: 'ConversationalGeminiService.ts', line: 0 },
300-
evidence: [message]
300+
evidence: [message],
301301
}],
302302
nextSteps,
303303
insight: classification.code === 'RATE_LIMIT_ERROR'
304304
? 'The system is making too many API requests in a short time period'
305305
: 'The Gemini API service is not properly configured or authenticated',
306306
code: classification.code,
307-
source: 'external_api'
307+
source: 'external_api',
308308
};
309-
309+
310310
case 'filesystem':
311311
return {
312312
description: classification.description,
313313
rootCauses: [{
314314
type: 'architecture',
315315
description: 'File access or permission issue',
316316
location: { file: 'CodeReader.ts', line: 0 },
317-
evidence: [message]
317+
evidence: [message],
318318
}],
319319
nextSteps,
320320
insight: 'The code reader cannot access required files',
321321
code: classification.code || 'FILE_ACCESS_ERROR',
322-
source: 'filesystem'
322+
source: 'filesystem',
323323
};
324-
324+
325325
case 'session':
326326
return {
327327
description: classification.description,
328328
rootCauses: [{
329329
type: 'architecture',
330330
description: 'Conversation session state issue',
331331
location: { file: 'ConversationManager.ts', line: 0 },
332-
evidence: [message]
332+
evidence: [message],
333333
}],
334334
nextSteps,
335335
insight: 'The conversation session is in an invalid state or does not exist',
336336
code: classification.code || 'SESSION_ERROR',
337-
source: 'internal'
337+
source: 'internal',
338338
};
339-
339+
340340
default:
341341
return {
342342
description: classification.description,
343343
rootCauses: [{
344344
type: 'unknown',
345345
description: error.name || 'Unknown error',
346346
location: { file: 'unknown', line: 0 },
347-
evidence: [message, error.stack || '']
347+
evidence: [message, error.stack || ''],
348348
}],
349349
nextSteps,
350350
insight: 'An unexpected error occurred during deep code analysis',
351351
code: 'UNKNOWN_ERROR',
352-
source: 'unknown'
352+
source: 'unknown',
353353
};
354354
}
355355
}

src/errors/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
export class SessionError extends Error {
66
readonly code: string;
77
readonly sessionId?: string;
8-
8+
99
constructor(message: string, code: string = 'SESSION_ERROR', sessionId?: string) {
1010
super(message);
1111
this.name = 'SessionError';
@@ -18,7 +18,7 @@ export class ApiError extends Error {
1818
readonly code: string;
1919
readonly statusCode?: number;
2020
readonly service: string;
21-
21+
2222
constructor(message: string, code: string = 'API_ERROR', service: string = 'unknown', statusCode?: number) {
2323
super(message);
2424
this.name = 'ApiError';
@@ -32,7 +32,7 @@ export class FileSystemError extends Error {
3232
readonly code: string;
3333
readonly path?: string;
3434
readonly operation?: string;
35-
35+
3636
constructor(message: string, code: string = 'FS_ERROR', path?: string, operation?: string) {
3737
super(message);
3838
this.name = 'FileSystemError';
@@ -44,7 +44,7 @@ export class FileSystemError extends Error {
4444

4545
export class RateLimitError extends ApiError {
4646
readonly retryAfter?: number;
47-
47+
4848
constructor(message: string, service: string = 'gemini', retryAfter?: number) {
4949
super(message, 'RATE_LIMIT_ERROR', service, 429);
5050
this.name = 'RateLimitError';

src/index.ts

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { z } from 'zod';
1111
import * as dotenv from 'dotenv';
1212

1313
import { DeepCodeReasonerV2 } from './analyzers/DeepCodeReasonerV2.js';
14-
import type { ClaudeCodeContext, CodeScope } from './models/types.js';
14+
import type { ClaudeCodeContext } from './models/types.js';
1515
import { ErrorClassifier } from './utils/ErrorClassifier.js';
1616
import { InputValidator } from './utils/InputValidator.js';
1717

@@ -406,10 +406,10 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
406406
switch (name) {
407407
case 'escalate_analysis': {
408408
const parsed = EscalateAnalysisSchema.parse(args);
409-
409+
410410
// Validate and sanitize the Claude context
411411
const validatedContext = InputValidator.validateClaudeContext(parsed.claude_context);
412-
412+
413413
// Override with specific values from the parsed input
414414
const context: ClaudeCodeContext = {
415415
...validatedContext,
@@ -434,7 +434,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
434434

435435
case 'trace_execution_path': {
436436
const parsed = TraceExecutionPathSchema.parse(args);
437-
437+
438438
// Validate the entry point file path
439439
const validatedPath = InputValidator.validateFilePaths([parsed.entry_point.file])[0];
440440
if (!validatedPath) {
@@ -443,7 +443,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
443443
'Invalid entry point file path',
444444
);
445445
}
446-
446+
447447
const result = await deepReasoner.traceExecutionPath(
448448
{ ...parsed.entry_point, file: validatedPath },
449449
parsed.max_depth,
@@ -462,7 +462,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
462462

463463
case 'hypothesis_test': {
464464
const parsed = HypothesisTestSchema.parse(args);
465-
465+
466466
// Validate file paths
467467
const validatedFiles = InputValidator.validateFilePaths(parsed.code_scope.files);
468468
if (validatedFiles.length === 0) {
@@ -471,7 +471,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
471471
'No valid file paths provided',
472472
);
473473
}
474-
474+
475475
const result = await deepReasoner.testHypothesis(
476476
InputValidator.validateString(parsed.hypothesis, 2000),
477477
validatedFiles,
@@ -490,7 +490,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
490490

491491
case 'cross_system_impact': {
492492
const parsed = CrossSystemImpactSchema.parse(args);
493-
493+
494494
// Validate file paths
495495
const validatedFiles = InputValidator.validateFilePaths(parsed.change_scope.files);
496496
if (validatedFiles.length === 0) {
@@ -499,7 +499,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
499499
'No valid file paths provided',
500500
);
501501
}
502-
502+
503503
const result = await deepReasoner.analyzeCrossSystemImpact(
504504
validatedFiles,
505505
parsed.impact_types,
@@ -517,7 +517,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
517517

518518
case 'performance_bottleneck': {
519519
const parsed = PerformanceBottleneckSchema.parse(args);
520-
520+
521521
// Validate the entry point file path
522522
const validatedPath = InputValidator.validateFilePaths([parsed.code_path.entry_point.file])[0];
523523
if (!validatedPath) {
@@ -526,12 +526,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
526526
'Invalid entry point file path',
527527
);
528528
}
529-
529+
530530
const result = await deepReasoner.analyzePerformance(
531531
{ ...parsed.code_path.entry_point, file: validatedPath },
532532
parsed.profile_depth,
533-
parsed.code_path.suspected_issues ?
534-
InputValidator.validateStringArray(parsed.code_path.suspected_issues) :
533+
parsed.code_path.suspected_issues ?
534+
InputValidator.validateStringArray(parsed.code_path.suspected_issues) :
535535
undefined,
536536
);
537537

@@ -547,10 +547,10 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
547547

548548
case 'start_conversation': {
549549
const parsed = StartConversationSchema.parse(args);
550-
550+
551551
// Validate and sanitize the Claude context
552552
const validatedContext = InputValidator.validateClaudeContext(parsed.claude_context);
553-
553+
554554
// Override default budget
555555
const context: ClaudeCodeContext = {
556556
...validatedContext,
@@ -637,30 +637,30 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
637637
`Invalid parameters: ${error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ')}`,
638638
);
639639
}
640-
640+
641641
// Use ErrorClassifier for consistent error handling
642642
if (error instanceof Error) {
643643
const classification = ErrorClassifier.classify(error);
644-
644+
645645
switch (classification.category) {
646646
case 'session':
647647
throw new McpError(
648648
ErrorCode.InvalidRequest,
649649
classification.description,
650650
);
651-
651+
652652
case 'api':
653653
throw new McpError(
654654
ErrorCode.InternalError,
655655
classification.description,
656656
);
657-
657+
658658
case 'filesystem':
659659
throw new McpError(
660660
ErrorCode.InvalidRequest,
661661
classification.description,
662662
);
663-
663+
664664
default:
665665
console.error('Unhandled error in request handler:', error);
666666
throw new McpError(
@@ -669,7 +669,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
669669
);
670670
}
671671
}
672-
672+
673673
throw error;
674674
}
675675
});

src/services/ConversationManager.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,20 +92,20 @@ export class ConversationManager {
9292
acquireLock(sessionId: string): boolean {
9393
const session = this.sessions.get(sessionId);
9494
if (!session) return false;
95-
95+
9696
// Check if session has timed out
9797
if (Date.now() - session.lastActivity > this.SESSION_TIMEOUT_MS) {
9898
session.status = 'abandoned';
9999
return false;
100100
}
101-
101+
102102
// Only acquire lock if session is active
103103
if (session.status === 'active') {
104104
session.status = 'processing';
105105
session.lastActivity = Date.now();
106106
return true;
107107
}
108-
108+
109109
return false;
110110
}
111111

src/services/ConversationalGeminiService.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type {
33
ClaudeCodeContext,
44
DeepAnalysisResult,
55
} from '../models/types.js';
6-
import { SessionError, SessionNotFoundError } from '../errors/index.js';
6+
import { SessionNotFoundError } from '../errors/index.js';
77
import { PromptSanitizer } from '../utils/PromptSanitizer.js';
88

99
export interface ConversationContext {
@@ -107,7 +107,7 @@ export class ConversationalGeminiService {
107107

108108
// Sanitize the incoming message
109109
const sanitizedMessage = PromptSanitizer.sanitizeString(message);
110-
110+
111111
// Check for potential injection attempts
112112
if (PromptSanitizer.containsInjectionAttempt(message)) {
113113
console.warn(`Potential injection attempt in session ${sessionId}:`, message.substring(0, 100));
@@ -329,12 +329,12 @@ Structure your response as JSON with the following format:
329329
const line = parseInt(lineNum);
330330
const start = Math.max(0, line - 3);
331331
const end = Math.min(lines.length, line + 3);
332-
332+
333333
// Use safe formatting for code snippets
334334
const snippet = lines.slice(start, end).join('\n');
335335
enrichedParts.push(PromptSanitizer.formatFileContent(
336336
`${file} (lines ${start + 1}-${end})`,
337-
snippet
337+
snippet,
338338
));
339339
}
340340
}

src/services/GeminiService.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ Provide a detailed execution trace with insights about the actual runtime behavi
361361
}
362362

363363
const userData = {
364-
'Code Files for Analysis': codeFileData.join('\n\n')
364+
'Code Files for Analysis': codeFileData.join('\n\n'),
365365
};
366366

367367
const prompt = PromptSanitizer.createSafePrompt(systemInstructions, userData);
@@ -393,7 +393,7 @@ Focus on both direct and indirect impacts across service boundaries.`;
393393

394394
const userData = {
395395
'Files with Changes': PromptSanitizer.sanitizeStringArray(changeScope),
396-
'Code Files for Analysis': codeFileData.join('\n\n')
396+
'Code Files for Analysis': codeFileData.join('\n\n'),
397397
};
398398

399399
const prompt = PromptSanitizer.createSafePrompt(systemInstructions, userData);
@@ -426,7 +426,7 @@ Provide specific, actionable performance improvements.`;
426426

427427
const userData = {
428428
'Suspected Issues': PromptSanitizer.sanitizeStringArray(suspectedIssues),
429-
'Code Files for Analysis': codeFileData.join('\n\n')
429+
'Code Files for Analysis': codeFileData.join('\n\n'),
430430
};
431431

432432
const prompt = PromptSanitizer.createSafePrompt(systemInstructions, userData);
@@ -460,7 +460,7 @@ Be rigorous and evidence-based in your analysis.`;
460460
const userData = {
461461
'Hypothesis': PromptSanitizer.sanitizeString(hypothesis),
462462
'Test Approach': PromptSanitizer.sanitizeString(testApproach),
463-
'Code Files for Analysis': codeFileData.join('\n\n')
463+
'Code Files for Analysis': codeFileData.join('\n\n'),
464464
};
465465

466466
const prompt = PromptSanitizer.createSafePrompt(systemInstructions, userData);

0 commit comments

Comments
 (0)