agent-inspect 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.
Files changed (40) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -1
  3. package/docs/SAFE-TRACE-SHARING.md +1 -1
  4. package/package.json +1 -1
  5. package/packages/cli/dist/{chunk-LKEPABND.mjs → chunk-YXDNWHNJ.mjs} +5 -8
  6. package/packages/cli/dist/chunk-YXDNWHNJ.mjs.map +1 -0
  7. package/packages/cli/dist/index.cjs +120 -21
  8. package/packages/cli/dist/index.cjs.map +1 -1
  9. package/packages/cli/dist/index.mjs +120 -18
  10. package/packages/cli/dist/index.mjs.map +1 -1
  11. package/packages/cli/dist/{src-4WYF5RFI.mjs → src-H22KNWAZ.mjs} +3 -3
  12. package/packages/cli/dist/{src-4WYF5RFI.mjs.map → src-H22KNWAZ.mjs.map} +1 -1
  13. package/packages/core/dist/advanced.cjs +1 -1
  14. package/packages/core/dist/advanced.cjs.map +1 -1
  15. package/packages/core/dist/advanced.mjs +9 -9
  16. package/packages/core/dist/checks.cjs +2 -5
  17. package/packages/core/dist/checks.cjs.map +1 -1
  18. package/packages/core/dist/checks.mjs +3 -3
  19. package/packages/core/dist/{chunk-2KJR6X4V.mjs → chunk-DK3OW6UI.mjs} +3 -3
  20. package/packages/core/dist/chunk-DK3OW6UI.mjs.map +1 -0
  21. package/packages/core/dist/{chunk-NY4ILMXK.mjs → chunk-EXGQLMVB.mjs} +3 -3
  22. package/packages/core/dist/{chunk-NY4ILMXK.mjs.map → chunk-EXGQLMVB.mjs.map} +1 -1
  23. package/packages/core/dist/{chunk-PKDBFBJ7.mjs → chunk-LXYPM2ZO.mjs} +5 -8
  24. package/packages/core/dist/{chunk-PKDBFBJ7.mjs.map → chunk-LXYPM2ZO.mjs.map} +1 -1
  25. package/packages/core/dist/{chunk-INE5IWLN.mjs → chunk-N5PZAI6Q.mjs} +3 -3
  26. package/packages/core/dist/{chunk-INE5IWLN.mjs.map → chunk-N5PZAI6Q.mjs.map} +1 -1
  27. package/packages/core/dist/{chunk-MTMTXTJL.mjs → chunk-VQUB3WRI.mjs} +4 -4
  28. package/packages/core/dist/{chunk-MTMTXTJL.mjs.map → chunk-VQUB3WRI.mjs.map} +1 -1
  29. package/packages/core/dist/exporters.cjs +58 -7
  30. package/packages/core/dist/exporters.cjs.map +1 -1
  31. package/packages/core/dist/exporters.mjs +60 -9
  32. package/packages/core/dist/exporters.mjs.map +1 -1
  33. package/packages/core/dist/index.cjs +1 -1
  34. package/packages/core/dist/index.cjs.map +1 -1
  35. package/packages/core/dist/index.mjs +4 -4
  36. package/packages/core/dist/writers.cjs +1 -1
  37. package/packages/core/dist/writers.cjs.map +1 -1
  38. package/packages/core/dist/writers.mjs +1 -1
  39. package/packages/cli/dist/chunk-LKEPABND.mjs.map +0 -1
  40. package/packages/core/dist/chunk-2KJR6X4V.mjs.map +0 -1
@@ -261,7 +261,7 @@ function stringContainsHighConfidenceCredential(value) {
261
261
  var KEY_VALUE_SECRET_PATTERN, HIGH_CONFIDENCE_CREDENTIAL_PATTERNS;
262
262
  var init_credential_value_patterns = __esm({
263
263
  "packages/core/src/safety/credential-value-patterns.ts"() {
264
- 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;
264
+ 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;
265
265
  HIGH_CONFIDENCE_CREDENTIAL_PATTERNS = [
266
266
  /^(?:basic|bearer|digest|apikey)\s+[a-z0-9._~+/=-]+$/i,
267
267
  /\bbearer\s+[a-z0-9._~+/=-]{12,}\b/i,
@@ -5848,9 +5848,6 @@ function limitFindings(findings, maxFindings) {
5848
5848
  if (maxFindings === void 0 || findings.length <= maxFindings) return findings;
5849
5849
  return findings.slice(0, Math.max(0, maxFindings));
5850
5850
  }
5851
- function hasRedactionMarker(value, markers) {
5852
- return markers.some((marker) => value.includes(marker)) || /^\[HASH:[A-Za-z0-9_-]+\]$/.test(value);
5853
- }
5854
5851
  function isFullyRedactedValue(value, markers = ["[REDACTED]", "[REDACTED:"]) {
5855
5852
  if (typeof value !== "string") return false;
5856
5853
  const trimmed = value.trim();
@@ -6837,7 +6834,7 @@ function createSafetyRedactionRule(options = {}) {
6837
6834
  for (const event of context.events) {
6838
6835
  for (const entry of eventValueEntries(event, { includeSummaries: true, includeError: true })) {
6839
6836
  if (!isSensitiveKey(entry.key ?? lastPathSegment(entry.path), sensitiveKeys)) continue;
6840
- if (typeof entry.value === "string" && hasRedactionMarker(entry.value, markers)) continue;
6837
+ if (isFullyRedactedValue(entry.value, markers)) continue;
6841
6838
  findings.push(
6842
6839
  failFinding(
6843
6840
  "safety.redaction",
@@ -7362,7 +7359,7 @@ var init_checks2 = __esm({
7362
7359
  // Keep in sync with packages/redact/src/key-value-secret.ts (KEY_VALUE_SECRET_PATTERN_SOURCE).
7363
7360
  {
7364
7361
  id: "key-value-secret",
7365
- pattern: /\b(?:api[_-]?key|internal[_-]?token|access[_-]?token|auth[_-]?token|password|secret|token)=(?!\[(?:REDACTED(?::[^\]]*)?|HASH:[0-9a-f]{8})\](?![^\s"'\\&#?;/]))([^\s"'\\]{8,})/i
7362
+ pattern: /\b(?:api[_-]?key|internal[_-]?token|access[_-]?token|auth[_-]?token|password|secret|token)=(?!\[(?:REDACTED(?::[^\]]*)?|HASH:[0-9a-f]{8})\](?![^\s"'\\&#?]))([^\s"'\\]{8,})/i
7366
7363
  }
7367
7364
  ];
7368
7365
  }
@@ -16165,7 +16162,7 @@ var init_src = __esm({
16165
16162
  });
16166
16163
 
16167
16164
  // package.json
16168
- var version = "6.31.4";
16165
+ var version = "6.31.6";
16169
16166
 
16170
16167
  // packages/cli/src/list.ts
16171
16168
  init_advanced();
@@ -17962,6 +17959,21 @@ init_credential_value_patterns();
17962
17959
  // packages/core/src/safety/url-redaction.ts
17963
17960
  init_sensitive_key();
17964
17961
  var HTTP_URL = /^https?:\/\/[^\s]+$/i;
17962
+ var CONNECTION_PROTOCOLS = /* @__PURE__ */ new Set([
17963
+ "postgres:",
17964
+ "postgresql:",
17965
+ "mysql:",
17966
+ "mariadb:",
17967
+ "mongodb:",
17968
+ "mongodb+srv:",
17969
+ "redis:",
17970
+ "rediss:",
17971
+ "amqp:",
17972
+ "amqps:"
17973
+ ]);
17974
+ var CONNECTION_URI = /^(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|rediss?|amqps?):\/\/[^\s]+$/i;
17975
+ var CONNECTION_USERINFO = /^(postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|rediss?|amqps?):\/\/([^@/?#]+)@(.+)$/i;
17976
+ var CONNECTION_HAS_USERINFO = /^(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|rediss?|amqps?):\/\/[^@/?#]+@/i;
17965
17977
  var UUID_SEGMENT = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
17966
17978
  var HEX_SEGMENT = /^[0-9a-f]{12,}$/i;
17967
17979
  var NUMERIC_SEGMENT = /^\d{5,}$/;
@@ -17969,14 +17981,47 @@ var OPAQUE_SEGMENT = /^[A-Za-z0-9_-]{20,}$/;
17969
17981
  function looksLikeHttpUrl(value) {
17970
17982
  return HTTP_URL.test(value.trim());
17971
17983
  }
17972
- function parseHttpUrl(value) {
17984
+ function looksLikeConnectionUri(value) {
17985
+ return CONNECTION_URI.test(value.trim());
17986
+ }
17987
+ function looksLikeUrlForRedaction(value) {
17988
+ return looksLikeHttpUrl(value) || looksLikeConnectionUri(value);
17989
+ }
17990
+ function parseRedactableUrl(value) {
17973
17991
  try {
17974
17992
  const url = new URL(value.trim());
17975
- return url.protocol === "http:" || url.protocol === "https:" ? url : void 0;
17993
+ if (url.protocol === "http:" || url.protocol === "https:") return url;
17994
+ if (CONNECTION_PROTOCOLS.has(url.protocol)) return url;
17995
+ return void 0;
17976
17996
  } catch {
17977
17997
  return void 0;
17978
17998
  }
17979
17999
  }
18000
+ function redactConnectionUserinfoFallback(value, replacement) {
18001
+ const trimmed = value.trim();
18002
+ const match = CONNECTION_USERINFO.exec(trimmed);
18003
+ if (match) {
18004
+ const [, scheme, , rest] = match;
18005
+ if (scheme && rest && rest.length > 0) {
18006
+ return {
18007
+ value: `${scheme}://${rest}`,
18008
+ credentialRedacted: true,
18009
+ identifiersMasked: false
18010
+ };
18011
+ }
18012
+ }
18013
+ if (looksLikeConnectionUri(trimmed) && CONNECTION_HAS_USERINFO.test(trimmed)) {
18014
+ return {
18015
+ value: replacement,
18016
+ credentialRedacted: true,
18017
+ identifiersMasked: false
18018
+ };
18019
+ }
18020
+ return void 0;
18021
+ }
18022
+ function isHttpProtocol(protocol) {
18023
+ return protocol === "http:" || protocol === "https:";
18024
+ }
17980
18025
  function isIdentifierSegment(segment) {
17981
18026
  if (UUID_SEGMENT.test(segment)) return true;
17982
18027
  if (HEX_SEGMENT.test(segment)) return true;
@@ -18014,15 +18059,18 @@ function redactUrlString(value, options) {
18014
18059
  credentialRedacted: false,
18015
18060
  identifiersMasked: false
18016
18061
  };
18017
- if (!looksLikeHttpUrl(value)) return unchanged;
18018
- const url = parseHttpUrl(value);
18019
- if (!url) return unchanged;
18062
+ if (!looksLikeUrlForRedaction(value)) return unchanged;
18020
18063
  const replacement = options.replacement ?? "[REDACTED]";
18064
+ const url = parseRedactableUrl(value);
18065
+ if (!url) {
18066
+ return redactConnectionUserinfoFallback(value, replacement) ?? unchanged;
18067
+ }
18021
18068
  const idPlaceholder = options.idPlaceholder ?? "[id]";
18069
+ const http = isHttpProtocol(url.protocol);
18022
18070
  let credentialRedacted = url.username.length > 0 || url.password.length > 0;
18023
18071
  let identifiersMasked = false;
18024
18072
  let pathname = url.pathname;
18025
- if (options.maskPathIds === true) {
18073
+ if (http && options.maskPathIds === true) {
18026
18074
  pathname = url.pathname.split("/").map((segment) => {
18027
18075
  if (segment.length === 0 || !isIdentifierSegment(decodeParam(segment))) {
18028
18076
  return segment;
@@ -20277,7 +20325,7 @@ function isCredentialSensitiveKey2(key, sensitiveKeys) {
20277
20325
  }
20278
20326
 
20279
20327
  // packages/redact/src/key-value-secret.ts
20280
- 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,})`;
20328
+ 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,})`;
20281
20329
  var KEY_VALUE_SECRET_PATTERN2 = new RegExp(
20282
20330
  KEY_VALUE_SECRET_PATTERN_SOURCE,
20283
20331
  "i"
@@ -20289,6 +20337,21 @@ function valueContainsKeyValueSecret(value) {
20289
20337
 
20290
20338
  // packages/redact/src/url-redaction.ts
20291
20339
  var HTTP_URL2 = /^https?:\/\/[^\s]+$/i;
20340
+ var CONNECTION_PROTOCOLS2 = /* @__PURE__ */ new Set([
20341
+ "postgres:",
20342
+ "postgresql:",
20343
+ "mysql:",
20344
+ "mariadb:",
20345
+ "mongodb:",
20346
+ "mongodb+srv:",
20347
+ "redis:",
20348
+ "rediss:",
20349
+ "amqp:",
20350
+ "amqps:"
20351
+ ]);
20352
+ var CONNECTION_URI2 = /^(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|rediss?|amqps?):\/\/[^\s]+$/i;
20353
+ var CONNECTION_USERINFO2 = /^(postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|rediss?|amqps?):\/\/([^@/?#]+)@(.+)$/i;
20354
+ var CONNECTION_HAS_USERINFO2 = /^(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|rediss?|amqps?):\/\/[^@/?#]+@/i;
20292
20355
  var UUID_SEGMENT2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
20293
20356
  var HEX_SEGMENT2 = /^[0-9a-f]{12,}$/i;
20294
20357
  var NUMERIC_SEGMENT2 = /^\d{5,}$/;
@@ -20296,14 +20359,47 @@ var OPAQUE_SEGMENT2 = /^[A-Za-z0-9_-]{20,}$/;
20296
20359
  function looksLikeHttpUrl2(value) {
20297
20360
  return HTTP_URL2.test(value.trim());
20298
20361
  }
20299
- function parseHttpUrl2(value) {
20362
+ function looksLikeConnectionUri2(value) {
20363
+ return CONNECTION_URI2.test(value.trim());
20364
+ }
20365
+ function looksLikeUrlForRedaction2(value) {
20366
+ return looksLikeHttpUrl2(value) || looksLikeConnectionUri2(value);
20367
+ }
20368
+ function parseRedactableUrl2(value) {
20300
20369
  try {
20301
20370
  const url = new URL(value.trim());
20302
- return url.protocol === "http:" || url.protocol === "https:" ? url : void 0;
20371
+ if (url.protocol === "http:" || url.protocol === "https:") return url;
20372
+ if (CONNECTION_PROTOCOLS2.has(url.protocol)) return url;
20373
+ return void 0;
20303
20374
  } catch {
20304
20375
  return void 0;
20305
20376
  }
20306
20377
  }
20378
+ function redactConnectionUserinfoFallback2(value, replacement) {
20379
+ const trimmed = value.trim();
20380
+ const match = CONNECTION_USERINFO2.exec(trimmed);
20381
+ if (match) {
20382
+ const [, scheme, , rest] = match;
20383
+ if (scheme && rest && rest.length > 0) {
20384
+ return {
20385
+ value: `${scheme}://${rest}`,
20386
+ credentialRedacted: true,
20387
+ identifiersMasked: false
20388
+ };
20389
+ }
20390
+ }
20391
+ if (looksLikeConnectionUri2(trimmed) && CONNECTION_HAS_USERINFO2.test(trimmed)) {
20392
+ return {
20393
+ value: replacement,
20394
+ credentialRedacted: true,
20395
+ identifiersMasked: false
20396
+ };
20397
+ }
20398
+ return void 0;
20399
+ }
20400
+ function isHttpProtocol2(protocol) {
20401
+ return protocol === "http:" || protocol === "https:";
20402
+ }
20307
20403
  function isIdentifierSegment2(segment) {
20308
20404
  if (UUID_SEGMENT2.test(segment)) return true;
20309
20405
  if (HEX_SEGMENT2.test(segment)) return true;
@@ -20341,15 +20437,18 @@ function redactUrlString2(value, options) {
20341
20437
  credentialRedacted: false,
20342
20438
  identifiersMasked: false
20343
20439
  };
20344
- if (!looksLikeHttpUrl2(value)) return unchanged;
20345
- const url = parseHttpUrl2(value);
20346
- if (!url) return unchanged;
20440
+ if (!looksLikeUrlForRedaction2(value)) return unchanged;
20347
20441
  const replacement = options.replacement ?? "[REDACTED]";
20442
+ const url = parseRedactableUrl2(value);
20443
+ if (!url) {
20444
+ return redactConnectionUserinfoFallback2(value, replacement) ?? unchanged;
20445
+ }
20348
20446
  const idPlaceholder = options.idPlaceholder ?? "[id]";
20447
+ const http = isHttpProtocol2(url.protocol);
20349
20448
  let credentialRedacted = url.username.length > 0 || url.password.length > 0;
20350
20449
  let identifiersMasked = false;
20351
20450
  let pathname = url.pathname;
20352
- if (options.maskPathIds === true) {
20451
+ if (http && options.maskPathIds === true) {
20353
20452
  pathname = url.pathname.split("/").map((segment) => {
20354
20453
  if (segment.length === 0 || !isIdentifierSegment2(decodeParam2(segment))) {
20355
20454
  return segment;
@@ -20799,7 +20898,7 @@ var Redactor2 = class {
20799
20898
  return applyRule(rule, value, this.#replacement);
20800
20899
  }
20801
20900
  }
20802
- if (typeof value === "string" && looksLikeHttpUrl2(value)) {
20901
+ if (typeof value === "string" && looksLikeUrlForRedaction2(value)) {
20803
20902
  const url = redactUrlString2(value, {
20804
20903
  sensitiveKeys: this.#sensitiveKeys,
20805
20904
  isSensitiveValue: (candidate) => this.#detect(candidate, key, path44) !== void 0,