@agent-inspect/jest 6.7.4 → 6.7.5

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/README.md CHANGED
@@ -26,21 +26,59 @@ npm install agent-inspect @agent-inspect/jest jest
26
26
 
27
27
  ```js
28
28
  // jest.config.js
29
+ const { AgentInspectJestReporter } = require("@agent-inspect/jest");
30
+
29
31
  module.exports = {
30
32
  reporters: [
31
33
  "default",
32
- ["@agent-inspect/jest", { traceDir: ".agent-inspect" }],
34
+ [AgentInspectJestReporter, { artifactDir: ".agent-inspect/jest-artifacts" }],
33
35
  ],
34
36
  };
35
37
  ```
36
38
 
39
+ ## Trace association
40
+
41
+ This reporter **does not** instrument Jest or invent associations from timestamps.
42
+ Failed tests without an association produce one `no-trace-association` diagnostic
43
+ (and a bounded `no-trace-association.md` note) instead of a silent no-op.
44
+
45
+ Associate a test to a local trace with one of:
46
+
47
+ ```js
48
+ const { withAgentInspectJestTrace } = require("@agent-inspect/jest");
49
+
50
+ // 1) Helper metadata on the assertion result
51
+ expect.extend({
52
+ /* your matcher can attach: */
53
+ ...withAgentInspectJestTrace({
54
+ runId: "run_abc",
55
+ tracePath: ".agent-inspect/run_abc.jsonl",
56
+ }),
57
+ });
58
+
59
+ // 2) Reporter options
60
+ [
61
+ AgentInspectJestReporter,
62
+ {
63
+ associations: {
64
+ "agent.test.js::does the thing": {
65
+ runId: "run_abc",
66
+ tracePath: ".agent-inspect/run_abc.jsonl",
67
+ },
68
+ },
69
+ // or resolveTrace: (test) => ({ runId, tracePath })
70
+ },
71
+ ];
72
+ ```
73
+
37
74
  ## Privacy
38
75
 
39
76
  - Local files on failure; no network from AgentInspect
40
77
 
41
78
  ## API
42
79
 
43
- Jest reporter class / factory (see package types).
80
+ - `createAgentInspectJestReporter` / `AgentInspectJestReporter`
81
+ - `withAgentInspectJestTrace` — explicit association helper (no automatic capture)
44
82
 
45
83
  ## CLI
46
84
 
package/dist/index.cjs CHANGED
@@ -17,13 +17,19 @@ var DEFAULT_SUCCESS_LIMIT = 20;
17
17
  var MAX_SUCCESS_LIMIT = 100;
18
18
  var MAX_TEXT = 180;
19
19
  var DEFAULT_GENERATED_AT = "1970-01-01T00:00:00.000Z";
20
+ var ASSOCIATION_DOCS = "https://github.com/rajudandigam/agent-inspect/blob/main/packages/jest/README.md#trace-association";
21
+ function withAgentInspectJestTrace(association) {
22
+ return { agentInspect: association };
23
+ }
20
24
  function createAgentInspectJestReporter(options = {}) {
21
25
  const diagnostics = [];
22
26
  const artifacts = [];
23
27
  const seenKeys = /* @__PURE__ */ new Set();
24
28
  const artifactNames = /* @__PURE__ */ new Map();
29
+ const failedWithoutAssociation = /* @__PURE__ */ new Set();
25
30
  const successLimit = normalizeSuccessLimit(options);
26
31
  let retainedSuccesses = 0;
32
+ let reportedMissingAssociation = false;
27
33
  const reporter = {
28
34
  async onTestResult(_test, testResult) {
29
35
  await handleFileResult(testResult);
@@ -32,6 +38,7 @@ function createAgentInspectJestReporter(options = {}) {
32
38
  for (const fileResult of readRunResults(results)) {
33
39
  await handleFileResult(fileResult);
34
40
  }
41
+ await emitMissingAssociationDiagnostic();
35
42
  await appendGithubSummary();
36
43
  },
37
44
  getDiagnostics() {
@@ -50,7 +57,12 @@ function createAgentInspectJestReporter(options = {}) {
50
57
  const seenKey = `${testCase.id}:${testCase.status}`;
51
58
  if (seenKeys.has(seenKey)) return;
52
59
  const association = resolveAssociation(testCase, options);
53
- if (association === void 0) return;
60
+ if (association === void 0) {
61
+ if (testCase.status === "failed") {
62
+ failedWithoutAssociation.add(testCase.id);
63
+ }
64
+ return;
65
+ }
54
66
  if (testCase.status === "passed") {
55
67
  if (retainedSuccesses >= successLimit) return;
56
68
  retainedSuccesses += 1;
@@ -94,8 +106,46 @@ function createAgentInspectJestReporter(options = {}) {
94
106
  });
95
107
  }
96
108
  }
109
+ async function emitMissingAssociationDiagnostic() {
110
+ if (reportedMissingAssociation || failedWithoutAssociation.size === 0) return;
111
+ reportedMissingAssociation = true;
112
+ const count = failedWithoutAssociation.size;
113
+ const sampleIds = [...failedWithoutAssociation].slice(0, 3);
114
+ const message = `${count} failed Jest test(s) had no AgentInspect trace association. Reporter does not instrument tests automatically; no trace artifact was generated. Use withAgentInspectJestTrace, associations, resolveTrace, or meta.agentInspect. Docs: ${ASSOCIATION_DOCS}. Samples: ${sampleIds.join("; ")}`;
115
+ reportDiagnostic({
116
+ code: "no-trace-association",
117
+ // Keep the helper name before truncation so the diagnostic stays actionable.
118
+ message: boundText(message, 320)
119
+ });
120
+ try {
121
+ const artifactDir = options.artifactDir ?? DEFAULT_ARTIFACT_DIR;
122
+ await promises.mkdir(artifactDir, { recursive: true });
123
+ const diagnosticPath = path__default.default.join(artifactDir, "no-trace-association.md");
124
+ const body = [
125
+ "# AgentInspect Jest \u2014 missing trace association",
126
+ "",
127
+ "Failed tests were observed without an explicit AgentInspect trace association.",
128
+ "No trace artifact was generated for those tests.",
129
+ "",
130
+ "The reporter does **not** instrument Jest automatically.",
131
+ `Associate traces explicitly. Docs: ${ASSOCIATION_DOCS}`,
132
+ "",
133
+ "## Failed tests without association",
134
+ "",
135
+ ...[...failedWithoutAssociation].slice(0, 20).map((id) => `- ${boundText(id)}`),
136
+ ""
137
+ ].join("\n");
138
+ await promises.writeFile(diagnosticPath, body, "utf-8");
139
+ } catch (error) {
140
+ reportDiagnostic({
141
+ code: "artifact-write-failed",
142
+ message: `Could not write AgentInspect Jest no-association diagnostic: ${errorMessage(error)}`
143
+ });
144
+ }
145
+ }
97
146
  async function appendGithubSummary() {
98
- if (options.githubSummary === void 0 || artifacts.length === 0) return;
147
+ if (options.githubSummary === void 0) return;
148
+ if (artifacts.length === 0 && failedWithoutAssociation.size === 0) return;
99
149
  const failed = artifacts.filter((artifact) => artifact.status === "failed").length;
100
150
  const passed = artifacts.filter((artifact) => artifact.status === "passed").length;
101
151
  const lines = [
@@ -104,9 +154,16 @@ function createAgentInspectJestReporter(options = {}) {
104
154
  "",
105
155
  `- Failed test artifacts: ${failed}`,
106
156
  `- Passing test artifacts retained: ${passed}`,
157
+ `- Failed tests without trace association: ${failedWithoutAssociation.size}`,
107
158
  `- Artifact directory: ${boundText(path__default.default.basename(options.artifactDir ?? DEFAULT_ARTIFACT_DIR))}`,
108
159
  ""
109
160
  ];
161
+ if (failedWithoutAssociation.size > 0) {
162
+ lines.push(
163
+ "No automatic instrumentation: associate traces via `associations`, `resolveTrace`, or `withAgentInspectJestTrace`.",
164
+ ""
165
+ );
166
+ }
110
167
  try {
111
168
  await promises.writeFile(options.githubSummary, `${lines.join("\n")}
112
169
  `, { flag: "a" });
@@ -345,10 +402,10 @@ function safeSegment(value) {
345
402
  const sanitized = redactText(value).toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
346
403
  return sanitized.length > 0 ? sanitized : "trace";
347
404
  }
348
- function boundText(value) {
405
+ function boundText(value, max = MAX_TEXT) {
349
406
  const compact = value.replace(/\s+/g, " ").trim();
350
- if (compact.length <= MAX_TEXT) return compact;
351
- return `${compact.slice(0, MAX_TEXT - 12)}...[truncated]`;
407
+ if (compact.length <= max) return compact;
408
+ return `${compact.slice(0, max - 12)}...[truncated]`;
352
409
  }
353
410
  function redactText(value) {
354
411
  return value.replace(/\bsk-[A-Za-z0-9_-]{8,}\b/g, "[REDACTED]").replace(/\b(?:api[_-]?key|authorization|token|secret|password)\s*[:=]\s*[^,\s]+/gi, "$1=[REDACTED]");
@@ -372,5 +429,6 @@ exports.AgentInspectJestReporter = AgentInspectJestReporter;
372
429
  exports.agentInspectJestReporter = agentInspectJestReporter;
373
430
  exports.createAgentInspectJestReporter = createAgentInspectJestReporter;
374
431
  exports.default = index_default;
432
+ exports.withAgentInspectJestTrace = withAgentInspectJestTrace;
375
433
  //# sourceMappingURL=index.cjs.map
376
434
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":["path","writeFile","createReporterArtifactPath","mkdir","createTraceArtifactManifest"],"mappings":"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","file":"index.cjs","sourcesContent":["import { mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport {\n createReporterArtifactPath,\n createTraceArtifactManifest,\n type TraceArtifact,\n type TraceArtifactManifest,\n type TraceArtifactRedactionProfile,\n type TraceReporterDiagnostic,\n} from \"agent-inspect/reporters\";\n\nexport type AgentInspectJestStatus = \"failed\" | \"passed\" | \"skipped\";\n\n/**\n * Experimental trace association read by `@agent-inspect/jest`.\n *\n * Jest does not expose Vitest-style task metadata, so the default path is an\n * explicit `associations` map keyed by test identity, or a `resolveTrace`\n * callback. The reporter never guesses by timestamps.\n */\nexport interface AgentInspectJestTraceAssociation {\n /** AgentInspect run/span identifier to show in safe artifacts. */\n readonly runId?: string;\n /** Local trace file path. Only the basename is written to artifacts. */\n readonly tracePath?: string;\n /** Optional stable label for the artifact directory. */\n readonly artifactLabel?: string;\n}\n\n/**\n * Experimental normalized view of one Jest assertion result.\n */\nexport interface AgentInspectJestTestCase {\n readonly id: string;\n readonly title: string;\n readonly fullName: string;\n readonly file?: string;\n readonly status: AgentInspectJestStatus;\n readonly raw: unknown;\n}\n\n/**\n * Experimental diagnostic emitted when reporter work cannot be completed.\n *\n * Diagnostics are reported instead of thrown so Jest's original test result\n * remains authoritative.\n */\nexport interface AgentInspectJestDiagnostic {\n readonly code:\n | \"artifact-write-failed\"\n | \"github-summary-write-failed\"\n | \"on-diagnostic-failed\";\n readonly message: string;\n readonly testId?: string;\n}\n\n/**\n * Experimental options for the AgentInspect Jest reporter.\n *\n * The reporter is local-only: it performs no network I/O and writes bounded,\n * structural artifacts without reading trace contents.\n */\nexport interface AgentInspectJestReporterOptions {\n /** Directory for safe Jest artifacts. Defaults to `.agent-inspect/jest-artifacts`. */\n readonly artifactDir?: string;\n /** Optional GitHub step-summary path. Only bounded structural lines are appended. */\n readonly githubSummary?: string;\n /**\n * Keep artifacts for passing tests. `false`/undefined keeps none; `true`\n * keeps up to `maxSuccessfulTraces`; a number keeps up to that many.\n */\n readonly retainSuccessful?: boolean | number;\n /** Upper bound for retained passing-test artifacts. Defaults to 20. */\n readonly maxSuccessfulTraces?: number;\n /** Redaction profile recorded on generated artifacts. Defaults to `share`. */\n readonly redactionProfile?: TraceArtifactRedactionProfile;\n /** Deterministic manifest timestamp. Defaults to the Unix epoch. */\n readonly generatedAt?: string;\n /** Explicit trace associations keyed by `file::fullName`, `basename::fullName`, or `fullName`. */\n readonly associations?: Record<string, AgentInspectJestTraceAssociation>;\n /** Resolve explicit test-to-trace associations from a normalized Jest case. */\n readonly resolveTrace?: (\n test: AgentInspectJestTestCase,\n ) => AgentInspectJestTraceAssociation | undefined;\n /** Observe non-fatal reporter diagnostics. */\n readonly onDiagnostic?: (diagnostic: AgentInspectJestDiagnostic) => void;\n}\n\nexport interface AgentInspectJestArtifact {\n readonly directory: string;\n readonly manifestPath: string;\n readonly summaryPath: string;\n readonly status: AgentInspectJestStatus;\n readonly testId: string;\n readonly manifest: TraceArtifactManifest;\n}\n\n/**\n * Experimental Jest reporter facade.\n *\n * The hooks mirror Jest reporter lifecycle names, while inputs stay structural\n * to avoid a runtime dependency on Jest internals.\n */\nexport interface AgentInspectJestReporterFacade {\n onTestResult(test: unknown, testResult: unknown, aggregatedResult?: unknown): Promise<void>;\n onRunComplete(contexts?: unknown, results?: unknown): Promise<void>;\n getDiagnostics(): readonly AgentInspectJestDiagnostic[];\n getArtifacts(): readonly AgentInspectJestArtifact[];\n}\n\ntype AssertionResultLike = {\n readonly ancestorTitles?: unknown;\n readonly title?: unknown;\n readonly fullName?: unknown;\n readonly status?: unknown;\n readonly meta?: unknown;\n readonly agentInspect?: unknown;\n};\n\ntype TestFileResultLike = {\n readonly testFilePath?: unknown;\n readonly testResults?: unknown;\n readonly assertionResults?: unknown;\n};\n\nconst PACKAGE_NAME = \"@agent-inspect/jest\";\nconst DEFAULT_ARTIFACT_DIR = \".agent-inspect/jest-artifacts\";\nconst DEFAULT_SUCCESS_LIMIT = 20;\nconst MAX_SUCCESS_LIMIT = 100;\nconst MAX_TEXT = 180;\nconst DEFAULT_GENERATED_AT = \"1970-01-01T00:00:00.000Z\";\n\n/**\n * Create the experimental AgentInspect Jest reporter.\n */\nexport function createAgentInspectJestReporter(\n options: AgentInspectJestReporterOptions = {},\n): AgentInspectJestReporterFacade {\n const diagnostics: AgentInspectJestDiagnostic[] = [];\n const artifacts: AgentInspectJestArtifact[] = [];\n const seenKeys = new Set<string>();\n const artifactNames = new Map<string, number>();\n const successLimit = normalizeSuccessLimit(options);\n let retainedSuccesses = 0;\n\n const reporter: AgentInspectJestReporterFacade = {\n async onTestResult(_test: unknown, testResult: unknown): Promise<void> {\n await handleFileResult(testResult);\n },\n async onRunComplete(_contexts?: unknown, results?: unknown): Promise<void> {\n for (const fileResult of readRunResults(results)) {\n await handleFileResult(fileResult);\n }\n await appendGithubSummary();\n },\n getDiagnostics(): readonly AgentInspectJestDiagnostic[] {\n return diagnostics.slice();\n },\n getArtifacts(): readonly AgentInspectJestArtifact[] {\n return artifacts.slice();\n },\n };\n\n async function handleFileResult(testResult: unknown): Promise<void> {\n for (const testCase of readTestCases(testResult)) {\n await handleTestCase(testCase);\n }\n }\n\n async function handleTestCase(testCase: AgentInspectJestTestCase): Promise<void> {\n const seenKey = `${testCase.id}:${testCase.status}`;\n if (seenKeys.has(seenKey)) return;\n\n const association = resolveAssociation(testCase, options);\n if (association === undefined) return;\n\n if (testCase.status === \"passed\") {\n if (retainedSuccesses >= successLimit) return;\n retainedSuccesses += 1;\n }\n\n seenKeys.add(seenKey);\n\n try {\n const artifact = await writeSafeArtifact({\n artifactDir: options.artifactDir ?? DEFAULT_ARTIFACT_DIR,\n association,\n generatedAt: options.generatedAt ?? DEFAULT_GENERATED_AT,\n redactionProfile: options.redactionProfile ?? \"share\",\n reserveArtifactName,\n status: testCase.status,\n testCase,\n });\n artifacts.push(artifact);\n } catch (error) {\n reportDiagnostic({\n code: \"artifact-write-failed\",\n message: `Could not write AgentInspect Jest artifact: ${errorMessage(error)}`,\n testId: testCase.id,\n });\n }\n }\n\n function reserveArtifactName(seed: string): string {\n const base = safeSegment(seed);\n const next = (artifactNames.get(base) ?? 0) + 1;\n artifactNames.set(base, next);\n return next === 1 ? base : `${base}-${next}`;\n }\n\n function reportDiagnostic(diagnostic: AgentInspectJestDiagnostic): void {\n diagnostics.push(diagnostic);\n if (options.onDiagnostic === undefined) return;\n try {\n options.onDiagnostic(diagnostic);\n } catch (error) {\n diagnostics.push({\n code: \"on-diagnostic-failed\",\n message: `AgentInspect Jest diagnostic callback failed: ${errorMessage(error)}`,\n testId: diagnostic.testId,\n });\n }\n }\n\n async function appendGithubSummary(): Promise<void> {\n if (options.githubSummary === undefined || artifacts.length === 0) return;\n const failed = artifacts.filter((artifact) => artifact.status === \"failed\").length;\n const passed = artifacts.filter((artifact) => artifact.status === \"passed\").length;\n const lines = [\n \"\",\n \"## AgentInspect Jest artifacts\",\n \"\",\n `- Failed test artifacts: ${failed}`,\n `- Passing test artifacts retained: ${passed}`,\n `- Artifact directory: ${boundText(path.basename(options.artifactDir ?? DEFAULT_ARTIFACT_DIR))}`,\n \"\",\n ];\n try {\n await writeFile(options.githubSummary, `${lines.join(\"\\n\")}\\n`, { flag: \"a\" });\n } catch (error) {\n reportDiagnostic({\n code: \"github-summary-write-failed\",\n message: `Could not append AgentInspect Jest summary: ${errorMessage(error)}`,\n });\n }\n }\n\n return reporter;\n}\n\n/**\n * Experimental Jest custom reporter class.\n */\nexport class AgentInspectJestReporter implements AgentInspectJestReporterFacade {\n private readonly reporter: AgentInspectJestReporterFacade;\n\n constructor(_globalConfig?: unknown, options: AgentInspectJestReporterOptions = {}) {\n this.reporter = createAgentInspectJestReporter(options);\n }\n\n async onTestResult(\n test: unknown,\n testResult: unknown,\n aggregatedResult?: unknown,\n ): Promise<void> {\n await this.reporter.onTestResult(test, testResult, aggregatedResult);\n }\n\n async onRunComplete(contexts?: unknown, results?: unknown): Promise<void> {\n await this.reporter.onRunComplete(contexts, results);\n }\n\n getDiagnostics(): readonly AgentInspectJestDiagnostic[] {\n return this.reporter.getDiagnostics();\n }\n\n getArtifacts(): readonly AgentInspectJestArtifact[] {\n return this.reporter.getArtifacts();\n }\n}\n\nexport const agentInspectJestReporter = createAgentInspectJestReporter;\nexport default AgentInspectJestReporter;\n\nfunction normalizeSuccessLimit(options: AgentInspectJestReporterOptions): number {\n const cap = clampCount(options.maxSuccessfulTraces, DEFAULT_SUCCESS_LIMIT);\n if (options.retainSuccessful === true) return cap;\n if (typeof options.retainSuccessful === \"number\") {\n return Math.min(clampCount(options.retainSuccessful, 0), cap);\n }\n return 0;\n}\n\nfunction clampCount(value: number | undefined, fallback: number): number {\n if (value === undefined || !Number.isFinite(value)) return fallback;\n return Math.max(0, Math.min(MAX_SUCCESS_LIMIT, Math.floor(value)));\n}\n\nfunction resolveAssociation(\n testCase: AgentInspectJestTestCase,\n options: AgentInspectJestReporterOptions,\n): AgentInspectJestTraceAssociation | undefined {\n const resolved = options.resolveTrace?.(testCase);\n if (isAssociation(resolved)) return resolved;\n\n const explicit = resolveFromAssociationMap(testCase, options.associations);\n if (explicit !== undefined) return explicit;\n\n return readAssociationFromAssertion(testCase.raw);\n}\n\nfunction resolveFromAssociationMap(\n testCase: AgentInspectJestTestCase,\n associations: Record<string, AgentInspectJestTraceAssociation> | undefined,\n): AgentInspectJestTraceAssociation | undefined {\n if (associations === undefined) return undefined;\n const basename = testCase.file === undefined ? undefined : path.basename(testCase.file);\n const candidates = [\n testCase.id,\n testCase.fullName,\n basename === undefined ? undefined : `${basename}::${testCase.fullName}`,\n ];\n for (const candidate of candidates) {\n if (candidate !== undefined && isAssociation(associations[candidate])) {\n return associations[candidate];\n }\n }\n return undefined;\n}\n\nfunction readAssociationFromAssertion(\n assertion: unknown,\n): AgentInspectJestTraceAssociation | undefined {\n if (!isObject(assertion)) return undefined;\n const direct = readProp(assertion, \"agentInspect\");\n if (isAssociation(direct)) return direct;\n\n const meta = readProp(assertion, \"meta\");\n if (!isObject(meta)) return undefined;\n for (const candidate of [\n readProp(meta, \"agentInspect\"),\n readProp(meta, \"agent-inspect\"),\n readProp(meta, \"trace\"),\n ]) {\n if (isAssociation(candidate)) return candidate;\n }\n return undefined;\n}\n\nfunction isAssociation(\n value: unknown,\n): value is AgentInspectJestTraceAssociation {\n if (!isObject(value)) return false;\n return (\n readOptionalString(value, \"runId\") !== undefined ||\n readOptionalString(value, \"tracePath\") !== undefined ||\n readOptionalString(value, \"artifactLabel\") !== undefined\n );\n}\n\nfunction readRunResults(results: unknown): unknown[] {\n if (!isObject(results)) return [];\n const testResults = readProp(results, \"testResults\");\n return Array.isArray(testResults) ? testResults : [];\n}\n\nfunction readTestCases(testResult: unknown): AgentInspectJestTestCase[] {\n if (!isObject(testResult)) return [];\n const result = testResult as TestFileResultLike;\n const file = readOptionalString(result, \"testFilePath\");\n const assertions = Array.isArray(result.testResults)\n ? result.testResults\n : Array.isArray(result.assertionResults)\n ? result.assertionResults\n : [];\n\n const cases: AgentInspectJestTestCase[] = [];\n for (const assertion of assertions) {\n if (!isObject(assertion)) continue;\n const status = readStatus(assertion);\n if (status === undefined || status === \"skipped\") continue;\n\n const title = readOptionalString(assertion, \"title\") ?? \"unknown-test\";\n const fullName = readFullName(assertion as AssertionResultLike, title);\n const id = `${file ?? \"unknown-file\"}::${fullName}`;\n cases.push({\n file,\n fullName: boundText(redactText(fullName)),\n id: boundText(redactText(id)),\n raw: assertion,\n status,\n title: boundText(redactText(title)),\n });\n }\n return cases;\n}\n\nfunction readFullName(assertion: AssertionResultLike, title: string): string {\n const explicit = readOptionalString(assertion, \"fullName\");\n if (explicit !== undefined) return explicit;\n\n const ancestors = Array.isArray(assertion.ancestorTitles)\n ? assertion.ancestorTitles.filter((item): item is string => typeof item === \"string\")\n : [];\n return [...ancestors, title].join(\" \");\n}\n\nfunction readStatus(assertion: object): AgentInspectJestStatus | undefined {\n const raw = readOptionalString(assertion, \"status\");\n if (raw === undefined) return undefined;\n\n const normalized = raw.toLowerCase();\n if (normalized === \"failed\" || normalized === \"fail\") return \"failed\";\n if (normalized === \"passed\" || normalized === \"pass\") return \"passed\";\n if (\n normalized === \"pending\" ||\n normalized === \"todo\" ||\n normalized === \"skipped\" ||\n normalized === \"skip\" ||\n normalized === \"disabled\"\n ) {\n return \"skipped\";\n }\n return undefined;\n}\n\nasync function writeSafeArtifact(input: {\n readonly artifactDir: string;\n readonly association: AgentInspectJestTraceAssociation;\n readonly generatedAt: string;\n readonly redactionProfile: TraceArtifactRedactionProfile;\n readonly reserveArtifactName: (seed: string) => string;\n readonly status: AgentInspectJestStatus;\n readonly testCase: AgentInspectJestTestCase;\n}): Promise<AgentInspectJestArtifact> {\n const artifactSeed =\n input.association.artifactLabel ??\n input.testCase.id ??\n input.testCase.fullName ??\n input.status;\n const artifactName = input.reserveArtifactName(artifactSeed);\n const testFile =\n input.testCase.file === undefined ? undefined : path.basename(input.testCase.file);\n const safeTestId = `${testFile ?? \"unknown-file\"}::${input.testCase.fullName}`;\n const manifestPathResult = createReporterArtifactPath({\n outputDir: input.artifactDir,\n testId: artifactName,\n name: input.testCase.fullName,\n file: testFile,\n kind: \"report\",\n format: \"json\",\n });\n const summaryPathResult = createReporterArtifactPath({\n outputDir: input.artifactDir,\n testId: artifactName,\n name: input.testCase.fullName,\n file: testFile,\n kind: \"summary\",\n format: \"md\",\n });\n\n if (\n !manifestPathResult.ok ||\n manifestPathResult.absolutePath === undefined ||\n manifestPathResult.relativePath === undefined\n ) {\n throw new Error(formatPathDiagnostics(manifestPathResult.diagnostics));\n }\n if (\n !summaryPathResult.ok ||\n summaryPathResult.absolutePath === undefined ||\n summaryPathResult.relativePath === undefined\n ) {\n throw new Error(formatPathDiagnostics(summaryPathResult.diagnostics));\n }\n\n const directory = path.dirname(manifestPathResult.absolutePath);\n await mkdir(directory, { recursive: true });\n\n const traceFile =\n input.association.tracePath === undefined\n ? undefined\n : path.basename(input.association.tracePath);\n const manifestArtifact: TraceArtifact = {\n kind: \"report\",\n path: manifestPathResult.relativePath,\n format: \"json\",\n redactionProfile: input.redactionProfile,\n };\n const summaryArtifact: TraceArtifact = {\n kind: \"summary\",\n path: summaryPathResult.relativePath,\n format: \"md\",\n redactionProfile: input.redactionProfile,\n };\n const manifest = createTraceArtifactManifest({\n framework: \"jest\",\n generatedAt: input.generatedAt,\n results: [\n {\n testId: safeTestId,\n name: input.testCase.fullName,\n ...(testFile === undefined ? {} : { file: testFile }),\n status: input.status,\n tracePath: safeOptional(traceFile),\n artifacts: [manifestArtifact, summaryArtifact],\n diagnostics: [],\n },\n ],\n artifacts: [manifestArtifact, summaryArtifact],\n diagnostics: [],\n });\n const trace = {\n runId: safeOptional(input.association.runId),\n file: safeOptional(traceFile),\n };\n\n await writeFile(\n manifestPathResult.absolutePath,\n `${JSON.stringify({ package: PACKAGE_NAME, manifest, trace }, null, 2)}\\n`,\n );\n const summaryPath = summaryPathResult.absolutePath;\n await writeFile(summaryPath, renderSummary(manifest, trace), \"utf-8\");\n\n return {\n directory,\n manifest,\n manifestPath: manifestPathResult.absolutePath,\n status: input.status,\n summaryPath,\n testId: safeTestId,\n };\n}\n\nfunction renderSummary(\n manifest: TraceArtifactManifest,\n trace: { readonly runId?: string; readonly file?: string },\n): string {\n const result = manifest.results[0];\n return [\n \"# AgentInspect Jest Artifact\",\n \"\",\n `- Test: ${result?.name ?? \"unknown\"}`,\n `- Test id: ${result?.testId ?? \"unknown\"}`,\n `- Status: ${result?.status ?? \"unknown\"}`,\n `- File: ${result?.file ?? \"unknown\"}`,\n `- Trace run: ${trace.runId ?? \"unknown\"}`,\n `- Trace file: ${result?.tracePath ?? \"unknown\"}`,\n `- Manifest schema: ${manifest.schemaVersion}`,\n \"\",\n \"Trace contents are intentionally not embedded in this artifact.\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction formatPathDiagnostics(\n diagnostics: readonly TraceReporterDiagnostic[],\n): string {\n if (diagnostics.length === 0) return \"Unsafe AgentInspect Jest artifact path.\";\n return diagnostics.map((diagnostic) => diagnostic.message).join(\"; \");\n}\n\nfunction safeOptional(value: string | undefined): string | undefined {\n return value === undefined ? undefined : boundText(redactText(value));\n}\n\nfunction safeSegment(value: string): string {\n const sanitized = redactText(value)\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 80);\n return sanitized.length > 0 ? sanitized : \"trace\";\n}\n\nfunction boundText(value: string): string {\n const compact = value.replace(/\\s+/g, \" \").trim();\n if (compact.length <= MAX_TEXT) return compact;\n return `${compact.slice(0, MAX_TEXT - 12)}...[truncated]`;\n}\n\nfunction redactText(value: string): string {\n return value\n .replace(/\\bsk-[A-Za-z0-9_-]{8,}\\b/g, \"[REDACTED]\")\n .replace(/\\b(?:api[_-]?key|authorization|token|secret|password)\\s*[:=]\\s*[^,\\s]+/gi, \"$1=[REDACTED]\");\n}\n\nfunction readOptionalString(value: unknown, key: string): string | undefined {\n if (!isObject(value)) return undefined;\n const property = readProp(value, key);\n return typeof property === \"string\" && property.length > 0 ? property : undefined;\n}\n\nfunction readProp(value: object, key: string): unknown {\n return (value as Record<string, unknown>)[key];\n}\n\nfunction isObject(value: unknown): value is object {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":["mkdir","path","writeFile","createReporterArtifactPath","createTraceArtifactManifest"],"mappings":"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","file":"index.cjs","sourcesContent":["import { mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport {\n createReporterArtifactPath,\n createTraceArtifactManifest,\n type TraceArtifact,\n type TraceArtifactManifest,\n type TraceArtifactRedactionProfile,\n type TraceReporterDiagnostic,\n} from \"agent-inspect/reporters\";\n\nexport type AgentInspectJestStatus = \"failed\" | \"passed\" | \"skipped\";\n\n/**\n * Experimental trace association read by `@agent-inspect/jest`.\n *\n * Jest does not expose Vitest-style task metadata, so the default path is an\n * explicit `associations` map keyed by test identity, or a `resolveTrace`\n * callback. The reporter never guesses by timestamps.\n */\nexport interface AgentInspectJestTraceAssociation {\n /** AgentInspect run/span identifier to show in safe artifacts. */\n readonly runId?: string;\n /** Local trace file path. Only the basename is written to artifacts. */\n readonly tracePath?: string;\n /** Optional stable label for the artifact directory. */\n readonly artifactLabel?: string;\n}\n\n/**\n * Experimental normalized view of one Jest assertion result.\n */\nexport interface AgentInspectJestTestCase {\n readonly id: string;\n readonly title: string;\n readonly fullName: string;\n readonly file?: string;\n readonly status: AgentInspectJestStatus;\n readonly raw: unknown;\n}\n\n/**\n * Experimental diagnostic emitted when reporter work cannot be completed.\n *\n * Diagnostics are reported instead of thrown so Jest's original test result\n * remains authoritative.\n */\nexport interface AgentInspectJestDiagnostic {\n readonly code:\n | \"artifact-write-failed\"\n | \"github-summary-write-failed\"\n | \"no-trace-association\"\n | \"on-diagnostic-failed\";\n readonly message: string;\n readonly testId?: string;\n}\n\n/**\n * Experimental options for the AgentInspect Jest reporter.\n *\n * The reporter is local-only: it performs no network I/O and writes bounded,\n * structural artifacts without reading trace contents.\n */\nexport interface AgentInspectJestReporterOptions {\n /** Directory for safe Jest artifacts. Defaults to `.agent-inspect/jest-artifacts`. */\n readonly artifactDir?: string;\n /** Optional GitHub step-summary path. Only bounded structural lines are appended. */\n readonly githubSummary?: string;\n /**\n * Keep artifacts for passing tests. `false`/undefined keeps none; `true`\n * keeps up to `maxSuccessfulTraces`; a number keeps up to that many.\n */\n readonly retainSuccessful?: boolean | number;\n /** Upper bound for retained passing-test artifacts. Defaults to 20. */\n readonly maxSuccessfulTraces?: number;\n /** Redaction profile recorded on generated artifacts. Defaults to `share`. */\n readonly redactionProfile?: TraceArtifactRedactionProfile;\n /** Deterministic manifest timestamp. Defaults to the Unix epoch. */\n readonly generatedAt?: string;\n /** Explicit trace associations keyed by `file::fullName`, `basename::fullName`, or `fullName`. */\n readonly associations?: Record<string, AgentInspectJestTraceAssociation>;\n /** Resolve explicit test-to-trace associations from a normalized Jest case. */\n readonly resolveTrace?: (\n test: AgentInspectJestTestCase,\n ) => AgentInspectJestTraceAssociation | undefined;\n /** Observe non-fatal reporter diagnostics. */\n readonly onDiagnostic?: (diagnostic: AgentInspectJestDiagnostic) => void;\n}\n\nexport interface AgentInspectJestArtifact {\n readonly directory: string;\n readonly manifestPath: string;\n readonly summaryPath: string;\n readonly status: AgentInspectJestStatus;\n readonly testId: string;\n readonly manifest: TraceArtifactManifest;\n}\n\n/**\n * Experimental Jest reporter facade.\n *\n * The hooks mirror Jest reporter lifecycle names, while inputs stay structural\n * to avoid a runtime dependency on Jest internals.\n */\nexport interface AgentInspectJestReporterFacade {\n onTestResult(test: unknown, testResult: unknown, aggregatedResult?: unknown): Promise<void>;\n onRunComplete(contexts?: unknown, results?: unknown): Promise<void>;\n getDiagnostics(): readonly AgentInspectJestDiagnostic[];\n getArtifacts(): readonly AgentInspectJestArtifact[];\n}\n\ntype AssertionResultLike = {\n readonly ancestorTitles?: unknown;\n readonly title?: unknown;\n readonly fullName?: unknown;\n readonly status?: unknown;\n readonly meta?: unknown;\n readonly agentInspect?: unknown;\n};\n\ntype TestFileResultLike = {\n readonly testFilePath?: unknown;\n readonly testResults?: unknown;\n readonly assertionResults?: unknown;\n};\n\nconst PACKAGE_NAME = \"@agent-inspect/jest\";\nconst DEFAULT_ARTIFACT_DIR = \".agent-inspect/jest-artifacts\";\nconst DEFAULT_SUCCESS_LIMIT = 20;\nconst MAX_SUCCESS_LIMIT = 100;\nconst MAX_TEXT = 180;\nconst DEFAULT_GENERATED_AT = \"1970-01-01T00:00:00.000Z\";\nconst ASSOCIATION_DOCS =\n \"https://github.com/rajudandigam/agent-inspect/blob/main/packages/jest/README.md#trace-association\";\n\n/**\n * Attach an explicit AgentInspect trace association to a Jest assertion result.\n *\n * The reporter does not instrument tests automatically; pass the returned object\n * as `agentInspect` / `meta.agentInspect` or use `associations` / `resolveTrace`.\n */\nexport function withAgentInspectJestTrace(\n association: AgentInspectJestTraceAssociation,\n): { readonly agentInspect: AgentInspectJestTraceAssociation } {\n return { agentInspect: association };\n}\n\n/**\n * Create the experimental AgentInspect Jest reporter.\n */\nexport function createAgentInspectJestReporter(\n options: AgentInspectJestReporterOptions = {},\n): AgentInspectJestReporterFacade {\n const diagnostics: AgentInspectJestDiagnostic[] = [];\n const artifacts: AgentInspectJestArtifact[] = [];\n const seenKeys = new Set<string>();\n const artifactNames = new Map<string, number>();\n const failedWithoutAssociation = new Set<string>();\n const successLimit = normalizeSuccessLimit(options);\n let retainedSuccesses = 0;\n let reportedMissingAssociation = false;\n\n const reporter: AgentInspectJestReporterFacade = {\n async onTestResult(_test: unknown, testResult: unknown): Promise<void> {\n await handleFileResult(testResult);\n },\n async onRunComplete(_contexts?: unknown, results?: unknown): Promise<void> {\n for (const fileResult of readRunResults(results)) {\n await handleFileResult(fileResult);\n }\n await emitMissingAssociationDiagnostic();\n await appendGithubSummary();\n },\n getDiagnostics(): readonly AgentInspectJestDiagnostic[] {\n return diagnostics.slice();\n },\n getArtifacts(): readonly AgentInspectJestArtifact[] {\n return artifacts.slice();\n },\n };\n\n async function handleFileResult(testResult: unknown): Promise<void> {\n for (const testCase of readTestCases(testResult)) {\n await handleTestCase(testCase);\n }\n }\n\n async function handleTestCase(testCase: AgentInspectJestTestCase): Promise<void> {\n const seenKey = `${testCase.id}:${testCase.status}`;\n if (seenKeys.has(seenKey)) return;\n\n const association = resolveAssociation(testCase, options);\n if (association === undefined) {\n if (testCase.status === \"failed\") {\n failedWithoutAssociation.add(testCase.id);\n }\n return;\n }\n\n if (testCase.status === \"passed\") {\n if (retainedSuccesses >= successLimit) return;\n retainedSuccesses += 1;\n }\n\n seenKeys.add(seenKey);\n\n try {\n const artifact = await writeSafeArtifact({\n artifactDir: options.artifactDir ?? DEFAULT_ARTIFACT_DIR,\n association,\n generatedAt: options.generatedAt ?? DEFAULT_GENERATED_AT,\n redactionProfile: options.redactionProfile ?? \"share\",\n reserveArtifactName,\n status: testCase.status,\n testCase,\n });\n artifacts.push(artifact);\n } catch (error) {\n reportDiagnostic({\n code: \"artifact-write-failed\",\n message: `Could not write AgentInspect Jest artifact: ${errorMessage(error)}`,\n testId: testCase.id,\n });\n }\n }\n\n function reserveArtifactName(seed: string): string {\n const base = safeSegment(seed);\n const next = (artifactNames.get(base) ?? 0) + 1;\n artifactNames.set(base, next);\n return next === 1 ? base : `${base}-${next}`;\n }\n\n function reportDiagnostic(diagnostic: AgentInspectJestDiagnostic): void {\n diagnostics.push(diagnostic);\n if (options.onDiagnostic === undefined) return;\n try {\n options.onDiagnostic(diagnostic);\n } catch (error) {\n diagnostics.push({\n code: \"on-diagnostic-failed\",\n message: `AgentInspect Jest diagnostic callback failed: ${errorMessage(error)}`,\n testId: diagnostic.testId,\n });\n }\n }\n\n async function emitMissingAssociationDiagnostic(): Promise<void> {\n if (reportedMissingAssociation || failedWithoutAssociation.size === 0) return;\n reportedMissingAssociation = true;\n const count = failedWithoutAssociation.size;\n const sampleIds = [...failedWithoutAssociation].slice(0, 3);\n const message =\n `${count} failed Jest test(s) had no AgentInspect trace association. ` +\n `Reporter does not instrument tests automatically; no trace artifact was generated. ` +\n `Use withAgentInspectJestTrace, associations, resolveTrace, or meta.agentInspect. ` +\n `Docs: ${ASSOCIATION_DOCS}. Samples: ${sampleIds.join(\"; \")}`;\n reportDiagnostic({\n code: \"no-trace-association\",\n // Keep the helper name before truncation so the diagnostic stays actionable.\n message: boundText(message, 320),\n });\n\n try {\n const artifactDir = options.artifactDir ?? DEFAULT_ARTIFACT_DIR;\n await mkdir(artifactDir, { recursive: true });\n const diagnosticPath = path.join(artifactDir, \"no-trace-association.md\");\n const body = [\n \"# AgentInspect Jest — missing trace association\",\n \"\",\n \"Failed tests were observed without an explicit AgentInspect trace association.\",\n \"No trace artifact was generated for those tests.\",\n \"\",\n \"The reporter does **not** instrument Jest automatically.\",\n `Associate traces explicitly. Docs: ${ASSOCIATION_DOCS}`,\n \"\",\n \"## Failed tests without association\",\n \"\",\n ...[...failedWithoutAssociation].slice(0, 20).map((id) => `- ${boundText(id)}`),\n \"\",\n ].join(\"\\n\");\n await writeFile(diagnosticPath, body, \"utf-8\");\n } catch (error) {\n reportDiagnostic({\n code: \"artifact-write-failed\",\n message: `Could not write AgentInspect Jest no-association diagnostic: ${errorMessage(error)}`,\n });\n }\n }\n\n async function appendGithubSummary(): Promise<void> {\n if (options.githubSummary === undefined) return;\n if (artifacts.length === 0 && failedWithoutAssociation.size === 0) return;\n const failed = artifacts.filter((artifact) => artifact.status === \"failed\").length;\n const passed = artifacts.filter((artifact) => artifact.status === \"passed\").length;\n const lines = [\n \"\",\n \"## AgentInspect Jest artifacts\",\n \"\",\n `- Failed test artifacts: ${failed}`,\n `- Passing test artifacts retained: ${passed}`,\n `- Failed tests without trace association: ${failedWithoutAssociation.size}`,\n `- Artifact directory: ${boundText(path.basename(options.artifactDir ?? DEFAULT_ARTIFACT_DIR))}`,\n \"\",\n ];\n if (failedWithoutAssociation.size > 0) {\n lines.push(\n \"No automatic instrumentation: associate traces via `associations`, `resolveTrace`, or `withAgentInspectJestTrace`.\",\n \"\",\n );\n }\n try {\n await writeFile(options.githubSummary, `${lines.join(\"\\n\")}\\n`, { flag: \"a\" });\n } catch (error) {\n reportDiagnostic({\n code: \"github-summary-write-failed\",\n message: `Could not append AgentInspect Jest summary: ${errorMessage(error)}`,\n });\n }\n }\n\n return reporter;\n}\n\n/**\n * Experimental Jest custom reporter class.\n */\nexport class AgentInspectJestReporter implements AgentInspectJestReporterFacade {\n private readonly reporter: AgentInspectJestReporterFacade;\n\n constructor(_globalConfig?: unknown, options: AgentInspectJestReporterOptions = {}) {\n this.reporter = createAgentInspectJestReporter(options);\n }\n\n async onTestResult(\n test: unknown,\n testResult: unknown,\n aggregatedResult?: unknown,\n ): Promise<void> {\n await this.reporter.onTestResult(test, testResult, aggregatedResult);\n }\n\n async onRunComplete(contexts?: unknown, results?: unknown): Promise<void> {\n await this.reporter.onRunComplete(contexts, results);\n }\n\n getDiagnostics(): readonly AgentInspectJestDiagnostic[] {\n return this.reporter.getDiagnostics();\n }\n\n getArtifacts(): readonly AgentInspectJestArtifact[] {\n return this.reporter.getArtifacts();\n }\n}\n\nexport const agentInspectJestReporter = createAgentInspectJestReporter;\nexport default AgentInspectJestReporter;\n\nfunction normalizeSuccessLimit(options: AgentInspectJestReporterOptions): number {\n const cap = clampCount(options.maxSuccessfulTraces, DEFAULT_SUCCESS_LIMIT);\n if (options.retainSuccessful === true) return cap;\n if (typeof options.retainSuccessful === \"number\") {\n return Math.min(clampCount(options.retainSuccessful, 0), cap);\n }\n return 0;\n}\n\nfunction clampCount(value: number | undefined, fallback: number): number {\n if (value === undefined || !Number.isFinite(value)) return fallback;\n return Math.max(0, Math.min(MAX_SUCCESS_LIMIT, Math.floor(value)));\n}\n\nfunction resolveAssociation(\n testCase: AgentInspectJestTestCase,\n options: AgentInspectJestReporterOptions,\n): AgentInspectJestTraceAssociation | undefined {\n const resolved = options.resolveTrace?.(testCase);\n if (isAssociation(resolved)) return resolved;\n\n const explicit = resolveFromAssociationMap(testCase, options.associations);\n if (explicit !== undefined) return explicit;\n\n return readAssociationFromAssertion(testCase.raw);\n}\n\nfunction resolveFromAssociationMap(\n testCase: AgentInspectJestTestCase,\n associations: Record<string, AgentInspectJestTraceAssociation> | undefined,\n): AgentInspectJestTraceAssociation | undefined {\n if (associations === undefined) return undefined;\n const basename = testCase.file === undefined ? undefined : path.basename(testCase.file);\n const candidates = [\n testCase.id,\n testCase.fullName,\n basename === undefined ? undefined : `${basename}::${testCase.fullName}`,\n ];\n for (const candidate of candidates) {\n if (candidate !== undefined && isAssociation(associations[candidate])) {\n return associations[candidate];\n }\n }\n return undefined;\n}\n\nfunction readAssociationFromAssertion(\n assertion: unknown,\n): AgentInspectJestTraceAssociation | undefined {\n if (!isObject(assertion)) return undefined;\n const direct = readProp(assertion, \"agentInspect\");\n if (isAssociation(direct)) return direct;\n\n const meta = readProp(assertion, \"meta\");\n if (!isObject(meta)) return undefined;\n for (const candidate of [\n readProp(meta, \"agentInspect\"),\n readProp(meta, \"agent-inspect\"),\n readProp(meta, \"trace\"),\n ]) {\n if (isAssociation(candidate)) return candidate;\n }\n return undefined;\n}\n\nfunction isAssociation(\n value: unknown,\n): value is AgentInspectJestTraceAssociation {\n if (!isObject(value)) return false;\n return (\n readOptionalString(value, \"runId\") !== undefined ||\n readOptionalString(value, \"tracePath\") !== undefined ||\n readOptionalString(value, \"artifactLabel\") !== undefined\n );\n}\n\nfunction readRunResults(results: unknown): unknown[] {\n if (!isObject(results)) return [];\n const testResults = readProp(results, \"testResults\");\n return Array.isArray(testResults) ? testResults : [];\n}\n\nfunction readTestCases(testResult: unknown): AgentInspectJestTestCase[] {\n if (!isObject(testResult)) return [];\n const result = testResult as TestFileResultLike;\n const file = readOptionalString(result, \"testFilePath\");\n const assertions = Array.isArray(result.testResults)\n ? result.testResults\n : Array.isArray(result.assertionResults)\n ? result.assertionResults\n : [];\n\n const cases: AgentInspectJestTestCase[] = [];\n for (const assertion of assertions) {\n if (!isObject(assertion)) continue;\n const status = readStatus(assertion);\n if (status === undefined || status === \"skipped\") continue;\n\n const title = readOptionalString(assertion, \"title\") ?? \"unknown-test\";\n const fullName = readFullName(assertion as AssertionResultLike, title);\n const id = `${file ?? \"unknown-file\"}::${fullName}`;\n cases.push({\n file,\n fullName: boundText(redactText(fullName)),\n id: boundText(redactText(id)),\n raw: assertion,\n status,\n title: boundText(redactText(title)),\n });\n }\n return cases;\n}\n\nfunction readFullName(assertion: AssertionResultLike, title: string): string {\n const explicit = readOptionalString(assertion, \"fullName\");\n if (explicit !== undefined) return explicit;\n\n const ancestors = Array.isArray(assertion.ancestorTitles)\n ? assertion.ancestorTitles.filter((item): item is string => typeof item === \"string\")\n : [];\n return [...ancestors, title].join(\" \");\n}\n\nfunction readStatus(assertion: object): AgentInspectJestStatus | undefined {\n const raw = readOptionalString(assertion, \"status\");\n if (raw === undefined) return undefined;\n\n const normalized = raw.toLowerCase();\n if (normalized === \"failed\" || normalized === \"fail\") return \"failed\";\n if (normalized === \"passed\" || normalized === \"pass\") return \"passed\";\n if (\n normalized === \"pending\" ||\n normalized === \"todo\" ||\n normalized === \"skipped\" ||\n normalized === \"skip\" ||\n normalized === \"disabled\"\n ) {\n return \"skipped\";\n }\n return undefined;\n}\n\nasync function writeSafeArtifact(input: {\n readonly artifactDir: string;\n readonly association: AgentInspectJestTraceAssociation;\n readonly generatedAt: string;\n readonly redactionProfile: TraceArtifactRedactionProfile;\n readonly reserveArtifactName: (seed: string) => string;\n readonly status: AgentInspectJestStatus;\n readonly testCase: AgentInspectJestTestCase;\n}): Promise<AgentInspectJestArtifact> {\n const artifactSeed =\n input.association.artifactLabel ??\n input.testCase.id ??\n input.testCase.fullName ??\n input.status;\n const artifactName = input.reserveArtifactName(artifactSeed);\n const testFile =\n input.testCase.file === undefined ? undefined : path.basename(input.testCase.file);\n const safeTestId = `${testFile ?? \"unknown-file\"}::${input.testCase.fullName}`;\n const manifestPathResult = createReporterArtifactPath({\n outputDir: input.artifactDir,\n testId: artifactName,\n name: input.testCase.fullName,\n file: testFile,\n kind: \"report\",\n format: \"json\",\n });\n const summaryPathResult = createReporterArtifactPath({\n outputDir: input.artifactDir,\n testId: artifactName,\n name: input.testCase.fullName,\n file: testFile,\n kind: \"summary\",\n format: \"md\",\n });\n\n if (\n !manifestPathResult.ok ||\n manifestPathResult.absolutePath === undefined ||\n manifestPathResult.relativePath === undefined\n ) {\n throw new Error(formatPathDiagnostics(manifestPathResult.diagnostics));\n }\n if (\n !summaryPathResult.ok ||\n summaryPathResult.absolutePath === undefined ||\n summaryPathResult.relativePath === undefined\n ) {\n throw new Error(formatPathDiagnostics(summaryPathResult.diagnostics));\n }\n\n const directory = path.dirname(manifestPathResult.absolutePath);\n await mkdir(directory, { recursive: true });\n\n const traceFile =\n input.association.tracePath === undefined\n ? undefined\n : path.basename(input.association.tracePath);\n const manifestArtifact: TraceArtifact = {\n kind: \"report\",\n path: manifestPathResult.relativePath,\n format: \"json\",\n redactionProfile: input.redactionProfile,\n };\n const summaryArtifact: TraceArtifact = {\n kind: \"summary\",\n path: summaryPathResult.relativePath,\n format: \"md\",\n redactionProfile: input.redactionProfile,\n };\n const manifest = createTraceArtifactManifest({\n framework: \"jest\",\n generatedAt: input.generatedAt,\n results: [\n {\n testId: safeTestId,\n name: input.testCase.fullName,\n ...(testFile === undefined ? {} : { file: testFile }),\n status: input.status,\n tracePath: safeOptional(traceFile),\n artifacts: [manifestArtifact, summaryArtifact],\n diagnostics: [],\n },\n ],\n artifacts: [manifestArtifact, summaryArtifact],\n diagnostics: [],\n });\n const trace = {\n runId: safeOptional(input.association.runId),\n file: safeOptional(traceFile),\n };\n\n await writeFile(\n manifestPathResult.absolutePath,\n `${JSON.stringify({ package: PACKAGE_NAME, manifest, trace }, null, 2)}\\n`,\n );\n const summaryPath = summaryPathResult.absolutePath;\n await writeFile(summaryPath, renderSummary(manifest, trace), \"utf-8\");\n\n return {\n directory,\n manifest,\n manifestPath: manifestPathResult.absolutePath,\n status: input.status,\n summaryPath,\n testId: safeTestId,\n };\n}\n\nfunction renderSummary(\n manifest: TraceArtifactManifest,\n trace: { readonly runId?: string; readonly file?: string },\n): string {\n const result = manifest.results[0];\n return [\n \"# AgentInspect Jest Artifact\",\n \"\",\n `- Test: ${result?.name ?? \"unknown\"}`,\n `- Test id: ${result?.testId ?? \"unknown\"}`,\n `- Status: ${result?.status ?? \"unknown\"}`,\n `- File: ${result?.file ?? \"unknown\"}`,\n `- Trace run: ${trace.runId ?? \"unknown\"}`,\n `- Trace file: ${result?.tracePath ?? \"unknown\"}`,\n `- Manifest schema: ${manifest.schemaVersion}`,\n \"\",\n \"Trace contents are intentionally not embedded in this artifact.\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction formatPathDiagnostics(\n diagnostics: readonly TraceReporterDiagnostic[],\n): string {\n if (diagnostics.length === 0) return \"Unsafe AgentInspect Jest artifact path.\";\n return diagnostics.map((diagnostic) => diagnostic.message).join(\"; \");\n}\n\nfunction safeOptional(value: string | undefined): string | undefined {\n return value === undefined ? undefined : boundText(redactText(value));\n}\n\nfunction safeSegment(value: string): string {\n const sanitized = redactText(value)\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 80);\n return sanitized.length > 0 ? sanitized : \"trace\";\n}\n\nfunction boundText(value: string, max = MAX_TEXT): string {\n const compact = value.replace(/\\s+/g, \" \").trim();\n if (compact.length <= max) return compact;\n return `${compact.slice(0, max - 12)}...[truncated]`;\n}\n\nfunction redactText(value: string): string {\n return value\n .replace(/\\bsk-[A-Za-z0-9_-]{8,}\\b/g, \"[REDACTED]\")\n .replace(/\\b(?:api[_-]?key|authorization|token|secret|password)\\s*[:=]\\s*[^,\\s]+/gi, \"$1=[REDACTED]\");\n}\n\nfunction readOptionalString(value: unknown, key: string): string | undefined {\n if (!isObject(value)) return undefined;\n const property = readProp(value, key);\n return typeof property === \"string\" && property.length > 0 ? property : undefined;\n}\n\nfunction readProp(value: object, key: string): unknown {\n return (value as Record<string, unknown>)[key];\n}\n\nfunction isObject(value: unknown): value is object {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -85,7 +85,7 @@ interface AgentInspectJestTestCase {
85
85
  * remains authoritative.
86
86
  */
87
87
  interface AgentInspectJestDiagnostic {
88
- readonly code: "artifact-write-failed" | "github-summary-write-failed" | "on-diagnostic-failed";
88
+ readonly code: "artifact-write-failed" | "github-summary-write-failed" | "no-trace-association" | "on-diagnostic-failed";
89
89
  readonly message: string;
90
90
  readonly testId?: string;
91
91
  }
@@ -138,6 +138,15 @@ interface AgentInspectJestReporterFacade {
138
138
  getDiagnostics(): readonly AgentInspectJestDiagnostic[];
139
139
  getArtifacts(): readonly AgentInspectJestArtifact[];
140
140
  }
141
+ /**
142
+ * Attach an explicit AgentInspect trace association to a Jest assertion result.
143
+ *
144
+ * The reporter does not instrument tests automatically; pass the returned object
145
+ * as `agentInspect` / `meta.agentInspect` or use `associations` / `resolveTrace`.
146
+ */
147
+ declare function withAgentInspectJestTrace(association: AgentInspectJestTraceAssociation): {
148
+ readonly agentInspect: AgentInspectJestTraceAssociation;
149
+ };
141
150
  /**
142
151
  * Create the experimental AgentInspect Jest reporter.
143
152
  */
@@ -155,4 +164,4 @@ declare class AgentInspectJestReporter implements AgentInspectJestReporterFacade
155
164
  }
156
165
  declare const agentInspectJestReporter: typeof createAgentInspectJestReporter;
157
166
 
158
- export { type AgentInspectJestArtifact, type AgentInspectJestDiagnostic, AgentInspectJestReporter, type AgentInspectJestReporterFacade, type AgentInspectJestReporterOptions, type AgentInspectJestStatus, type AgentInspectJestTestCase, type AgentInspectJestTraceAssociation, agentInspectJestReporter, createAgentInspectJestReporter, AgentInspectJestReporter as default };
167
+ export { type AgentInspectJestArtifact, type AgentInspectJestDiagnostic, AgentInspectJestReporter, type AgentInspectJestReporterFacade, type AgentInspectJestReporterOptions, type AgentInspectJestStatus, type AgentInspectJestTestCase, type AgentInspectJestTraceAssociation, agentInspectJestReporter, createAgentInspectJestReporter, AgentInspectJestReporter as default, withAgentInspectJestTrace };
package/dist/index.d.ts CHANGED
@@ -85,7 +85,7 @@ interface AgentInspectJestTestCase {
85
85
  * remains authoritative.
86
86
  */
87
87
  interface AgentInspectJestDiagnostic {
88
- readonly code: "artifact-write-failed" | "github-summary-write-failed" | "on-diagnostic-failed";
88
+ readonly code: "artifact-write-failed" | "github-summary-write-failed" | "no-trace-association" | "on-diagnostic-failed";
89
89
  readonly message: string;
90
90
  readonly testId?: string;
91
91
  }
@@ -138,6 +138,15 @@ interface AgentInspectJestReporterFacade {
138
138
  getDiagnostics(): readonly AgentInspectJestDiagnostic[];
139
139
  getArtifacts(): readonly AgentInspectJestArtifact[];
140
140
  }
141
+ /**
142
+ * Attach an explicit AgentInspect trace association to a Jest assertion result.
143
+ *
144
+ * The reporter does not instrument tests automatically; pass the returned object
145
+ * as `agentInspect` / `meta.agentInspect` or use `associations` / `resolveTrace`.
146
+ */
147
+ declare function withAgentInspectJestTrace(association: AgentInspectJestTraceAssociation): {
148
+ readonly agentInspect: AgentInspectJestTraceAssociation;
149
+ };
141
150
  /**
142
151
  * Create the experimental AgentInspect Jest reporter.
143
152
  */
@@ -155,4 +164,4 @@ declare class AgentInspectJestReporter implements AgentInspectJestReporterFacade
155
164
  }
156
165
  declare const agentInspectJestReporter: typeof createAgentInspectJestReporter;
157
166
 
158
- export { type AgentInspectJestArtifact, type AgentInspectJestDiagnostic, AgentInspectJestReporter, type AgentInspectJestReporterFacade, type AgentInspectJestReporterOptions, type AgentInspectJestStatus, type AgentInspectJestTestCase, type AgentInspectJestTraceAssociation, agentInspectJestReporter, createAgentInspectJestReporter, AgentInspectJestReporter as default };
167
+ export { type AgentInspectJestArtifact, type AgentInspectJestDiagnostic, AgentInspectJestReporter, type AgentInspectJestReporterFacade, type AgentInspectJestReporterOptions, type AgentInspectJestStatus, type AgentInspectJestTestCase, type AgentInspectJestTraceAssociation, agentInspectJestReporter, createAgentInspectJestReporter, AgentInspectJestReporter as default, withAgentInspectJestTrace };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { writeFile, mkdir } from 'fs/promises';
1
+ import { mkdir, writeFile } from 'fs/promises';
2
2
  import path from 'path';
3
3
  import { createReporterArtifactPath, createTraceArtifactManifest } from 'agent-inspect/reporters';
4
4
 
@@ -9,13 +9,19 @@ var DEFAULT_SUCCESS_LIMIT = 20;
9
9
  var MAX_SUCCESS_LIMIT = 100;
10
10
  var MAX_TEXT = 180;
11
11
  var DEFAULT_GENERATED_AT = "1970-01-01T00:00:00.000Z";
12
+ var ASSOCIATION_DOCS = "https://github.com/rajudandigam/agent-inspect/blob/main/packages/jest/README.md#trace-association";
13
+ function withAgentInspectJestTrace(association) {
14
+ return { agentInspect: association };
15
+ }
12
16
  function createAgentInspectJestReporter(options = {}) {
13
17
  const diagnostics = [];
14
18
  const artifacts = [];
15
19
  const seenKeys = /* @__PURE__ */ new Set();
16
20
  const artifactNames = /* @__PURE__ */ new Map();
21
+ const failedWithoutAssociation = /* @__PURE__ */ new Set();
17
22
  const successLimit = normalizeSuccessLimit(options);
18
23
  let retainedSuccesses = 0;
24
+ let reportedMissingAssociation = false;
19
25
  const reporter = {
20
26
  async onTestResult(_test, testResult) {
21
27
  await handleFileResult(testResult);
@@ -24,6 +30,7 @@ function createAgentInspectJestReporter(options = {}) {
24
30
  for (const fileResult of readRunResults(results)) {
25
31
  await handleFileResult(fileResult);
26
32
  }
33
+ await emitMissingAssociationDiagnostic();
27
34
  await appendGithubSummary();
28
35
  },
29
36
  getDiagnostics() {
@@ -42,7 +49,12 @@ function createAgentInspectJestReporter(options = {}) {
42
49
  const seenKey = `${testCase.id}:${testCase.status}`;
43
50
  if (seenKeys.has(seenKey)) return;
44
51
  const association = resolveAssociation(testCase, options);
45
- if (association === void 0) return;
52
+ if (association === void 0) {
53
+ if (testCase.status === "failed") {
54
+ failedWithoutAssociation.add(testCase.id);
55
+ }
56
+ return;
57
+ }
46
58
  if (testCase.status === "passed") {
47
59
  if (retainedSuccesses >= successLimit) return;
48
60
  retainedSuccesses += 1;
@@ -86,8 +98,46 @@ function createAgentInspectJestReporter(options = {}) {
86
98
  });
87
99
  }
88
100
  }
101
+ async function emitMissingAssociationDiagnostic() {
102
+ if (reportedMissingAssociation || failedWithoutAssociation.size === 0) return;
103
+ reportedMissingAssociation = true;
104
+ const count = failedWithoutAssociation.size;
105
+ const sampleIds = [...failedWithoutAssociation].slice(0, 3);
106
+ const message = `${count} failed Jest test(s) had no AgentInspect trace association. Reporter does not instrument tests automatically; no trace artifact was generated. Use withAgentInspectJestTrace, associations, resolveTrace, or meta.agentInspect. Docs: ${ASSOCIATION_DOCS}. Samples: ${sampleIds.join("; ")}`;
107
+ reportDiagnostic({
108
+ code: "no-trace-association",
109
+ // Keep the helper name before truncation so the diagnostic stays actionable.
110
+ message: boundText(message, 320)
111
+ });
112
+ try {
113
+ const artifactDir = options.artifactDir ?? DEFAULT_ARTIFACT_DIR;
114
+ await mkdir(artifactDir, { recursive: true });
115
+ const diagnosticPath = path.join(artifactDir, "no-trace-association.md");
116
+ const body = [
117
+ "# AgentInspect Jest \u2014 missing trace association",
118
+ "",
119
+ "Failed tests were observed without an explicit AgentInspect trace association.",
120
+ "No trace artifact was generated for those tests.",
121
+ "",
122
+ "The reporter does **not** instrument Jest automatically.",
123
+ `Associate traces explicitly. Docs: ${ASSOCIATION_DOCS}`,
124
+ "",
125
+ "## Failed tests without association",
126
+ "",
127
+ ...[...failedWithoutAssociation].slice(0, 20).map((id) => `- ${boundText(id)}`),
128
+ ""
129
+ ].join("\n");
130
+ await writeFile(diagnosticPath, body, "utf-8");
131
+ } catch (error) {
132
+ reportDiagnostic({
133
+ code: "artifact-write-failed",
134
+ message: `Could not write AgentInspect Jest no-association diagnostic: ${errorMessage(error)}`
135
+ });
136
+ }
137
+ }
89
138
  async function appendGithubSummary() {
90
- if (options.githubSummary === void 0 || artifacts.length === 0) return;
139
+ if (options.githubSummary === void 0) return;
140
+ if (artifacts.length === 0 && failedWithoutAssociation.size === 0) return;
91
141
  const failed = artifacts.filter((artifact) => artifact.status === "failed").length;
92
142
  const passed = artifacts.filter((artifact) => artifact.status === "passed").length;
93
143
  const lines = [
@@ -96,9 +146,16 @@ function createAgentInspectJestReporter(options = {}) {
96
146
  "",
97
147
  `- Failed test artifacts: ${failed}`,
98
148
  `- Passing test artifacts retained: ${passed}`,
149
+ `- Failed tests without trace association: ${failedWithoutAssociation.size}`,
99
150
  `- Artifact directory: ${boundText(path.basename(options.artifactDir ?? DEFAULT_ARTIFACT_DIR))}`,
100
151
  ""
101
152
  ];
153
+ if (failedWithoutAssociation.size > 0) {
154
+ lines.push(
155
+ "No automatic instrumentation: associate traces via `associations`, `resolveTrace`, or `withAgentInspectJestTrace`.",
156
+ ""
157
+ );
158
+ }
102
159
  try {
103
160
  await writeFile(options.githubSummary, `${lines.join("\n")}
104
161
  `, { flag: "a" });
@@ -337,10 +394,10 @@ function safeSegment(value) {
337
394
  const sanitized = redactText(value).toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
338
395
  return sanitized.length > 0 ? sanitized : "trace";
339
396
  }
340
- function boundText(value) {
397
+ function boundText(value, max = MAX_TEXT) {
341
398
  const compact = value.replace(/\s+/g, " ").trim();
342
- if (compact.length <= MAX_TEXT) return compact;
343
- return `${compact.slice(0, MAX_TEXT - 12)}...[truncated]`;
399
+ if (compact.length <= max) return compact;
400
+ return `${compact.slice(0, max - 12)}...[truncated]`;
344
401
  }
345
402
  function redactText(value) {
346
403
  return value.replace(/\bsk-[A-Za-z0-9_-]{8,}\b/g, "[REDACTED]").replace(/\b(?:api[_-]?key|authorization|token|secret|password)\s*[:=]\s*[^,\s]+/gi, "$1=[REDACTED]");
@@ -360,6 +417,6 @@ function errorMessage(error) {
360
417
  return error instanceof Error ? error.message : String(error);
361
418
  }
362
419
 
363
- export { AgentInspectJestReporter, agentInspectJestReporter, createAgentInspectJestReporter, index_default as default };
420
+ export { AgentInspectJestReporter, agentInspectJestReporter, createAgentInspectJestReporter, index_default as default, withAgentInspectJestTrace };
364
421
  //# sourceMappingURL=index.mjs.map
365
422
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport {\n createReporterArtifactPath,\n createTraceArtifactManifest,\n type TraceArtifact,\n type TraceArtifactManifest,\n type TraceArtifactRedactionProfile,\n type TraceReporterDiagnostic,\n} from \"agent-inspect/reporters\";\n\nexport type AgentInspectJestStatus = \"failed\" | \"passed\" | \"skipped\";\n\n/**\n * Experimental trace association read by `@agent-inspect/jest`.\n *\n * Jest does not expose Vitest-style task metadata, so the default path is an\n * explicit `associations` map keyed by test identity, or a `resolveTrace`\n * callback. The reporter never guesses by timestamps.\n */\nexport interface AgentInspectJestTraceAssociation {\n /** AgentInspect run/span identifier to show in safe artifacts. */\n readonly runId?: string;\n /** Local trace file path. Only the basename is written to artifacts. */\n readonly tracePath?: string;\n /** Optional stable label for the artifact directory. */\n readonly artifactLabel?: string;\n}\n\n/**\n * Experimental normalized view of one Jest assertion result.\n */\nexport interface AgentInspectJestTestCase {\n readonly id: string;\n readonly title: string;\n readonly fullName: string;\n readonly file?: string;\n readonly status: AgentInspectJestStatus;\n readonly raw: unknown;\n}\n\n/**\n * Experimental diagnostic emitted when reporter work cannot be completed.\n *\n * Diagnostics are reported instead of thrown so Jest's original test result\n * remains authoritative.\n */\nexport interface AgentInspectJestDiagnostic {\n readonly code:\n | \"artifact-write-failed\"\n | \"github-summary-write-failed\"\n | \"on-diagnostic-failed\";\n readonly message: string;\n readonly testId?: string;\n}\n\n/**\n * Experimental options for the AgentInspect Jest reporter.\n *\n * The reporter is local-only: it performs no network I/O and writes bounded,\n * structural artifacts without reading trace contents.\n */\nexport interface AgentInspectJestReporterOptions {\n /** Directory for safe Jest artifacts. Defaults to `.agent-inspect/jest-artifacts`. */\n readonly artifactDir?: string;\n /** Optional GitHub step-summary path. Only bounded structural lines are appended. */\n readonly githubSummary?: string;\n /**\n * Keep artifacts for passing tests. `false`/undefined keeps none; `true`\n * keeps up to `maxSuccessfulTraces`; a number keeps up to that many.\n */\n readonly retainSuccessful?: boolean | number;\n /** Upper bound for retained passing-test artifacts. Defaults to 20. */\n readonly maxSuccessfulTraces?: number;\n /** Redaction profile recorded on generated artifacts. Defaults to `share`. */\n readonly redactionProfile?: TraceArtifactRedactionProfile;\n /** Deterministic manifest timestamp. Defaults to the Unix epoch. */\n readonly generatedAt?: string;\n /** Explicit trace associations keyed by `file::fullName`, `basename::fullName`, or `fullName`. */\n readonly associations?: Record<string, AgentInspectJestTraceAssociation>;\n /** Resolve explicit test-to-trace associations from a normalized Jest case. */\n readonly resolveTrace?: (\n test: AgentInspectJestTestCase,\n ) => AgentInspectJestTraceAssociation | undefined;\n /** Observe non-fatal reporter diagnostics. */\n readonly onDiagnostic?: (diagnostic: AgentInspectJestDiagnostic) => void;\n}\n\nexport interface AgentInspectJestArtifact {\n readonly directory: string;\n readonly manifestPath: string;\n readonly summaryPath: string;\n readonly status: AgentInspectJestStatus;\n readonly testId: string;\n readonly manifest: TraceArtifactManifest;\n}\n\n/**\n * Experimental Jest reporter facade.\n *\n * The hooks mirror Jest reporter lifecycle names, while inputs stay structural\n * to avoid a runtime dependency on Jest internals.\n */\nexport interface AgentInspectJestReporterFacade {\n onTestResult(test: unknown, testResult: unknown, aggregatedResult?: unknown): Promise<void>;\n onRunComplete(contexts?: unknown, results?: unknown): Promise<void>;\n getDiagnostics(): readonly AgentInspectJestDiagnostic[];\n getArtifacts(): readonly AgentInspectJestArtifact[];\n}\n\ntype AssertionResultLike = {\n readonly ancestorTitles?: unknown;\n readonly title?: unknown;\n readonly fullName?: unknown;\n readonly status?: unknown;\n readonly meta?: unknown;\n readonly agentInspect?: unknown;\n};\n\ntype TestFileResultLike = {\n readonly testFilePath?: unknown;\n readonly testResults?: unknown;\n readonly assertionResults?: unknown;\n};\n\nconst PACKAGE_NAME = \"@agent-inspect/jest\";\nconst DEFAULT_ARTIFACT_DIR = \".agent-inspect/jest-artifacts\";\nconst DEFAULT_SUCCESS_LIMIT = 20;\nconst MAX_SUCCESS_LIMIT = 100;\nconst MAX_TEXT = 180;\nconst DEFAULT_GENERATED_AT = \"1970-01-01T00:00:00.000Z\";\n\n/**\n * Create the experimental AgentInspect Jest reporter.\n */\nexport function createAgentInspectJestReporter(\n options: AgentInspectJestReporterOptions = {},\n): AgentInspectJestReporterFacade {\n const diagnostics: AgentInspectJestDiagnostic[] = [];\n const artifacts: AgentInspectJestArtifact[] = [];\n const seenKeys = new Set<string>();\n const artifactNames = new Map<string, number>();\n const successLimit = normalizeSuccessLimit(options);\n let retainedSuccesses = 0;\n\n const reporter: AgentInspectJestReporterFacade = {\n async onTestResult(_test: unknown, testResult: unknown): Promise<void> {\n await handleFileResult(testResult);\n },\n async onRunComplete(_contexts?: unknown, results?: unknown): Promise<void> {\n for (const fileResult of readRunResults(results)) {\n await handleFileResult(fileResult);\n }\n await appendGithubSummary();\n },\n getDiagnostics(): readonly AgentInspectJestDiagnostic[] {\n return diagnostics.slice();\n },\n getArtifacts(): readonly AgentInspectJestArtifact[] {\n return artifacts.slice();\n },\n };\n\n async function handleFileResult(testResult: unknown): Promise<void> {\n for (const testCase of readTestCases(testResult)) {\n await handleTestCase(testCase);\n }\n }\n\n async function handleTestCase(testCase: AgentInspectJestTestCase): Promise<void> {\n const seenKey = `${testCase.id}:${testCase.status}`;\n if (seenKeys.has(seenKey)) return;\n\n const association = resolveAssociation(testCase, options);\n if (association === undefined) return;\n\n if (testCase.status === \"passed\") {\n if (retainedSuccesses >= successLimit) return;\n retainedSuccesses += 1;\n }\n\n seenKeys.add(seenKey);\n\n try {\n const artifact = await writeSafeArtifact({\n artifactDir: options.artifactDir ?? DEFAULT_ARTIFACT_DIR,\n association,\n generatedAt: options.generatedAt ?? DEFAULT_GENERATED_AT,\n redactionProfile: options.redactionProfile ?? \"share\",\n reserveArtifactName,\n status: testCase.status,\n testCase,\n });\n artifacts.push(artifact);\n } catch (error) {\n reportDiagnostic({\n code: \"artifact-write-failed\",\n message: `Could not write AgentInspect Jest artifact: ${errorMessage(error)}`,\n testId: testCase.id,\n });\n }\n }\n\n function reserveArtifactName(seed: string): string {\n const base = safeSegment(seed);\n const next = (artifactNames.get(base) ?? 0) + 1;\n artifactNames.set(base, next);\n return next === 1 ? base : `${base}-${next}`;\n }\n\n function reportDiagnostic(diagnostic: AgentInspectJestDiagnostic): void {\n diagnostics.push(diagnostic);\n if (options.onDiagnostic === undefined) return;\n try {\n options.onDiagnostic(diagnostic);\n } catch (error) {\n diagnostics.push({\n code: \"on-diagnostic-failed\",\n message: `AgentInspect Jest diagnostic callback failed: ${errorMessage(error)}`,\n testId: diagnostic.testId,\n });\n }\n }\n\n async function appendGithubSummary(): Promise<void> {\n if (options.githubSummary === undefined || artifacts.length === 0) return;\n const failed = artifacts.filter((artifact) => artifact.status === \"failed\").length;\n const passed = artifacts.filter((artifact) => artifact.status === \"passed\").length;\n const lines = [\n \"\",\n \"## AgentInspect Jest artifacts\",\n \"\",\n `- Failed test artifacts: ${failed}`,\n `- Passing test artifacts retained: ${passed}`,\n `- Artifact directory: ${boundText(path.basename(options.artifactDir ?? DEFAULT_ARTIFACT_DIR))}`,\n \"\",\n ];\n try {\n await writeFile(options.githubSummary, `${lines.join(\"\\n\")}\\n`, { flag: \"a\" });\n } catch (error) {\n reportDiagnostic({\n code: \"github-summary-write-failed\",\n message: `Could not append AgentInspect Jest summary: ${errorMessage(error)}`,\n });\n }\n }\n\n return reporter;\n}\n\n/**\n * Experimental Jest custom reporter class.\n */\nexport class AgentInspectJestReporter implements AgentInspectJestReporterFacade {\n private readonly reporter: AgentInspectJestReporterFacade;\n\n constructor(_globalConfig?: unknown, options: AgentInspectJestReporterOptions = {}) {\n this.reporter = createAgentInspectJestReporter(options);\n }\n\n async onTestResult(\n test: unknown,\n testResult: unknown,\n aggregatedResult?: unknown,\n ): Promise<void> {\n await this.reporter.onTestResult(test, testResult, aggregatedResult);\n }\n\n async onRunComplete(contexts?: unknown, results?: unknown): Promise<void> {\n await this.reporter.onRunComplete(contexts, results);\n }\n\n getDiagnostics(): readonly AgentInspectJestDiagnostic[] {\n return this.reporter.getDiagnostics();\n }\n\n getArtifacts(): readonly AgentInspectJestArtifact[] {\n return this.reporter.getArtifacts();\n }\n}\n\nexport const agentInspectJestReporter = createAgentInspectJestReporter;\nexport default AgentInspectJestReporter;\n\nfunction normalizeSuccessLimit(options: AgentInspectJestReporterOptions): number {\n const cap = clampCount(options.maxSuccessfulTraces, DEFAULT_SUCCESS_LIMIT);\n if (options.retainSuccessful === true) return cap;\n if (typeof options.retainSuccessful === \"number\") {\n return Math.min(clampCount(options.retainSuccessful, 0), cap);\n }\n return 0;\n}\n\nfunction clampCount(value: number | undefined, fallback: number): number {\n if (value === undefined || !Number.isFinite(value)) return fallback;\n return Math.max(0, Math.min(MAX_SUCCESS_LIMIT, Math.floor(value)));\n}\n\nfunction resolveAssociation(\n testCase: AgentInspectJestTestCase,\n options: AgentInspectJestReporterOptions,\n): AgentInspectJestTraceAssociation | undefined {\n const resolved = options.resolveTrace?.(testCase);\n if (isAssociation(resolved)) return resolved;\n\n const explicit = resolveFromAssociationMap(testCase, options.associations);\n if (explicit !== undefined) return explicit;\n\n return readAssociationFromAssertion(testCase.raw);\n}\n\nfunction resolveFromAssociationMap(\n testCase: AgentInspectJestTestCase,\n associations: Record<string, AgentInspectJestTraceAssociation> | undefined,\n): AgentInspectJestTraceAssociation | undefined {\n if (associations === undefined) return undefined;\n const basename = testCase.file === undefined ? undefined : path.basename(testCase.file);\n const candidates = [\n testCase.id,\n testCase.fullName,\n basename === undefined ? undefined : `${basename}::${testCase.fullName}`,\n ];\n for (const candidate of candidates) {\n if (candidate !== undefined && isAssociation(associations[candidate])) {\n return associations[candidate];\n }\n }\n return undefined;\n}\n\nfunction readAssociationFromAssertion(\n assertion: unknown,\n): AgentInspectJestTraceAssociation | undefined {\n if (!isObject(assertion)) return undefined;\n const direct = readProp(assertion, \"agentInspect\");\n if (isAssociation(direct)) return direct;\n\n const meta = readProp(assertion, \"meta\");\n if (!isObject(meta)) return undefined;\n for (const candidate of [\n readProp(meta, \"agentInspect\"),\n readProp(meta, \"agent-inspect\"),\n readProp(meta, \"trace\"),\n ]) {\n if (isAssociation(candidate)) return candidate;\n }\n return undefined;\n}\n\nfunction isAssociation(\n value: unknown,\n): value is AgentInspectJestTraceAssociation {\n if (!isObject(value)) return false;\n return (\n readOptionalString(value, \"runId\") !== undefined ||\n readOptionalString(value, \"tracePath\") !== undefined ||\n readOptionalString(value, \"artifactLabel\") !== undefined\n );\n}\n\nfunction readRunResults(results: unknown): unknown[] {\n if (!isObject(results)) return [];\n const testResults = readProp(results, \"testResults\");\n return Array.isArray(testResults) ? testResults : [];\n}\n\nfunction readTestCases(testResult: unknown): AgentInspectJestTestCase[] {\n if (!isObject(testResult)) return [];\n const result = testResult as TestFileResultLike;\n const file = readOptionalString(result, \"testFilePath\");\n const assertions = Array.isArray(result.testResults)\n ? result.testResults\n : Array.isArray(result.assertionResults)\n ? result.assertionResults\n : [];\n\n const cases: AgentInspectJestTestCase[] = [];\n for (const assertion of assertions) {\n if (!isObject(assertion)) continue;\n const status = readStatus(assertion);\n if (status === undefined || status === \"skipped\") continue;\n\n const title = readOptionalString(assertion, \"title\") ?? \"unknown-test\";\n const fullName = readFullName(assertion as AssertionResultLike, title);\n const id = `${file ?? \"unknown-file\"}::${fullName}`;\n cases.push({\n file,\n fullName: boundText(redactText(fullName)),\n id: boundText(redactText(id)),\n raw: assertion,\n status,\n title: boundText(redactText(title)),\n });\n }\n return cases;\n}\n\nfunction readFullName(assertion: AssertionResultLike, title: string): string {\n const explicit = readOptionalString(assertion, \"fullName\");\n if (explicit !== undefined) return explicit;\n\n const ancestors = Array.isArray(assertion.ancestorTitles)\n ? assertion.ancestorTitles.filter((item): item is string => typeof item === \"string\")\n : [];\n return [...ancestors, title].join(\" \");\n}\n\nfunction readStatus(assertion: object): AgentInspectJestStatus | undefined {\n const raw = readOptionalString(assertion, \"status\");\n if (raw === undefined) return undefined;\n\n const normalized = raw.toLowerCase();\n if (normalized === \"failed\" || normalized === \"fail\") return \"failed\";\n if (normalized === \"passed\" || normalized === \"pass\") return \"passed\";\n if (\n normalized === \"pending\" ||\n normalized === \"todo\" ||\n normalized === \"skipped\" ||\n normalized === \"skip\" ||\n normalized === \"disabled\"\n ) {\n return \"skipped\";\n }\n return undefined;\n}\n\nasync function writeSafeArtifact(input: {\n readonly artifactDir: string;\n readonly association: AgentInspectJestTraceAssociation;\n readonly generatedAt: string;\n readonly redactionProfile: TraceArtifactRedactionProfile;\n readonly reserveArtifactName: (seed: string) => string;\n readonly status: AgentInspectJestStatus;\n readonly testCase: AgentInspectJestTestCase;\n}): Promise<AgentInspectJestArtifact> {\n const artifactSeed =\n input.association.artifactLabel ??\n input.testCase.id ??\n input.testCase.fullName ??\n input.status;\n const artifactName = input.reserveArtifactName(artifactSeed);\n const testFile =\n input.testCase.file === undefined ? undefined : path.basename(input.testCase.file);\n const safeTestId = `${testFile ?? \"unknown-file\"}::${input.testCase.fullName}`;\n const manifestPathResult = createReporterArtifactPath({\n outputDir: input.artifactDir,\n testId: artifactName,\n name: input.testCase.fullName,\n file: testFile,\n kind: \"report\",\n format: \"json\",\n });\n const summaryPathResult = createReporterArtifactPath({\n outputDir: input.artifactDir,\n testId: artifactName,\n name: input.testCase.fullName,\n file: testFile,\n kind: \"summary\",\n format: \"md\",\n });\n\n if (\n !manifestPathResult.ok ||\n manifestPathResult.absolutePath === undefined ||\n manifestPathResult.relativePath === undefined\n ) {\n throw new Error(formatPathDiagnostics(manifestPathResult.diagnostics));\n }\n if (\n !summaryPathResult.ok ||\n summaryPathResult.absolutePath === undefined ||\n summaryPathResult.relativePath === undefined\n ) {\n throw new Error(formatPathDiagnostics(summaryPathResult.diagnostics));\n }\n\n const directory = path.dirname(manifestPathResult.absolutePath);\n await mkdir(directory, { recursive: true });\n\n const traceFile =\n input.association.tracePath === undefined\n ? undefined\n : path.basename(input.association.tracePath);\n const manifestArtifact: TraceArtifact = {\n kind: \"report\",\n path: manifestPathResult.relativePath,\n format: \"json\",\n redactionProfile: input.redactionProfile,\n };\n const summaryArtifact: TraceArtifact = {\n kind: \"summary\",\n path: summaryPathResult.relativePath,\n format: \"md\",\n redactionProfile: input.redactionProfile,\n };\n const manifest = createTraceArtifactManifest({\n framework: \"jest\",\n generatedAt: input.generatedAt,\n results: [\n {\n testId: safeTestId,\n name: input.testCase.fullName,\n ...(testFile === undefined ? {} : { file: testFile }),\n status: input.status,\n tracePath: safeOptional(traceFile),\n artifacts: [manifestArtifact, summaryArtifact],\n diagnostics: [],\n },\n ],\n artifacts: [manifestArtifact, summaryArtifact],\n diagnostics: [],\n });\n const trace = {\n runId: safeOptional(input.association.runId),\n file: safeOptional(traceFile),\n };\n\n await writeFile(\n manifestPathResult.absolutePath,\n `${JSON.stringify({ package: PACKAGE_NAME, manifest, trace }, null, 2)}\\n`,\n );\n const summaryPath = summaryPathResult.absolutePath;\n await writeFile(summaryPath, renderSummary(manifest, trace), \"utf-8\");\n\n return {\n directory,\n manifest,\n manifestPath: manifestPathResult.absolutePath,\n status: input.status,\n summaryPath,\n testId: safeTestId,\n };\n}\n\nfunction renderSummary(\n manifest: TraceArtifactManifest,\n trace: { readonly runId?: string; readonly file?: string },\n): string {\n const result = manifest.results[0];\n return [\n \"# AgentInspect Jest Artifact\",\n \"\",\n `- Test: ${result?.name ?? \"unknown\"}`,\n `- Test id: ${result?.testId ?? \"unknown\"}`,\n `- Status: ${result?.status ?? \"unknown\"}`,\n `- File: ${result?.file ?? \"unknown\"}`,\n `- Trace run: ${trace.runId ?? \"unknown\"}`,\n `- Trace file: ${result?.tracePath ?? \"unknown\"}`,\n `- Manifest schema: ${manifest.schemaVersion}`,\n \"\",\n \"Trace contents are intentionally not embedded in this artifact.\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction formatPathDiagnostics(\n diagnostics: readonly TraceReporterDiagnostic[],\n): string {\n if (diagnostics.length === 0) return \"Unsafe AgentInspect Jest artifact path.\";\n return diagnostics.map((diagnostic) => diagnostic.message).join(\"; \");\n}\n\nfunction safeOptional(value: string | undefined): string | undefined {\n return value === undefined ? undefined : boundText(redactText(value));\n}\n\nfunction safeSegment(value: string): string {\n const sanitized = redactText(value)\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 80);\n return sanitized.length > 0 ? sanitized : \"trace\";\n}\n\nfunction boundText(value: string): string {\n const compact = value.replace(/\\s+/g, \" \").trim();\n if (compact.length <= MAX_TEXT) return compact;\n return `${compact.slice(0, MAX_TEXT - 12)}...[truncated]`;\n}\n\nfunction redactText(value: string): string {\n return value\n .replace(/\\bsk-[A-Za-z0-9_-]{8,}\\b/g, \"[REDACTED]\")\n .replace(/\\b(?:api[_-]?key|authorization|token|secret|password)\\s*[:=]\\s*[^,\\s]+/gi, \"$1=[REDACTED]\");\n}\n\nfunction readOptionalString(value: unknown, key: string): string | undefined {\n if (!isObject(value)) return undefined;\n const property = readProp(value, key);\n return typeof property === \"string\" && property.length > 0 ? property : undefined;\n}\n\nfunction readProp(value: object, key: string): unknown {\n return (value as Record<string, unknown>)[key];\n}\n\nfunction isObject(value: unknown): value is object {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;;AA+HA,IAAM,YAAA,GAAe,qBAAA;AACrB,IAAM,oBAAA,GAAuB,+BAAA;AAC7B,IAAM,qBAAA,GAAwB,EAAA;AAC9B,IAAM,iBAAA,GAAoB,GAAA;AAC1B,IAAM,QAAA,GAAW,GAAA;AACjB,IAAM,oBAAA,GAAuB,0BAAA;AAC7B,IAAM,gBAAA,GACJ,mGAAA;AAQK,SAAS,0BACd,WAAA,EAC6D;AAC7D,EAAA,OAAO,EAAE,cAAc,WAAA,EAAY;AACrC;AAKO,SAAS,8BAAA,CACd,OAAA,GAA2C,EAAC,EACZ;AAChC,EAAA,MAAM,cAA4C,EAAC;AACnD,EAAA,MAAM,YAAwC,EAAC;AAC/C,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAY;AACjC,EAAA,MAAM,aAAA,uBAAoB,GAAA,EAAoB;AAC9C,EAAA,MAAM,wBAAA,uBAA+B,GAAA,EAAY;AACjD,EAAA,MAAM,YAAA,GAAe,sBAAsB,OAAO,CAAA;AAClD,EAAA,IAAI,iBAAA,GAAoB,CAAA;AACxB,EAAA,IAAI,0BAAA,GAA6B,KAAA;AAEjC,EAAA,MAAM,QAAA,GAA2C;AAAA,IAC/C,MAAM,YAAA,CAAa,KAAA,EAAgB,UAAA,EAAoC;AACrE,MAAA,MAAM,iBAAiB,UAAU,CAAA;AAAA,IACnC,CAAA;AAAA,IACA,MAAM,aAAA,CAAc,SAAA,EAAqB,OAAA,EAAkC;AACzE,MAAA,KAAA,MAAW,UAAA,IAAc,cAAA,CAAe,OAAO,CAAA,EAAG;AAChD,QAAA,MAAM,iBAAiB,UAAU,CAAA;AAAA,MACnC;AACA,MAAA,MAAM,gCAAA,EAAiC;AACvC,MAAA,MAAM,mBAAA,EAAoB;AAAA,IAC5B,CAAA;AAAA,IACA,cAAA,GAAwD;AACtD,MAAA,OAAO,YAAY,KAAA,EAAM;AAAA,IAC3B,CAAA;AAAA,IACA,YAAA,GAAoD;AAClD,MAAA,OAAO,UAAU,KAAA,EAAM;AAAA,IACzB;AAAA,GACF;AAEA,EAAA,eAAe,iBAAiB,UAAA,EAAoC;AAClE,IAAA,KAAA,MAAW,QAAA,IAAY,aAAA,CAAc,UAAU,CAAA,EAAG;AAChD,MAAA,MAAM,eAAe,QAAQ,CAAA;AAAA,IAC/B;AAAA,EACF;AAEA,EAAA,eAAe,eAAe,QAAA,EAAmD;AAC/E,IAAA,MAAM,UAAU,CAAA,EAAG,QAAA,CAAS,EAAE,CAAA,CAAA,EAAI,SAAS,MAAM,CAAA,CAAA;AACjD,IAAA,IAAI,QAAA,CAAS,GAAA,CAAI,OAAO,CAAA,EAAG;AAE3B,IAAA,MAAM,WAAA,GAAc,kBAAA,CAAmB,QAAA,EAAU,OAAO,CAAA;AACxD,IAAA,IAAI,gBAAgB,MAAA,EAAW;AAC7B,MAAA,IAAI,QAAA,CAAS,WAAW,QAAA,EAAU;AAChC,QAAA,wBAAA,CAAyB,GAAA,CAAI,SAAS,EAAE,CAAA;AAAA,MAC1C;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,QAAA,CAAS,WAAW,QAAA,EAAU;AAChC,MAAA,IAAI,qBAAqB,YAAA,EAAc;AACvC,MAAA,iBAAA,IAAqB,CAAA;AAAA,IACvB;AAEA,IAAA,QAAA,CAAS,IAAI,OAAO,CAAA;AAEpB,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,iBAAA,CAAkB;AAAA,QACvC,WAAA,EAAa,QAAQ,WAAA,IAAe,oBAAA;AAAA,QACpC,WAAA;AAAA,QACA,WAAA,EAAa,QAAQ,WAAA,IAAe,oBAAA;AAAA,QACpC,gBAAA,EAAkB,QAAQ,gBAAA,IAAoB,OAAA;AAAA,QAC9C,mBAAA;AAAA,QACA,QAAQ,QAAA,CAAS,MAAA;AAAA,QACjB;AAAA,OACD,CAAA;AACD,MAAA,SAAA,CAAU,KAAK,QAAQ,CAAA;AAAA,IACzB,SAAS,KAAA,EAAO;AACd,MAAA,gBAAA,CAAiB;AAAA,QACf,IAAA,EAAM,uBAAA;AAAA,QACN,OAAA,EAAS,CAAA,4CAAA,EAA+C,YAAA,CAAa,KAAK,CAAC,CAAA,CAAA;AAAA,QAC3E,QAAQ,QAAA,CAAS;AAAA,OAClB,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,SAAS,oBAAoB,IAAA,EAAsB;AACjD,IAAA,MAAM,IAAA,GAAO,YAAY,IAAI,CAAA;AAC7B,IAAA,MAAM,IAAA,GAAA,CAAQ,aAAA,CAAc,GAAA,CAAI,IAAI,KAAK,CAAA,IAAK,CAAA;AAC9C,IAAA,aAAA,CAAc,GAAA,CAAI,MAAM,IAAI,CAAA;AAC5B,IAAA,OAAO,SAAS,CAAA,GAAI,IAAA,GAAO,CAAA,EAAG,IAAI,IAAI,IAAI,CAAA,CAAA;AAAA,EAC5C;AAEA,EAAA,SAAS,iBAAiB,UAAA,EAA8C;AACtE,IAAA,WAAA,CAAY,KAAK,UAAU,CAAA;AAC3B,IAAA,IAAI,OAAA,CAAQ,iBAAiB,MAAA,EAAW;AACxC,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,aAAa,UAAU,CAAA;AAAA,IACjC,SAAS,KAAA,EAAO;AACd,MAAA,WAAA,CAAY,IAAA,CAAK;AAAA,QACf,IAAA,EAAM,sBAAA;AAAA,QACN,OAAA,EAAS,CAAA,8CAAA,EAAiD,YAAA,CAAa,KAAK,CAAC,CAAA,CAAA;AAAA,QAC7E,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,eAAe,gCAAA,GAAkD;AAC/D,IAAA,IAAI,0BAAA,IAA8B,wBAAA,CAAyB,IAAA,KAAS,CAAA,EAAG;AACvE,IAAA,0BAAA,GAA6B,IAAA;AAC7B,IAAA,MAAM,QAAQ,wBAAA,CAAyB,IAAA;AACvC,IAAA,MAAM,YAAY,CAAC,GAAG,wBAAwB,CAAA,CAAE,KAAA,CAAM,GAAG,CAAC,CAAA;AAC1D,IAAA,MAAM,OAAA,GACJ,GAAG,KAAK,CAAA,sOAAA,EAGC,gBAAgB,CAAA,WAAA,EAAc,SAAA,CAAU,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAC7D,IAAA,gBAAA,CAAiB;AAAA,MACf,IAAA,EAAM,sBAAA;AAAA;AAAA,MAEN,OAAA,EAAS,SAAA,CAAU,OAAA,EAAS,GAAG;AAAA,KAChC,CAAA;AAED,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,GAAc,QAAQ,WAAA,IAAe,oBAAA;AAC3C,MAAA,MAAM,KAAA,CAAM,WAAA,EAAa,EAAE,SAAA,EAAW,MAAM,CAAA;AAC5C,MAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,IAAA,CAAK,WAAA,EAAa,yBAAyB,CAAA;AACvE,MAAA,MAAM,IAAA,GAAO;AAAA,QACX,sDAAA;AAAA,QACA,EAAA;AAAA,QACA,gFAAA;AAAA,QACA,kDAAA;AAAA,QACA,EAAA;AAAA,QACA,0DAAA;AAAA,QACA,sCAAsC,gBAAgB,CAAA,CAAA;AAAA,QACtD,EAAA;AAAA,QACA,qCAAA;AAAA,QACA,EAAA;AAAA,QACA,GAAG,CAAC,GAAG,wBAAwB,CAAA,CAAE,MAAM,CAAA,EAAG,EAAE,CAAA,CAAE,GAAA,CAAI,CAAC,EAAA,KAAO,CAAA,EAAA,EAAK,SAAA,CAAU,EAAE,CAAC,CAAA,CAAE,CAAA;AAAA,QAC9E;AAAA,OACF,CAAE,KAAK,IAAI,CAAA;AACX,MAAA,MAAM,SAAA,CAAU,cAAA,EAAgB,IAAA,EAAM,OAAO,CAAA;AAAA,IAC/C,SAAS,KAAA,EAAO;AACd,MAAA,gBAAA,CAAiB;AAAA,QACf,IAAA,EAAM,uBAAA;AAAA,QACN,OAAA,EAAS,CAAA,6DAAA,EAAgE,YAAA,CAAa,KAAK,CAAC,CAAA;AAAA,OAC7F,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,eAAe,mBAAA,GAAqC;AAClD,IAAA,IAAI,OAAA,CAAQ,kBAAkB,MAAA,EAAW;AACzC,IAAA,IAAI,SAAA,CAAU,MAAA,KAAW,CAAA,IAAK,wBAAA,CAAyB,SAAS,CAAA,EAAG;AACnE,IAAA,MAAM,MAAA,GAAS,UAAU,MAAA,CAAO,CAAC,aAAa,QAAA,CAAS,MAAA,KAAW,QAAQ,CAAA,CAAE,MAAA;AAC5E,IAAA,MAAM,MAAA,GAAS,UAAU,MAAA,CAAO,CAAC,aAAa,QAAA,CAAS,MAAA,KAAW,QAAQ,CAAA,CAAE,MAAA;AAC5E,IAAA,MAAM,KAAA,GAAQ;AAAA,MACZ,EAAA;AAAA,MACA,gCAAA;AAAA,MACA,EAAA;AAAA,MACA,4BAA4B,MAAM,CAAA,CAAA;AAAA,MAClC,sCAAsC,MAAM,CAAA,CAAA;AAAA,MAC5C,CAAA,0CAAA,EAA6C,yBAAyB,IAAI,CAAA,CAAA;AAAA,MAC1E,CAAA,sBAAA,EAAyB,UAAU,IAAA,CAAK,QAAA,CAAS,QAAQ,WAAA,IAAe,oBAAoB,CAAC,CAAC,CAAA,CAAA;AAAA,MAC9F;AAAA,KACF;AACA,IAAA,IAAI,wBAAA,CAAyB,OAAO,CAAA,EAAG;AACrC,MAAA,KAAA,CAAM,IAAA;AAAA,QACJ,oHAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AACA,IAAA,IAAI;AACF,MAAA,MAAM,UAAU,OAAA,CAAQ,aAAA,EAAe,GAAG,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC;AAAA,CAAA,EAAM,EAAE,IAAA,EAAM,GAAA,EAAK,CAAA;AAAA,IAC/E,SAAS,KAAA,EAAO;AACd,MAAA,gBAAA,CAAiB;AAAA,QACf,IAAA,EAAM,6BAAA;AAAA,QACN,OAAA,EAAS,CAAA,4CAAA,EAA+C,YAAA,CAAa,KAAK,CAAC,CAAA;AAAA,OAC5E,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,OAAO,QAAA;AACT;AAKO,IAAM,2BAAN,MAAyE;AAAA,EAC7D,QAAA;AAAA,EAEjB,WAAA,CAAY,aAAA,EAAyB,OAAA,GAA2C,EAAC,EAAG;AAClF,IAAA,IAAA,CAAK,QAAA,GAAW,+BAA+B,OAAO,CAAA;AAAA,EACxD;AAAA,EAEA,MAAM,YAAA,CACJ,IAAA,EACA,UAAA,EACA,gBAAA,EACe;AACf,IAAA,MAAM,IAAA,CAAK,QAAA,CAAS,YAAA,CAAa,IAAA,EAAM,YAAY,gBAAgB,CAAA;AAAA,EACrE;AAAA,EAEA,MAAM,aAAA,CAAc,QAAA,EAAoB,OAAA,EAAkC;AACxE,IAAA,MAAM,IAAA,CAAK,QAAA,CAAS,aAAA,CAAc,QAAA,EAAU,OAAO,CAAA;AAAA,EACrD;AAAA,EAEA,cAAA,GAAwD;AACtD,IAAA,OAAO,IAAA,CAAK,SAAS,cAAA,EAAe;AAAA,EACtC;AAAA,EAEA,YAAA,GAAoD;AAClD,IAAA,OAAO,IAAA,CAAK,SAAS,YAAA,EAAa;AAAA,EACpC;AACF;AAEO,IAAM,wBAAA,GAA2B;AACxC,IAAO,aAAA,GAAQ;AAEf,SAAS,sBAAsB,OAAA,EAAkD;AAC/E,EAAA,MAAM,GAAA,GAAM,UAAA,CAAW,OAAA,CAAQ,mBAAA,EAAqB,qBAAqB,CAAA;AACzE,EAAA,IAAI,OAAA,CAAQ,gBAAA,KAAqB,IAAA,EAAM,OAAO,GAAA;AAC9C,EAAA,IAAI,OAAO,OAAA,CAAQ,gBAAA,KAAqB,QAAA,EAAU;AAChD,IAAA,OAAO,KAAK,GAAA,CAAI,UAAA,CAAW,QAAQ,gBAAA,EAAkB,CAAC,GAAG,GAAG,CAAA;AAAA,EAC9D;AACA,EAAA,OAAO,CAAA;AACT;AAEA,SAAS,UAAA,CAAW,OAA2B,QAAA,EAA0B;AACvE,EAAA,IAAI,UAAU,MAAA,IAAa,CAAC,OAAO,QAAA,CAAS,KAAK,GAAG,OAAO,QAAA;AAC3D,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,mBAAmB,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAC,CAAA;AACnE;AAEA,SAAS,kBAAA,CACP,UACA,OAAA,EAC8C;AAC9C,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,YAAA,GAAe,QAAQ,CAAA;AAChD,EAAA,IAAI,aAAA,CAAc,QAAQ,CAAA,EAAG,OAAO,QAAA;AAEpC,EAAA,MAAM,QAAA,GAAW,yBAAA,CAA0B,QAAA,EAAU,OAAA,CAAQ,YAAY,CAAA;AACzE,EAAA,IAAI,QAAA,KAAa,QAAW,OAAO,QAAA;AAEnC,EAAA,OAAO,4BAAA,CAA6B,SAAS,GAAG,CAAA;AAClD;AAEA,SAAS,yBAAA,CACP,UACA,YAAA,EAC8C;AAC9C,EAAA,IAAI,YAAA,KAAiB,QAAW,OAAO,MAAA;AACvC,EAAA,MAAM,QAAA,GAAW,SAAS,IAAA,KAAS,MAAA,GAAY,SAAY,IAAA,CAAK,QAAA,CAAS,SAAS,IAAI,CAAA;AACtF,EAAA,MAAM,UAAA,GAAa;AAAA,IACjB,QAAA,CAAS,EAAA;AAAA,IACT,QAAA,CAAS,QAAA;AAAA,IACT,aAAa,MAAA,GAAY,MAAA,GAAY,GAAG,QAAQ,CAAA,EAAA,EAAK,SAAS,QAAQ,CAAA;AAAA,GACxE;AACA,EAAA,KAAA,MAAW,aAAa,UAAA,EAAY;AAClC,IAAA,IAAI,cAAc,MAAA,IAAa,aAAA,CAAc,YAAA,CAAa,SAAS,CAAC,CAAA,EAAG;AACrE,MAAA,OAAO,aAAa,SAAS,CAAA;AAAA,IAC/B;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,6BACP,SAAA,EAC8C;AAC9C,EAAA,IAAI,CAAC,QAAA,CAAS,SAAS,CAAA,EAAG,OAAO,MAAA;AACjC,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,SAAA,EAAW,cAAc,CAAA;AACjD,EAAA,IAAI,aAAA,CAAc,MAAM,CAAA,EAAG,OAAO,MAAA;AAElC,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,SAAA,EAAW,MAAM,CAAA;AACvC,EAAA,IAAI,CAAC,QAAA,CAAS,IAAI,CAAA,EAAG,OAAO,MAAA;AAC5B,EAAA,KAAA,MAAW,SAAA,IAAa;AAAA,IACtB,QAAA,CAAS,MAAM,cAAc,CAAA;AAAA,IAC7B,QAAA,CAAS,MAAM,eAAe,CAAA;AAAA,IAC9B,QAAA,CAAS,MAAM,OAAO;AAAA,GACxB,EAAG;AACD,IAAA,IAAI,aAAA,CAAc,SAAS,CAAA,EAAG,OAAO,SAAA;AAAA,EACvC;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,cACP,KAAA,EAC2C;AAC3C,EAAA,IAAI,CAAC,QAAA,CAAS,KAAK,CAAA,EAAG,OAAO,KAAA;AAC7B,EAAA,OACE,kBAAA,CAAmB,KAAA,EAAO,OAAO,CAAA,KAAM,MAAA,IACvC,kBAAA,CAAmB,KAAA,EAAO,WAAW,CAAA,KAAM,MAAA,IAC3C,kBAAA,CAAmB,KAAA,EAAO,eAAe,CAAA,KAAM,MAAA;AAEnD;AAEA,SAAS,eAAe,OAAA,EAA6B;AACnD,EAAA,IAAI,CAAC,QAAA,CAAS,OAAO,CAAA,SAAU,EAAC;AAChC,EAAA,MAAM,WAAA,GAAc,QAAA,CAAS,OAAA,EAAS,aAAa,CAAA;AACnD,EAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,WAAW,CAAA,GAAI,cAAc,EAAC;AACrD;AAEA,SAAS,cAAc,UAAA,EAAiD;AACtE,EAAA,IAAI,CAAC,QAAA,CAAS,UAAU,CAAA,SAAU,EAAC;AACnC,EAAA,MAAM,MAAA,GAAS,UAAA;AACf,EAAA,MAAM,IAAA,GAAO,kBAAA,CAAmB,MAAA,EAAQ,cAAc,CAAA;AACtD,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO,WAAW,CAAA,GAC/C,MAAA,CAAO,WAAA,GACP,KAAA,CAAM,QAAQ,MAAA,CAAO,gBAAgB,CAAA,GACnC,MAAA,CAAO,mBACP,EAAC;AAEP,EAAA,MAAM,QAAoC,EAAC;AAC3C,EAAA,KAAA,MAAW,aAAa,UAAA,EAAY;AAClC,IAAA,IAAI,CAAC,QAAA,CAAS,SAAS,CAAA,EAAG;AAC1B,IAAA,MAAM,MAAA,GAAS,WAAW,SAAS,CAAA;AACnC,IAAA,IAAI,MAAA,KAAW,MAAA,IAAa,MAAA,KAAW,SAAA,EAAW;AAElD,IAAA,MAAM,KAAA,GAAQ,kBAAA,CAAmB,SAAA,EAAW,OAAO,CAAA,IAAK,cAAA;AACxD,IAAA,MAAM,QAAA,GAAW,YAAA,CAAa,SAAA,EAAkC,KAAK,CAAA;AACrE,IAAA,MAAM,EAAA,GAAK,CAAA,EAAG,IAAA,IAAQ,cAAc,KAAK,QAAQ,CAAA,CAAA;AACjD,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,IAAA;AAAA,MACA,QAAA,EAAU,SAAA,CAAU,UAAA,CAAW,QAAQ,CAAC,CAAA;AAAA,MACxC,EAAA,EAAI,SAAA,CAAU,UAAA,CAAW,EAAE,CAAC,CAAA;AAAA,MAC5B,GAAA,EAAK,SAAA;AAAA,MACL,MAAA;AAAA,MACA,KAAA,EAAO,SAAA,CAAU,UAAA,CAAW,KAAK,CAAC;AAAA,KACnC,CAAA;AAAA,EACH;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,YAAA,CAAa,WAAgC,KAAA,EAAuB;AAC3E,EAAA,MAAM,QAAA,GAAW,kBAAA,CAAmB,SAAA,EAAW,UAAU,CAAA;AACzD,EAAA,IAAI,QAAA,KAAa,QAAW,OAAO,QAAA;AAEnC,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,OAAA,CAAQ,SAAA,CAAU,cAAc,CAAA,GACpD,SAAA,CAAU,cAAA,CAAe,MAAA,CAAO,CAAC,IAAA,KAAyB,OAAO,IAAA,KAAS,QAAQ,IAClF,EAAC;AACL,EAAA,OAAO,CAAC,GAAG,SAAA,EAAW,KAAK,CAAA,CAAE,KAAK,GAAG,CAAA;AACvC;AAEA,SAAS,WAAW,SAAA,EAAuD;AACzE,EAAA,MAAM,GAAA,GAAM,kBAAA,CAAmB,SAAA,EAAW,QAAQ,CAAA;AAClD,EAAA,IAAI,GAAA,KAAQ,QAAW,OAAO,MAAA;AAE9B,EAAA,MAAM,UAAA,GAAa,IAAI,WAAA,EAAY;AACnC,EAAA,IAAI,UAAA,KAAe,QAAA,IAAY,UAAA,KAAe,MAAA,EAAQ,OAAO,QAAA;AAC7D,EAAA,IAAI,UAAA,KAAe,QAAA,IAAY,UAAA,KAAe,MAAA,EAAQ,OAAO,QAAA;AAC7D,EAAA,IACE,UAAA,KAAe,aACf,UAAA,KAAe,MAAA,IACf,eAAe,SAAA,IACf,UAAA,KAAe,MAAA,IACf,UAAA,KAAe,UAAA,EACf;AACA,IAAA,OAAO,SAAA;AAAA,EACT;AACA,EAAA,OAAO,MAAA;AACT;AAEA,eAAe,kBAAkB,KAAA,EAQK;AACpC,EAAA,MAAM,YAAA,GACJ,KAAA,CAAM,WAAA,CAAY,aAAA,IAClB,KAAA,CAAM,SAAS,EAAA,IACf,KAAA,CAAM,QAAA,CAAS,QAAA,IACf,KAAA,CAAM,MAAA;AACR,EAAA,MAAM,YAAA,GAAe,KAAA,CAAM,mBAAA,CAAoB,YAAY,CAAA;AAC3D,EAAA,MAAM,QAAA,GACJ,KAAA,CAAM,QAAA,CAAS,IAAA,KAAS,MAAA,GAAY,SAAY,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,QAAA,CAAS,IAAI,CAAA;AACnF,EAAA,MAAM,aAAa,CAAA,EAAG,QAAA,IAAY,cAAc,CAAA,EAAA,EAAK,KAAA,CAAM,SAAS,QAAQ,CAAA,CAAA;AAC5E,EAAA,MAAM,qBAAqB,0BAAA,CAA2B;AAAA,IACpD,WAAW,KAAA,CAAM,WAAA;AAAA,IACjB,MAAA,EAAQ,YAAA;AAAA,IACR,IAAA,EAAM,MAAM,QAAA,CAAS,QAAA;AAAA,IACrB,IAAA,EAAM,QAAA;AAAA,IACN,IAAA,EAAM,QAAA;AAAA,IACN,MAAA,EAAQ;AAAA,GACT,CAAA;AACD,EAAA,MAAM,oBAAoB,0BAAA,CAA2B;AAAA,IACnD,WAAW,KAAA,CAAM,WAAA;AAAA,IACjB,MAAA,EAAQ,YAAA;AAAA,IACR,IAAA,EAAM,MAAM,QAAA,CAAS,QAAA;AAAA,IACrB,IAAA,EAAM,QAAA;AAAA,IACN,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,GACT,CAAA;AAED,EAAA,IACE,CAAC,mBAAmB,EAAA,IACpB,kBAAA,CAAmB,iBAAiB,MAAA,IACpC,kBAAA,CAAmB,iBAAiB,MAAA,EACpC;AACA,IAAA,MAAM,IAAI,KAAA,CAAM,qBAAA,CAAsB,kBAAA,CAAmB,WAAW,CAAC,CAAA;AAAA,EACvE;AACA,EAAA,IACE,CAAC,kBAAkB,EAAA,IACnB,iBAAA,CAAkB,iBAAiB,MAAA,IACnC,iBAAA,CAAkB,iBAAiB,MAAA,EACnC;AACA,IAAA,MAAM,IAAI,KAAA,CAAM,qBAAA,CAAsB,iBAAA,CAAkB,WAAW,CAAC,CAAA;AAAA,EACtE;AAEA,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,OAAA,CAAQ,kBAAA,CAAmB,YAAY,CAAA;AAC9D,EAAA,MAAM,KAAA,CAAM,SAAA,EAAW,EAAE,SAAA,EAAW,MAAM,CAAA;AAE1C,EAAA,MAAM,SAAA,GACJ,KAAA,CAAM,WAAA,CAAY,SAAA,KAAc,MAAA,GAC5B,SACA,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,WAAA,CAAY,SAAS,CAAA;AAC/C,EAAA,MAAM,gBAAA,GAAkC;AAAA,IACtC,IAAA,EAAM,QAAA;AAAA,IACN,MAAM,kBAAA,CAAmB,YAAA;AAAA,IACzB,MAAA,EAAQ,MAAA;AAAA,IACR,kBAAkB,KAAA,CAAM;AAAA,GAC1B;AACA,EAAA,MAAM,eAAA,GAAiC;AAAA,IACrC,IAAA,EAAM,SAAA;AAAA,IACN,MAAM,iBAAA,CAAkB,YAAA;AAAA,IACxB,MAAA,EAAQ,IAAA;AAAA,IACR,kBAAkB,KAAA,CAAM;AAAA,GAC1B;AACA,EAAA,MAAM,WAAW,2BAAA,CAA4B;AAAA,IAC3C,SAAA,EAAW,MAAA;AAAA,IACX,aAAa,KAAA,CAAM,WAAA;AAAA,IACnB,OAAA,EAAS;AAAA,MACP;AAAA,QACE,MAAA,EAAQ,UAAA;AAAA,QACR,IAAA,EAAM,MAAM,QAAA,CAAS,QAAA;AAAA,QACrB,GAAI,QAAA,KAAa,MAAA,GAAY,EAAC,GAAI,EAAE,MAAM,QAAA,EAAS;AAAA,QACnD,QAAQ,KAAA,CAAM,MAAA;AAAA,QACd,SAAA,EAAW,aAAa,SAAS,CAAA;AAAA,QACjC,SAAA,EAAW,CAAC,gBAAA,EAAkB,eAAe,CAAA;AAAA,QAC7C,aAAa;AAAC;AAChB,KACF;AAAA,IACA,SAAA,EAAW,CAAC,gBAAA,EAAkB,eAAe,CAAA;AAAA,IAC7C,aAAa;AAAC,GACf,CAAA;AACD,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,KAAA,EAAO,YAAA,CAAa,KAAA,CAAM,WAAA,CAAY,KAAK,CAAA;AAAA,IAC3C,IAAA,EAAM,aAAa,SAAS;AAAA,GAC9B;AAEA,EAAA,MAAM,SAAA;AAAA,IACJ,kBAAA,CAAmB,YAAA;AAAA,IACnB,CAAA,EAAG,IAAA,CAAK,SAAA,CAAU,EAAE,OAAA,EAAS,YAAA,EAAc,QAAA,EAAU,KAAA,EAAM,EAAG,IAAA,EAAM,CAAC,CAAC;AAAA;AAAA,GACxE;AACA,EAAA,MAAM,cAAc,iBAAA,CAAkB,YAAA;AACtC,EAAA,MAAM,UAAU,WAAA,EAAa,aAAA,CAAc,QAAA,EAAU,KAAK,GAAG,OAAO,CAAA;AAEpE,EAAA,OAAO;AAAA,IACL,SAAA;AAAA,IACA,QAAA;AAAA,IACA,cAAc,kBAAA,CAAmB,YAAA;AAAA,IACjC,QAAQ,KAAA,CAAM,MAAA;AAAA,IACd,WAAA;AAAA,IACA,MAAA,EAAQ;AAAA,GACV;AACF;AAEA,SAAS,aAAA,CACP,UACA,KAAA,EACQ;AACR,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,OAAA,CAAQ,CAAC,CAAA;AACjC,EAAA,OAAO;AAAA,IACL,8BAAA;AAAA,IACA,EAAA;AAAA,IACA,CAAA,QAAA,EAAW,MAAA,EAAQ,IAAA,IAAQ,SAAS,CAAA,CAAA;AAAA,IACpC,CAAA,WAAA,EAAc,MAAA,EAAQ,MAAA,IAAU,SAAS,CAAA,CAAA;AAAA,IACzC,CAAA,UAAA,EAAa,MAAA,EAAQ,MAAA,IAAU,SAAS,CAAA,CAAA;AAAA,IACxC,CAAA,QAAA,EAAW,MAAA,EAAQ,IAAA,IAAQ,SAAS,CAAA,CAAA;AAAA,IACpC,CAAA,aAAA,EAAgB,KAAA,CAAM,KAAA,IAAS,SAAS,CAAA,CAAA;AAAA,IACxC,CAAA,cAAA,EAAiB,MAAA,EAAQ,SAAA,IAAa,SAAS,CAAA,CAAA;AAAA,IAC/C,CAAA,mBAAA,EAAsB,SAAS,aAAa,CAAA,CAAA;AAAA,IAC5C,EAAA;AAAA,IACA,iEAAA;AAAA,IACA;AAAA,GACF,CAAE,KAAK,IAAI,CAAA;AACb;AAEA,SAAS,sBACP,WAAA,EACQ;AACR,EAAA,IAAI,WAAA,CAAY,MAAA,KAAW,CAAA,EAAG,OAAO,yCAAA;AACrC,EAAA,OAAO,WAAA,CAAY,IAAI,CAAC,UAAA,KAAe,WAAW,OAAO,CAAA,CAAE,KAAK,IAAI,CAAA;AACtE;AAEA,SAAS,aAAa,KAAA,EAA+C;AACnE,EAAA,OAAO,UAAU,MAAA,GAAY,MAAA,GAAY,SAAA,CAAU,UAAA,CAAW,KAAK,CAAC,CAAA;AACtE;AAEA,SAAS,YAAY,KAAA,EAAuB;AAC1C,EAAA,MAAM,YAAY,UAAA,CAAW,KAAK,CAAA,CAC/B,WAAA,GACA,OAAA,CAAQ,gBAAA,EAAkB,GAAG,CAAA,CAC7B,QAAQ,UAAA,EAAY,EAAE,CAAA,CACtB,KAAA,CAAM,GAAG,EAAE,CAAA;AACd,EAAA,OAAO,SAAA,CAAU,MAAA,GAAS,CAAA,GAAI,SAAA,GAAY,OAAA;AAC5C;AAEA,SAAS,SAAA,CAAU,KAAA,EAAe,GAAA,GAAM,QAAA,EAAkB;AACxD,EAAA,MAAM,UAAU,KAAA,CAAM,OAAA,CAAQ,MAAA,EAAQ,GAAG,EAAE,IAAA,EAAK;AAChD,EAAA,IAAI,OAAA,CAAQ,MAAA,IAAU,GAAA,EAAK,OAAO,OAAA;AAClC,EAAA,OAAO,GAAG,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,GAAA,GAAM,EAAE,CAAC,CAAA,cAAA,CAAA;AACtC;AAEA,SAAS,WAAW,KAAA,EAAuB;AACzC,EAAA,OAAO,MACJ,OAAA,CAAQ,2BAAA,EAA6B,YAAY,CAAA,CACjD,OAAA,CAAQ,4EAA4E,eAAe,CAAA;AACxG;AAEA,SAAS,kBAAA,CAAmB,OAAgB,GAAA,EAAiC;AAC3E,EAAA,IAAI,CAAC,QAAA,CAAS,KAAK,CAAA,EAAG,OAAO,MAAA;AAC7B,EAAA,MAAM,QAAA,GAAW,QAAA,CAAS,KAAA,EAAO,GAAG,CAAA;AACpC,EAAA,OAAO,OAAO,QAAA,KAAa,QAAA,IAAY,QAAA,CAAS,MAAA,GAAS,IAAI,QAAA,GAAW,MAAA;AAC1E;AAEA,SAAS,QAAA,CAAS,OAAe,GAAA,EAAsB;AACrD,EAAA,OAAQ,MAAkC,GAAG,CAAA;AAC/C;AAEA,SAAS,SAAS,KAAA,EAAiC;AACjD,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA;AAChD;AAEA,SAAS,aAAa,KAAA,EAAwB;AAC5C,EAAA,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAC9D","file":"index.mjs","sourcesContent":["import { mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport {\n createReporterArtifactPath,\n createTraceArtifactManifest,\n type TraceArtifact,\n type TraceArtifactManifest,\n type TraceArtifactRedactionProfile,\n type TraceReporterDiagnostic,\n} from \"agent-inspect/reporters\";\n\nexport type AgentInspectJestStatus = \"failed\" | \"passed\" | \"skipped\";\n\n/**\n * Experimental trace association read by `@agent-inspect/jest`.\n *\n * Jest does not expose Vitest-style task metadata, so the default path is an\n * explicit `associations` map keyed by test identity, or a `resolveTrace`\n * callback. The reporter never guesses by timestamps.\n */\nexport interface AgentInspectJestTraceAssociation {\n /** AgentInspect run/span identifier to show in safe artifacts. */\n readonly runId?: string;\n /** Local trace file path. Only the basename is written to artifacts. */\n readonly tracePath?: string;\n /** Optional stable label for the artifact directory. */\n readonly artifactLabel?: string;\n}\n\n/**\n * Experimental normalized view of one Jest assertion result.\n */\nexport interface AgentInspectJestTestCase {\n readonly id: string;\n readonly title: string;\n readonly fullName: string;\n readonly file?: string;\n readonly status: AgentInspectJestStatus;\n readonly raw: unknown;\n}\n\n/**\n * Experimental diagnostic emitted when reporter work cannot be completed.\n *\n * Diagnostics are reported instead of thrown so Jest's original test result\n * remains authoritative.\n */\nexport interface AgentInspectJestDiagnostic {\n readonly code:\n | \"artifact-write-failed\"\n | \"github-summary-write-failed\"\n | \"no-trace-association\"\n | \"on-diagnostic-failed\";\n readonly message: string;\n readonly testId?: string;\n}\n\n/**\n * Experimental options for the AgentInspect Jest reporter.\n *\n * The reporter is local-only: it performs no network I/O and writes bounded,\n * structural artifacts without reading trace contents.\n */\nexport interface AgentInspectJestReporterOptions {\n /** Directory for safe Jest artifacts. Defaults to `.agent-inspect/jest-artifacts`. */\n readonly artifactDir?: string;\n /** Optional GitHub step-summary path. Only bounded structural lines are appended. */\n readonly githubSummary?: string;\n /**\n * Keep artifacts for passing tests. `false`/undefined keeps none; `true`\n * keeps up to `maxSuccessfulTraces`; a number keeps up to that many.\n */\n readonly retainSuccessful?: boolean | number;\n /** Upper bound for retained passing-test artifacts. Defaults to 20. */\n readonly maxSuccessfulTraces?: number;\n /** Redaction profile recorded on generated artifacts. Defaults to `share`. */\n readonly redactionProfile?: TraceArtifactRedactionProfile;\n /** Deterministic manifest timestamp. Defaults to the Unix epoch. */\n readonly generatedAt?: string;\n /** Explicit trace associations keyed by `file::fullName`, `basename::fullName`, or `fullName`. */\n readonly associations?: Record<string, AgentInspectJestTraceAssociation>;\n /** Resolve explicit test-to-trace associations from a normalized Jest case. */\n readonly resolveTrace?: (\n test: AgentInspectJestTestCase,\n ) => AgentInspectJestTraceAssociation | undefined;\n /** Observe non-fatal reporter diagnostics. */\n readonly onDiagnostic?: (diagnostic: AgentInspectJestDiagnostic) => void;\n}\n\nexport interface AgentInspectJestArtifact {\n readonly directory: string;\n readonly manifestPath: string;\n readonly summaryPath: string;\n readonly status: AgentInspectJestStatus;\n readonly testId: string;\n readonly manifest: TraceArtifactManifest;\n}\n\n/**\n * Experimental Jest reporter facade.\n *\n * The hooks mirror Jest reporter lifecycle names, while inputs stay structural\n * to avoid a runtime dependency on Jest internals.\n */\nexport interface AgentInspectJestReporterFacade {\n onTestResult(test: unknown, testResult: unknown, aggregatedResult?: unknown): Promise<void>;\n onRunComplete(contexts?: unknown, results?: unknown): Promise<void>;\n getDiagnostics(): readonly AgentInspectJestDiagnostic[];\n getArtifacts(): readonly AgentInspectJestArtifact[];\n}\n\ntype AssertionResultLike = {\n readonly ancestorTitles?: unknown;\n readonly title?: unknown;\n readonly fullName?: unknown;\n readonly status?: unknown;\n readonly meta?: unknown;\n readonly agentInspect?: unknown;\n};\n\ntype TestFileResultLike = {\n readonly testFilePath?: unknown;\n readonly testResults?: unknown;\n readonly assertionResults?: unknown;\n};\n\nconst PACKAGE_NAME = \"@agent-inspect/jest\";\nconst DEFAULT_ARTIFACT_DIR = \".agent-inspect/jest-artifacts\";\nconst DEFAULT_SUCCESS_LIMIT = 20;\nconst MAX_SUCCESS_LIMIT = 100;\nconst MAX_TEXT = 180;\nconst DEFAULT_GENERATED_AT = \"1970-01-01T00:00:00.000Z\";\nconst ASSOCIATION_DOCS =\n \"https://github.com/rajudandigam/agent-inspect/blob/main/packages/jest/README.md#trace-association\";\n\n/**\n * Attach an explicit AgentInspect trace association to a Jest assertion result.\n *\n * The reporter does not instrument tests automatically; pass the returned object\n * as `agentInspect` / `meta.agentInspect` or use `associations` / `resolveTrace`.\n */\nexport function withAgentInspectJestTrace(\n association: AgentInspectJestTraceAssociation,\n): { readonly agentInspect: AgentInspectJestTraceAssociation } {\n return { agentInspect: association };\n}\n\n/**\n * Create the experimental AgentInspect Jest reporter.\n */\nexport function createAgentInspectJestReporter(\n options: AgentInspectJestReporterOptions = {},\n): AgentInspectJestReporterFacade {\n const diagnostics: AgentInspectJestDiagnostic[] = [];\n const artifacts: AgentInspectJestArtifact[] = [];\n const seenKeys = new Set<string>();\n const artifactNames = new Map<string, number>();\n const failedWithoutAssociation = new Set<string>();\n const successLimit = normalizeSuccessLimit(options);\n let retainedSuccesses = 0;\n let reportedMissingAssociation = false;\n\n const reporter: AgentInspectJestReporterFacade = {\n async onTestResult(_test: unknown, testResult: unknown): Promise<void> {\n await handleFileResult(testResult);\n },\n async onRunComplete(_contexts?: unknown, results?: unknown): Promise<void> {\n for (const fileResult of readRunResults(results)) {\n await handleFileResult(fileResult);\n }\n await emitMissingAssociationDiagnostic();\n await appendGithubSummary();\n },\n getDiagnostics(): readonly AgentInspectJestDiagnostic[] {\n return diagnostics.slice();\n },\n getArtifacts(): readonly AgentInspectJestArtifact[] {\n return artifacts.slice();\n },\n };\n\n async function handleFileResult(testResult: unknown): Promise<void> {\n for (const testCase of readTestCases(testResult)) {\n await handleTestCase(testCase);\n }\n }\n\n async function handleTestCase(testCase: AgentInspectJestTestCase): Promise<void> {\n const seenKey = `${testCase.id}:${testCase.status}`;\n if (seenKeys.has(seenKey)) return;\n\n const association = resolveAssociation(testCase, options);\n if (association === undefined) {\n if (testCase.status === \"failed\") {\n failedWithoutAssociation.add(testCase.id);\n }\n return;\n }\n\n if (testCase.status === \"passed\") {\n if (retainedSuccesses >= successLimit) return;\n retainedSuccesses += 1;\n }\n\n seenKeys.add(seenKey);\n\n try {\n const artifact = await writeSafeArtifact({\n artifactDir: options.artifactDir ?? DEFAULT_ARTIFACT_DIR,\n association,\n generatedAt: options.generatedAt ?? DEFAULT_GENERATED_AT,\n redactionProfile: options.redactionProfile ?? \"share\",\n reserveArtifactName,\n status: testCase.status,\n testCase,\n });\n artifacts.push(artifact);\n } catch (error) {\n reportDiagnostic({\n code: \"artifact-write-failed\",\n message: `Could not write AgentInspect Jest artifact: ${errorMessage(error)}`,\n testId: testCase.id,\n });\n }\n }\n\n function reserveArtifactName(seed: string): string {\n const base = safeSegment(seed);\n const next = (artifactNames.get(base) ?? 0) + 1;\n artifactNames.set(base, next);\n return next === 1 ? base : `${base}-${next}`;\n }\n\n function reportDiagnostic(diagnostic: AgentInspectJestDiagnostic): void {\n diagnostics.push(diagnostic);\n if (options.onDiagnostic === undefined) return;\n try {\n options.onDiagnostic(diagnostic);\n } catch (error) {\n diagnostics.push({\n code: \"on-diagnostic-failed\",\n message: `AgentInspect Jest diagnostic callback failed: ${errorMessage(error)}`,\n testId: diagnostic.testId,\n });\n }\n }\n\n async function emitMissingAssociationDiagnostic(): Promise<void> {\n if (reportedMissingAssociation || failedWithoutAssociation.size === 0) return;\n reportedMissingAssociation = true;\n const count = failedWithoutAssociation.size;\n const sampleIds = [...failedWithoutAssociation].slice(0, 3);\n const message =\n `${count} failed Jest test(s) had no AgentInspect trace association. ` +\n `Reporter does not instrument tests automatically; no trace artifact was generated. ` +\n `Use withAgentInspectJestTrace, associations, resolveTrace, or meta.agentInspect. ` +\n `Docs: ${ASSOCIATION_DOCS}. Samples: ${sampleIds.join(\"; \")}`;\n reportDiagnostic({\n code: \"no-trace-association\",\n // Keep the helper name before truncation so the diagnostic stays actionable.\n message: boundText(message, 320),\n });\n\n try {\n const artifactDir = options.artifactDir ?? DEFAULT_ARTIFACT_DIR;\n await mkdir(artifactDir, { recursive: true });\n const diagnosticPath = path.join(artifactDir, \"no-trace-association.md\");\n const body = [\n \"# AgentInspect Jest — missing trace association\",\n \"\",\n \"Failed tests were observed without an explicit AgentInspect trace association.\",\n \"No trace artifact was generated for those tests.\",\n \"\",\n \"The reporter does **not** instrument Jest automatically.\",\n `Associate traces explicitly. Docs: ${ASSOCIATION_DOCS}`,\n \"\",\n \"## Failed tests without association\",\n \"\",\n ...[...failedWithoutAssociation].slice(0, 20).map((id) => `- ${boundText(id)}`),\n \"\",\n ].join(\"\\n\");\n await writeFile(diagnosticPath, body, \"utf-8\");\n } catch (error) {\n reportDiagnostic({\n code: \"artifact-write-failed\",\n message: `Could not write AgentInspect Jest no-association diagnostic: ${errorMessage(error)}`,\n });\n }\n }\n\n async function appendGithubSummary(): Promise<void> {\n if (options.githubSummary === undefined) return;\n if (artifacts.length === 0 && failedWithoutAssociation.size === 0) return;\n const failed = artifacts.filter((artifact) => artifact.status === \"failed\").length;\n const passed = artifacts.filter((artifact) => artifact.status === \"passed\").length;\n const lines = [\n \"\",\n \"## AgentInspect Jest artifacts\",\n \"\",\n `- Failed test artifacts: ${failed}`,\n `- Passing test artifacts retained: ${passed}`,\n `- Failed tests without trace association: ${failedWithoutAssociation.size}`,\n `- Artifact directory: ${boundText(path.basename(options.artifactDir ?? DEFAULT_ARTIFACT_DIR))}`,\n \"\",\n ];\n if (failedWithoutAssociation.size > 0) {\n lines.push(\n \"No automatic instrumentation: associate traces via `associations`, `resolveTrace`, or `withAgentInspectJestTrace`.\",\n \"\",\n );\n }\n try {\n await writeFile(options.githubSummary, `${lines.join(\"\\n\")}\\n`, { flag: \"a\" });\n } catch (error) {\n reportDiagnostic({\n code: \"github-summary-write-failed\",\n message: `Could not append AgentInspect Jest summary: ${errorMessage(error)}`,\n });\n }\n }\n\n return reporter;\n}\n\n/**\n * Experimental Jest custom reporter class.\n */\nexport class AgentInspectJestReporter implements AgentInspectJestReporterFacade {\n private readonly reporter: AgentInspectJestReporterFacade;\n\n constructor(_globalConfig?: unknown, options: AgentInspectJestReporterOptions = {}) {\n this.reporter = createAgentInspectJestReporter(options);\n }\n\n async onTestResult(\n test: unknown,\n testResult: unknown,\n aggregatedResult?: unknown,\n ): Promise<void> {\n await this.reporter.onTestResult(test, testResult, aggregatedResult);\n }\n\n async onRunComplete(contexts?: unknown, results?: unknown): Promise<void> {\n await this.reporter.onRunComplete(contexts, results);\n }\n\n getDiagnostics(): readonly AgentInspectJestDiagnostic[] {\n return this.reporter.getDiagnostics();\n }\n\n getArtifacts(): readonly AgentInspectJestArtifact[] {\n return this.reporter.getArtifacts();\n }\n}\n\nexport const agentInspectJestReporter = createAgentInspectJestReporter;\nexport default AgentInspectJestReporter;\n\nfunction normalizeSuccessLimit(options: AgentInspectJestReporterOptions): number {\n const cap = clampCount(options.maxSuccessfulTraces, DEFAULT_SUCCESS_LIMIT);\n if (options.retainSuccessful === true) return cap;\n if (typeof options.retainSuccessful === \"number\") {\n return Math.min(clampCount(options.retainSuccessful, 0), cap);\n }\n return 0;\n}\n\nfunction clampCount(value: number | undefined, fallback: number): number {\n if (value === undefined || !Number.isFinite(value)) return fallback;\n return Math.max(0, Math.min(MAX_SUCCESS_LIMIT, Math.floor(value)));\n}\n\nfunction resolveAssociation(\n testCase: AgentInspectJestTestCase,\n options: AgentInspectJestReporterOptions,\n): AgentInspectJestTraceAssociation | undefined {\n const resolved = options.resolveTrace?.(testCase);\n if (isAssociation(resolved)) return resolved;\n\n const explicit = resolveFromAssociationMap(testCase, options.associations);\n if (explicit !== undefined) return explicit;\n\n return readAssociationFromAssertion(testCase.raw);\n}\n\nfunction resolveFromAssociationMap(\n testCase: AgentInspectJestTestCase,\n associations: Record<string, AgentInspectJestTraceAssociation> | undefined,\n): AgentInspectJestTraceAssociation | undefined {\n if (associations === undefined) return undefined;\n const basename = testCase.file === undefined ? undefined : path.basename(testCase.file);\n const candidates = [\n testCase.id,\n testCase.fullName,\n basename === undefined ? undefined : `${basename}::${testCase.fullName}`,\n ];\n for (const candidate of candidates) {\n if (candidate !== undefined && isAssociation(associations[candidate])) {\n return associations[candidate];\n }\n }\n return undefined;\n}\n\nfunction readAssociationFromAssertion(\n assertion: unknown,\n): AgentInspectJestTraceAssociation | undefined {\n if (!isObject(assertion)) return undefined;\n const direct = readProp(assertion, \"agentInspect\");\n if (isAssociation(direct)) return direct;\n\n const meta = readProp(assertion, \"meta\");\n if (!isObject(meta)) return undefined;\n for (const candidate of [\n readProp(meta, \"agentInspect\"),\n readProp(meta, \"agent-inspect\"),\n readProp(meta, \"trace\"),\n ]) {\n if (isAssociation(candidate)) return candidate;\n }\n return undefined;\n}\n\nfunction isAssociation(\n value: unknown,\n): value is AgentInspectJestTraceAssociation {\n if (!isObject(value)) return false;\n return (\n readOptionalString(value, \"runId\") !== undefined ||\n readOptionalString(value, \"tracePath\") !== undefined ||\n readOptionalString(value, \"artifactLabel\") !== undefined\n );\n}\n\nfunction readRunResults(results: unknown): unknown[] {\n if (!isObject(results)) return [];\n const testResults = readProp(results, \"testResults\");\n return Array.isArray(testResults) ? testResults : [];\n}\n\nfunction readTestCases(testResult: unknown): AgentInspectJestTestCase[] {\n if (!isObject(testResult)) return [];\n const result = testResult as TestFileResultLike;\n const file = readOptionalString(result, \"testFilePath\");\n const assertions = Array.isArray(result.testResults)\n ? result.testResults\n : Array.isArray(result.assertionResults)\n ? result.assertionResults\n : [];\n\n const cases: AgentInspectJestTestCase[] = [];\n for (const assertion of assertions) {\n if (!isObject(assertion)) continue;\n const status = readStatus(assertion);\n if (status === undefined || status === \"skipped\") continue;\n\n const title = readOptionalString(assertion, \"title\") ?? \"unknown-test\";\n const fullName = readFullName(assertion as AssertionResultLike, title);\n const id = `${file ?? \"unknown-file\"}::${fullName}`;\n cases.push({\n file,\n fullName: boundText(redactText(fullName)),\n id: boundText(redactText(id)),\n raw: assertion,\n status,\n title: boundText(redactText(title)),\n });\n }\n return cases;\n}\n\nfunction readFullName(assertion: AssertionResultLike, title: string): string {\n const explicit = readOptionalString(assertion, \"fullName\");\n if (explicit !== undefined) return explicit;\n\n const ancestors = Array.isArray(assertion.ancestorTitles)\n ? assertion.ancestorTitles.filter((item): item is string => typeof item === \"string\")\n : [];\n return [...ancestors, title].join(\" \");\n}\n\nfunction readStatus(assertion: object): AgentInspectJestStatus | undefined {\n const raw = readOptionalString(assertion, \"status\");\n if (raw === undefined) return undefined;\n\n const normalized = raw.toLowerCase();\n if (normalized === \"failed\" || normalized === \"fail\") return \"failed\";\n if (normalized === \"passed\" || normalized === \"pass\") return \"passed\";\n if (\n normalized === \"pending\" ||\n normalized === \"todo\" ||\n normalized === \"skipped\" ||\n normalized === \"skip\" ||\n normalized === \"disabled\"\n ) {\n return \"skipped\";\n }\n return undefined;\n}\n\nasync function writeSafeArtifact(input: {\n readonly artifactDir: string;\n readonly association: AgentInspectJestTraceAssociation;\n readonly generatedAt: string;\n readonly redactionProfile: TraceArtifactRedactionProfile;\n readonly reserveArtifactName: (seed: string) => string;\n readonly status: AgentInspectJestStatus;\n readonly testCase: AgentInspectJestTestCase;\n}): Promise<AgentInspectJestArtifact> {\n const artifactSeed =\n input.association.artifactLabel ??\n input.testCase.id ??\n input.testCase.fullName ??\n input.status;\n const artifactName = input.reserveArtifactName(artifactSeed);\n const testFile =\n input.testCase.file === undefined ? undefined : path.basename(input.testCase.file);\n const safeTestId = `${testFile ?? \"unknown-file\"}::${input.testCase.fullName}`;\n const manifestPathResult = createReporterArtifactPath({\n outputDir: input.artifactDir,\n testId: artifactName,\n name: input.testCase.fullName,\n file: testFile,\n kind: \"report\",\n format: \"json\",\n });\n const summaryPathResult = createReporterArtifactPath({\n outputDir: input.artifactDir,\n testId: artifactName,\n name: input.testCase.fullName,\n file: testFile,\n kind: \"summary\",\n format: \"md\",\n });\n\n if (\n !manifestPathResult.ok ||\n manifestPathResult.absolutePath === undefined ||\n manifestPathResult.relativePath === undefined\n ) {\n throw new Error(formatPathDiagnostics(manifestPathResult.diagnostics));\n }\n if (\n !summaryPathResult.ok ||\n summaryPathResult.absolutePath === undefined ||\n summaryPathResult.relativePath === undefined\n ) {\n throw new Error(formatPathDiagnostics(summaryPathResult.diagnostics));\n }\n\n const directory = path.dirname(manifestPathResult.absolutePath);\n await mkdir(directory, { recursive: true });\n\n const traceFile =\n input.association.tracePath === undefined\n ? undefined\n : path.basename(input.association.tracePath);\n const manifestArtifact: TraceArtifact = {\n kind: \"report\",\n path: manifestPathResult.relativePath,\n format: \"json\",\n redactionProfile: input.redactionProfile,\n };\n const summaryArtifact: TraceArtifact = {\n kind: \"summary\",\n path: summaryPathResult.relativePath,\n format: \"md\",\n redactionProfile: input.redactionProfile,\n };\n const manifest = createTraceArtifactManifest({\n framework: \"jest\",\n generatedAt: input.generatedAt,\n results: [\n {\n testId: safeTestId,\n name: input.testCase.fullName,\n ...(testFile === undefined ? {} : { file: testFile }),\n status: input.status,\n tracePath: safeOptional(traceFile),\n artifacts: [manifestArtifact, summaryArtifact],\n diagnostics: [],\n },\n ],\n artifacts: [manifestArtifact, summaryArtifact],\n diagnostics: [],\n });\n const trace = {\n runId: safeOptional(input.association.runId),\n file: safeOptional(traceFile),\n };\n\n await writeFile(\n manifestPathResult.absolutePath,\n `${JSON.stringify({ package: PACKAGE_NAME, manifest, trace }, null, 2)}\\n`,\n );\n const summaryPath = summaryPathResult.absolutePath;\n await writeFile(summaryPath, renderSummary(manifest, trace), \"utf-8\");\n\n return {\n directory,\n manifest,\n manifestPath: manifestPathResult.absolutePath,\n status: input.status,\n summaryPath,\n testId: safeTestId,\n };\n}\n\nfunction renderSummary(\n manifest: TraceArtifactManifest,\n trace: { readonly runId?: string; readonly file?: string },\n): string {\n const result = manifest.results[0];\n return [\n \"# AgentInspect Jest Artifact\",\n \"\",\n `- Test: ${result?.name ?? \"unknown\"}`,\n `- Test id: ${result?.testId ?? \"unknown\"}`,\n `- Status: ${result?.status ?? \"unknown\"}`,\n `- File: ${result?.file ?? \"unknown\"}`,\n `- Trace run: ${trace.runId ?? \"unknown\"}`,\n `- Trace file: ${result?.tracePath ?? \"unknown\"}`,\n `- Manifest schema: ${manifest.schemaVersion}`,\n \"\",\n \"Trace contents are intentionally not embedded in this artifact.\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction formatPathDiagnostics(\n diagnostics: readonly TraceReporterDiagnostic[],\n): string {\n if (diagnostics.length === 0) return \"Unsafe AgentInspect Jest artifact path.\";\n return diagnostics.map((diagnostic) => diagnostic.message).join(\"; \");\n}\n\nfunction safeOptional(value: string | undefined): string | undefined {\n return value === undefined ? undefined : boundText(redactText(value));\n}\n\nfunction safeSegment(value: string): string {\n const sanitized = redactText(value)\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 80);\n return sanitized.length > 0 ? sanitized : \"trace\";\n}\n\nfunction boundText(value: string, max = MAX_TEXT): string {\n const compact = value.replace(/\\s+/g, \" \").trim();\n if (compact.length <= max) return compact;\n return `${compact.slice(0, max - 12)}...[truncated]`;\n}\n\nfunction redactText(value: string): string {\n return value\n .replace(/\\bsk-[A-Za-z0-9_-]{8,}\\b/g, \"[REDACTED]\")\n .replace(/\\b(?:api[_-]?key|authorization|token|secret|password)\\s*[:=]\\s*[^,\\s]+/gi, \"$1=[REDACTED]\");\n}\n\nfunction readOptionalString(value: unknown, key: string): string | undefined {\n if (!isObject(value)) return undefined;\n const property = readProp(value, key);\n return typeof property === \"string\" && property.length > 0 ? property : undefined;\n}\n\nfunction readProp(value: object, key: string): unknown {\n return (value as Record<string, unknown>)[key];\n}\n\nfunction isObject(value: unknown): value is object {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-inspect/jest",
3
- "version": "6.7.4",
3
+ "version": "6.7.5",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Optional Jest reporter for AgentInspect local trace artifacts",
@@ -42,7 +42,7 @@
42
42
  }
43
43
  },
44
44
  "dependencies": {
45
- "agent-inspect": "6.7.4"
45
+ "agent-inspect": "6.7.5"
46
46
  },
47
47
  "devDependencies": {
48
48
  "jest": "^30.2.0"