agent-inspect 6.31.30 → 6.31.32

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 (48) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -1
  3. package/docs/CLI.md +3 -1
  4. package/docs/TRACE-CONTRACTS.md +2 -0
  5. package/package.json +2 -2
  6. package/packages/cli/dist/{chunk-4GTOJ3G2.mjs → chunk-PEGM6T2X.mjs} +82 -9
  7. package/packages/cli/dist/chunk-PEGM6T2X.mjs.map +1 -0
  8. package/packages/cli/dist/index.cjs +185 -33
  9. package/packages/cli/dist/index.cjs.map +1 -1
  10. package/packages/cli/dist/index.mjs +109 -30
  11. package/packages/cli/dist/index.mjs.map +1 -1
  12. package/packages/cli/dist/{src-BF74ZVDF.mjs → src-CWUJTMRD.mjs} +3 -3
  13. package/packages/cli/dist/{src-BF74ZVDF.mjs.map → src-CWUJTMRD.mjs.map} +1 -1
  14. package/packages/core/dist/advanced.cjs +4 -0
  15. package/packages/core/dist/advanced.cjs.map +1 -1
  16. package/packages/core/dist/advanced.d.cts +2 -2
  17. package/packages/core/dist/advanced.d.ts +2 -2
  18. package/packages/core/dist/advanced.mjs +9 -9
  19. package/packages/core/dist/checks.cjs +76 -7
  20. package/packages/core/dist/checks.cjs.map +1 -1
  21. package/packages/core/dist/checks.d.cts +2 -2
  22. package/packages/core/dist/checks.d.ts +2 -2
  23. package/packages/core/dist/checks.mjs +3 -3
  24. package/packages/core/dist/{chunk-BYNAJPNH.mjs → chunk-6G67ZN72.mjs} +79 -10
  25. package/packages/core/dist/chunk-6G67ZN72.mjs.map +1 -0
  26. package/packages/core/dist/{chunk-76QIWWJ5.mjs → chunk-6S666BF4.mjs} +3 -3
  27. package/packages/core/dist/{chunk-76QIWWJ5.mjs.map → chunk-6S666BF4.mjs.map} +1 -1
  28. package/packages/core/dist/{chunk-QMO3ITYF.mjs → chunk-FBPDF7HO.mjs} +3 -3
  29. package/packages/core/dist/{chunk-QMO3ITYF.mjs.map → chunk-FBPDF7HO.mjs.map} +1 -1
  30. package/packages/core/dist/{chunk-XM27TZLD.mjs → chunk-RB6WANSW.mjs} +6 -2
  31. package/packages/core/dist/chunk-RB6WANSW.mjs.map +1 -0
  32. package/packages/core/dist/{chunk-JTJN4KBJ.mjs → chunk-VIEJJ5JB.mjs} +4 -4
  33. package/packages/core/dist/{chunk-JTJN4KBJ.mjs.map → chunk-VIEJJ5JB.mjs.map} +1 -1
  34. package/packages/core/dist/exporters.cjs +89 -22
  35. package/packages/core/dist/exporters.cjs.map +1 -1
  36. package/packages/core/dist/exporters.mjs +88 -25
  37. package/packages/core/dist/exporters.mjs.map +1 -1
  38. package/packages/core/dist/{index-DACU4Dy1.d.cts → index-Ceyw5x7b.d.cts} +4 -2
  39. package/packages/core/dist/{index-b4tIGrzq.d.ts → index-K5Cinf1r.d.ts} +4 -2
  40. package/packages/core/dist/index.cjs +4 -0
  41. package/packages/core/dist/index.cjs.map +1 -1
  42. package/packages/core/dist/index.mjs +4 -4
  43. package/packages/core/dist/writers.cjs +4 -0
  44. package/packages/core/dist/writers.cjs.map +1 -1
  45. package/packages/core/dist/writers.mjs +1 -1
  46. package/packages/cli/dist/chunk-4GTOJ3G2.mjs.map +0 -1
  47. package/packages/core/dist/chunk-BYNAJPNH.mjs.map +0 -1
  48. package/packages/core/dist/chunk-XM27TZLD.mjs.map +0 -1
@@ -268,6 +268,10 @@ var init_credential_value_patterns = __esm({
268
268
  /\b[a-z0-9_.-]+=[^;\s]+(?:;\s*[a-z0-9_.-]+=[^;\s]+)+/i,
269
269
  /\beyJ[a-zA-Z0-9_-]{8,}\.[a-zA-Z0-9_-]{8,}\.[a-zA-Z0-9_-]{8,}\b/,
270
270
  /\b(?:sk-(?:proj-)?[a-zA-Z0-9_-]{16,}|sk-ant-[a-zA-Z0-9_-]{16,}|AIza[0-9A-Za-z_-]{20,})\b/,
271
+ // Stripe secret / restricted keys use underscores (not sk-). Keep in sync with
272
+ // packages/redact/src/index.ts + packages/core/src/checks DEFAULT_SECRET_PATTERNS (#520).
273
+ /\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\b/,
274
+ /\bxox[abposr]-[A-Za-z0-9-]{10,}\b/,
271
275
  /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{20,}\b/,
272
276
  /\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/,
273
277
  /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*-----END [A-Z ]*PRIVATE KEY-----/,
@@ -5933,6 +5937,56 @@ function eventEndMs(event) {
5933
5937
  }
5934
5938
  return void 0;
5935
5939
  }
5940
+ function rowIndexByEventId(events) {
5941
+ const index = /* @__PURE__ */ new Map();
5942
+ for (const [position, event] of events.entries()) {
5943
+ if (!index.has(event.eventId)) index.set(event.eventId, position);
5944
+ }
5945
+ return index;
5946
+ }
5947
+ function recordedRowSpan(rowIndex, event) {
5948
+ const sourceIds = "sourceEventIds" in event && Array.isArray(event.sourceEventIds) ? event.sourceEventIds : [event.eventId];
5949
+ const rows = [];
5950
+ for (const id of sourceIds) {
5951
+ const row = typeof id === "string" ? rowIndex.get(id) : void 0;
5952
+ if (row === void 0) return void 0;
5953
+ rows.push(row);
5954
+ }
5955
+ if (rows.length === 0) return void 0;
5956
+ return { first: Math.min(...rows), last: Math.max(...rows) };
5957
+ }
5958
+ function recordedTieOrder(context, tiedBefore, tiedAfter) {
5959
+ const rowIndex = rowIndexByEventId(context.events);
5960
+ let lastFinished;
5961
+ let firstStarted;
5962
+ for (const event of tiedBefore) {
5963
+ const span = recordedRowSpan(rowIndex, event);
5964
+ if (span === void 0) return { inOrder: void 0 };
5965
+ if (lastFinished === void 0 || span.last > lastFinished.row) {
5966
+ lastFinished = { event, row: span.last };
5967
+ }
5968
+ }
5969
+ for (const event of tiedAfter) {
5970
+ const span = recordedRowSpan(rowIndex, event);
5971
+ if (span === void 0) return { inOrder: void 0 };
5972
+ if (firstStarted === void 0 || span.first < firstStarted.row) {
5973
+ firstStarted = { event, row: span.first };
5974
+ }
5975
+ }
5976
+ if (lastFinished === void 0 || firstStarted === void 0) return { inOrder: void 0 };
5977
+ return {
5978
+ inOrder: lastFinished.row < firstStarted.row,
5979
+ lastFinishedBefore: lastFinished.event,
5980
+ firstStartedAfter: firstStarted.event
5981
+ };
5982
+ }
5983
+ function tieResolution(order) {
5984
+ return order.inOrder === void 0 ? "recorded-order-unavailable" : "recorded-order";
5985
+ }
5986
+ function tieMessage(order, beforeLabel, afterLabel) {
5987
+ if (order === void 0 || order.inOrder === true) return "";
5988
+ return order.inOrder === void 0 ? " Their timestamps tie at the same millisecond and the recorded event order could not be resolved." : ` Their timestamps tie at the same millisecond; the recorded event order shows ${afterLabel} started before ${beforeLabel} finished.`;
5989
+ }
5936
5990
  function normalizedKey(value) {
5937
5991
  return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
5938
5992
  }
@@ -6512,16 +6566,18 @@ function createStepOrderingRule(options) {
6512
6566
  )
6513
6567
  ];
6514
6568
  }
6515
- if (beforeEnd > afterStart) {
6569
+ const tie = beforeEnd === afterStart ? recordedTieOrder(context, [beforeEvent], [afterEvent]) : void 0;
6570
+ if (beforeEnd > afterStart || tie !== void 0 && tie.inOrder !== true) {
6516
6571
  return [
6517
6572
  failFinding(
6518
6573
  ruleId,
6519
- `${subject} ${beforeLabel} must finish before ${afterLabel} starts.`,
6574
+ `${subject} ${beforeLabel} must finish before ${afterLabel} starts.${tieMessage(tie, beforeLabel, afterLabel)}`,
6520
6575
  [eventEvidence(beforeEvent), eventEvidence(afterEvent)],
6521
6576
  expected,
6522
6577
  {
6523
6578
  beforeEndedAt: new Date(beforeEnd).toISOString(),
6524
- afterStartedAt: new Date(afterStart).toISOString()
6579
+ afterStartedAt: new Date(afterStart).toISOString(),
6580
+ ...tie !== void 0 ? { resolvedBy: tieResolution(tie) } : {}
6525
6581
  }
6526
6582
  )
6527
6583
  ];
@@ -6584,16 +6640,27 @@ function createStepOrderingRule(options) {
6584
6640
  )
6585
6641
  ];
6586
6642
  }
6587
- if (latestBefore.end > earliestAfter.start) {
6643
+ const tiedEnd = latestBefore.end;
6644
+ const tiedStart = earliestAfter.start;
6645
+ const tie = tiedEnd === tiedStart ? recordedTieOrder(
6646
+ context,
6647
+ beforeEvents.filter((event) => eventEndMs(event) === tiedEnd),
6648
+ afterEvents.filter((event) => eventStartMs(event) === tiedStart)
6649
+ ) : void 0;
6650
+ if (latestBefore.end > earliestAfter.start || tie !== void 0 && tie.inOrder !== true) {
6588
6651
  return [
6589
6652
  failFinding(
6590
6653
  ruleId,
6591
- bothTools ? `Every ${options.before.name} tool call must finish before any ${options.after.name} tool call starts.` : `Every ${beforeLabel} must finish before any ${afterLabel} starts.`,
6592
- [eventEvidence(latestBefore.event), eventEvidence(earliestAfter.event)],
6654
+ (bothTools ? `Every ${options.before.name} tool call must finish before any ${options.after.name} tool call starts.` : `Every ${beforeLabel} must finish before any ${afterLabel} starts.`) + tieMessage(tie, beforeLabel, afterLabel),
6655
+ [
6656
+ eventEvidence(tie?.lastFinishedBefore ?? latestBefore.event),
6657
+ eventEvidence(tie?.firstStartedAfter ?? earliestAfter.event)
6658
+ ],
6593
6659
  expected,
6594
6660
  {
6595
6661
  latestBeforeEndedAt: new Date(latestBefore.end).toISOString(),
6596
- earliestAfterStartedAt: new Date(earliestAfter.start).toISOString()
6662
+ earliestAfterStartedAt: new Date(earliestAfter.start).toISOString(),
6663
+ ...tie !== void 0 ? { resolvedBy: tieResolution(tie) } : {}
6597
6664
  }
6598
6665
  )
6599
6666
  ];
@@ -7540,6 +7607,12 @@ var init_checks2 = __esm({
7540
7607
  DEFAULT_SECRET_PATTERNS = [
7541
7608
  { id: "bearer-token", pattern: /Bearer\s+[A-Za-z0-9._~+/-]{12,}=*/ },
7542
7609
  { id: "openai-key", pattern: /sk-[A-Za-z0-9_-]{16,}/ },
7610
+ // Stripe + Slack: keep in sync with packages/redact + credential-value-patterns (#520).
7611
+ {
7612
+ id: "stripe-key",
7613
+ pattern: /\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\b/
7614
+ },
7615
+ { id: "slack-token", pattern: /\bxox[abposr]-[A-Za-z0-9-]{10,}\b/ },
7543
7616
  { id: "aws-access-key", pattern: /AKIA[0-9A-Z]{16}/ },
7544
7617
  { id: "github-token", pattern: /gh[opsu]_[A-Za-z0-9_]{20,}/ },
7545
7618
  // Keep in sync with packages/redact/src/key-value-secret.ts (KEY_VALUE_SECRET_PATTERN_SOURCE).
@@ -17304,7 +17377,7 @@ var init_src = __esm({
17304
17377
  });
17305
17378
 
17306
17379
  // package.json
17307
- var version = "6.31.30";
17380
+ var version = "6.31.32";
17308
17381
 
17309
17382
  // packages/cli/src/list.ts
17310
17383
  init_advanced();
@@ -19522,6 +19595,16 @@ function stepIdOf2(event) {
19522
19595
  const value = event.attributes?.stepId;
19523
19596
  return typeof value === "string" && value.trim() !== "" ? value : void 0;
19524
19597
  }
19598
+ function attemptIdOf3(event) {
19599
+ const direct = event.attributes?.attemptId;
19600
+ if (typeof direct === "string" && direct.trim() !== "") return direct;
19601
+ const meta2 = event.attributes?.metadata;
19602
+ if (meta2 && typeof meta2 === "object" && !Array.isArray(meta2)) {
19603
+ const nested = meta2.attemptId;
19604
+ if (typeof nested === "string" && nested.trim() !== "") return nested;
19605
+ }
19606
+ return void 0;
19607
+ }
19525
19608
  function lifecycleKey(event) {
19526
19609
  if (event.kind === "RUN") return `run:${event.runId}`;
19527
19610
  const stepId = stepIdOf2(event);
@@ -19531,6 +19614,9 @@ function lifecycleKey(event) {
19531
19614
  function isTerminal(status) {
19532
19615
  return status === "ok" || status === "error";
19533
19616
  }
19617
+ function eventTime3(event) {
19618
+ return typeof event.timestamp === "number" ? event.timestamp : 0;
19619
+ }
19534
19620
  function cloneNode(node) {
19535
19621
  return {
19536
19622
  event: {
@@ -19541,37 +19627,87 @@ function cloneNode(node) {
19541
19627
  depth: node.depth
19542
19628
  };
19543
19629
  }
19630
+ function joinOnePair(start, terminal) {
19631
+ const childMap = /* @__PURE__ */ new Map();
19632
+ if (start) {
19633
+ for (const child of start.children) {
19634
+ childMap.set(child.event.eventId, child);
19635
+ }
19636
+ }
19637
+ for (const child of terminal.children) {
19638
+ childMap.set(child.event.eventId, child);
19639
+ }
19640
+ return {
19641
+ event: {
19642
+ ...terminal.event,
19643
+ name: start?.event.name ?? terminal.event.name,
19644
+ kind: start?.event.kind ?? terminal.event.kind,
19645
+ ...start && attemptIdOf3(terminal.event) === void 0 && attemptIdOf3(start.event) ? {
19646
+ attributes: {
19647
+ ...terminal.event.attributes,
19648
+ attemptId: attemptIdOf3(start.event)
19649
+ }
19650
+ } : {}
19651
+ },
19652
+ children: presentSiblingNodes([...childMap.values()]),
19653
+ depth: terminal.depth
19654
+ };
19655
+ }
19544
19656
  function joinSiblingGroup(group) {
19545
19657
  if (group.length <= 1) return group;
19546
- const terminals = group.filter((n) => isTerminal(n.event.status));
19547
- const runnings = group.filter((n) => n.event.status === "running");
19658
+ const terminals = group.filter((n) => isTerminal(n.event.status)).sort((a, b) => eventTime3(a.event) - eventTime3(b.event));
19659
+ const runnings = group.filter((n) => n.event.status === "running").sort((a, b) => eventTime3(a.event) - eventTime3(b.event));
19660
+ const others = group.filter(
19661
+ (n) => !isTerminal(n.event.status) && n.event.status !== "running"
19662
+ );
19548
19663
  const terminalStatuses = new Set(terminals.map((n) => n.event.status));
19549
19664
  if (terminalStatuses.size > 1) {
19550
19665
  return group;
19551
19666
  }
19552
- if (terminals.length >= 1) {
19553
- const terminal = terminals[terminals.length - 1];
19554
- const start = runnings[0];
19555
- const childMap = /* @__PURE__ */ new Map();
19556
- for (const n of group) {
19557
- for (const child of n.children) {
19558
- childMap.set(child.event.eventId, child);
19667
+ if (terminals.length > 1 && terminals.every((t) => attemptIdOf3(t.event) === void 0) && runnings.every((r) => attemptIdOf3(r.event) === void 0)) {
19668
+ return group;
19669
+ }
19670
+ const usedRunning = /* @__PURE__ */ new Set();
19671
+ const out = [];
19672
+ for (const terminal of terminals) {
19673
+ const terminalAttempt = attemptIdOf3(terminal.event);
19674
+ const terminalTs = eventTime3(terminal.event);
19675
+ const candidate = runnings.find((r) => {
19676
+ if (usedRunning.has(r.event.eventId)) return false;
19677
+ if (eventTime3(r.event) > terminalTs) return false;
19678
+ const runningAttempt = attemptIdOf3(r.event);
19679
+ if (terminalAttempt !== void 0) {
19680
+ return runningAttempt === terminalAttempt;
19681
+ }
19682
+ if (runningAttempt !== void 0) {
19683
+ return true;
19559
19684
  }
19685
+ return true;
19686
+ });
19687
+ if (candidate) {
19688
+ usedRunning.add(candidate.event.eventId);
19689
+ out.push(joinOnePair(candidate, terminal));
19690
+ } else {
19691
+ out.push({
19692
+ ...terminal,
19693
+ children: presentSiblingNodes(terminal.children)
19694
+ });
19560
19695
  }
19561
- return [
19562
- {
19563
- event: {
19564
- ...terminal.event,
19565
- name: start?.event.name ?? terminal.event.name,
19566
- kind: start?.event.kind ?? terminal.event.kind,
19567
- ...start?.event.timestamp !== void 0 && terminal.event.durationMs === void 0 ? {} : {}
19568
- },
19569
- children: presentSiblingNodes([...childMap.values()]),
19570
- depth: terminal.depth
19571
- }
19572
- ];
19573
19696
  }
19574
- return group;
19697
+ for (const running of runnings) {
19698
+ if (usedRunning.has(running.event.eventId)) continue;
19699
+ out.push({
19700
+ ...running,
19701
+ children: presentSiblingNodes(running.children)
19702
+ });
19703
+ }
19704
+ for (const other of others) {
19705
+ out.push({
19706
+ ...other,
19707
+ children: presentSiblingNodes(other.children)
19708
+ });
19709
+ }
19710
+ return out;
19575
19711
  }
19576
19712
  function presentSiblingNodes(nodes) {
19577
19713
  const prepared = nodes.map((n) => ({
@@ -22436,6 +22572,18 @@ var credentialDetectors = [
22436
22572
  pattern: /\b(?:sk-(?:proj-)?[a-zA-Z0-9_-]{16,}|sk-ant-[a-zA-Z0-9_-]{16,}|AIza[0-9A-Za-z_-]{20,})\b/,
22437
22573
  severity: "error"
22438
22574
  }),
22575
+ // Stripe secret/restricted keys (underscore form). Keep in sync with
22576
+ // packages/core/src/safety/credential-value-patterns.ts + checks DEFAULT_SECRET_PATTERNS (#520).
22577
+ patternDetector({
22578
+ id: "value.stripeSecretKey",
22579
+ pattern: /\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\b/,
22580
+ severity: "error"
22581
+ }),
22582
+ patternDetector({
22583
+ id: "value.slackToken",
22584
+ pattern: /\bxox[abposr]-[A-Za-z0-9-]{10,}\b/,
22585
+ severity: "error"
22586
+ }),
22439
22587
  patternDetector({
22440
22588
  id: "value.githubToken",
22441
22589
  pattern: /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{20,}\b/,
@@ -24201,8 +24349,9 @@ function parseEvidenceFormat(value) {
24201
24349
  `Unsupported --evidence-format "${value}". Use directory, html, or zip.`
24202
24350
  );
24203
24351
  }
24204
- function toAssessmentStatus(failed) {
24205
- return failed ? "UNSAFE" : "SAFE";
24352
+ function residualStatusToEvidenceSafe(status) {
24353
+ if (status === "SAFE_WITH_WARNINGS") return "SAFE WITH WARNINGS";
24354
+ return status;
24206
24355
  }
24207
24356
  function stableJson2(value) {
24208
24357
  return `${JSON.stringify(value, null, 2)}
@@ -24242,7 +24391,10 @@ async function writeLocalEvidence(input3) {
24242
24391
  combined += redacted.content.endsWith("\n") ? redacted.content : `${redacted.content}
24243
24392
  `;
24244
24393
  }
24245
- const assessmentStatus = toAssessmentStatus(input3.failed);
24394
+ const residual = await assessResidualFromContent(combined, {
24395
+ format: "agent-inspect-jsonl"
24396
+ });
24397
+ const assessmentStatus = residualStatusToEvidenceSafe(residual.status);
24246
24398
  const evidencePackage = buildEvidenceCiPackage({
24247
24399
  generatorVersion: version,
24248
24400
  runIds: input3.runIds,