@agent-inspect/mcp-server 6.31.4 → 6.31.6

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.cjs CHANGED
@@ -218,7 +218,7 @@ var Redactor = class {
218
218
  };
219
219
 
220
220
  // packages/core/src/safety/credential-value-patterns.ts
221
- var KEY_VALUE_SECRET_PATTERN = /\b(?:api[_-]?key|internal[_-]?token|access[_-]?token|auth[_-]?token|password|secret|token)=(?!\[(?:REDACTED(?::[^\]]*)?|HASH:[0-9a-f]{8})\](?![^\s"'\\&#?;/]))([^\s"'\\]{8,})/i;
221
+ var KEY_VALUE_SECRET_PATTERN = /\b(?:api[_-]?key|internal[_-]?token|access[_-]?token|auth[_-]?token|password|secret|token)=(?!\[(?:REDACTED(?::[^\]]*)?|HASH:[0-9a-f]{8})\](?![^\s"'\\&#?]))([^\s"'\\]{8,})/i;
222
222
  var HIGH_CONFIDENCE_CREDENTIAL_PATTERNS = [
223
223
  /^(?:basic|bearer|digest|apikey)\s+[a-z0-9._~+/=-]+$/i,
224
224
  /\bbearer\s+[a-z0-9._~+/=-]{12,}\b/i,
@@ -3361,7 +3361,7 @@ var DEFAULT_SECRET_PATTERNS = [
3361
3361
  // Keep in sync with packages/redact/src/key-value-secret.ts (KEY_VALUE_SECRET_PATTERN_SOURCE).
3362
3362
  {
3363
3363
  id: "key-value-secret",
3364
- pattern: /\b(?:api[_-]?key|internal[_-]?token|access[_-]?token|auth[_-]?token|password|secret|token)=(?!\[(?:REDACTED(?::[^\]]*)?|HASH:[0-9a-f]{8})\](?![^\s"'\\&#?;/]))([^\s"'\\]{8,})/i
3364
+ pattern: /\b(?:api[_-]?key|internal[_-]?token|access[_-]?token|auth[_-]?token|password|secret|token)=(?!\[(?:REDACTED(?::[^\]]*)?|HASH:[0-9a-f]{8})\](?![^\s"'\\&#?]))([^\s"'\\]{8,})/i
3365
3365
  }
3366
3366
  ];
3367
3367
  function compareStrings(a, b) {
@@ -3676,9 +3676,6 @@ function limitFindings(findings, maxFindings) {
3676
3676
  if (maxFindings === void 0 || findings.length <= maxFindings) return findings;
3677
3677
  return findings.slice(0, Math.max(0, maxFindings));
3678
3678
  }
3679
- function hasRedactionMarker(value, markers) {
3680
- return markers.some((marker) => value.includes(marker)) || /^\[HASH:[A-Za-z0-9_-]+\]$/.test(value);
3681
- }
3682
3679
  function isFullyRedactedValue(value, markers = ["[REDACTED]", "[REDACTED:"]) {
3683
3680
  if (typeof value !== "string") return false;
3684
3681
  const trimmed = value.trim();
@@ -3763,7 +3760,7 @@ function createSafetyRedactionRule(options = {}) {
3763
3760
  for (const event of context.events) {
3764
3761
  for (const entry of eventValueEntries(event, { includeSummaries: true, includeError: true })) {
3765
3762
  if (!isSensitiveKey(entry.key ?? lastPathSegment(entry.path), sensitiveKeys)) continue;
3766
- if (typeof entry.value === "string" && hasRedactionMarker(entry.value, markers)) continue;
3763
+ if (isFullyRedactedValue(entry.value, markers)) continue;
3767
3764
  findings.push(
3768
3765
  failFinding(
3769
3766
  "safety.redaction",
@@ -6704,6 +6701,21 @@ var EXPORT_PAYLOAD_VERSION = "0.1.2";
6704
6701
 
6705
6702
  // packages/core/src/safety/url-redaction.ts
6706
6703
  var HTTP_URL = /^https?:\/\/[^\s]+$/i;
6704
+ var CONNECTION_PROTOCOLS = /* @__PURE__ */ new Set([
6705
+ "postgres:",
6706
+ "postgresql:",
6707
+ "mysql:",
6708
+ "mariadb:",
6709
+ "mongodb:",
6710
+ "mongodb+srv:",
6711
+ "redis:",
6712
+ "rediss:",
6713
+ "amqp:",
6714
+ "amqps:"
6715
+ ]);
6716
+ var CONNECTION_URI = /^(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|rediss?|amqps?):\/\/[^\s]+$/i;
6717
+ var CONNECTION_USERINFO = /^(postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|rediss?|amqps?):\/\/([^@/?#]+)@(.+)$/i;
6718
+ var CONNECTION_HAS_USERINFO = /^(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|rediss?|amqps?):\/\/[^@/?#]+@/i;
6707
6719
  var UUID_SEGMENT = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
6708
6720
  var HEX_SEGMENT = /^[0-9a-f]{12,}$/i;
6709
6721
  var NUMERIC_SEGMENT = /^\d{5,}$/;
@@ -6711,14 +6723,47 @@ var OPAQUE_SEGMENT = /^[A-Za-z0-9_-]{20,}$/;
6711
6723
  function looksLikeHttpUrl(value) {
6712
6724
  return HTTP_URL.test(value.trim());
6713
6725
  }
6714
- function parseHttpUrl(value) {
6726
+ function looksLikeConnectionUri(value) {
6727
+ return CONNECTION_URI.test(value.trim());
6728
+ }
6729
+ function looksLikeUrlForRedaction(value) {
6730
+ return looksLikeHttpUrl(value) || looksLikeConnectionUri(value);
6731
+ }
6732
+ function parseRedactableUrl(value) {
6715
6733
  try {
6716
6734
  const url = new URL(value.trim());
6717
- return url.protocol === "http:" || url.protocol === "https:" ? url : void 0;
6735
+ if (url.protocol === "http:" || url.protocol === "https:") return url;
6736
+ if (CONNECTION_PROTOCOLS.has(url.protocol)) return url;
6737
+ return void 0;
6718
6738
  } catch {
6719
6739
  return void 0;
6720
6740
  }
6721
6741
  }
6742
+ function redactConnectionUserinfoFallback(value, replacement) {
6743
+ const trimmed = value.trim();
6744
+ const match = CONNECTION_USERINFO.exec(trimmed);
6745
+ if (match) {
6746
+ const [, scheme, , rest] = match;
6747
+ if (scheme && rest && rest.length > 0) {
6748
+ return {
6749
+ value: `${scheme}://${rest}`,
6750
+ credentialRedacted: true,
6751
+ identifiersMasked: false
6752
+ };
6753
+ }
6754
+ }
6755
+ if (looksLikeConnectionUri(trimmed) && CONNECTION_HAS_USERINFO.test(trimmed)) {
6756
+ return {
6757
+ value: replacement,
6758
+ credentialRedacted: true,
6759
+ identifiersMasked: false
6760
+ };
6761
+ }
6762
+ return void 0;
6763
+ }
6764
+ function isHttpProtocol(protocol) {
6765
+ return protocol === "http:" || protocol === "https:";
6766
+ }
6722
6767
  function isIdentifierSegment(segment) {
6723
6768
  if (UUID_SEGMENT.test(segment)) return true;
6724
6769
  if (HEX_SEGMENT.test(segment)) return true;
@@ -6756,15 +6801,18 @@ function redactUrlString(value, options) {
6756
6801
  credentialRedacted: false,
6757
6802
  identifiersMasked: false
6758
6803
  };
6759
- if (!looksLikeHttpUrl(value)) return unchanged;
6760
- const url = parseHttpUrl(value);
6761
- if (!url) return unchanged;
6804
+ if (!looksLikeUrlForRedaction(value)) return unchanged;
6762
6805
  const replacement = options.replacement ?? "[REDACTED]";
6806
+ const url = parseRedactableUrl(value);
6807
+ if (!url) {
6808
+ return redactConnectionUserinfoFallback(value, replacement) ?? unchanged;
6809
+ }
6763
6810
  const idPlaceholder = options.idPlaceholder ?? "[id]";
6811
+ const http = isHttpProtocol(url.protocol);
6764
6812
  let credentialRedacted = url.username.length > 0 || url.password.length > 0;
6765
6813
  let identifiersMasked = false;
6766
6814
  let pathname = url.pathname;
6767
- if (options.maskPathIds === true) {
6815
+ if (http && options.maskPathIds === true) {
6768
6816
  pathname = url.pathname.split("/").map((segment) => {
6769
6817
  if (segment.length === 0 || !isIdentifierSegment(decodeParam(segment))) {
6770
6818
  return segment;
@@ -7550,7 +7598,7 @@ function isCredentialSensitiveKey2(key, sensitiveKeys) {
7550
7598
  }
7551
7599
 
7552
7600
  // packages/redact/src/key-value-secret.ts
7553
- var KEY_VALUE_SECRET_PATTERN_SOURCE = String.raw`\b(?:api[_-]?key|internal[_-]?token|access[_-]?token|auth[_-]?token|password|secret|token)=(?!\[(?:REDACTED(?::[^\]]*)?|HASH:[0-9a-f]{8})\](?![^\s"'\\&#?;/]))([^\s"'\\]{8,})`;
7601
+ var KEY_VALUE_SECRET_PATTERN_SOURCE = String.raw`\b(?:api[_-]?key|internal[_-]?token|access[_-]?token|auth[_-]?token|password|secret|token)=(?!\[(?:REDACTED(?::[^\]]*)?|HASH:[0-9a-f]{8})\](?![^\s"'\\&#?]))([^\s"'\\]{8,})`;
7554
7602
  var KEY_VALUE_SECRET_PATTERN2 = new RegExp(
7555
7603
  KEY_VALUE_SECRET_PATTERN_SOURCE,
7556
7604
  "i"
@@ -7562,6 +7610,21 @@ function valueContainsKeyValueSecret(value) {
7562
7610
 
7563
7611
  // packages/redact/src/url-redaction.ts
7564
7612
  var HTTP_URL2 = /^https?:\/\/[^\s]+$/i;
7613
+ var CONNECTION_PROTOCOLS2 = /* @__PURE__ */ new Set([
7614
+ "postgres:",
7615
+ "postgresql:",
7616
+ "mysql:",
7617
+ "mariadb:",
7618
+ "mongodb:",
7619
+ "mongodb+srv:",
7620
+ "redis:",
7621
+ "rediss:",
7622
+ "amqp:",
7623
+ "amqps:"
7624
+ ]);
7625
+ var CONNECTION_URI2 = /^(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|rediss?|amqps?):\/\/[^\s]+$/i;
7626
+ var CONNECTION_USERINFO2 = /^(postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|rediss?|amqps?):\/\/([^@/?#]+)@(.+)$/i;
7627
+ var CONNECTION_HAS_USERINFO2 = /^(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|rediss?|amqps?):\/\/[^@/?#]+@/i;
7565
7628
  var UUID_SEGMENT2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
7566
7629
  var HEX_SEGMENT2 = /^[0-9a-f]{12,}$/i;
7567
7630
  var NUMERIC_SEGMENT2 = /^\d{5,}$/;
@@ -7569,14 +7632,47 @@ var OPAQUE_SEGMENT2 = /^[A-Za-z0-9_-]{20,}$/;
7569
7632
  function looksLikeHttpUrl2(value) {
7570
7633
  return HTTP_URL2.test(value.trim());
7571
7634
  }
7572
- function parseHttpUrl2(value) {
7635
+ function looksLikeConnectionUri2(value) {
7636
+ return CONNECTION_URI2.test(value.trim());
7637
+ }
7638
+ function looksLikeUrlForRedaction2(value) {
7639
+ return looksLikeHttpUrl2(value) || looksLikeConnectionUri2(value);
7640
+ }
7641
+ function parseRedactableUrl2(value) {
7573
7642
  try {
7574
7643
  const url = new URL(value.trim());
7575
- return url.protocol === "http:" || url.protocol === "https:" ? url : void 0;
7644
+ if (url.protocol === "http:" || url.protocol === "https:") return url;
7645
+ if (CONNECTION_PROTOCOLS2.has(url.protocol)) return url;
7646
+ return void 0;
7576
7647
  } catch {
7577
7648
  return void 0;
7578
7649
  }
7579
7650
  }
7651
+ function redactConnectionUserinfoFallback2(value, replacement) {
7652
+ const trimmed = value.trim();
7653
+ const match = CONNECTION_USERINFO2.exec(trimmed);
7654
+ if (match) {
7655
+ const [, scheme, , rest] = match;
7656
+ if (scheme && rest && rest.length > 0) {
7657
+ return {
7658
+ value: `${scheme}://${rest}`,
7659
+ credentialRedacted: true,
7660
+ identifiersMasked: false
7661
+ };
7662
+ }
7663
+ }
7664
+ if (looksLikeConnectionUri2(trimmed) && CONNECTION_HAS_USERINFO2.test(trimmed)) {
7665
+ return {
7666
+ value: replacement,
7667
+ credentialRedacted: true,
7668
+ identifiersMasked: false
7669
+ };
7670
+ }
7671
+ return void 0;
7672
+ }
7673
+ function isHttpProtocol2(protocol) {
7674
+ return protocol === "http:" || protocol === "https:";
7675
+ }
7580
7676
  function isIdentifierSegment2(segment) {
7581
7677
  if (UUID_SEGMENT2.test(segment)) return true;
7582
7678
  if (HEX_SEGMENT2.test(segment)) return true;
@@ -7614,15 +7710,18 @@ function redactUrlString2(value, options) {
7614
7710
  credentialRedacted: false,
7615
7711
  identifiersMasked: false
7616
7712
  };
7617
- if (!looksLikeHttpUrl2(value)) return unchanged;
7618
- const url = parseHttpUrl2(value);
7619
- if (!url) return unchanged;
7713
+ if (!looksLikeUrlForRedaction2(value)) return unchanged;
7620
7714
  const replacement = options.replacement ?? "[REDACTED]";
7715
+ const url = parseRedactableUrl2(value);
7716
+ if (!url) {
7717
+ return redactConnectionUserinfoFallback2(value, replacement) ?? unchanged;
7718
+ }
7621
7719
  const idPlaceholder = options.idPlaceholder ?? "[id]";
7720
+ const http = isHttpProtocol2(url.protocol);
7622
7721
  let credentialRedacted = url.username.length > 0 || url.password.length > 0;
7623
7722
  let identifiersMasked = false;
7624
7723
  let pathname = url.pathname;
7625
- if (options.maskPathIds === true) {
7724
+ if (http && options.maskPathIds === true) {
7626
7725
  pathname = url.pathname.split("/").map((segment) => {
7627
7726
  if (segment.length === 0 || !isIdentifierSegment2(decodeParam2(segment))) {
7628
7727
  return segment;
@@ -8072,7 +8171,7 @@ var Redactor2 = class {
8072
8171
  return applyRule(rule, value, this.#replacement);
8073
8172
  }
8074
8173
  }
8075
- if (typeof value === "string" && looksLikeHttpUrl2(value)) {
8174
+ if (typeof value === "string" && looksLikeUrlForRedaction2(value)) {
8076
8175
  const url = redactUrlString2(value, {
8077
8176
  sensitiveKeys: this.#sensitiveKeys,
8078
8177
  isSensitiveValue: (candidate) => this.#detect(candidate, key, path17) !== void 0,