agent-inspect 6.4.0 → 6.4.1

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 (59) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +2 -2
  3. package/package.json +2 -2
  4. package/packages/cli/dist/{chunk-YS2I722C.mjs → chunk-M6PC5KUT.mjs} +78 -31
  5. package/packages/cli/dist/chunk-M6PC5KUT.mjs.map +1 -0
  6. package/packages/cli/dist/index.cjs +153 -42
  7. package/packages/cli/dist/index.cjs.map +1 -1
  8. package/packages/cli/dist/index.mjs +88 -36
  9. package/packages/cli/dist/index.mjs.map +1 -1
  10. package/packages/cli/dist/{src-FVNE44UA.mjs → src-27LC2BB3.mjs} +8 -5
  11. package/packages/cli/dist/src-27LC2BB3.mjs.map +1 -0
  12. package/packages/core/dist/advanced.cjs +91 -35
  13. package/packages/core/dist/advanced.cjs.map +1 -1
  14. package/packages/core/dist/advanced.d.cts +36 -12
  15. package/packages/core/dist/advanced.d.ts +36 -12
  16. package/packages/core/dist/advanced.mjs +77 -24
  17. package/packages/core/dist/advanced.mjs.map +1 -1
  18. package/packages/core/dist/checks.cjs +113 -0
  19. package/packages/core/dist/checks.cjs.map +1 -1
  20. package/packages/core/dist/checks.d.cts +40 -599
  21. package/packages/core/dist/checks.d.ts +40 -599
  22. package/packages/core/dist/checks.mjs +1 -1
  23. package/packages/core/dist/{chunk-QLYOCCEF.mjs → chunk-EWHN6NA4.mjs} +114 -3
  24. package/packages/core/dist/chunk-EWHN6NA4.mjs.map +1 -0
  25. package/packages/core/dist/{context-DyKbkmd4.d.cts → context-BHAgRjOe.d.cts} +4 -4
  26. package/packages/core/dist/{context-BJ5UQLDi.d.ts → context-Blyjb5my.d.ts} +4 -4
  27. package/packages/core/dist/diff.d.cts +3 -3
  28. package/packages/core/dist/diff.d.ts +3 -3
  29. package/packages/core/dist/exporters.cjs +47 -0
  30. package/packages/core/dist/exporters.cjs.map +1 -1
  31. package/packages/core/dist/exporters.d.cts +11 -4
  32. package/packages/core/dist/exporters.d.ts +11 -4
  33. package/packages/core/dist/exporters.mjs +46 -1
  34. package/packages/core/dist/exporters.mjs.map +1 -1
  35. package/packages/core/dist/index-BblJEdYZ.d.ts +618 -0
  36. package/packages/core/dist/index-DyKk7iR9.d.cts +618 -0
  37. package/packages/core/dist/index.d.cts +7 -7
  38. package/packages/core/dist/index.d.ts +7 -7
  39. package/packages/core/dist/{inspect-event-IqwOHbGo.d.cts → inspect-event-DVg84S4v.d.cts} +1 -1
  40. package/packages/core/dist/{inspect-event-IqwOHbGo.d.ts → inspect-event-DVg84S4v.d.ts} +1 -1
  41. package/packages/core/dist/{log-config-CW8w5YQ9.d.cts → log-config-BG1WmWf2.d.cts} +1 -1
  42. package/packages/core/dist/{log-config-SRA4xTp8.d.ts → log-config-Ck0aT_Ou.d.ts} +1 -1
  43. package/packages/core/dist/logs.d.cts +3 -3
  44. package/packages/core/dist/logs.d.ts +3 -3
  45. package/packages/core/dist/{persisted-inspect-event-DruwqARZ.d.ts → persisted-inspect-event-ChE7pGb7.d.ts} +1 -1
  46. package/packages/core/dist/{persisted-inspect-event-Gd-W8vB7.d.cts → persisted-inspect-event-d-mSP8kd.d.cts} +1 -1
  47. package/packages/core/dist/persisted.d.cts +5 -5
  48. package/packages/core/dist/persisted.d.ts +5 -5
  49. package/packages/core/dist/readers.d.cts +2 -2
  50. package/packages/core/dist/readers.d.ts +2 -2
  51. package/packages/core/dist/{types-J3Xtuf9x.d.cts → types-B562HgN_.d.cts} +1 -1
  52. package/packages/core/dist/{types-J3Xtuf9x.d.ts → types-B562HgN_.d.ts} +1 -1
  53. package/packages/core/dist/{types-B1X87dUW.d.cts → types-BLX3tiOW.d.cts} +1 -1
  54. package/packages/core/dist/{types-BVkjSd0q.d.ts → types-MuwXSJ4b.d.ts} +1 -1
  55. package/packages/core/dist/writers.d.cts +2 -2
  56. package/packages/core/dist/writers.d.ts +2 -2
  57. package/packages/cli/dist/chunk-YS2I722C.mjs.map +0 -1
  58. package/packages/cli/dist/src-FVNE44UA.mjs.map +0 -1
  59. package/packages/core/dist/chunk-QLYOCCEF.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createSafetyOversizedAttributeRule, resolveTraceDir, parseDuration, buildSessionIndex, enrichSessionRunRecord, TraceDirectory, loadTraceMetadataList, loadSessionRunRecords, extractMetadata, filterTraces, truncateName, getTraceFilePath, buildRunSummary, formatDuration, formatTimestamp, isAgentInspectTrace, openTrace, TraceReadError, filterMetasBySessionScope, runTraceChecks, aggregateSessionCheckResults, createBaselineRegressionRule, resolveBundleRunIds, aggregateBundleSafeStatus, bundleFailsOnSafety, buildPlaceholderArtifact, buildBundleMetadata, buildBundleSummaryMarkdown, buildRunTimeline, renderTimeline, buildTraceStats, renderTraceStats, parseDurationFilter, searchTraces, buildActivitySummary, renderActivitySummaryHuman, buildRunWhatSummary, renderRunWhat, buildLocalExplanation, resolveSuiteTemplate, defaultSuiteConfigTemplate, loadSuiteConfig, validateSuiteConfig, runSuite, renderSuiteReport, analyzeCohort, renderCohortReport, gateHasThresholds, runGate, renderGateReport, persistedInspectEventsToTraceEvents, renderStepLine, renderErrorLine, getIndent, Redactor, TreeBuilder, zeroKinds, validateEvent, traceEventToPersistedInspectEvent, isPersistedInspectEvent, createRunStatusRule, createStructureOrphanRule, createStructureCycleRule, createRunDurationRule, createMaxStepDurationRule, createRequireCompletedRule, createStallDetectionRule, createObservedOutcomeRule, createRunDepthRule, createToolUsageRule, createLlmUsageRule, createStructureRelationshipRule, createStructureParallelWidthRule, normalizeBundleOutputPath, defaultBundleOutputPath, summarizeObservedOutcomes, extractOutcomesFromTraceEvents, renderObservedOutcomesMarkdown, renderObservedOutcomesHtml, escapeMarkdown, escapeHtml, DEFAULT_SUITE_ARTIFACTS_DIR, parseCohortMetricList, COHORT_METRIC_IDS, parseGateList, nanoid, resolveRedactionProfile, applyProfileMetadataCaps, flattenTree, safeString, compactAttributes, stableJson, truncateStringForProfile } from './chunk-YS2I722C.mjs';
2
+ import { createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createSafetyOversizedAttributeRule, resolveTraceDir, parseDuration, buildSessionIndex, enrichSessionRunRecord, TraceDirectory, loadTraceMetadataList, loadSessionRunRecords, extractMetadata, filterTraces, truncateName, getTraceFilePath, buildRunSummary, formatDuration, formatTimestamp, isAgentInspectTrace, openTrace, TraceReadError, filterMetasBySessionScope, runTraceChecks, aggregateSessionCheckResults, createBaselineRegressionRule, resolveBundleRunIds, aggregateBundleSafeStatus, bundleFailsOnSafety, bundleRunAssetRelativePath, buildPlaceholderArtifact, buildBundleMetadata, buildBundleSummaryMarkdown, buildRunTimeline, renderTimeline, buildTraceStats, renderTraceStats, parseDurationFilter, searchTraces, buildActivitySummary, renderActivitySummaryHuman, buildRunWhatSummary, renderRunWhat, buildLocalExplanation, resolveSuiteTemplate, defaultSuiteConfigTemplate, loadSuiteConfig, validateSuiteConfig, runSuite, renderSuiteReport, analyzeCohort, renderCohortReport, gateHasThresholds, runGate, renderGateReport, persistedInspectEventsToTraceEvents, renderStepLine, renderErrorLine, getIndent, Redactor, TreeBuilder, zeroKinds, validateEvent, traceEventToPersistedInspectEvent, isPersistedInspectEvent, createRunStatusRule, createStructureOrphanRule, createStructureCycleRule, createRunDurationRule, createMaxStepDurationRule, createRequireCompletedRule, createStallDetectionRule, createObservedOutcomeRule, createRunDepthRule, createToolUsageRule, createLlmUsageRule, createStructureRelationshipRule, createStructureParallelWidthRule, normalizeBundleOutputPath, sanitizeBundleRunId, defaultBundleOutputPath, assertBundlePathContained, summarizeObservedOutcomes, extractOutcomesFromTraceEvents, renderObservedOutcomesMarkdown, renderObservedOutcomesHtml, escapeMarkdown, escapeHtml, DEFAULT_SUITE_ARTIFACTS_DIR, parseCohortMetricList, COHORT_METRIC_IDS, parseGateList, nanoid, resolveRedactionProfile, applyProfileMetadataCaps, flattenTree, safeString, compactAttributes, stableJson, truncateStringForProfile } from './chunk-M6PC5KUT.mjs';
3
3
  import { realpathSync, constants as constants$1 } from 'fs';
4
4
  import path14 from 'path';
5
5
  import { fileURLToPath, pathToFileURL } from 'url';
@@ -11,7 +11,7 @@ import { createServer } from 'http';
11
11
  import { createRequire } from 'module';
12
12
 
13
13
  // package.json
14
- var version = "6.4.0";
14
+ var version = "6.4.1";
15
15
 
16
16
  // packages/cli/src/trace-dir-scale.ts
17
17
  var TRACE_COUNT_WARN = 1e3;
@@ -3782,7 +3782,7 @@ async function newestTraceMtimeMs(traceDir) {
3782
3782
  }
3783
3783
  async function loadSessionRuns(traceDir) {
3784
3784
  try {
3785
- const mod = await import('./src-FVNE44UA.mjs');
3785
+ const mod = await import('./src-27LC2BB3.mjs');
3786
3786
  const dbPath = mod.resolveIndexDbPath(traceDir);
3787
3787
  const status = mod.indexStatus(dbPath);
3788
3788
  if (!status.healthy) {
@@ -6203,27 +6203,36 @@ var viewerIndexHtml = `<!DOCTYPE html>
6203
6203
  const params = new URLSearchParams(location.search);
6204
6204
  const mode = params.get("mode") || "traces";
6205
6205
 
6206
+ function escapeHtml(value) {
6207
+ return String(value ?? "")
6208
+ .replaceAll("&", "&amp;")
6209
+ .replaceAll("<", "&lt;")
6210
+ .replaceAll(">", "&gt;")
6211
+ .replaceAll('"', "&quot;")
6212
+ .replaceAll("'", "&#39;");
6213
+ }
6214
+
6206
6215
  function renderSuite(data) {
6207
6216
  const rows = data.cases.map((c) =>
6208
- '<tr><td>' + c.id + '</td><td class="' + c.status + '">' + c.status +
6209
- '</td><td>' + (c.message || '') + '</td><td>' + c.toolPath.join(' \u2192 ') +
6210
- '</td><td>' + c.observations.map((o) => o.name + ':' + o.status).join(', ') + '</td></tr>'
6217
+ '<tr><td>' + escapeHtml(c.id) + '</td><td class="' + escapeHtml(c.status) + '">' + escapeHtml(c.status) +
6218
+ '</td><td>' + escapeHtml(c.message || '') + '</td><td>' + escapeHtml(c.toolPath.join(' \u2192 ')) +
6219
+ '</td><td>' + escapeHtml(c.observations.map((o) => o.name + ':' + o.status).join(', ')) + '</td></tr>'
6211
6220
  ).join('');
6212
6221
  const failed = data.cases.filter((c) => c.status !== 'pass');
6213
6222
  const detail = failed.map((c) => {
6214
- let html = '<h3>Case ' + c.id + '</h3><ul>';
6215
- if (c.failureDiff) html += '<li>Diff errors: ' + c.failureDiff.summary.errors + '</li>';
6216
- if (c.timeline) html += '<li>Timeline steps: ' + c.timeline.entries.length + '</li>';
6217
- html += '<li>Diagnostics: ' + c.diagnostics.map((d) => d.message).join('; ') + '</li></ul>';
6223
+ let html = '<h3>Case ' + escapeHtml(c.id) + '</h3><ul>';
6224
+ if (c.failureDiff) html += '<li>Diff errors: ' + escapeHtml(c.failureDiff.summary.errors) + '</li>';
6225
+ if (c.timeline) html += '<li>Timeline steps: ' + escapeHtml(c.timeline.entries.length) + '</li>';
6226
+ html += '<li>Diagnostics: ' + escapeHtml(c.diagnostics.map((d) => d.message).join('; ')) + '</li></ul>';
6218
6227
  return html;
6219
6228
  }).join('');
6220
- return '<section><h2>Suite: ' + data.suiteName + ' (' + data.status + ')</h2>' +
6221
- '<p>Passed ' + data.summary.passed + ', failed ' + data.summary.failed + '</p>' +
6229
+ return '<section><h2>Suite: ' + escapeHtml(data.suiteName) + ' (' + escapeHtml(data.status) + ')</h2>' +
6230
+ '<p>Passed ' + escapeHtml(data.summary.passed) + ', failed ' + escapeHtml(data.summary.failed) + '</p>' +
6222
6231
  '<table><thead><tr><th>Case</th><th>Status</th><th>Message</th><th>Tool path</th><th>Observations</th></tr></thead><tbody>' +
6223
6232
  rows + '</tbody></table>' +
6224
6233
  '<section><h2>Failure detail</h2>' + (detail || '<p class="pass">No failures</p>') + '</section>' +
6225
- '<section><h2>CI artifacts</h2><p>' + (data.ciArtifactsDir || 'n/a') + '</p></section>' +
6226
- '<section><h2>Bundle export</h2><p>' + data.bundleExportHint + '</p></section>';
6234
+ '<section><h2>CI artifacts</h2><p>' + escapeHtml(data.ciArtifactsDir || 'n/a') + '</p></section>' +
6235
+ '<section><h2>Bundle export</h2><p>' + escapeHtml(data.bundleExportHint) + '</p></section>';
6227
6236
  }
6228
6237
 
6229
6238
  async function load() {
@@ -6239,8 +6248,8 @@ var viewerIndexHtml = `<!DOCTYPE html>
6239
6248
  if (mode === "workspace") {
6240
6249
  nav.innerHTML = '<a href="/api/workspace">/api/workspace</a>';
6241
6250
  const data = await fetch("/api/workspace").then((r) => r.json());
6242
- content.innerHTML = '<section><h2>Workspace: ' + (data.project || 'workspace') + '</h2>' +
6243
- '<p>Runs: ' + data.runs.length + '</p><pre>' + JSON.stringify(data, null, 2) + '</pre></section>';
6251
+ content.innerHTML = '<section><h2>Workspace: ' + escapeHtml(data.project || 'workspace') + '</h2>' +
6252
+ '<p>Runs: ' + escapeHtml(data.runs.length) + '</p><pre>' + escapeHtml(JSON.stringify(data, null, 2)) + '</pre></section>';
6244
6253
  return;
6245
6254
  }
6246
6255
  nav.innerHTML = '<a href="/api/traces">/api/traces</a> \xB7 <a href="/api/sessions">/api/sessions</a>';
@@ -8785,7 +8794,7 @@ async function resolveOutputDir(options, runIds, cwd) {
8785
8794
  const manifest = await readWorkspaceManifestFile(location);
8786
8795
  if (manifest.ok && manifest.manifest) {
8787
8796
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
8788
- const label = runIds.length === 1 ? runIds[0] : `multi-${runIds.length}`;
8797
+ const label = runIds.length === 1 ? sanitizeBundleRunId(runIds[0]) : `multi-${runIds.length}`;
8789
8798
  return resolveInsideWorkspace(
8790
8799
  location.workspaceDir,
8791
8800
  path14.join(manifest.manifest.bundlesDir, `bundle-${label}-${stamp}`)
@@ -8796,14 +8805,14 @@ async function resolveOutputDir(options, runIds, cwd) {
8796
8805
  return defaultBundleOutputPath(runIds);
8797
8806
  }
8798
8807
  async function writeBundleFile(outputDir, relativePath, content, files) {
8799
- const outPath = path14.join(outputDir, relativePath);
8808
+ const outPath = assertBundlePathContained(outputDir, relativePath);
8800
8809
  await mkdir(path14.dirname(outPath), { recursive: true });
8801
8810
  await writeFile(outPath, content, "utf-8");
8802
8811
  files.push(relativePath);
8803
8812
  }
8804
8813
  function renderBundleIndexHtml(parts) {
8805
8814
  const links = parts.runIds.map(
8806
- (runId) => `<li><a href="assets/runs/${escapeHtml3(runId)}.html">${escapeHtml3(runId)}</a></li>`
8815
+ (runId) => `<li><a href="${escapeHtml3(bundleRunAssetRelativePath(runId, ".html"))}">${escapeHtml3(runId)}</a></li>`
8807
8816
  ).join("");
8808
8817
  const sections = parts.runIds.map((runId) => {
8809
8818
  const html = parts.reports.get(runId) ?? "";
@@ -8971,11 +8980,16 @@ async function bundleCommand(runIdArg, options = {}) {
8971
8980
  await mkdir(outputDir, { recursive: true });
8972
8981
  for (const runId of resolveResult.runIds) {
8973
8982
  const jsonl = redactedJsonlByRun.get(runId) ?? "";
8974
- await writeBundleFile(outputDir, `assets/runs/${runId}.jsonl`, jsonl, files);
8983
+ await writeBundleFile(
8984
+ outputDir,
8985
+ bundleRunAssetRelativePath(runId, ".jsonl"),
8986
+ jsonl,
8987
+ files
8988
+ );
8975
8989
  const html = htmlByRun.get(runId) ?? "";
8976
8990
  await writeBundleFile(
8977
8991
  outputDir,
8978
- `assets/runs/${runId}.html`,
8992
+ bundleRunAssetRelativePath(runId, ".html"),
8979
8993
  runReportWrap(html, runId),
8980
8994
  files
8981
8995
  );
@@ -9512,7 +9526,7 @@ main().catch((error) => {
9512
9526
  return `import { observe } from "agent-inspect";
9513
9527
 
9514
9528
  class DemoAgent {
9515
- async run(input: { question: string }) {
9529
+ async run(input) {
9516
9530
  return { answer: \`Echo: \${input.question}\` };
9517
9531
  }
9518
9532
  }
@@ -9933,6 +9947,23 @@ var PLUGIN_NAME_PREFIXES = [
9933
9947
  "agent-inspect-check-",
9934
9948
  "agent-inspect-importer-"
9935
9949
  ];
9950
+ var CAPTURE_MODES = /* @__PURE__ */ new Set(["metadata-only", "preview", "full"]);
9951
+ function parseStrictBoolean(value, label, errors) {
9952
+ if (value === void 0) return void 0;
9953
+ if (value === true) return true;
9954
+ if (value === false) return false;
9955
+ errors.push(`${label} must be a boolean true or false, not ${JSON.stringify(value)}`);
9956
+ return void 0;
9957
+ }
9958
+ function parseCaptureMode(value, errors) {
9959
+ if (value === void 0) return void 0;
9960
+ const mode = String(value);
9961
+ if (!CAPTURE_MODES.has(mode)) {
9962
+ errors.push(`privacy.captureMode must be one of: metadata-only, preview, full`);
9963
+ return void 0;
9964
+ }
9965
+ return mode;
9966
+ }
9936
9967
  function isPlainObject2(value) {
9937
9968
  return typeof value === "object" && value !== null && !Array.isArray(value);
9938
9969
  }
@@ -9981,20 +10012,35 @@ function parsePluginManifest(input3) {
9981
10012
  errors.push("privacy must be an object");
9982
10013
  } else {
9983
10014
  privacy = {};
9984
- if (input3.privacy.captureMode !== void 0) {
9985
- privacy.captureMode = String(input3.privacy.captureMode);
9986
- }
9987
- if (input3.privacy.networkAllowed !== void 0) {
9988
- privacy.networkAllowed = Boolean(input3.privacy.networkAllowed);
9989
- }
9990
- if (input3.privacy.uploadAllowed !== void 0) {
9991
- privacy.uploadAllowed = Boolean(input3.privacy.uploadAllowed);
9992
- }
9993
- if (input3.privacy.redactionDocumented !== void 0) {
9994
- privacy.redactionDocumented = Boolean(input3.privacy.redactionDocumented);
10015
+ const captureMode = parseCaptureMode(input3.privacy.captureMode, errors);
10016
+ if (captureMode !== void 0) privacy.captureMode = captureMode;
10017
+ const networkAllowed = parseStrictBoolean(
10018
+ input3.privacy.networkAllowed,
10019
+ "privacy.networkAllowed",
10020
+ errors
10021
+ );
10022
+ if (networkAllowed !== void 0) privacy.networkAllowed = networkAllowed;
10023
+ const uploadAllowed = parseStrictBoolean(
10024
+ input3.privacy.uploadAllowed,
10025
+ "privacy.uploadAllowed",
10026
+ errors
10027
+ );
10028
+ if (uploadAllowed !== void 0) privacy.uploadAllowed = uploadAllowed;
10029
+ const redactionDocumented = parseStrictBoolean(
10030
+ input3.privacy.redactionDocumented,
10031
+ "privacy.redactionDocumented",
10032
+ errors
10033
+ );
10034
+ if (redactionDocumented !== void 0) {
10035
+ privacy.redactionDocumented = redactionDocumented;
9995
10036
  }
9996
- if (input3.privacy.frameworkDepsPackageScoped !== void 0) {
9997
- privacy.frameworkDepsPackageScoped = Boolean(input3.privacy.frameworkDepsPackageScoped);
10037
+ const frameworkDepsPackageScoped = parseStrictBoolean(
10038
+ input3.privacy.frameworkDepsPackageScoped,
10039
+ "privacy.frameworkDepsPackageScoped",
10040
+ errors
10041
+ );
10042
+ if (frameworkDepsPackageScoped !== void 0) {
10043
+ privacy.frameworkDepsPackageScoped = frameworkDepsPackageScoped;
9998
10044
  }
9999
10045
  if (privacy.networkAllowed === true || privacy.uploadAllowed === true) {
10000
10046
  warnings.push("plugin declares network or upload \u2014 review before install");
@@ -10314,7 +10360,7 @@ function isModuleNotFound4(e) {
10314
10360
  }
10315
10361
  async function loadIndexSqlite() {
10316
10362
  try {
10317
- return await import('./src-FVNE44UA.mjs');
10363
+ return await import('./src-27LC2BB3.mjs');
10318
10364
  } catch (e) {
10319
10365
  if (isModuleNotFound4(e)) {
10320
10366
  console.error(
@@ -10898,6 +10944,12 @@ function parseRate(value) {
10898
10944
  if (!Number.isFinite(parsed)) {
10899
10945
  throw new Error(`Invalid --max-error-rate: ${value}`);
10900
10946
  }
10947
+ if (parsed < 0) {
10948
+ throw new Error("--max-error-rate must be a non-negative percentage.");
10949
+ }
10950
+ if (parsed > 100) {
10951
+ throw new Error("--max-error-rate must be at most 100.");
10952
+ }
10901
10953
  return parsed;
10902
10954
  }
10903
10955
  function parseDuration2(value) {