@agent-inspect/mcp-server 6.14.0 → 6.14.2

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-C6EBJS57.mjs';
1
+ import { runReadOnlyMcpServer } from './chunk-7AL325ZU.mjs';
2
2
  import { readFileSync } from 'fs';
3
3
  import path from 'path';
4
4
  import { fileURLToPath } from 'url';
package/dist/index.cjs CHANGED
@@ -2578,6 +2578,73 @@ function diffRuns(left, right, options) {
2578
2578
  return table;
2579
2579
  })();
2580
2580
 
2581
+ // packages/core/src/safety/sensitive-key.ts
2582
+ function normalizeSensitiveKey(value) {
2583
+ return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
2584
+ }
2585
+ var NON_CREDENTIAL_TOKEN_CONFIG_KEYS = new Set(
2586
+ [
2587
+ "tokens",
2588
+ "max_tokens",
2589
+ "min_tokens",
2590
+ "ls_max_tokens",
2591
+ "token_count",
2592
+ "token_limit",
2593
+ "token_budget",
2594
+ "input_tokens",
2595
+ "output_tokens",
2596
+ "total_tokens",
2597
+ "cached_tokens",
2598
+ "prompt_tokens",
2599
+ "completion_tokens"
2600
+ ].map(normalizeSensitiveKey)
2601
+ );
2602
+ var DEFAULT_CREDENTIAL_SENSITIVE_KEYS = [
2603
+ "authorization",
2604
+ "cookie",
2605
+ "token",
2606
+ "access_token",
2607
+ "accesstoken",
2608
+ "auth_token",
2609
+ "authtoken",
2610
+ "refresh_token",
2611
+ "refreshtoken",
2612
+ "id_token",
2613
+ "idtoken",
2614
+ "bearer_token",
2615
+ "bearertoken",
2616
+ "api_token",
2617
+ "apitoken",
2618
+ "apikey",
2619
+ "api_key",
2620
+ "password",
2621
+ "secret",
2622
+ "email"
2623
+ ];
2624
+ function isTokenCredentialKey(normalized) {
2625
+ if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
2626
+ if (normalized === "token") return true;
2627
+ if (normalized.endsWith("tokens")) return false;
2628
+ return normalized.endsWith("token");
2629
+ }
2630
+ function isCredentialSensitiveKey(key, sensitiveKeys = DEFAULT_CREDENTIAL_SENSITIVE_KEYS) {
2631
+ if (!key) return false;
2632
+ const normalized = normalizeSensitiveKey(key);
2633
+ if (!normalized) return false;
2634
+ if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
2635
+ for (const sensitive of sensitiveKeys) {
2636
+ const s = normalizeSensitiveKey(sensitive);
2637
+ if (!s) continue;
2638
+ if (s === "token") {
2639
+ if (isTokenCredentialKey(normalized)) return true;
2640
+ continue;
2641
+ }
2642
+ if (normalized === s) return true;
2643
+ if (normalized.endsWith(`_${s}`) || normalized.startsWith(`${s}_`)) return true;
2644
+ }
2645
+ return false;
2646
+ }
2647
+
2581
2648
  // packages/core/src/checks/logical-events.ts
2582
2649
  function isRecord6(value) {
2583
2650
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -2773,6 +2840,23 @@ function projectLogicalEvents(events) {
2773
2840
  }
2774
2841
  }
2775
2842
  if (!remapped) {
2843
+ if (originalParentId === event.eventId) {
2844
+ diagnostics.push({
2845
+ code: "AI_LOGICAL_SELF_PARENT_REMOVED",
2846
+ message: `Removed self-parent edge on ${event.eventId}.`,
2847
+ eventIds: [event.eventId]
2848
+ });
2849
+ const { parentId: _drop, ...rest } = event;
2850
+ normalized.push({
2851
+ ...rest,
2852
+ projection: {
2853
+ ...event.projection,
2854
+ parentNormalized: true,
2855
+ originalParentId
2856
+ }
2857
+ });
2858
+ continue;
2859
+ }
2776
2860
  if (!logicalById.has(originalParentId) && !logicalByRawId.has(originalParentId)) {
2777
2861
  const mapping = event.attributes?.parentMapping;
2778
2862
  const unresolved = mapping === "unresolved" || event.attributes?.parentUnresolved === true || event.attributes?.unresolvedParent === true || // LangGraph/framework scaffolding sentinel labels are not event ids.
@@ -2788,6 +2872,23 @@ function projectLogicalEvents(events) {
2788
2872
  normalized.push(event);
2789
2873
  continue;
2790
2874
  }
2875
+ if (nextParent === event.eventId) {
2876
+ diagnostics.push({
2877
+ code: "AI_LOGICAL_SELF_PARENT_REMOVED",
2878
+ message: `Removed self-parent edge on ${event.eventId} (was ${originalParentId}).`,
2879
+ eventIds: [event.eventId]
2880
+ });
2881
+ const { parentId: _drop, ...rest } = event;
2882
+ normalized.push({
2883
+ ...rest,
2884
+ projection: {
2885
+ ...event.projection,
2886
+ parentNormalized: true,
2887
+ originalParentId
2888
+ }
2889
+ });
2890
+ continue;
2891
+ }
2791
2892
  diagnostics.push({
2792
2893
  code: "AI_LOGICAL_PARENT_REMAPPED",
2793
2894
  message: `Remapped parent ${originalParentId} \u2192 ${nextParent} for ${event.eventId}.`,
@@ -2904,16 +3005,7 @@ var STATUS_RANK = {
2904
3005
  warning: 1,
2905
3006
  pass: 2
2906
3007
  };
2907
- var DEFAULT_SENSITIVE_KEYS = [
2908
- "authorization",
2909
- "cookie",
2910
- "token",
2911
- "apikey",
2912
- "api_key",
2913
- "password",
2914
- "secret",
2915
- "email"
2916
- ];
3008
+ var DEFAULT_SENSITIVE_KEYS = DEFAULT_CREDENTIAL_SENSITIVE_KEYS;
2917
3009
  var DEFAULT_RAW_CONTENT_KEYS = [
2918
3010
  "body",
2919
3011
  "headers",
@@ -3268,9 +3360,7 @@ function hasRedactionMarker(value, markers) {
3268
3360
  return markers.some((marker) => value.includes(marker)) || /^\[HASH:[A-Za-z0-9_-]+\]$/.test(value);
3269
3361
  }
3270
3362
  function isSensitiveKey(key, sensitiveKeys) {
3271
- if (!key) return false;
3272
- const normalized = normalizedKey(key);
3273
- return sensitiveKeys.some((sensitive) => normalized.includes(normalizedKey(sensitive)));
3363
+ return isCredentialSensitiveKey(key, sensitiveKeys);
3274
3364
  }
3275
3365
  function isRawContentKey(key, forbiddenKeys) {
3276
3366
  if (!key) return false;
@@ -3840,6 +3930,20 @@ function traceEventsToPersistedInspectEvents(events, options) {
3840
3930
  function inc(map, key) {
3841
3931
  map[key] = (map[key] ?? 0) + 1;
3842
3932
  }
3933
+ function confidenceRank(confidence) {
3934
+ switch (confidence) {
3935
+ case "unknown":
3936
+ return 0;
3937
+ case "heuristic":
3938
+ return 1;
3939
+ case "correlated":
3940
+ return 2;
3941
+ case "explicit":
3942
+ return 3;
3943
+ default:
3944
+ return 0;
3945
+ }
3946
+ }
3843
3947
  function computeRunStatus(events) {
3844
3948
  let runTerminal;
3845
3949
  let sawRunEvent = false;
@@ -3860,6 +3964,84 @@ function computeRunStatus(events) {
3860
3964
  }
3861
3965
  return hasRunning ? "running" : "ok";
3862
3966
  }
3967
+ function linkNodesVisibilityFirst(nodes) {
3968
+ let selfParentCount = 0;
3969
+ let unresolvedParentCount = 0;
3970
+ let normalizedEdgeCount = 0;
3971
+ let cycleCount = 0;
3972
+ const pending = [];
3973
+ for (const node of nodes.values()) {
3974
+ const parentId = node.event.parentId;
3975
+ if (!parentId) continue;
3976
+ if (parentId === node.event.eventId) {
3977
+ selfParentCount += 1;
3978
+ normalizedEdgeCount += 1;
3979
+ continue;
3980
+ }
3981
+ if (!nodes.has(parentId)) {
3982
+ unresolvedParentCount += 1;
3983
+ continue;
3984
+ }
3985
+ pending.push({
3986
+ childId: node.event.eventId,
3987
+ parentId,
3988
+ childTimestamp: node.event.timestamp,
3989
+ childConfidence: node.event.confidence
3990
+ });
3991
+ }
3992
+ pending.sort((a, b) => {
3993
+ const conf = confidenceRank(b.childConfidence) - confidenceRank(a.childConfidence);
3994
+ if (conf !== 0) return conf;
3995
+ return a.childTimestamp - b.childTimestamp;
3996
+ });
3997
+ const parentOf = /* @__PURE__ */ new Map();
3998
+ for (const edge of pending) {
3999
+ parentOf.set(edge.childId, edge.parentId);
4000
+ let cursor = edge.parentId;
4001
+ const seen = /* @__PURE__ */ new Set([edge.childId]);
4002
+ let cyclic = false;
4003
+ while (cursor) {
4004
+ if (seen.has(cursor)) {
4005
+ cyclic = true;
4006
+ break;
4007
+ }
4008
+ seen.add(cursor);
4009
+ cursor = parentOf.get(cursor);
4010
+ }
4011
+ if (cyclic) {
4012
+ parentOf.delete(edge.childId);
4013
+ cycleCount += 1;
4014
+ normalizedEdgeCount += 1;
4015
+ }
4016
+ }
4017
+ for (const [childId, parentId] of parentOf) {
4018
+ nodes.get(parentId).children.push(nodes.get(childId));
4019
+ }
4020
+ const roots = [];
4021
+ for (const node of nodes.values()) {
4022
+ if (!parentOf.has(node.event.eventId)) {
4023
+ roots.push(node);
4024
+ }
4025
+ }
4026
+ const assignDepth = (n, depth, stack) => {
4027
+ if (stack.has(n.event.eventId)) return;
4028
+ n.depth = depth;
4029
+ stack.add(n.event.eventId);
4030
+ for (const c of n.children) assignDepth(c, depth + 1, stack);
4031
+ stack.delete(n.event.eventId);
4032
+ };
4033
+ for (const r of roots) assignDepth(r, 0, /* @__PURE__ */ new Set());
4034
+ return {
4035
+ roots,
4036
+ summary: {
4037
+ rootCount: roots.length,
4038
+ selfParentCount,
4039
+ cycleCount,
4040
+ unresolvedParentCount,
4041
+ normalizedEdgeCount
4042
+ }
4043
+ };
4044
+ }
3863
4045
  var TreeBuilder = class {
3864
4046
  constructor(options) {
3865
4047
  void options?.config;
@@ -3877,20 +4059,7 @@ var TreeBuilder = class {
3877
4059
  for (const e of sorted) {
3878
4060
  nodes.set(e.eventId, { event: e, children: [], depth: 0 });
3879
4061
  }
3880
- const roots = [];
3881
- for (const node of nodes.values()) {
3882
- const parentId = node.event.parentId;
3883
- if (parentId && nodes.has(parentId)) {
3884
- nodes.get(parentId).children.push(node);
3885
- } else {
3886
- roots.push(node);
3887
- }
3888
- }
3889
- const assignDepth = (n, depth) => {
3890
- n.depth = depth;
3891
- for (const c of n.children) assignDepth(c, depth + 1);
3892
- };
3893
- for (const r of roots) assignDepth(r, 0);
4062
+ const { roots, summary } = linkNodesVisibilityFirst(nodes);
3894
4063
  const confidenceBreakdown = {
3895
4064
  explicit: 0,
3896
4065
  correlated: 0,
@@ -3918,7 +4087,8 @@ var TreeBuilder = class {
3918
4087
  metadata: {
3919
4088
  totalEvents: sorted.length,
3920
4089
  confidenceBreakdown,
3921
- kinds
4090
+ kinds,
4091
+ relationshipSummary: summary
3922
4092
  }
3923
4093
  });
3924
4094
  }
@@ -6332,6 +6502,53 @@ function exportRunTree(tree, options) {
6332
6502
  }
6333
6503
  }
6334
6504
  }
6505
+
6506
+ // packages/redact/src/sensitive-key.ts
6507
+ function normalizeSensitiveKey2(value) {
6508
+ return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
6509
+ }
6510
+ var NON_CREDENTIAL_TOKEN_CONFIG_KEYS2 = new Set(
6511
+ [
6512
+ "tokens",
6513
+ "max_tokens",
6514
+ "min_tokens",
6515
+ "ls_max_tokens",
6516
+ "token_count",
6517
+ "token_limit",
6518
+ "token_budget",
6519
+ "input_tokens",
6520
+ "output_tokens",
6521
+ "total_tokens",
6522
+ "cached_tokens",
6523
+ "prompt_tokens",
6524
+ "completion_tokens"
6525
+ ].map(normalizeSensitiveKey2)
6526
+ );
6527
+ function isTokenCredentialKey2(normalized) {
6528
+ if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS2.has(normalized)) return false;
6529
+ if (normalized === "token") return true;
6530
+ if (normalized.endsWith("tokens")) return false;
6531
+ return normalized.endsWith("token");
6532
+ }
6533
+ function isCredentialSensitiveKey2(key, sensitiveKeys) {
6534
+ if (!key) return false;
6535
+ const normalized = normalizeSensitiveKey2(key);
6536
+ if (!normalized) return false;
6537
+ if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS2.has(normalized)) return false;
6538
+ for (const sensitive of sensitiveKeys) {
6539
+ const s = normalizeSensitiveKey2(sensitive);
6540
+ if (!s) continue;
6541
+ if (s === "token") {
6542
+ if (isTokenCredentialKey2(normalized)) return true;
6543
+ continue;
6544
+ }
6545
+ if (normalized === s) return true;
6546
+ if (normalized.endsWith(`_${s}`) || normalized.startsWith(`${s}_`)) return true;
6547
+ }
6548
+ return false;
6549
+ }
6550
+
6551
+ // packages/redact/src/index.ts
6335
6552
  var DEFAULT_REDACT_KEYS2 = [
6336
6553
  "authorization",
6337
6554
  "cookie",
@@ -6393,6 +6610,12 @@ function isRecord11(value) {
6393
6610
  function toKey2(key) {
6394
6611
  return key.toLowerCase();
6395
6612
  }
6613
+ function findCompiledKeyRule(key, rules) {
6614
+ const exact = toKey2(key);
6615
+ const direct = rules.find((candidate) => candidate.key === exact);
6616
+ if (direct) return direct;
6617
+ return rules.find((candidate) => isCredentialSensitiveKey2(key, [candidate.key]));
6618
+ }
6396
6619
  function stableHash2(value) {
6397
6620
  const hash = crypto__default.default.createHash("sha256").update(value, "utf8").digest("hex");
6398
6621
  return hash.slice(0, 8);
@@ -6714,7 +6937,7 @@ var Redactor2 = class {
6714
6937
  return "[Truncated]";
6715
6938
  }
6716
6939
  if (key !== void 0) {
6717
- const rule = this.#rules.find((candidate) => candidate.key === toKey2(key));
6940
+ const rule = findCompiledKeyRule(key, this.#rules);
6718
6941
  if (rule) {
6719
6942
  this.#recordFinding(
6720
6943
  state,