agent-inspect 6.31.2 → 6.31.4

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 (60) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +1 -1
  3. package/SECURITY.md +2 -0
  4. package/docs/GETTING-STARTED.md +2 -0
  5. package/docs/SAFE-TRACE-SHARING.md +1 -0
  6. package/package.json +1 -1
  7. package/packages/cli/dist/{chunk-SJ6FRNOE.mjs → chunk-LKEPABND.mjs} +86 -80
  8. package/packages/cli/dist/chunk-LKEPABND.mjs.map +1 -0
  9. package/packages/cli/dist/index.cjs +406 -93
  10. package/packages/cli/dist/index.cjs.map +1 -1
  11. package/packages/cli/dist/index.mjs +314 -16
  12. package/packages/cli/dist/index.mjs.map +1 -1
  13. package/packages/cli/dist/{src-YNEJOPRA.mjs → src-4WYF5RFI.mjs} +3 -3
  14. package/packages/cli/dist/{src-YNEJOPRA.mjs.map → src-4WYF5RFI.mjs.map} +1 -1
  15. package/packages/core/dist/advanced.cjs +97 -30
  16. package/packages/core/dist/advanced.cjs.map +1 -1
  17. package/packages/core/dist/advanced.mjs +13 -13
  18. package/packages/core/dist/checks.cjs +51 -49
  19. package/packages/core/dist/checks.cjs.map +1 -1
  20. package/packages/core/dist/checks.mjs +5 -5
  21. package/packages/core/dist/{chunk-PBNBQRXV.mjs → chunk-2KJR6X4V.mjs} +9 -9
  22. package/packages/core/dist/chunk-2KJR6X4V.mjs.map +1 -0
  23. package/packages/core/dist/{chunk-26YJSETN.mjs → chunk-7DHSWDKB.mjs} +19 -6
  24. package/packages/core/dist/chunk-7DHSWDKB.mjs.map +1 -0
  25. package/packages/core/dist/{chunk-BGF5JDJN.mjs → chunk-INE5IWLN.mjs} +3 -3
  26. package/packages/core/dist/{chunk-BGF5JDJN.mjs.map → chunk-INE5IWLN.mjs.map} +1 -1
  27. package/packages/core/dist/{chunk-ZFJ2ICTC.mjs → chunk-MTMTXTJL.mjs} +5 -5
  28. package/packages/core/dist/{chunk-ZFJ2ICTC.mjs.map → chunk-MTMTXTJL.mjs.map} +1 -1
  29. package/packages/core/dist/{chunk-KWBO36PH.mjs → chunk-NY4ILMXK.mjs} +4 -4
  30. package/packages/core/dist/{chunk-KWBO36PH.mjs.map → chunk-NY4ILMXK.mjs.map} +1 -1
  31. package/packages/core/dist/{chunk-WN5PT4GV.mjs → chunk-OSGNGRHF.mjs} +3 -3
  32. package/packages/core/dist/{chunk-WN5PT4GV.mjs.map → chunk-OSGNGRHF.mjs.map} +1 -1
  33. package/packages/core/dist/{chunk-CBPWLHNQ.mjs → chunk-PKDBFBJ7.mjs} +5 -76
  34. package/packages/core/dist/chunk-PKDBFBJ7.mjs.map +1 -0
  35. package/packages/core/dist/{chunk-VU6O5QAH.mjs → chunk-VLVCLAPB.mjs} +83 -5
  36. package/packages/core/dist/chunk-VLVCLAPB.mjs.map +1 -0
  37. package/packages/core/dist/exporters.cjs +224 -8
  38. package/packages/core/dist/exporters.cjs.map +1 -1
  39. package/packages/core/dist/exporters.mjs +125 -11
  40. package/packages/core/dist/exporters.mjs.map +1 -1
  41. package/packages/core/dist/index.cjs +97 -8
  42. package/packages/core/dist/index.cjs.map +1 -1
  43. package/packages/core/dist/index.mjs +6 -6
  44. package/packages/core/dist/logs.cjs +80 -2
  45. package/packages/core/dist/logs.cjs.map +1 -1
  46. package/packages/core/dist/logs.d.cts +2 -0
  47. package/packages/core/dist/logs.d.ts +2 -0
  48. package/packages/core/dist/logs.mjs +2 -2
  49. package/packages/core/dist/readers.cjs +2 -0
  50. package/packages/core/dist/readers.cjs.map +1 -1
  51. package/packages/core/dist/readers.mjs +2 -2
  52. package/packages/core/dist/writers.cjs +96 -8
  53. package/packages/core/dist/writers.cjs.map +1 -1
  54. package/packages/core/dist/writers.mjs +7 -8
  55. package/packages/core/dist/writers.mjs.map +1 -1
  56. package/packages/cli/dist/chunk-SJ6FRNOE.mjs.map +0 -1
  57. package/packages/core/dist/chunk-26YJSETN.mjs.map +0 -1
  58. package/packages/core/dist/chunk-CBPWLHNQ.mjs.map +0 -1
  59. package/packages/core/dist/chunk-PBNBQRXV.mjs.map +0 -1
  60. package/packages/core/dist/chunk-VU6O5QAH.mjs.map +0 -1
@@ -62,6 +62,80 @@ function buildRunStartedMetadata(options) {
62
62
  }
63
63
  return Object.keys(merged).length > 0 ? merged : void 0;
64
64
  }
65
+
66
+ // packages/core/src/safety/sensitive-key.ts
67
+ function keyHasExplicitSeparator(value) {
68
+ return /[_\-.]/.test(value);
69
+ }
70
+ function normalizeSensitiveKey(value) {
71
+ return value.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
72
+ }
73
+ var NON_CREDENTIAL_TOKEN_CONFIG_KEYS = new Set(
74
+ [
75
+ "tokens",
76
+ "max_tokens",
77
+ "min_tokens",
78
+ "ls_max_tokens",
79
+ "token_count",
80
+ "token_limit",
81
+ "token_budget",
82
+ "input_tokens",
83
+ "output_tokens",
84
+ "total_tokens",
85
+ "cached_tokens",
86
+ "prompt_tokens",
87
+ "completion_tokens"
88
+ ].map(normalizeSensitiveKey)
89
+ );
90
+ var DEFAULT_CREDENTIAL_SENSITIVE_KEYS = [
91
+ "authorization",
92
+ "cookie",
93
+ "token",
94
+ "access_token",
95
+ "accesstoken",
96
+ "auth_token",
97
+ "authtoken",
98
+ "refresh_token",
99
+ "refreshtoken",
100
+ "id_token",
101
+ "idtoken",
102
+ "bearer_token",
103
+ "bearertoken",
104
+ "api_token",
105
+ "apitoken",
106
+ "apikey",
107
+ "api_key",
108
+ "password",
109
+ "secret",
110
+ "email"
111
+ ];
112
+ function isTokenCredentialKey(normalized) {
113
+ if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
114
+ if (normalized === "token") return true;
115
+ if (normalized.endsWith("tokens")) return false;
116
+ return normalized.endsWith("token");
117
+ }
118
+ function isCredentialSensitiveKey(key, sensitiveKeys = DEFAULT_CREDENTIAL_SENSITIVE_KEYS) {
119
+ if (!key) return false;
120
+ const normalized = normalizeSensitiveKey(key);
121
+ if (!normalized) return false;
122
+ if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
123
+ const allowPrefixCompound = keyHasExplicitSeparator(key);
124
+ for (const sensitive of sensitiveKeys) {
125
+ const s = normalizeSensitiveKey(sensitive);
126
+ if (!s) continue;
127
+ if (s === "token") {
128
+ if (isTokenCredentialKey(normalized)) return true;
129
+ continue;
130
+ }
131
+ if (normalized === s) return true;
132
+ if (normalized.endsWith(`_${s}`)) return true;
133
+ if (allowPrefixCompound && normalized.startsWith(`${s}_`)) return true;
134
+ }
135
+ return false;
136
+ }
137
+
138
+ // packages/core/src/logs/redactor.ts
65
139
  var DEFAULT_REDACT_KEYS = [
66
140
  "authorization",
67
141
  "cookie",
@@ -85,7 +159,7 @@ function compileRules(rules, extraKeys) {
85
159
  const out = /* @__PURE__ */ new Map();
86
160
  const set = (r) => {
87
161
  const k = toKey(r.key);
88
- out.set(k, { ...r, key: k });
162
+ out.set(k, { ...r, key: k, raw: r.raw ?? r.key });
89
163
  };
90
164
  for (const k of DEFAULT_REDACT_KEYS) {
91
165
  set({ key: k, strategy: "full" });
@@ -114,9 +188,13 @@ var Redactor = class {
114
188
  constructor(options) {
115
189
  this.#rules = compileRules(options?.rules, options?.extraKeys);
116
190
  }
191
+ /** Field names this redactor treats as sensitive, for value-level helpers. */
192
+ get sensitiveKeys() {
193
+ return this.#rules.map((rule) => rule.raw ?? rule.key);
194
+ }
117
195
  redactValue(key, value) {
118
196
  const k = toKey(key);
119
- const rule = this.#rules.find((r) => r.key === k);
197
+ const rule = this.#rules.find((r) => r.key === k) ?? this.#rules.find((r) => isCredentialSensitiveKey(key, [r.raw ?? r.key]));
120
198
  if (!rule) {
121
199
  return this.#redactNested(value);
122
200
  }
@@ -156,7 +234,7 @@ var Redactor = class {
156
234
  };
157
235
 
158
236
  // packages/core/src/safety/credential-value-patterns.ts
159
- var KEY_VALUE_SECRET_PATTERN = /\b(?:api[_-]?key|internal[_-]?token|access[_-]?token|auth[_-]?token|password|secret|token)=([^\s"'\\]{8,})/i;
237
+ 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;
160
238
  var HIGH_CONFIDENCE_CREDENTIAL_PATTERNS = [
161
239
  /^(?:basic|bearer|digest|apikey)\s+[a-z0-9._~+/=-]+$/i,
162
240
  /\bbearer\s+[a-z0-9._~+/=-]{12,}\b/i,
@@ -435,6 +513,17 @@ function nanoid(size = 21) {
435
513
  }
436
514
  return id;
437
515
  }
516
+ var TRACE_DIR_MODE = 448;
517
+ var TRACE_FILE_MODE = 384;
518
+ async function mkdirTraceDir(dirPath) {
519
+ await promises.mkdir(dirPath, { recursive: true, mode: TRACE_DIR_MODE });
520
+ }
521
+ async function createEmptyTraceFile(filePath) {
522
+ await promises.writeFile(filePath, "", { encoding: "utf-8", mode: TRACE_FILE_MODE });
523
+ }
524
+ async function appendTraceFile(filePath, data) {
525
+ await promises.appendFile(filePath, data, { encoding: "utf-8", mode: TRACE_FILE_MODE });
526
+ }
438
527
 
439
528
  // packages/core/src/utils/duration.ts
440
529
  function formatDuration(ms) {
@@ -501,13 +590,13 @@ function getTraceFilePath(runId, traceDir) {
501
590
  async function ensureTraceDir(traceDir) {
502
591
  const primary = path__default.default.resolve(traceDir);
503
592
  try {
504
- await promises.mkdir(primary, { recursive: true });
593
+ await mkdirTraceDir(primary);
505
594
  return primary;
506
595
  } catch {
507
596
  warn(`Failed to create trace directory: ${primary}`);
508
597
  const fallback = path__default.default.resolve(FALLBACK_TRACE_DIR);
509
598
  try {
510
- await promises.mkdir(fallback, { recursive: true });
599
+ await mkdirTraceDir(fallback);
511
600
  return fallback;
512
601
  } catch {
513
602
  warn(`Failed to create fallback trace directory: ${fallback}`);
@@ -635,7 +724,7 @@ async function initializeTraceFile(runId, traceDir) {
635
724
  try {
636
725
  const usable = await ensureTraceDir(traceDir);
637
726
  const filePath = getTraceFilePath(runId, usable);
638
- await promises.writeFile(filePath, "", "utf-8");
727
+ await createEmptyTraceFile(filePath);
639
728
  return filePath;
640
729
  } catch (e) {
641
730
  warn("Failed to initialize trace file", e);
@@ -643,7 +732,7 @@ async function initializeTraceFile(runId, traceDir) {
643
732
  try {
644
733
  const usable = await ensureTraceDir(FALLBACK_TRACE_DIR);
645
734
  const filePath = getTraceFilePath(runId, usable);
646
- await promises.writeFile(filePath, "", "utf-8");
735
+ await createEmptyTraceFile(filePath);
647
736
  return filePath;
648
737
  } catch (e) {
649
738
  warn("Failed to initialize trace file on fallback directory", e);
@@ -674,7 +763,7 @@ async function writeTraceEvent(event, traceDir) {
674
763
  try {
675
764
  const usable = await ensureTraceDir(dir);
676
765
  const filePath = getTraceFilePath(event.runId, usable);
677
- await promises.appendFile(filePath, payload, "utf-8");
766
+ await appendTraceFile(filePath, payload);
678
767
  return true;
679
768
  } catch {
680
769
  return false;