@bryan-thompson/inspector-assessment 1.35.3 → 1.36.1

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.
Files changed (50) hide show
  1. package/cli/build/__tests__/assess-full-e2e.test.js +12 -2
  2. package/cli/build/__tests__/assess-full.test.js +1 -1
  3. package/cli/build/__tests__/assessment-runner/assessment-executor.test.js +1 -1
  4. package/cli/build/__tests__/assessment-runner/index.test.js +6 -4
  5. package/cli/build/__tests__/assessment-runner/path-resolver.test.js +112 -0
  6. package/cli/build/__tests__/assessment-runner/source-loader.test.js +92 -0
  7. package/cli/build/__tests__/assessment-runner-facade.test.js +4 -2
  8. package/cli/build/__tests__/cli-build-fixes.test.js +1 -1
  9. package/cli/build/__tests__/http-transport-integration.test.js +9 -2
  10. package/cli/build/__tests__/jsonl-events.test.js +1 -1
  11. package/cli/build/__tests__/security/security-pattern-count.test.js +3 -3
  12. package/cli/build/__tests__/stage3-fix-validation.test.js +1 -1
  13. package/cli/build/__tests__/testbed-integration.test.js +9 -2
  14. package/cli/build/__tests__/transport.test.js +1 -1
  15. package/cli/build/lib/__tests__/cli-parserSchemas.test.js +1 -1
  16. package/cli/build/lib/assessment-runner/__tests__/server-configSchemas.test.js +1 -1
  17. package/cli/build/lib/assessment-runner/assessment-executor.js +23 -4
  18. package/cli/build/lib/assessment-runner/index.js +2 -0
  19. package/cli/build/lib/assessment-runner/path-resolver.js +48 -0
  20. package/cli/build/lib/assessment-runner/source-loader.js +47 -5
  21. package/cli/build/lib/cli-parser.js +10 -0
  22. package/cli/package.json +1 -1
  23. package/client/dist/assets/{OAuthCallback-BglPlsRX.js → OAuthCallback-DHYVVs-U.js} +1 -1
  24. package/client/dist/assets/{OAuthDebugCallback-CWrUH2KB.js → OAuthDebugCallback-BrarwoAx.js} +1 -1
  25. package/client/dist/assets/{index-iCeeS8vg.js → index-Dup6F6QC.js} +4 -4
  26. package/client/dist/index.html +1 -1
  27. package/client/lib/lib/assessment/extendedTypes.d.ts +4 -0
  28. package/client/lib/lib/assessment/extendedTypes.d.ts.map +1 -1
  29. package/client/lib/lib/assessment/jsonlEventSchemas.d.ts +4 -4
  30. package/client/lib/lib/assessment/resultTypes.d.ts +22 -0
  31. package/client/lib/lib/assessment/resultTypes.d.ts.map +1 -1
  32. package/client/lib/lib/moduleScoring.d.ts.map +1 -1
  33. package/client/lib/lib/moduleScoring.js +45 -2
  34. package/client/lib/services/assessment/modules/ErrorHandlingAssessor.d.ts +1 -0
  35. package/client/lib/services/assessment/modules/ErrorHandlingAssessor.d.ts.map +1 -1
  36. package/client/lib/services/assessment/modules/ErrorHandlingAssessor.js +103 -8
  37. package/client/lib/services/assessment/modules/ProhibitedLibrariesAssessor.d.ts +5 -0
  38. package/client/lib/services/assessment/modules/ProhibitedLibrariesAssessor.d.ts.map +1 -1
  39. package/client/lib/services/assessment/modules/ProhibitedLibrariesAssessor.js +29 -0
  40. package/client/lib/services/assessment/modules/SecurityAssessor.d.ts.map +1 -1
  41. package/client/lib/services/assessment/modules/SecurityAssessor.js +13 -0
  42. package/client/lib/services/assessment/modules/annotations/AlignmentChecker.d.ts +7 -2
  43. package/client/lib/services/assessment/modules/annotations/AlignmentChecker.d.ts.map +1 -1
  44. package/client/lib/services/assessment/modules/annotations/AlignmentChecker.js +116 -18
  45. package/client/lib/services/assessment/modules/annotations/index.d.ts +1 -1
  46. package/client/lib/services/assessment/modules/annotations/index.d.ts.map +1 -1
  47. package/client/lib/services/assessment/modules/annotations/index.js +2 -1
  48. package/client/package.json +1 -1
  49. package/package.json +1 -1
  50. package/server/package.json +1 -1
@@ -6,13 +6,16 @@ import { BaseAssessor } from "./BaseAssessor.js";
6
6
  import { createConcurrencyLimit } from "../lib/concurrencyLimit.js";
7
7
  import { ExecutionArtifactDetector } from "./securityTests/ExecutionArtifactDetector.js";
8
8
  import { SafeResponseDetector } from "./securityTests/SafeResponseDetector.js";
9
+ import { ErrorClassifier } from "./securityTests/ErrorClassifier.js";
9
10
  export class ErrorHandlingAssessor extends BaseAssessor {
10
11
  executionDetector;
11
12
  safeResponseDetector;
13
+ errorClassifier;
12
14
  constructor(config) {
13
15
  super(config);
14
16
  this.executionDetector = new ExecutionArtifactDetector();
15
17
  this.safeResponseDetector = new SafeResponseDetector();
18
+ this.errorClassifier = new ErrorClassifier();
16
19
  }
17
20
  async assess(context) {
18
21
  this.logger.info("Starting error handling assessment");
@@ -56,6 +59,15 @@ export class ErrorHandlingAssessor extends BaseAssessor {
56
59
  passedTests += toolTests.filter((t) => t.passed).length;
57
60
  }
58
61
  this.testCount = testDetails.length;
62
+ // Issue #153: Calculate test execution metadata for score validation
63
+ // Count connection errors from test results (tests with isConnectionError flag)
64
+ const connectionErrorTests = testDetails.filter((t) => t.isConnectionError);
65
+ const connectionErrorCount = connectionErrorTests.length;
66
+ const validTestsCompleted = testDetails.length - connectionErrorCount;
67
+ const totalTestsAttempted = testDetails.length;
68
+ const testCoveragePercent = totalTestsAttempted > 0
69
+ ? Math.round((validTestsCompleted / totalTestsAttempted) * 100)
70
+ : 0;
59
71
  const metrics = this.calculateMetrics(testDetails, passedTests);
60
72
  const status = this.determineErrorHandlingStatus(metrics, testDetails.length);
61
73
  const explanation = this.generateExplanation(metrics, testDetails);
@@ -68,6 +80,13 @@ export class ErrorHandlingAssessor extends BaseAssessor {
68
80
  score: Math.round(metrics.mcpComplianceScore),
69
81
  explanation,
70
82
  recommendations,
83
+ // Issue #153: Test execution metadata for score validation
84
+ testExecutionMetadata: {
85
+ totalTestsAttempted,
86
+ validTestsCompleted,
87
+ connectionErrorCount,
88
+ testCoveragePercent,
89
+ },
71
90
  };
72
91
  }
73
92
  selectToolsForTesting(tools) {
@@ -175,6 +194,25 @@ export class ErrorHandlingAssessor extends BaseAssessor {
175
194
  };
176
195
  }
177
196
  catch (error) {
197
+ // Issue #153: Check for connection errors first - these should NOT count as passed
198
+ if (this.errorClassifier.isConnectionErrorFromException(error)) {
199
+ const errorInfo = this.extractErrorInfo(error);
200
+ return {
201
+ toolName: tool.name,
202
+ testType: "missing_required",
203
+ testInput,
204
+ expectedError: "Missing required parameters",
205
+ actualResponse: {
206
+ isError: true,
207
+ errorCode: errorInfo.code,
208
+ errorMessage: errorInfo.message,
209
+ rawResponse: error,
210
+ },
211
+ passed: false,
212
+ reason: "Connection error - unable to test",
213
+ isConnectionError: true,
214
+ };
215
+ }
178
216
  // Check if the error message is meaningful (not just a generic crash)
179
217
  const errorInfo = this.extractErrorInfo(error);
180
218
  const messageLower = errorInfo.message?.toLowerCase() ?? "";
@@ -183,8 +221,8 @@ export class ErrorHandlingAssessor extends BaseAssessor {
183
221
  messageLower.includes("parameter") ||
184
222
  messageLower.includes("must") ||
185
223
  messageLower.includes("invalid") ||
186
- messageLower.includes("validation") ||
187
- (errorInfo.message?.length ?? 0) > 20; // Longer messages are likely intentional
224
+ messageLower.includes("validation");
225
+ // Removed: (errorInfo.message?.length ?? 0) > 20 - this was causing false positives
188
226
  return {
189
227
  toolName: tool.name,
190
228
  testType: "missing_required",
@@ -242,6 +280,25 @@ export class ErrorHandlingAssessor extends BaseAssessor {
242
280
  };
243
281
  }
244
282
  catch (error) {
283
+ // Issue #153: Check for connection errors first - these should NOT count as passed
284
+ if (this.errorClassifier.isConnectionErrorFromException(error)) {
285
+ const errorInfo = this.extractErrorInfo(error);
286
+ return {
287
+ toolName: tool.name,
288
+ testType: "wrong_type",
289
+ testInput,
290
+ expectedError: "Type validation error",
291
+ actualResponse: {
292
+ isError: true,
293
+ errorCode: errorInfo.code,
294
+ errorMessage: errorInfo.message,
295
+ rawResponse: error,
296
+ },
297
+ passed: false,
298
+ reason: "Connection error - unable to test",
299
+ isConnectionError: true,
300
+ };
301
+ }
245
302
  // Check if the error message is meaningful (not just a generic crash)
246
303
  const errorInfo = this.extractErrorInfo(error);
247
304
  const messageLower = errorInfo.message?.toLowerCase() ?? "";
@@ -251,8 +308,8 @@ export class ErrorHandlingAssessor extends BaseAssessor {
251
308
  messageLower.includes("must be") ||
252
309
  messageLower.includes("validation") ||
253
310
  messageLower.includes("string") ||
254
- messageLower.includes("number") ||
255
- (errorInfo.message?.length ?? 0) > 20; // Longer messages are likely intentional
311
+ messageLower.includes("number");
312
+ // Removed: (errorInfo.message?.length ?? 0) > 20 - this was causing false positives
256
313
  return {
257
314
  toolName: tool.name,
258
315
  testType: "wrong_type",
@@ -294,6 +351,25 @@ export class ErrorHandlingAssessor extends BaseAssessor {
294
351
  };
295
352
  }
296
353
  catch (error) {
354
+ // Issue #153: Check for connection errors first - these should NOT count as passed
355
+ if (this.errorClassifier.isConnectionErrorFromException(error)) {
356
+ const errorInfo = this.extractErrorInfo(error);
357
+ return {
358
+ toolName: tool.name,
359
+ testType: "invalid_values",
360
+ testInput,
361
+ expectedError: "Invalid parameter values",
362
+ actualResponse: {
363
+ isError: true,
364
+ errorCode: errorInfo.code,
365
+ errorMessage: errorInfo.message,
366
+ rawResponse: error,
367
+ },
368
+ passed: false,
369
+ reason: "Connection error - unable to test",
370
+ isConnectionError: true,
371
+ };
372
+ }
297
373
  // Check if the error message is meaningful (not just a generic crash)
298
374
  const errorInfo = this.extractErrorInfo(error);
299
375
  const messageLower = errorInfo.message?.toLowerCase() ?? "";
@@ -302,8 +378,8 @@ export class ErrorHandlingAssessor extends BaseAssessor {
302
378
  messageLower.includes("must") ||
303
379
  messageLower.includes("cannot") ||
304
380
  messageLower.includes("validation") ||
305
- messageLower.includes("error") ||
306
- (errorInfo.message?.length ?? 0) > 15; // Even shorter messages OK for invalid values
381
+ messageLower.includes("error");
382
+ // Removed: (errorInfo.message?.length ?? 0) > 15 - this was causing false positives
307
383
  return {
308
384
  toolName: tool.name,
309
385
  testType: "invalid_values",
@@ -343,6 +419,25 @@ export class ErrorHandlingAssessor extends BaseAssessor {
343
419
  };
344
420
  }
345
421
  catch (error) {
422
+ // Issue #153: Check for connection errors first - these should NOT count as passed
423
+ if (this.errorClassifier.isConnectionErrorFromException(error)) {
424
+ const errorInfo = this.extractErrorInfo(error);
425
+ return {
426
+ toolName: tool.name,
427
+ testType: "excessive_input",
428
+ testInput: { value: "[100KB string]" },
429
+ expectedError: "Input size limit exceeded",
430
+ actualResponse: {
431
+ isError: true,
432
+ errorCode: errorInfo.code,
433
+ errorMessage: errorInfo.message,
434
+ rawResponse: "[error details omitted]",
435
+ },
436
+ passed: false,
437
+ reason: "Connection error - unable to test",
438
+ isConnectionError: true,
439
+ };
440
+ }
346
441
  // Check if the error message is meaningful (not just a generic crash)
347
442
  const errorInfo = this.extractErrorInfo(error);
348
443
  const messageLower = errorInfo.message?.toLowerCase() ?? "";
@@ -351,8 +446,8 @@ export class ErrorHandlingAssessor extends BaseAssessor {
351
446
  messageLower.includes("limit") ||
352
447
  messageLower.includes("exceed") ||
353
448
  messageLower.includes("too") ||
354
- messageLower.includes("maximum") ||
355
- (errorInfo.message?.length ?? 0) > 10; // Short messages OK for size limits
449
+ messageLower.includes("maximum");
450
+ // Removed: (errorInfo.message?.length ?? 0) > 10 - this was causing false positives
356
451
  return {
357
452
  toolName: tool.name,
358
453
  testType: "excessive_input",
@@ -17,6 +17,11 @@ export declare class ProhibitedLibrariesAssessor extends BaseAssessor {
17
17
  * Run prohibited libraries assessment
18
18
  */
19
19
  assess(context: AssessmentContext): Promise<ProhibitedLibrariesAssessment>;
20
+ /**
21
+ * Create result when no files are available to scan (Issue #154)
22
+ * Follows the pattern established by ConformanceAssessor
23
+ */
24
+ private createSkippedResult;
20
25
  /**
21
26
  * Check if file is a source file worth scanning
22
27
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ProhibitedLibrariesAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/ProhibitedLibrariesAssessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EACV,6BAA6B,EAI9B,MAAM,uBAAuB,CAAC;AAS/B,qBAAa,2BAA4B,SAAQ,YAAY;IAC3D;;OAEG;IACG,MAAM,CACV,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,6BAA6B,CAAC;IAiKzC;;OAEG;IACH,OAAO,CAAC,YAAY;IA0BpB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAqB1B;;;;;;;OAOG;IACH,OAAO,CAAC,0BAA0B;IAiClC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAoD3B;;;;OAIG;IACH,OAAO,CAAC,uBAAuB;CA2EhC"}
1
+ {"version":3,"file":"ProhibitedLibrariesAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/ProhibitedLibrariesAssessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EACV,6BAA6B,EAI9B,MAAM,uBAAuB,CAAC;AAS/B,qBAAa,2BAA4B,SAAQ,YAAY;IAC3D;;OAEG;IACG,MAAM,CACV,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,6BAA6B,CAAC;IAkLzC;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAiB3B;;OAEG;IACH,OAAO,CAAC,YAAY;IA0BpB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAqB1B;;;;;;;OAOG;IACH,OAAO,CAAC,0BAA0B;IAiClC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAoD3B;;;;OAIG;IACH,OAAO,CAAC,uBAAuB;CA2EhC"}
@@ -18,6 +18,15 @@ export class ProhibitedLibrariesAssessor extends BaseAssessor {
18
18
  async assess(context) {
19
19
  this.logger.info("Starting prohibited libraries assessment");
20
20
  this.testCount = 0;
21
+ // Issue #154: Check if there are any files to scan
22
+ const hasPackageJson = Boolean(context.packageJson);
23
+ const hasSourceFiles = Boolean(context.sourceCodeFiles &&
24
+ context.config.enableSourceCodeAnalysis &&
25
+ context.sourceCodeFiles.size > 0);
26
+ if (!hasPackageJson && !hasSourceFiles) {
27
+ this.logger.info("No package.json or source files available, skipping assessment");
28
+ return this.createSkippedResult("No package.json or source files provided. Enable source code analysis with --source flag.");
29
+ }
21
30
  const matches = [];
22
31
  const scannedFiles = [];
23
32
  let hasFinancialLibraries = false;
@@ -137,6 +146,26 @@ export class ProhibitedLibrariesAssessor extends BaseAssessor {
137
146
  recommendations,
138
147
  };
139
148
  }
149
+ /**
150
+ * Create result when no files are available to scan (Issue #154)
151
+ * Follows the pattern established by ConformanceAssessor
152
+ */
153
+ createSkippedResult(reason) {
154
+ return {
155
+ matches: [],
156
+ scannedFiles: [],
157
+ hasFinancialLibraries: false,
158
+ hasMediaLibraries: false,
159
+ status: "NEED_MORE_INFO",
160
+ explanation: `Prohibited libraries assessment skipped: ${reason}`,
161
+ recommendations: [
162
+ "Provide --source <path> to enable package.json and source file scanning",
163
+ "Ensure the source path exists and contains package.json or source files",
164
+ ],
165
+ skipped: true,
166
+ skipReason: reason,
167
+ };
168
+ }
140
169
  /**
141
170
  * Check if file is a source file worth scanning
142
171
  */
@@ -1 +1 @@
1
- {"version":3,"file":"SecurityAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/SecurityAssessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EACL,kBAAkB,EAInB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAiB9D,OAAO,EACL,gBAAgB,EAGjB,MAAM,yBAAyB,CAAC;AAEjC,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,aAAa,CAAwB;IAC7C,OAAO,CAAC,gBAAgB,CAA2B;IACnD,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,YAAY,CAAiC;IAErD;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,GAAG,IAAI;IAStD;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAOjC;;;OAGG;YACW,0BAA0B;gBAwBtC,MAAM,EAAE,OAAO,8BAA8B,EAAE,uBAAuB;IAwClE,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA+OrE;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAoC7B;;OAEG;YACW,+BAA+B;IAiC7C;;;OAGG;YACW,yBAAyB;IA0CvC;;;;;;;OAOG;YACW,yBAAyB;IAmFvC;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAYjC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA0B/B;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAkEnC;;;OAGG;IACH,OAAO,CAAC,0BAA0B;CAgDnC"}
1
+ {"version":3,"file":"SecurityAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/SecurityAssessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EACL,kBAAkB,EAInB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAiB9D,OAAO,EACL,gBAAgB,EAGjB,MAAM,yBAAyB,CAAC;AAEjC,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,aAAa,CAAwB;IAC7C,OAAO,CAAC,gBAAgB,CAA2B;IACnD,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,YAAY,CAAiC;IAErD;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,GAAG,IAAI;IAStD;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAOjC;;;OAGG;YACW,0BAA0B;gBAwBtC,MAAM,EAAE,OAAO,8BAA8B,EAAE,uBAAuB;IAwClE,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA8PrE;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAoC7B;;OAEG;YACW,+BAA+B;IAiC7C;;;OAGG;YACW,yBAAyB;IA0CvC;;;;;;;OAOG;YACW,yBAAyB;IAmFvC;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAYjC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA0B/B;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAkEnC;;;OAGG;IACH,OAAO,CAAC,0BAA0B;CAgDnC"}
@@ -253,6 +253,12 @@ export class SecurityAssessor extends BaseAssessor {
253
253
  }
254
254
  // Issue #75: Aggregate auth bypass detection results
255
255
  const authBypassSummary = this.aggregateAuthBypassResults(allTests);
256
+ // Issue #152: Calculate test execution metadata for score validation
257
+ const totalTestsAttempted = allTests.length;
258
+ const validTestsCompleted = validTests.length;
259
+ const testCoveragePercent = totalTestsAttempted > 0
260
+ ? Math.round((validTestsCompleted / totalTestsAttempted) * 100)
261
+ : 0;
256
262
  return {
257
263
  promptInjectionTests: allTests,
258
264
  vulnerabilities,
@@ -263,6 +269,13 @@ export class SecurityAssessor extends BaseAssessor {
263
269
  // Issue #134: Test validity warning for response uniformity detection
264
270
  testValidityWarning: validityResult.warning,
265
271
  overallConfidence,
272
+ // Issue #152: Test execution metadata for score validation
273
+ testExecutionMetadata: {
274
+ totalTestsAttempted,
275
+ validTestsCompleted,
276
+ connectionErrorCount: connectionErrors.length,
277
+ testCoveragePercent,
278
+ },
266
279
  };
267
280
  }
268
281
  /**
@@ -38,9 +38,14 @@ export interface AlignmentMetricsResult {
38
38
  };
39
39
  }
40
40
  /**
41
- * Extract annotations from a tool
42
- * Checks multiple sources in priority order: annotations object, direct properties, metadata
41
+ * Enable or disable annotation debug logging (Issue #155)
42
+ * Called by CLI when --debug-annotations flag is provided
43
43
  */
44
+ export declare function setAnnotationDebugMode(enabled: boolean): void;
45
+ /**
46
+ * Check if annotation debug mode is enabled
47
+ */
48
+ export declare function isAnnotationDebugEnabled(): boolean;
44
49
  export declare function extractAnnotations(tool: Tool): ExtractedAnnotations;
45
50
  /**
46
51
  * Extract extended metadata from tool (Issue #54)
@@ -1 +1 @@
1
- {"version":3,"file":"AlignmentChecker.d.ts","sourceRoot":"","sources":["../../../../../src/services/assessment/modules/annotations/AlignmentChecker.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,EACV,oBAAoB,EACpB,gBAAgB,EAEhB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EACV,gBAAgB,EAChB,wBAAwB,EACzB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,gCAAgC,CAAC;AAoExC;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,kBAAkB,EAAE;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,oBAAoB,CA8DnE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,IAAI,GACT,oBAAoB,CAAC,kBAAkB,CAAC,CA6D1C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,iBAAiB,EAAE,CAqBtE;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,IAAI,GAAG,mBAAmB,CAmD3E;AAqCD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,IAAI,EACV,gBAAgB,EAAE,gBAAgB,EAClC,kBAAkB,CAAC,EAAE,wBAAwB,GAC5C,oBAAoB,CA0JtB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,oBAAoB,EAAE,EAC/B,UAAU,EAAE,MAAM,GACjB,gBAAgB,CA8BlB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,oBAAoB,EAAE,EAC/B,UAAU,EAAE,MAAM,GACjB,sBAAsB,CA2BxB"}
1
+ {"version":3,"file":"AlignmentChecker.d.ts","sourceRoot":"","sources":["../../../../../src/services/assessment/modules/annotations/AlignmentChecker.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,EACV,oBAAoB,EACpB,gBAAgB,EAEhB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EACV,gBAAgB,EAChB,wBAAwB,EACzB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,gCAAgC,CAAC;AAuFxC;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,kBAAkB,EAAE;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AA0CD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAE7D;AAED;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,CAElD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,oBAAoB,CAiNnE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,IAAI,GACT,oBAAoB,CAAC,kBAAkB,CAAC,CA6D1C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,iBAAiB,EAAE,CAqBtE;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,IAAI,GAAG,mBAAmB,CAmD3E;AAqCD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,IAAI,EACV,gBAAgB,EAAE,gBAAgB,EAClC,kBAAkB,CAAC,EAAE,wBAAwB,GAC5C,oBAAoB,CA0JtB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,oBAAoB,EAAE,EAC/B,UAAU,EAAE,MAAM,GACjB,gBAAgB,CA8BlB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,oBAAoB,EAAE,EAC/B,UAAU,EAAE,MAAM,GACjB,sBAAsB,CA2BxB"}
@@ -7,57 +7,155 @@
7
7
  import { scanDescriptionForPoisoning, } from "./DescriptionPoisoningDetector.js";
8
8
  import { detectAnnotationDeception, isActionableConfidence, } from "./AnnotationDeceptionDetector.js";
9
9
  import { inferBehavior } from "./BehaviorInference.js";
10
+ /**
11
+ * Helper to resolve annotation value with fallback (Issue #150)
12
+ * Checks *Hint suffix first (MCP spec), then non-suffixed version as fallback
13
+ * This handles servers that use 'readOnly' instead of 'readOnlyHint'
14
+ *
15
+ * @param obj - The object to search for annotation properties
16
+ * @param hintKey - The MCP spec compliant key (e.g., 'readOnlyHint')
17
+ * @param fallbackKey - The non-suffixed fallback key (e.g., 'readOnly')
18
+ * @returns The boolean annotation value, or undefined if not found or not a boolean
19
+ */
20
+ function resolveAnnotationValue(obj, hintKey, fallbackKey) {
21
+ if (!obj)
22
+ return undefined;
23
+ // Priority: *Hint version (MCP spec)
24
+ if (obj[hintKey] !== undefined) {
25
+ const val = obj[hintKey];
26
+ if (typeof val === "boolean")
27
+ return val;
28
+ }
29
+ // Fallback: non-suffixed version (Issue #150)
30
+ if (obj[fallbackKey] !== undefined) {
31
+ const val = obj[fallbackKey];
32
+ if (typeof val === "boolean")
33
+ return val;
34
+ }
35
+ return undefined;
36
+ }
10
37
  /**
11
38
  * Extract annotations from a tool
12
39
  * Checks multiple sources in priority order: annotations object, direct properties, metadata
40
+ * Issue #150: Also checks non-suffixed property names (readOnly, destructive) as fallback
41
+ */
42
+ /**
43
+ * Global debug flag for annotation extraction (Issue #155)
44
+ * Set via setAnnotationDebugMode() when --debug-annotations flag is used
45
+ */
46
+ let annotationDebugMode = false;
47
+ /**
48
+ * Enable or disable annotation debug logging (Issue #155)
49
+ * Called by CLI when --debug-annotations flag is provided
50
+ */
51
+ export function setAnnotationDebugMode(enabled) {
52
+ annotationDebugMode = enabled;
53
+ }
54
+ /**
55
+ * Check if annotation debug mode is enabled
13
56
  */
57
+ export function isAnnotationDebugEnabled() {
58
+ return annotationDebugMode;
59
+ }
14
60
  export function extractAnnotations(tool) {
15
61
  const extendedTool = tool;
62
+ // Issue #155: Debug logging when --debug-annotations flag is enabled
63
+ if (annotationDebugMode) {
64
+ console.log("[DEBUG-ANNOTATIONS]", tool.name, "| keys:", Object.keys(tool), "| annotations:", JSON.stringify(extendedTool.annotations), "| direct.readOnlyHint:", extendedTool.readOnlyHint);
65
+ }
16
66
  // Priority 1: Check annotations object (MCP 2024-11 spec)
67
+ // Issue #150: Use resolveAnnotationValue to check both *Hint and non-suffixed versions
17
68
  if (extendedTool.annotations) {
18
- const hasAnnotations = extendedTool.annotations.readOnlyHint !== undefined ||
19
- extendedTool.annotations.destructiveHint !== undefined;
69
+ const annotationsObj = extendedTool.annotations;
70
+ const readOnlyValue = resolveAnnotationValue(annotationsObj, "readOnlyHint", "readOnly");
71
+ const destructiveValue = resolveAnnotationValue(annotationsObj, "destructiveHint", "destructive");
72
+ const hasAnnotations = readOnlyValue !== undefined || destructiveValue !== undefined;
20
73
  if (hasAnnotations) {
21
74
  return {
22
- readOnlyHint: extendedTool.annotations.readOnlyHint,
23
- destructiveHint: extendedTool.annotations.destructiveHint,
75
+ readOnlyHint: readOnlyValue,
76
+ destructiveHint: destructiveValue,
24
77
  title: extendedTool.annotations.title || extendedTool.title,
25
78
  description: tool.description,
26
- idempotentHint: extendedTool.annotations.idempotentHint,
27
- openWorldHint: extendedTool.annotations.openWorldHint,
79
+ idempotentHint: resolveAnnotationValue(annotationsObj, "idempotentHint", "idempotent"),
80
+ openWorldHint: resolveAnnotationValue(annotationsObj, "openWorldHint", "openWorld"),
28
81
  source: "mcp",
29
82
  };
30
83
  }
31
84
  }
32
85
  // Priority 2: Check direct properties
33
- if (extendedTool.readOnlyHint !== undefined ||
34
- extendedTool.destructiveHint !== undefined) {
86
+ // Issue #150: Use resolveAnnotationValue to check both *Hint and non-suffixed versions
87
+ const directObj = extendedTool;
88
+ const directReadOnly = resolveAnnotationValue(directObj, "readOnlyHint", "readOnly");
89
+ const directDestructive = resolveAnnotationValue(directObj, "destructiveHint", "destructive");
90
+ if (directReadOnly !== undefined || directDestructive !== undefined) {
35
91
  return {
36
- readOnlyHint: extendedTool.readOnlyHint,
37
- destructiveHint: extendedTool.destructiveHint,
92
+ readOnlyHint: directReadOnly,
93
+ destructiveHint: directDestructive,
38
94
  title: extendedTool.title,
39
95
  description: tool.description,
40
- idempotentHint: extendedTool.idempotentHint,
41
- openWorldHint: extendedTool.openWorldHint,
96
+ idempotentHint: resolveAnnotationValue(directObj, "idempotentHint", "idempotent"),
97
+ openWorldHint: resolveAnnotationValue(directObj, "openWorldHint", "openWorld"),
42
98
  source: "mcp",
43
99
  };
44
100
  }
45
101
  // Priority 3: Check metadata
102
+ // Issue #150: Use resolveAnnotationValue to check both *Hint and non-suffixed versions
46
103
  if (extendedTool.metadata) {
47
- const hasMetadataAnnotations = extendedTool.metadata.readOnlyHint !== undefined ||
48
- extendedTool.metadata.destructiveHint !== undefined;
104
+ const metadataObj = extendedTool.metadata;
105
+ const metaReadOnly = resolveAnnotationValue(metadataObj, "readOnlyHint", "readOnly");
106
+ const metaDestructive = resolveAnnotationValue(metadataObj, "destructiveHint", "destructive");
107
+ const hasMetadataAnnotations = metaReadOnly !== undefined || metaDestructive !== undefined;
49
108
  if (hasMetadataAnnotations) {
50
109
  return {
51
- readOnlyHint: extendedTool.metadata.readOnlyHint,
52
- destructiveHint: extendedTool.metadata.destructiveHint,
110
+ readOnlyHint: metaReadOnly,
111
+ destructiveHint: metaDestructive,
53
112
  title: extendedTool.metadata.title || extendedTool.title,
54
113
  description: tool.description,
55
- idempotentHint: extendedTool.metadata.idempotentHint,
56
- openWorldHint: extendedTool.metadata.openWorldHint,
114
+ idempotentHint: resolveAnnotationValue(metadataObj, "idempotentHint", "idempotent"),
115
+ openWorldHint: resolveAnnotationValue(metadataObj, "openWorldHint", "openWorld"),
116
+ source: "mcp",
117
+ };
118
+ }
119
+ }
120
+ // Priority 4: Check _meta object (MCP spec allows arbitrary data here)
121
+ // Issue #155: Some servers may store annotations in _meta
122
+ if (extendedTool._meta) {
123
+ const metaObj = extendedTool._meta;
124
+ const metaReadOnly = resolveAnnotationValue(metaObj, "readOnlyHint", "readOnly");
125
+ const metaDestructive = resolveAnnotationValue(metaObj, "destructiveHint", "destructive");
126
+ if (metaReadOnly !== undefined || metaDestructive !== undefined) {
127
+ return {
128
+ readOnlyHint: metaReadOnly,
129
+ destructiveHint: metaDestructive,
130
+ title: metaObj.title,
131
+ description: tool.description,
132
+ idempotentHint: resolveAnnotationValue(metaObj, "idempotentHint", "idempotent"),
133
+ openWorldHint: resolveAnnotationValue(metaObj, "openWorldHint", "openWorld"),
57
134
  source: "mcp",
58
135
  };
59
136
  }
60
137
  }
138
+ // Priority 5: Check annotations.hints (nested structure some servers use)
139
+ // Issue #155: Handle servers that nest hints inside annotations object
140
+ if (extendedTool.annotations) {
141
+ const hintsObj = extendedTool.annotations
142
+ .hints;
143
+ if (hintsObj) {
144
+ const hintsReadOnly = resolveAnnotationValue(hintsObj, "readOnlyHint", "readOnly");
145
+ const hintsDestructive = resolveAnnotationValue(hintsObj, "destructiveHint", "destructive");
146
+ if (hintsReadOnly !== undefined || hintsDestructive !== undefined) {
147
+ return {
148
+ readOnlyHint: hintsReadOnly,
149
+ destructiveHint: hintsDestructive,
150
+ title: extendedTool.annotations.title,
151
+ description: tool.description,
152
+ idempotentHint: resolveAnnotationValue(hintsObj, "idempotentHint", "idempotent"),
153
+ openWorldHint: resolveAnnotationValue(hintsObj, "openWorldHint", "openWorld"),
154
+ source: "mcp",
155
+ };
156
+ }
157
+ }
158
+ }
61
159
  return {
62
160
  title: extendedTool.title,
63
161
  description: tool.description,
@@ -16,7 +16,7 @@ export { analyzeDescription, hasReadOnlyIndicators, hasDestructiveIndicators, ha
16
16
  export { analyzeInputSchema, analyzeOutputSchema, hasBulkOperationIndicators, hasPaginationParameters, hasForceFlags, INPUT_READONLY_PATTERNS, INPUT_DESTRUCTIVE_PATTERNS, INPUT_WRITE_PATTERNS, OUTPUT_READONLY_PATTERNS, OUTPUT_DESTRUCTIVE_PATTERNS, OUTPUT_WRITE_PATTERNS, type JSONSchema, } from "./SchemaAnalyzer.js";
17
17
  export { detectArchitecture, hasDatabaseToolPatterns, extractDatabasesFromDependencies, type Tool as ArchitectureTool, type ArchitectureContext, } from "./ArchitectureDetector.js";
18
18
  export { type ClaudeInference, type EnhancedToolAnnotationResult, } from "./types.js";
19
- export { extractAnnotations, extractExtendedMetadata, extractToolParams, scanInputSchemaDescriptions, assessSingleTool, determineAnnotationStatus, calculateMetrics, type ExtractedAnnotations, type AlignmentMetricsResult, } from "./AlignmentChecker.js";
19
+ export { extractAnnotations, extractExtendedMetadata, extractToolParams, scanInputSchemaDescriptions, assessSingleTool, determineAnnotationStatus, calculateMetrics, setAnnotationDebugMode, isAnnotationDebugEnabled, type ExtractedAnnotations, type AlignmentMetricsResult, } from "./AlignmentChecker.js";
20
20
  export { generateExplanation, generateEnhancedExplanation, generateRecommendations, generateEnhancedRecommendations, } from "./ExplanationGenerator.js";
21
21
  export { emitAnnotationEvents, emitMismatchEvent } from "./EventEmitter.js";
22
22
  export { enhanceWithClaudeInference, createPatternBasedInference, } from "./ClaudeIntegration.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/services/assessment/modules/annotations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,8BAA8B,EAC9B,2BAA2B,EAC3B,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,GACzB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACL,+BAA+B,EAC/B,4BAA4B,EAC5B,kCAAkC,EAClC,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,yBAAyB,EACzB,KAAK,eAAe,GACrB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,EACxB,kBAAkB,EAClB,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,0BAA0B,EAC1B,uBAAuB,EACvB,aAAa,EACb,uBAAuB,EACvB,0BAA0B,EAC1B,oBAAoB,EACpB,wBAAwB,EACxB,2BAA2B,EAC3B,qBAAqB,EACrB,KAAK,UAAU,GAChB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,gCAAgC,EAChC,KAAK,IAAI,IAAI,gBAAgB,EAC7B,KAAK,mBAAmB,GACzB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,4BAA4B,GAClC,MAAM,SAAS,CAAC;AAIjB,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EACjB,2BAA2B,EAC3B,gBAAgB,EAChB,yBAAyB,EACzB,gBAAgB,EAChB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,GAC5B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,uBAAuB,EACvB,+BAA+B,GAChC,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGzE,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/services/assessment/modules/annotations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,8BAA8B,EAC9B,2BAA2B,EAC3B,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,GACzB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACL,+BAA+B,EAC/B,4BAA4B,EAC5B,kCAAkC,EAClC,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,yBAAyB,EACzB,KAAK,eAAe,GACrB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,EACxB,kBAAkB,EAClB,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,0BAA0B,EAC1B,uBAAuB,EACvB,aAAa,EACb,uBAAuB,EACvB,0BAA0B,EAC1B,oBAAoB,EACpB,wBAAwB,EACxB,2BAA2B,EAC3B,qBAAqB,EACrB,KAAK,UAAU,GAChB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,gCAAgC,EAChC,KAAK,IAAI,IAAI,gBAAgB,EAC7B,KAAK,mBAAmB,GACzB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,4BAA4B,GAClC,MAAM,SAAS,CAAC;AAKjB,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EACjB,2BAA2B,EAC3B,gBAAgB,EAChB,yBAAyB,EACzB,gBAAgB,EAChB,sBAAsB,EACtB,wBAAwB,EACxB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,GAC5B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,uBAAuB,EACvB,+BAA+B,GAChC,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGzE,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC"}
@@ -20,7 +20,8 @@ export { analyzeInputSchema, analyzeOutputSchema, hasBulkOperationIndicators, ha
20
20
  export { detectArchitecture, hasDatabaseToolPatterns, extractDatabasesFromDependencies, } from "./ArchitectureDetector.js";
21
21
  // Issue #105: Alignment Checker
22
22
  // Issue #119: Added scanInputSchemaDescriptions for Challenge #15
23
- export { extractAnnotations, extractExtendedMetadata, extractToolParams, scanInputSchemaDescriptions, assessSingleTool, determineAnnotationStatus, calculateMetrics, } from "./AlignmentChecker.js";
23
+ // Issue #155: Added setAnnotationDebugMode for debug logging
24
+ export { extractAnnotations, extractExtendedMetadata, extractToolParams, scanInputSchemaDescriptions, assessSingleTool, determineAnnotationStatus, calculateMetrics, setAnnotationDebugMode, isAnnotationDebugEnabled, } from "./AlignmentChecker.js";
24
25
  // Issue #105: Explanation Generator
25
26
  export { generateExplanation, generateEnhancedExplanation, generateRecommendations, generateEnhancedRecommendations, } from "./ExplanationGenerator.js";
26
27
  // Issue #105: Event Emitter
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bryan-thompson/inspector-assessment-client",
3
- "version": "1.35.3",
3
+ "version": "1.36.1",
4
4
  "description": "Client-side application for the Enhanced MCP Inspector with assessment capabilities",
5
5
  "license": "MIT",
6
6
  "author": "Bryan Thompson <bryan@triepod.ai>",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bryan-thompson/inspector-assessment",
3
- "version": "1.35.3",
3
+ "version": "1.36.1",
4
4
  "description": "Enhanced MCP Inspector with comprehensive assessment capabilities for server validation",
5
5
  "license": "MIT",
6
6
  "author": "Bryan Thompson <bryan@triepod.ai>",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bryan-thompson/inspector-assessment-server",
3
- "version": "1.35.3",
3
+ "version": "1.36.1",
4
4
  "description": "Server-side application for the Enhanced MCP Inspector with assessment capabilities",
5
5
  "license": "MIT",
6
6
  "author": "Bryan Thompson <bryan@triepod.ai>",