@agent-inspect/mcp-server 6.17.3 → 6.17.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/cli.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { runReadOnlyMcpServer } from './chunk-RAYFTVFK.mjs';
1
+ import { runReadOnlyMcpServer } from './chunk-GMXH2CU3.mjs';
2
2
  import { readFileSync } from 'fs';
3
3
  import path from 'path';
4
4
  import { fileURLToPath } from 'url';
package/dist/index.cjs CHANGED
@@ -2632,8 +2632,11 @@ function formatProgrammaticDiagnostic(code, detail) {
2632
2632
  }
2633
2633
 
2634
2634
  // packages/core/src/safety/sensitive-key.ts
2635
+ function keyHasExplicitSeparator(value) {
2636
+ return /[_\-.]/.test(value);
2637
+ }
2635
2638
  function normalizeSensitiveKey(value) {
2636
- return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
2639
+ return value.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
2637
2640
  }
2638
2641
  var NON_CREDENTIAL_TOKEN_CONFIG_KEYS = new Set(
2639
2642
  [
@@ -2685,6 +2688,7 @@ function isCredentialSensitiveKey(key, sensitiveKeys = DEFAULT_CREDENTIAL_SENSIT
2685
2688
  const normalized = normalizeSensitiveKey(key);
2686
2689
  if (!normalized) return false;
2687
2690
  if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
2691
+ const allowPrefixCompound = keyHasExplicitSeparator(key);
2688
2692
  for (const sensitive of sensitiveKeys) {
2689
2693
  const s = normalizeSensitiveKey(sensitive);
2690
2694
  if (!s) continue;
@@ -2693,7 +2697,8 @@ function isCredentialSensitiveKey(key, sensitiveKeys = DEFAULT_CREDENTIAL_SENSIT
2693
2697
  continue;
2694
2698
  }
2695
2699
  if (normalized === s) return true;
2696
- if (normalized.endsWith(`_${s}`) || normalized.startsWith(`${s}_`)) return true;
2700
+ if (normalized.endsWith(`_${s}`)) return true;
2701
+ if (allowPrefixCompound && normalized.startsWith(`${s}_`)) return true;
2697
2702
  }
2698
2703
  return false;
2699
2704
  }
@@ -3178,10 +3183,11 @@ function emptySummary() {
3178
3183
  passed: 0,
3179
3184
  failed: 0,
3180
3185
  warnings: 0,
3181
- errors: 0
3186
+ errors: 0,
3187
+ rulesEvaluated: 0
3182
3188
  };
3183
3189
  }
3184
- function errorResult(input, diagnostics, selectedRun) {
3190
+ function errorResult(input, diagnostics, selectedRun, ruleExecutions = []) {
3185
3191
  return {
3186
3192
  ok: false,
3187
3193
  status: "error",
@@ -3189,10 +3195,12 @@ function errorResult(input, diagnostics, selectedRun) {
3189
3195
  ...selectedRun ? { runId: selectedRun.runId } : {},
3190
3196
  summary: {
3191
3197
  ...emptySummary(),
3192
- errors: diagnostics.filter((item) => item.severity === "error").length
3198
+ errors: diagnostics.filter((item) => item.severity === "error").length,
3199
+ rulesEvaluated: ruleExecutions.length
3193
3200
  },
3194
3201
  findings: [],
3195
- diagnostics: [...diagnostics]
3202
+ diagnostics: [...diagnostics],
3203
+ ruleExecutions: [...ruleExecutions]
3196
3204
  };
3197
3205
  }
3198
3206
  function flattenNodes(nodes) {
@@ -3348,7 +3356,7 @@ function normalizeFinding(rule, finding) {
3348
3356
  ...finding.action !== void 0 ? { action: finding.action } : {}
3349
3357
  };
3350
3358
  }
3351
- function summarize(findings, diagnostics) {
3359
+ function summarize(findings, diagnostics, rulesEvaluated) {
3352
3360
  return {
3353
3361
  passed: findings.filter((finding) => finding.status === "pass").length,
3354
3362
  failed: findings.filter(
@@ -3357,9 +3365,21 @@ function summarize(findings, diagnostics) {
3357
3365
  warnings: findings.filter(
3358
3366
  (finding) => finding.status === "warning" || finding.severity === "warning"
3359
3367
  ).length,
3360
- errors: diagnostics.filter((item) => item.severity === "error").length
3368
+ errors: diagnostics.filter((item) => item.severity === "error").length,
3369
+ rulesEvaluated
3361
3370
  };
3362
3371
  }
3372
+ function classifyRuleExecution(findings, threw) {
3373
+ if (findings.some((finding) => finding.status === "fail" && finding.severity === "error")) {
3374
+ return "fail";
3375
+ }
3376
+ if (findings.some(
3377
+ (finding) => finding.status === "warning" || finding.severity === "warning"
3378
+ )) {
3379
+ return "warning";
3380
+ }
3381
+ return "pass";
3382
+ }
3363
3383
  function eventEvidence(event, path16) {
3364
3384
  return {
3365
3385
  runId: event.runId,
@@ -3725,6 +3745,18 @@ function runTraceChecks(input, options = {}) {
3725
3745
  if (rules.diagnostics.length > 0) {
3726
3746
  return errorResult(input, rules.diagnostics, selected.run);
3727
3747
  }
3748
+ if (rules.rules.length === 0) {
3749
+ return errorResult(
3750
+ input,
3751
+ [
3752
+ diagnostic(
3753
+ "AI_CHECK_NO_RULES_EVALUATED",
3754
+ "No trace check rules were evaluated. Configure at least one rule, contract, or CLI check option."
3755
+ )
3756
+ ],
3757
+ selected.run
3758
+ );
3759
+ }
3728
3760
  const facts = buildFacts(input, selected.run);
3729
3761
  const context = {
3730
3762
  ...facts,
@@ -3733,22 +3765,38 @@ function runTraceChecks(input, options = {}) {
3733
3765
  };
3734
3766
  const diagnostics = [];
3735
3767
  const findings = [];
3768
+ const ruleExecutions = [];
3736
3769
  for (const rule of rules.rules) {
3737
3770
  try {
3738
- findings.push(...rule.evaluate(context).map((finding) => normalizeFinding(rule, finding)));
3771
+ const ruleFindings = rule.evaluate(context).map((finding) => normalizeFinding(rule, finding));
3772
+ findings.push(...ruleFindings);
3773
+ ruleExecutions.push({
3774
+ ruleId: rule.id,
3775
+ category: rule.category,
3776
+ status: classifyRuleExecution(ruleFindings, false),
3777
+ findingCount: ruleFindings.length,
3778
+ ...selected.run ? { runId: selected.run.runId } : {}
3779
+ });
3739
3780
  } catch (error) {
3740
3781
  const message = error instanceof Error ? error.message : String(error);
3741
3782
  diagnostics.push(
3742
3783
  diagnostic("AI_CHECK_INTERNAL_ERROR", `Rule ${rule.id} failed: ${message}`, rule.id)
3743
3784
  );
3785
+ ruleExecutions.push({
3786
+ ruleId: rule.id,
3787
+ category: rule.category,
3788
+ status: "error",
3789
+ findingCount: 0,
3790
+ ...selected.run ? { runId: selected.run.runId } : {}
3791
+ });
3744
3792
  }
3745
3793
  }
3746
3794
  if (diagnostics.length > 0) {
3747
- return errorResult(input, diagnostics, selected.run);
3795
+ return errorResult(input, diagnostics, selected.run, ruleExecutions);
3748
3796
  }
3749
3797
  const eventById = new Map(input.read.events.map((event) => [event.eventId, event]));
3750
3798
  const sortedFindings = findings.sort(compareFindings(eventById));
3751
- const summary = summarize(sortedFindings, diagnostics);
3799
+ const summary = summarize(sortedFindings, diagnostics, ruleExecutions.length);
3752
3800
  const status = summary.failed > 0 ? "fail" : "pass";
3753
3801
  return {
3754
3802
  ok: status === "pass",
@@ -3757,7 +3805,8 @@ function runTraceChecks(input, options = {}) {
3757
3805
  ...selected.run ? { runId: selected.run.runId } : {},
3758
3806
  summary,
3759
3807
  findings: sortedFindings,
3760
- diagnostics
3808
+ diagnostics,
3809
+ ruleExecutions
3761
3810
  };
3762
3811
  }
3763
3812
 
@@ -6644,8 +6693,11 @@ function exportRunTree(tree, options) {
6644
6693
  }
6645
6694
 
6646
6695
  // packages/redact/src/sensitive-key.ts
6696
+ function keyHasExplicitSeparator2(value) {
6697
+ return /[_\-.]/.test(value);
6698
+ }
6647
6699
  function normalizeSensitiveKey2(value) {
6648
- return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
6700
+ return value.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
6649
6701
  }
6650
6702
  var NON_CREDENTIAL_TOKEN_CONFIG_KEYS2 = new Set(
6651
6703
  [
@@ -6675,6 +6727,7 @@ function isCredentialSensitiveKey2(key, sensitiveKeys) {
6675
6727
  const normalized = normalizeSensitiveKey2(key);
6676
6728
  if (!normalized) return false;
6677
6729
  if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS2.has(normalized)) return false;
6730
+ const allowPrefixCompound = keyHasExplicitSeparator2(key);
6678
6731
  for (const sensitive of sensitiveKeys) {
6679
6732
  const s = normalizeSensitiveKey2(sensitive);
6680
6733
  if (!s) continue;
@@ -6683,7 +6736,8 @@ function isCredentialSensitiveKey2(key, sensitiveKeys) {
6683
6736
  continue;
6684
6737
  }
6685
6738
  if (normalized === s) return true;
6686
- if (normalized.endsWith(`_${s}`) || normalized.startsWith(`${s}_`)) return true;
6739
+ if (normalized.endsWith(`_${s}`)) return true;
6740
+ if (allowPrefixCompound && normalized.startsWith(`${s}_`)) return true;
6687
6741
  }
6688
6742
  return false;
6689
6743
  }