@bryan-thompson/inspector-assessment-client 1.25.4 → 1.25.5
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/dist/assets/{OAuthCallback-DE62cdTZ.js → OAuthCallback-Dl4GYls3.js} +1 -1
- package/dist/assets/{OAuthDebugCallback-CWjFdCIE.js → OAuthDebugCallback-BdJ38Z-r.js} +1 -1
- package/dist/assets/{index-Df9Sx1jt.css → index-cHhcEXbr.css} +4 -0
- package/dist/assets/{index-PCQVSwHa.js → index-pfUiTdQb.js} +4 -4
- package/dist/index.html +2 -2
- package/lib/lib/assessment/coreTypes.d.ts +65 -0
- package/lib/lib/assessment/coreTypes.d.ts.map +1 -1
- package/lib/lib/assessment/extendedTypes.d.ts +127 -0
- package/lib/lib/assessment/extendedTypes.d.ts.map +1 -1
- package/lib/lib/assessment/resultTypes.d.ts +45 -0
- package/lib/lib/assessment/resultTypes.d.ts.map +1 -1
- package/lib/services/assessment/AssessmentOrchestrator.d.ts +3 -7
- package/lib/services/assessment/AssessmentOrchestrator.d.ts.map +1 -1
- package/lib/services/assessment/AssessmentOrchestrator.js +13 -2
- package/lib/services/assessment/TestDataGenerator.d.ts +9 -1
- package/lib/services/assessment/TestDataGenerator.d.ts.map +1 -1
- package/lib/services/assessment/TestDataGenerator.js +32 -6
- package/lib/services/assessment/TestScenarioEngine.d.ts +9 -1
- package/lib/services/assessment/TestScenarioEngine.d.ts.map +1 -1
- package/lib/services/assessment/TestScenarioEngine.js +17 -14
- package/lib/services/assessment/config/annotationPatterns.d.ts +3 -1
- package/lib/services/assessment/config/annotationPatterns.d.ts.map +1 -1
- package/lib/services/assessment/config/annotationPatterns.js +5 -2
- package/lib/services/assessment/config/architecturePatterns.d.ts +101 -0
- package/lib/services/assessment/config/architecturePatterns.d.ts.map +1 -0
- package/lib/services/assessment/config/architecturePatterns.js +248 -0
- package/lib/services/assessment/config/performanceConfig.d.ts +122 -0
- package/lib/services/assessment/config/performanceConfig.d.ts.map +1 -0
- package/lib/services/assessment/config/performanceConfig.js +154 -0
- package/lib/services/assessment/config/sanitizationPatterns.d.ts +63 -0
- package/lib/services/assessment/config/sanitizationPatterns.d.ts.map +1 -0
- package/lib/services/assessment/config/sanitizationPatterns.js +223 -0
- package/lib/services/assessment/lib/claudeCodeBridge.d.ts +3 -1
- package/lib/services/assessment/lib/claudeCodeBridge.d.ts.map +1 -1
- package/lib/services/assessment/lib/claudeCodeBridge.js +5 -3
- package/lib/services/assessment/lib/concurrencyLimit.d.ts +6 -2
- package/lib/services/assessment/lib/concurrencyLimit.d.ts.map +1 -1
- package/lib/services/assessment/lib/concurrencyLimit.js +13 -6
- package/lib/services/assessment/lib/errors.d.ts +90 -0
- package/lib/services/assessment/lib/errors.d.ts.map +1 -0
- package/lib/services/assessment/lib/errors.js +136 -0
- package/lib/services/assessment/lib/timeoutUtils.d.ts +69 -0
- package/lib/services/assessment/lib/timeoutUtils.d.ts.map +1 -0
- package/lib/services/assessment/lib/timeoutUtils.js +103 -0
- package/lib/services/assessment/modules/BaseAssessor.d.ts +43 -8
- package/lib/services/assessment/modules/BaseAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/BaseAssessor.js +103 -34
- package/lib/services/assessment/modules/DeveloperExperienceAssessor.d.ts +38 -1
- package/lib/services/assessment/modules/DeveloperExperienceAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/DeveloperExperienceAssessor.js +185 -19
- package/lib/services/assessment/modules/DocumentationAssessor.d.ts +5 -0
- package/lib/services/assessment/modules/DocumentationAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/DocumentationAssessor.js +11 -0
- package/lib/services/assessment/modules/ErrorHandlingAssessor.js +1 -1
- package/lib/services/assessment/modules/FunctionalityAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/FunctionalityAssessor.js +6 -3
- package/lib/services/assessment/modules/MCPSpecComplianceAssessor.d.ts +3 -0
- package/lib/services/assessment/modules/MCPSpecComplianceAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/MCPSpecComplianceAssessor.js +14 -2
- package/lib/services/assessment/modules/ManifestValidationAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/ManifestValidationAssessor.js +7 -2
- package/lib/services/assessment/modules/PromptAssessor.d.ts +1 -0
- package/lib/services/assessment/modules/PromptAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/PromptAssessor.js +26 -16
- package/lib/services/assessment/modules/ProtocolComplianceAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/ProtocolComplianceAssessor.js +6 -2
- package/lib/services/assessment/modules/ProtocolConformanceAssessor.d.ts +5 -0
- package/lib/services/assessment/modules/ProtocolConformanceAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/ProtocolConformanceAssessor.js +15 -0
- package/lib/services/assessment/modules/ResourceAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/ResourceAssessor.js +8 -2
- package/lib/services/assessment/modules/SecurityAssessor.d.ts +3 -171
- package/lib/services/assessment/modules/SecurityAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/SecurityAssessor.js +25 -1480
- package/lib/services/assessment/modules/ToolAnnotationAssessor.d.ts +27 -28
- package/lib/services/assessment/modules/ToolAnnotationAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/ToolAnnotationAssessor.js +340 -863
- package/lib/services/assessment/modules/UsabilityAssessor.d.ts +5 -0
- package/lib/services/assessment/modules/UsabilityAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/UsabilityAssessor.js +11 -0
- package/lib/services/assessment/modules/annotations/AnnotationDeceptionDetector.d.ts +57 -0
- package/lib/services/assessment/modules/annotations/AnnotationDeceptionDetector.d.ts.map +1 -0
- package/lib/services/assessment/modules/annotations/AnnotationDeceptionDetector.js +176 -0
- package/lib/services/assessment/modules/annotations/ArchitectureDetector.d.ts +67 -0
- package/lib/services/assessment/modules/annotations/ArchitectureDetector.d.ts.map +1 -0
- package/lib/services/assessment/modules/annotations/ArchitectureDetector.js +239 -0
- package/lib/services/assessment/modules/annotations/BehaviorInference.d.ts +46 -0
- package/lib/services/assessment/modules/annotations/BehaviorInference.d.ts.map +1 -0
- package/lib/services/assessment/modules/annotations/BehaviorInference.js +394 -0
- package/lib/services/assessment/modules/annotations/DescriptionAnalyzer.d.ts +64 -0
- package/lib/services/assessment/modules/annotations/DescriptionAnalyzer.d.ts.map +1 -0
- package/lib/services/assessment/modules/annotations/DescriptionAnalyzer.js +304 -0
- package/lib/services/assessment/modules/annotations/DescriptionPoisoningDetector.d.ts +43 -0
- package/lib/services/assessment/modules/annotations/DescriptionPoisoningDetector.d.ts.map +1 -0
- package/lib/services/assessment/modules/annotations/DescriptionPoisoningDetector.js +276 -0
- package/lib/services/assessment/modules/annotations/SchemaAnalyzer.d.ts +122 -0
- package/lib/services/assessment/modules/annotations/SchemaAnalyzer.d.ts.map +1 -0
- package/lib/services/assessment/modules/annotations/SchemaAnalyzer.js +388 -0
- package/lib/services/assessment/modules/annotations/index.d.ts +13 -0
- package/lib/services/assessment/modules/annotations/index.d.ts.map +1 -0
- package/lib/services/assessment/modules/annotations/index.js +15 -0
- package/lib/services/assessment/modules/index.d.ts +10 -0
- package/lib/services/assessment/modules/index.d.ts.map +1 -1
- package/lib/services/assessment/modules/index.js +13 -0
- package/lib/services/assessment/modules/securityTests/SanitizationDetector.d.ts +125 -0
- package/lib/services/assessment/modules/securityTests/SanitizationDetector.d.ts.map +1 -0
- package/lib/services/assessment/modules/securityTests/SanitizationDetector.js +345 -0
- package/lib/services/assessment/modules/securityTests/SecurityPayloadGenerator.d.ts +33 -0
- package/lib/services/assessment/modules/securityTests/SecurityPayloadGenerator.d.ts.map +1 -0
- package/lib/services/assessment/modules/securityTests/SecurityPayloadGenerator.js +128 -0
- package/lib/services/assessment/modules/securityTests/SecurityPayloadTester.d.ts +67 -0
- package/lib/services/assessment/modules/securityTests/SecurityPayloadTester.d.ts.map +1 -0
- package/lib/services/assessment/modules/securityTests/SecurityPayloadTester.js +372 -0
- package/lib/services/assessment/modules/securityTests/SecurityResponseAnalyzer.d.ts +178 -0
- package/lib/services/assessment/modules/securityTests/SecurityResponseAnalyzer.d.ts.map +1 -0
- package/lib/services/assessment/modules/securityTests/SecurityResponseAnalyzer.js +1207 -0
- package/lib/services/assessment/modules/securityTests/index.d.ts +8 -0
- package/lib/services/assessment/modules/securityTests/index.d.ts.map +1 -0
- package/lib/services/assessment/modules/securityTests/index.js +7 -0
- package/lib/services/assessment/tool-classifier-patterns.d.ts +1 -0
- package/lib/services/assessment/tool-classifier-patterns.d.ts.map +1 -1
- package/lib/services/assessment/tool-classifier-patterns.js +17 -0
- package/package.json +1 -1
|
@@ -3,10 +3,17 @@
|
|
|
3
3
|
* Provides common functionality for all assessment modules
|
|
4
4
|
*/
|
|
5
5
|
import { createLogger, DEFAULT_LOGGING_CONFIG } from "../lib/logger.js";
|
|
6
|
+
import { ErrorCategory, categorizeError, } from "../lib/errors.js";
|
|
7
|
+
import { executeWithTimeout as executeWithTimeoutUtil } from "../lib/timeoutUtils.js";
|
|
6
8
|
export class BaseAssessor {
|
|
7
9
|
config;
|
|
8
10
|
logger;
|
|
9
11
|
testCount = 0;
|
|
12
|
+
// Track deprecation warnings to emit only once per instance
|
|
13
|
+
deprecationWarningsEmitted = {
|
|
14
|
+
log: false,
|
|
15
|
+
logError: false,
|
|
16
|
+
};
|
|
10
17
|
constructor(config) {
|
|
11
18
|
this.config = config;
|
|
12
19
|
// Create logger from config, using class name as prefix
|
|
@@ -27,18 +34,70 @@ export class BaseAssessor {
|
|
|
27
34
|
}
|
|
28
35
|
/**
|
|
29
36
|
* Log assessment progress
|
|
30
|
-
* @deprecated Use this.logger.info() directly for structured logging with context
|
|
37
|
+
* @deprecated Use this.logger.info() directly for structured logging with context. Will be removed in v2.0.0.
|
|
31
38
|
*/
|
|
32
39
|
log(message) {
|
|
40
|
+
if (!this.deprecationWarningsEmitted.log) {
|
|
41
|
+
this.logger.warn("BaseAssessor.log() is deprecated. Use this.logger.info() instead. " +
|
|
42
|
+
"This method will be removed in v2.0.0.");
|
|
43
|
+
this.deprecationWarningsEmitted.log = true;
|
|
44
|
+
}
|
|
33
45
|
this.logger.info(message);
|
|
34
46
|
}
|
|
35
47
|
/**
|
|
36
|
-
* Log error
|
|
37
|
-
* @deprecated Use this.logger.error() directly for structured logging with context
|
|
48
|
+
* Log error with optional context
|
|
49
|
+
* @deprecated Use this.logger.error() directly for structured logging with context. Will be removed in v2.0.0.
|
|
50
|
+
*
|
|
51
|
+
* @param message - Description of what operation failed
|
|
52
|
+
* @param error - The error that occurred (optional)
|
|
38
53
|
*/
|
|
39
54
|
logError(message, error) {
|
|
55
|
+
if (!this.deprecationWarningsEmitted.logError) {
|
|
56
|
+
this.logger.warn("BaseAssessor.logError() is deprecated. Use this.logger.error() instead. " +
|
|
57
|
+
"This method will be removed in v2.0.0.");
|
|
58
|
+
this.deprecationWarningsEmitted.logError = true;
|
|
59
|
+
}
|
|
40
60
|
this.logger.error(message, error ? { error: String(error) } : undefined);
|
|
41
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Handle an error with logging and structured result
|
|
64
|
+
*
|
|
65
|
+
* Use this method in catch blocks to ensure consistent error handling:
|
|
66
|
+
* 1. Logs the error with context
|
|
67
|
+
* 2. Categorizes the error automatically
|
|
68
|
+
* 3. Returns a structured result with error info
|
|
69
|
+
*
|
|
70
|
+
* @param error - The caught error
|
|
71
|
+
* @param context - Description of what operation failed
|
|
72
|
+
* @param defaults - Default values to merge into result
|
|
73
|
+
* @returns A result object with error information
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* try {
|
|
77
|
+
* const result = await this.callTool(tool);
|
|
78
|
+
* return { passed: true, result };
|
|
79
|
+
* } catch (error) {
|
|
80
|
+
* return this.handleError(error, `Failed to call tool ${tool.name}`, { passed: false });
|
|
81
|
+
* }
|
|
82
|
+
*/
|
|
83
|
+
handleError(error, context, defaults = {}) {
|
|
84
|
+
const category = categorizeError(error);
|
|
85
|
+
const message = this.extractErrorMessage(error);
|
|
86
|
+
this.logger.error(context, {
|
|
87
|
+
error: message,
|
|
88
|
+
category,
|
|
89
|
+
});
|
|
90
|
+
const errorInfo = {
|
|
91
|
+
message,
|
|
92
|
+
code: category,
|
|
93
|
+
recoverable: category !== ErrorCategory.CONNECTION,
|
|
94
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
95
|
+
};
|
|
96
|
+
return {
|
|
97
|
+
...defaults,
|
|
98
|
+
error: errorInfo,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
42
101
|
/**
|
|
43
102
|
* Get test count for this assessor
|
|
44
103
|
*/
|
|
@@ -64,13 +123,21 @@ export class BaseAssessor {
|
|
|
64
123
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
65
124
|
}
|
|
66
125
|
/**
|
|
67
|
-
* Execute with timeout
|
|
126
|
+
* Execute with timeout and proper cleanup.
|
|
127
|
+
*
|
|
128
|
+
* Uses AbortController-based timeout handling that clears the timer
|
|
129
|
+
* when the operation completes, preventing timer leaks.
|
|
130
|
+
*
|
|
131
|
+
* @param promise - The promise to execute
|
|
132
|
+
* @param timeoutMs - Timeout in milliseconds (defaults to config.testTimeout)
|
|
133
|
+
* @returns The result of the promise
|
|
134
|
+
* @throws Error if operation times out
|
|
68
135
|
*/
|
|
69
136
|
async executeWithTimeout(promise, timeoutMs = this.config.testTimeout) {
|
|
70
|
-
|
|
71
|
-
|
|
137
|
+
return executeWithTimeoutUtil(promise, {
|
|
138
|
+
timeoutMs,
|
|
139
|
+
errorMessage: `Operation timed out after ${timeoutMs}ms`,
|
|
72
140
|
});
|
|
73
|
-
return Promise.race([promise, timeoutPromise]);
|
|
74
141
|
}
|
|
75
142
|
/**
|
|
76
143
|
* Safe JSON parse with error handling
|
|
@@ -90,17 +157,19 @@ export class BaseAssessor {
|
|
|
90
157
|
extractErrorMessage(error) {
|
|
91
158
|
if (typeof error === "string")
|
|
92
159
|
return error;
|
|
93
|
-
if (error
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
.join(" ");
|
|
160
|
+
if (error && typeof error === "object") {
|
|
161
|
+
const err = error;
|
|
162
|
+
if (err.message && typeof err.message === "string")
|
|
163
|
+
return err.message;
|
|
164
|
+
if (err.error)
|
|
165
|
+
return this.extractErrorMessage(err.error);
|
|
166
|
+
if (err.content) {
|
|
167
|
+
if (Array.isArray(err.content)) {
|
|
168
|
+
return err.content.map((c) => c.text || "").join(" ");
|
|
169
|
+
}
|
|
170
|
+
if (typeof err.content === "string")
|
|
171
|
+
return err.content;
|
|
102
172
|
}
|
|
103
|
-
return error.content;
|
|
104
173
|
}
|
|
105
174
|
return JSON.stringify(error);
|
|
106
175
|
}
|
|
@@ -112,10 +181,11 @@ export class BaseAssessor {
|
|
|
112
181
|
* @param strictMode - If true, only check explicit error indicators (default: false)
|
|
113
182
|
*/
|
|
114
183
|
isErrorResponse(response, strictMode = false) {
|
|
115
|
-
if (!response)
|
|
184
|
+
if (!response || typeof response !== "object")
|
|
116
185
|
return false;
|
|
186
|
+
const resp = response;
|
|
117
187
|
// Check explicit error flag first (always check these)
|
|
118
|
-
if (
|
|
188
|
+
if (resp.isError === true || resp.error !== undefined) {
|
|
119
189
|
return true;
|
|
120
190
|
}
|
|
121
191
|
// In strict mode, only rely on explicit error indicators
|
|
@@ -125,9 +195,9 @@ export class BaseAssessor {
|
|
|
125
195
|
}
|
|
126
196
|
// In non-strict mode, also check content for error patterns
|
|
127
197
|
// Used by ErrorHandlingAssessor where we're deliberately triggering errors
|
|
128
|
-
if (
|
|
129
|
-
if (typeof
|
|
130
|
-
const lower =
|
|
198
|
+
if (resp.content) {
|
|
199
|
+
if (typeof resp.content === "string") {
|
|
200
|
+
const lower = resp.content.toLowerCase();
|
|
131
201
|
// Only flag if error appears at start or with strong indicators
|
|
132
202
|
return (lower.startsWith("error:") ||
|
|
133
203
|
lower.startsWith("error ") ||
|
|
@@ -135,9 +205,9 @@ export class BaseAssessor {
|
|
|
135
205
|
lower.includes("failed to") ||
|
|
136
206
|
lower.includes("exception:"));
|
|
137
207
|
}
|
|
138
|
-
else if (Array.isArray(
|
|
208
|
+
else if (Array.isArray(resp.content)) {
|
|
139
209
|
// Check if any text content starts with error indicators
|
|
140
|
-
return
|
|
210
|
+
return resp.content.some((c) => {
|
|
141
211
|
if (c.type !== "text" || !c.text)
|
|
142
212
|
return false;
|
|
143
213
|
const lower = c.text.toLowerCase();
|
|
@@ -155,23 +225,22 @@ export class BaseAssessor {
|
|
|
155
225
|
* Extract error information from a response
|
|
156
226
|
*/
|
|
157
227
|
extractErrorInfo(response) {
|
|
158
|
-
if (!response)
|
|
228
|
+
if (!response || typeof response !== "object")
|
|
159
229
|
return {};
|
|
230
|
+
const resp = response;
|
|
160
231
|
// Extract text from content array if present
|
|
161
232
|
let contentText;
|
|
162
|
-
if (Array.isArray(
|
|
163
|
-
const textContent =
|
|
233
|
+
if (Array.isArray(resp.content)) {
|
|
234
|
+
const textContent = resp.content.find((c) => c.type === "text");
|
|
164
235
|
contentText = textContent?.text;
|
|
165
236
|
}
|
|
166
|
-
else if (typeof
|
|
167
|
-
contentText =
|
|
237
|
+
else if (typeof resp.content === "string") {
|
|
238
|
+
contentText = resp.content;
|
|
168
239
|
}
|
|
240
|
+
const error = resp.error;
|
|
169
241
|
return {
|
|
170
|
-
code:
|
|
171
|
-
message:
|
|
172
|
-
response.message ||
|
|
173
|
-
response.error?.message ||
|
|
174
|
-
contentText,
|
|
242
|
+
code: (resp.errorCode ?? resp.code ?? error?.code),
|
|
243
|
+
message: (resp.errorMessage ?? resp.message ?? error?.message) || contentText,
|
|
175
244
|
};
|
|
176
245
|
}
|
|
177
246
|
}
|
|
@@ -51,7 +51,44 @@ export declare class DeveloperExperienceAssessor extends BaseAssessor<DeveloperE
|
|
|
51
51
|
private extractSection;
|
|
52
52
|
private extractSectionHeadings;
|
|
53
53
|
private classifyCodeExample;
|
|
54
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Assess documentation quality using Issue #55 point-based scoring
|
|
56
|
+
* Max 100 points: README (30), Install (20), Config (20), Examples (20), License (10)
|
|
57
|
+
*/
|
|
58
|
+
private assessDocumentationQuality;
|
|
59
|
+
/**
|
|
60
|
+
* Determine README quality tier based on size
|
|
61
|
+
* - minimal: <5KB
|
|
62
|
+
* - adequate: 5KB-15KB
|
|
63
|
+
* - comprehensive: >15KB
|
|
64
|
+
*/
|
|
65
|
+
private determineReadmeQuality;
|
|
66
|
+
/**
|
|
67
|
+
* Calculate point-based quality score per Issue #55
|
|
68
|
+
* Max 100 points:
|
|
69
|
+
* - README exists: +10
|
|
70
|
+
* - README >5KB: +10 (adequate)
|
|
71
|
+
* - README >15KB: +10 more (comprehensive = +20 total)
|
|
72
|
+
* - Installation section: +20
|
|
73
|
+
* - Configuration section: +20
|
|
74
|
+
* - Examples present: +20
|
|
75
|
+
* - License file: +10
|
|
76
|
+
*/
|
|
77
|
+
private calculateQualityScore;
|
|
78
|
+
/**
|
|
79
|
+
* Check for configuration/environment section
|
|
80
|
+
* Looks for: configuration, config, environment, env vars, .env
|
|
81
|
+
*/
|
|
82
|
+
private checkConfigurationSection;
|
|
83
|
+
/**
|
|
84
|
+
* Detect license presence from context
|
|
85
|
+
* Checks sourceCodeFiles for LICENSE/LICENSE.md or README for license section
|
|
86
|
+
*/
|
|
87
|
+
private detectLicense;
|
|
88
|
+
/**
|
|
89
|
+
* Detect license type (MIT, Apache-2.0, GPL, BSD, etc.)
|
|
90
|
+
*/
|
|
91
|
+
private detectLicenseType;
|
|
55
92
|
private analyzeUsability;
|
|
56
93
|
private analyzeNamingConvention;
|
|
57
94
|
private analyzeParameterClarity;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeveloperExperienceAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/DeveloperExperienceAssessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAEhB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"DeveloperExperienceAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/DeveloperExperienceAssessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAEhB,gBAAgB,EAIjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C,yCAAyC;IACzC,aAAa,EAAE,oBAAoB,CAAC;IACpC,qCAAqC;IACrC,SAAS,EAAE,gBAAgB,CAAC;IAC5B,gDAAgD;IAChD,MAAM,EAAE,gBAAgB,CAAC;IACzB,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,iDAAiD;IACjD,MAAM,EAAE;QACN,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,qBAAa,2BAA4B,SAAQ,YAAY,CAAC,6BAA6B,CAAC;IACpF,MAAM,CACV,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,6BAA6B,CAAC;IAsEzC,OAAO,CAAC,oBAAoB;IAmH5B,OAAO,CAAC,yBAAyB;IA4CjC,OAAO,CAAC,wBAAwB;IAiBhC,OAAO,CAAC,sBAAsB;IA8B9B,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,mBAAmB;IAoB3B,OAAO,CAAC,mBAAmB;IAwC3B,OAAO,CAAC,wBAAwB;IAahC,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,sBAAsB;IAY9B,OAAO,CAAC,mBAAmB;IA6B3B;;;OAGG;IACH,OAAO,CAAC,0BAA0B;IAkBlC;;;;;OAKG;IACH,OAAO,CAAC,sBAAsB;IAW9B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,qBAAqB;IAgC7B;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAgBjC;;;OAGG;IACH,OAAO,CAAC,aAAa;IAoBrB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAsEzB,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,uBAAuB;IAoC/B,OAAO,CAAC,uBAAuB;IAsC/B,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,kBAAkB;IAsC1B,OAAO,CAAC,iBAAiB;IAiCzB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,uBAAuB;IAgB/B,OAAO,CAAC,sBAAsB;IAM9B,OAAO,CAAC,mBAAmB;IAyC3B,OAAO,CAAC,uBAAuB;CAmDhC"}
|
|
@@ -16,20 +16,28 @@ import { BaseAssessor } from "./BaseAssessor.js";
|
|
|
16
16
|
export class DeveloperExperienceAssessor extends BaseAssessor {
|
|
17
17
|
async assess(context) {
|
|
18
18
|
this.log("Starting developer experience assessment");
|
|
19
|
+
const readmeContent = context.readmeContent || "";
|
|
19
20
|
// Assess documentation
|
|
20
|
-
const documentationMetrics = this.analyzeDocumentation(
|
|
21
|
-
|
|
21
|
+
const documentationMetrics = this.analyzeDocumentation(readmeContent, context.tools, "verbose");
|
|
22
|
+
// Issue #55: Add quality scoring
|
|
23
|
+
const { checks: qualityChecks, score: qualityScore } = this.assessDocumentationQuality(readmeContent, context);
|
|
24
|
+
// Add quality data to metrics
|
|
25
|
+
documentationMetrics.qualityChecks = qualityChecks;
|
|
26
|
+
documentationMetrics.qualityScore = qualityScore;
|
|
27
|
+
documentationMetrics.readmeSizeBytes = Buffer.byteLength(readmeContent, "utf8");
|
|
28
|
+
// Use quality score for documentation scoring (Issue #55)
|
|
29
|
+
const documentationScore = qualityScore.total;
|
|
22
30
|
// Assess usability
|
|
23
31
|
const usabilityMetrics = this.analyzeUsability(context.tools);
|
|
24
32
|
const usabilityScore = this.calculateUsabilityScore(usabilityMetrics);
|
|
25
|
-
// Calculate overall score (weighted average)
|
|
33
|
+
// Calculate overall score (weighted average: 60% docs, 40% usability)
|
|
26
34
|
const overallScore = Math.round(documentationScore * 0.6 + usabilityScore * 0.4);
|
|
27
|
-
// Determine status
|
|
35
|
+
// Determine status using Issue #55 thresholds
|
|
28
36
|
const status = this.determineOverallStatus(overallScore);
|
|
29
37
|
// Generate explanation and recommendations
|
|
30
38
|
const explanation = this.generateExplanation(documentationMetrics, usabilityMetrics, context.tools);
|
|
31
39
|
const recommendations = this.generateRecommendations(documentationMetrics, usabilityMetrics);
|
|
32
|
-
this.testCount =
|
|
40
|
+
this.testCount = 15; // Documentation (5) + Quality (6) + Usability (4) checks
|
|
33
41
|
return {
|
|
34
42
|
documentation: documentationMetrics,
|
|
35
43
|
usability: usabilityMetrics,
|
|
@@ -321,20 +329,178 @@ export class DeveloperExperienceAssessor extends BaseAssessor {
|
|
|
321
329
|
}
|
|
322
330
|
return "functional";
|
|
323
331
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
332
|
+
// ============================================================================
|
|
333
|
+
// Issue #55: Documentation Quality Scoring
|
|
334
|
+
// ============================================================================
|
|
335
|
+
/**
|
|
336
|
+
* Assess documentation quality using Issue #55 point-based scoring
|
|
337
|
+
* Max 100 points: README (30), Install (20), Config (20), Examples (20), License (10)
|
|
338
|
+
*/
|
|
339
|
+
assessDocumentationQuality(content, context) {
|
|
340
|
+
const checks = {
|
|
341
|
+
hasReadme: content.length > 0,
|
|
342
|
+
readmeQuality: this.determineReadmeQuality(content),
|
|
343
|
+
hasInstallation: this.checkInstallInstructions(content),
|
|
344
|
+
hasConfiguration: this.checkConfigurationSection(content),
|
|
345
|
+
hasExamples: this.checkUsageGuide(content),
|
|
346
|
+
hasLicense: this.detectLicense(context),
|
|
347
|
+
licenseType: this.detectLicenseType(context),
|
|
348
|
+
};
|
|
349
|
+
const score = this.calculateQualityScore(checks, content);
|
|
350
|
+
return { checks, score };
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Determine README quality tier based on size
|
|
354
|
+
* - minimal: <5KB
|
|
355
|
+
* - adequate: 5KB-15KB
|
|
356
|
+
* - comprehensive: >15KB
|
|
357
|
+
*/
|
|
358
|
+
determineReadmeQuality(content) {
|
|
359
|
+
const sizeBytes = Buffer.byteLength(content, "utf8");
|
|
360
|
+
const sizeKB = sizeBytes / 1024;
|
|
361
|
+
if (sizeKB > 15)
|
|
362
|
+
return "comprehensive";
|
|
363
|
+
if (sizeKB > 5)
|
|
364
|
+
return "adequate";
|
|
365
|
+
return "minimal";
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Calculate point-based quality score per Issue #55
|
|
369
|
+
* Max 100 points:
|
|
370
|
+
* - README exists: +10
|
|
371
|
+
* - README >5KB: +10 (adequate)
|
|
372
|
+
* - README >15KB: +10 more (comprehensive = +20 total)
|
|
373
|
+
* - Installation section: +20
|
|
374
|
+
* - Configuration section: +20
|
|
375
|
+
* - Examples present: +20
|
|
376
|
+
* - License file: +10
|
|
377
|
+
*/
|
|
378
|
+
calculateQualityScore(checks, content) {
|
|
379
|
+
const sizeBytes = Buffer.byteLength(content, "utf8");
|
|
380
|
+
const sizeKB = sizeBytes / 1024;
|
|
381
|
+
// Calculate README size bonus
|
|
382
|
+
let readmeComprehensive = 0;
|
|
383
|
+
if (checks.hasReadme) {
|
|
384
|
+
if (sizeKB > 15) {
|
|
385
|
+
readmeComprehensive = 20; // comprehensive: +10 + +10
|
|
386
|
+
}
|
|
387
|
+
else if (sizeKB > 5) {
|
|
388
|
+
readmeComprehensive = 10; // adequate: +10
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
const breakdown = {
|
|
392
|
+
readmeExists: checks.hasReadme ? 10 : 0,
|
|
393
|
+
readmeComprehensive,
|
|
394
|
+
installation: checks.hasInstallation ? 20 : 0,
|
|
395
|
+
configuration: checks.hasConfiguration ? 20 : 0,
|
|
396
|
+
examples: checks.hasExamples ? 20 : 0,
|
|
397
|
+
license: checks.hasLicense ? 10 : 0,
|
|
398
|
+
};
|
|
399
|
+
return {
|
|
400
|
+
total: Object.values(breakdown).reduce((sum, v) => sum + v, 0),
|
|
401
|
+
breakdown,
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Check for configuration/environment section
|
|
406
|
+
* Looks for: configuration, config, environment, env vars, .env
|
|
407
|
+
*/
|
|
408
|
+
checkConfigurationSection(content) {
|
|
409
|
+
const configKeywords = [
|
|
410
|
+
"configuration",
|
|
411
|
+
"config",
|
|
412
|
+
"environment variable",
|
|
413
|
+
"env var",
|
|
414
|
+
".env",
|
|
415
|
+
"api key",
|
|
416
|
+
"api_key",
|
|
417
|
+
"apikey",
|
|
418
|
+
"setup",
|
|
419
|
+
];
|
|
420
|
+
const contentLower = content.toLowerCase();
|
|
421
|
+
return configKeywords.some((keyword) => contentLower.includes(keyword));
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Detect license presence from context
|
|
425
|
+
* Checks sourceCodeFiles for LICENSE/LICENSE.md or README for license section
|
|
426
|
+
*/
|
|
427
|
+
detectLicense(context) {
|
|
428
|
+
// Check source code files if available
|
|
429
|
+
if (context.sourceCodeFiles) {
|
|
430
|
+
const licenseFiles = [
|
|
431
|
+
"LICENSE",
|
|
432
|
+
"LICENSE.md",
|
|
433
|
+
"LICENSE.txt",
|
|
434
|
+
"LICENCE",
|
|
435
|
+
"LICENCE.md",
|
|
436
|
+
];
|
|
437
|
+
for (const file of licenseFiles) {
|
|
438
|
+
if (context.sourceCodeFiles.has(file))
|
|
439
|
+
return true;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
// Fallback: check README for license section
|
|
443
|
+
const content = context.readmeContent || "";
|
|
444
|
+
return /^#+\s*licen[sc]e/im.test(content);
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Detect license type (MIT, Apache-2.0, GPL, BSD, etc.)
|
|
448
|
+
*/
|
|
449
|
+
detectLicenseType(context) {
|
|
450
|
+
if (!context.sourceCodeFiles)
|
|
451
|
+
return undefined;
|
|
452
|
+
// Try common license file names
|
|
453
|
+
const licenseFiles = [
|
|
454
|
+
"LICENSE",
|
|
455
|
+
"LICENSE.md",
|
|
456
|
+
"LICENSE.txt",
|
|
457
|
+
"LICENCE",
|
|
458
|
+
"LICENCE.md",
|
|
459
|
+
];
|
|
460
|
+
let licenseContent;
|
|
461
|
+
for (const file of licenseFiles) {
|
|
462
|
+
if (context.sourceCodeFiles.has(file)) {
|
|
463
|
+
licenseContent = context.sourceCodeFiles.get(file);
|
|
464
|
+
break;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
if (!licenseContent)
|
|
468
|
+
return undefined;
|
|
469
|
+
// Simple license detection patterns
|
|
470
|
+
if (licenseContent.includes("MIT License") ||
|
|
471
|
+
licenseContent.includes("Permission is hereby granted, free of charge")) {
|
|
472
|
+
return "MIT";
|
|
473
|
+
}
|
|
474
|
+
if (licenseContent.includes("Apache License") &&
|
|
475
|
+
licenseContent.includes("2.0")) {
|
|
476
|
+
return "Apache-2.0";
|
|
477
|
+
}
|
|
478
|
+
if (licenseContent.includes("GNU GENERAL PUBLIC LICENSE")) {
|
|
479
|
+
if (licenseContent.includes("Version 3"))
|
|
480
|
+
return "GPL-3.0";
|
|
481
|
+
if (licenseContent.includes("Version 2"))
|
|
482
|
+
return "GPL-2.0";
|
|
483
|
+
return "GPL";
|
|
484
|
+
}
|
|
485
|
+
if (licenseContent.includes("BSD")) {
|
|
486
|
+
if (licenseContent.includes("3-Clause") || licenseContent.includes("New"))
|
|
487
|
+
return "BSD-3-Clause";
|
|
488
|
+
if (licenseContent.includes("2-Clause") ||
|
|
489
|
+
licenseContent.includes("Simplified"))
|
|
490
|
+
return "BSD-2-Clause";
|
|
491
|
+
return "BSD";
|
|
492
|
+
}
|
|
493
|
+
if (licenseContent.includes("ISC License")) {
|
|
494
|
+
return "ISC";
|
|
495
|
+
}
|
|
496
|
+
if (licenseContent.includes("Mozilla Public License")) {
|
|
497
|
+
return "MPL-2.0";
|
|
498
|
+
}
|
|
499
|
+
if (licenseContent.includes("UNLICENSE") ||
|
|
500
|
+
licenseContent.includes("unlicense")) {
|
|
501
|
+
return "Unlicense";
|
|
502
|
+
}
|
|
503
|
+
return "Unknown";
|
|
338
504
|
}
|
|
339
505
|
// ============================================================================
|
|
340
506
|
// Usability Analysis (from UsabilityAssessor)
|
|
@@ -3,9 +3,14 @@
|
|
|
3
3
|
* Evaluates documentation quality and completeness
|
|
4
4
|
*/
|
|
5
5
|
import { DocumentationAssessment } from "../../../lib/assessmentTypes.js";
|
|
6
|
+
import { AssessmentConfiguration } from "../../../lib/assessment/configTypes.js";
|
|
6
7
|
import { BaseAssessor } from "./BaseAssessor.js";
|
|
7
8
|
import { AssessmentContext } from "../AssessmentOrchestrator.js";
|
|
9
|
+
/**
|
|
10
|
+
* @deprecated Use DeveloperExperienceAssessor instead. Will be removed in v2.0.0.
|
|
11
|
+
*/
|
|
8
12
|
export declare class DocumentationAssessor extends BaseAssessor {
|
|
13
|
+
constructor(config: AssessmentConfiguration);
|
|
9
14
|
assess(context: AssessmentContext): Promise<DocumentationAssessment>;
|
|
10
15
|
private analyzeDocumentation;
|
|
11
16
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocumentationAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/DocumentationAssessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,uBAAuB,EAKxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,qBAAa,qBAAsB,SAAQ,YAAY;
|
|
1
|
+
{"version":3,"file":"DocumentationAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/DocumentationAssessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,uBAAuB,EAKxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,YAAY;gBACzC,MAAM,EAAE,uBAAuB;IAYrC,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAyC1E,OAAO,CAAC,oBAAoB;IAuJ5B;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAuEjC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAiBhC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAmC9B;;OAEG;IACH,OAAO,CAAC,aAAa;IAKrB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAqB3B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IA4C3B,OAAO,CAAC,wBAAwB;IAchC,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,cAAc;IAUtB;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAY9B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IA4B3B,OAAO,CAAC,4BAA4B;IAmBpC,OAAO,CAAC,mBAAmB;IAyB3B,OAAO,CAAC,uBAAuB;CA+BhC"}
|
|
@@ -3,7 +3,18 @@
|
|
|
3
3
|
* Evaluates documentation quality and completeness
|
|
4
4
|
*/
|
|
5
5
|
import { BaseAssessor } from "./BaseAssessor.js";
|
|
6
|
+
/**
|
|
7
|
+
* @deprecated Use DeveloperExperienceAssessor instead. Will be removed in v2.0.0.
|
|
8
|
+
*/
|
|
6
9
|
export class DocumentationAssessor extends BaseAssessor {
|
|
10
|
+
constructor(config) {
|
|
11
|
+
super(config);
|
|
12
|
+
this.logger.warn("DocumentationAssessor is deprecated. Use DeveloperExperienceAssessor instead. " +
|
|
13
|
+
"This module will be removed in v2.0.0.", {
|
|
14
|
+
module: "DocumentationAssessor",
|
|
15
|
+
replacement: "DeveloperExperienceAssessor",
|
|
16
|
+
});
|
|
17
|
+
}
|
|
7
18
|
async assess(context) {
|
|
8
19
|
this.log("Starting documentation assessment");
|
|
9
20
|
const readmeContent = context.readmeContent || "";
|
|
@@ -13,7 +13,7 @@ export class ErrorHandlingAssessor extends BaseAssessor {
|
|
|
13
13
|
const toolsToTest = this.selectToolsForTesting(context.tools);
|
|
14
14
|
// Parallel tool testing with concurrency limit
|
|
15
15
|
const concurrency = this.config.maxParallelTests ?? 5;
|
|
16
|
-
const limit = createConcurrencyLimit(concurrency);
|
|
16
|
+
const limit = createConcurrencyLimit(concurrency, this.logger);
|
|
17
17
|
this.log(`Testing ${toolsToTest.length} tools for error handling with concurrency limit of ${concurrency}`);
|
|
18
18
|
const allToolTests = await Promise.all(toolsToTest.map((tool) => limit(async () => {
|
|
19
19
|
const toolTests = await this.testToolErrorHandling(tool, context.callTool);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FunctionalityAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/FunctionalityAssessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,uBAAuB,EAGxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"FunctionalityAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/FunctionalityAssessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,uBAAuB,EAGxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAU9D,qBAAa,qBAAsB,SAAQ,YAAY;IACrD,OAAO,CAAC,cAAc,CAAwB;IAE9C;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAoCvB,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,uBAAuB,CAAC;YAmI5D,QAAQ;IAiGtB,OAAO,CAAC,qBAAqB;IAmE7B,OAAO,CAAC,kBAAkB;IA4G1B;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAe7C;IAEF;;;OAGG;IACH,OAAO,CAAC,mCAAmC;IAsF3C;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAWlB,iBAAiB,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO;IAI9C,OAAO,CAAC,mBAAmB;CA+B5B"}
|
|
@@ -9,6 +9,7 @@ import { ToolClassifier, ToolCategory } from "../ToolClassifier.js";
|
|
|
9
9
|
import { TestDataGenerator } from "../TestDataGenerator.js";
|
|
10
10
|
import { cleanParams } from "../../../utils/paramUtils.js";
|
|
11
11
|
import { resolveRef, normalizeUnionType } from "../../../utils/schemaUtils.js";
|
|
12
|
+
import { DEFAULT_PERFORMANCE_CONFIG } from "../config/performanceConfig.js";
|
|
12
13
|
export class FunctionalityAssessor extends BaseAssessor {
|
|
13
14
|
toolClassifier = new ToolClassifier();
|
|
14
15
|
/**
|
|
@@ -46,14 +47,15 @@ export class FunctionalityAssessor extends BaseAssessor {
|
|
|
46
47
|
const toolsToTest = this.selectToolsForTesting(context.tools);
|
|
47
48
|
// Parallel tool testing with concurrency limit
|
|
48
49
|
const concurrency = this.config.maxParallelTests ?? 5;
|
|
49
|
-
const limit = createConcurrencyLimit(concurrency);
|
|
50
|
+
const limit = createConcurrencyLimit(concurrency, this.logger);
|
|
50
51
|
// Progress tracking for batched events
|
|
52
|
+
// Uses centralized PerformanceConfig values (Issue #37)
|
|
51
53
|
const totalEstimate = toolsToTest.length;
|
|
52
54
|
let completedTests = 0;
|
|
53
55
|
let lastBatchTime = Date.now();
|
|
54
56
|
const startTime = Date.now();
|
|
55
|
-
const BATCH_INTERVAL =
|
|
56
|
-
const BATCH_SIZE =
|
|
57
|
+
const BATCH_INTERVAL = DEFAULT_PERFORMANCE_CONFIG.batchFlushIntervalMs;
|
|
58
|
+
const BATCH_SIZE = DEFAULT_PERFORMANCE_CONFIG.functionalityBatchSize;
|
|
57
59
|
let batchCount = 0;
|
|
58
60
|
const emitProgressBatch = () => {
|
|
59
61
|
if (context.onProgress) {
|
|
@@ -195,6 +197,7 @@ export class FunctionalityAssessor extends BaseAssessor {
|
|
|
195
197
|
};
|
|
196
198
|
}
|
|
197
199
|
catch (error) {
|
|
200
|
+
this.logError(`Tool execution failed: ${tool.name}`, error);
|
|
198
201
|
return {
|
|
199
202
|
toolName: tool.name,
|
|
200
203
|
tested: true,
|
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
import { MCPSpecComplianceAssessment, AssessmentConfiguration } from "../../../lib/assessmentTypes.js";
|
|
6
6
|
import { BaseAssessor } from "./BaseAssessor.js";
|
|
7
7
|
import { AssessmentContext } from "../AssessmentOrchestrator.js";
|
|
8
|
+
/**
|
|
9
|
+
* @deprecated Use ProtocolComplianceAssessor instead. Will be removed in v2.0.0.
|
|
10
|
+
*/
|
|
8
11
|
export declare class MCPSpecComplianceAssessor extends BaseAssessor {
|
|
9
12
|
private ajv;
|
|
10
13
|
constructor(config: AssessmentConfiguration);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MCPSpecComplianceAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/MCPSpecComplianceAssessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,2BAA2B,EAM3B,uBAAuB,EAGxB,MAAM,uBAAuB,CAAC;AAO/B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,qBAAa,yBAA0B,SAAQ,YAAY;IACzD,OAAO,CAAC,GAAG,CAAc;gBAEb,MAAM,EAAE,uBAAuB;
|
|
1
|
+
{"version":3,"file":"MCPSpecComplianceAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/MCPSpecComplianceAssessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,2BAA2B,EAM3B,uBAAuB,EAGxB,MAAM,uBAAuB,CAAC;AAO/B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D;;GAEG;AACH,qBAAa,yBAA0B,SAAQ,YAAY;IACzD,OAAO,CAAC,GAAG,CAAc;gBAEb,MAAM,EAAE,uBAAuB;IAa3C;;;OAGG;IACG,MAAM,CACV,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,2BAA2B,CAAC;IAmHvC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAwB9B;;;OAGG;YACW,sBAAsB;IA6BpC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAyB/B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA0C7B;;;OAGG;YACW,mBAAmB;IAsCjC;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAiBpC;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IA0FnC;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAyFjC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAsB/B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA4B9B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA2C7B;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAoF5B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAyBjC;;OAEG;IACH,OAAO,CAAC,6BAA6B;CA0DtC"}
|
|
@@ -4,10 +4,18 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import Ajv from "ajv";
|
|
6
6
|
import { BaseAssessor } from "./BaseAssessor.js";
|
|
7
|
+
/**
|
|
8
|
+
* @deprecated Use ProtocolComplianceAssessor instead. Will be removed in v2.0.0.
|
|
9
|
+
*/
|
|
7
10
|
export class MCPSpecComplianceAssessor extends BaseAssessor {
|
|
8
11
|
ajv;
|
|
9
12
|
constructor(config) {
|
|
10
13
|
super(config);
|
|
14
|
+
this.logger.warn("MCPSpecComplianceAssessor is deprecated. Use ProtocolComplianceAssessor instead. " +
|
|
15
|
+
"This module will be removed in v2.0.0.", {
|
|
16
|
+
module: "MCPSpecComplianceAssessor",
|
|
17
|
+
replacement: "ProtocolComplianceAssessor",
|
|
18
|
+
});
|
|
11
19
|
this.ajv = new Ajv({ allErrors: true });
|
|
12
20
|
}
|
|
13
21
|
/**
|
|
@@ -198,7 +206,9 @@ export class MCPSpecComplianceAssessor extends BaseAssessor {
|
|
|
198
206
|
hasErrors = true;
|
|
199
207
|
const errorMsg = `${tool.name}: ${JSON.stringify(this.ajv.errors)}`;
|
|
200
208
|
errors.push(errorMsg);
|
|
201
|
-
|
|
209
|
+
this.logger.warn(`Invalid schema for tool ${tool.name}`, {
|
|
210
|
+
errors: this.ajv.errors,
|
|
211
|
+
});
|
|
202
212
|
}
|
|
203
213
|
}
|
|
204
214
|
}
|
|
@@ -210,7 +220,9 @@ export class MCPSpecComplianceAssessor extends BaseAssessor {
|
|
|
210
220
|
};
|
|
211
221
|
}
|
|
212
222
|
catch (error) {
|
|
213
|
-
|
|
223
|
+
this.logger.error("Schema compliance check failed", {
|
|
224
|
+
error: String(error),
|
|
225
|
+
});
|
|
214
226
|
return {
|
|
215
227
|
passed: false,
|
|
216
228
|
confidence: "low",
|