agent-inspect 6.9.0 → 6.11.0
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/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/docs/BUNDLES.md +31 -9
- package/docs/CI-ARTIFACTS.md +10 -1
- package/docs/CLI.md +22 -2
- package/package.json +1 -1
- package/packages/cli/dist/{chunk-WQ5XMFH2.mjs → chunk-XTAA733P.mjs} +1756 -149
- package/packages/cli/dist/chunk-XTAA733P.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +10634 -8880
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +729 -708
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-C4EUHTER.mjs → src-G7PM24W2.mjs} +3 -3
- package/packages/cli/dist/{src-C4EUHTER.mjs.map → src-G7PM24W2.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +1846 -12
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.d.cts +373 -4
- package/packages/core/dist/advanced.d.ts +373 -4
- package/packages/core/dist/advanced.mjs +1307 -12
- package/packages/core/dist/advanced.mjs.map +1 -1
- package/packages/core/dist/chunk-F7STQ5JF.mjs +479 -0
- package/packages/core/dist/chunk-F7STQ5JF.mjs.map +1 -0
- package/packages/core/dist/{chunk-KDDU2R5P.mjs → chunk-LFWZEO2L.mjs} +2 -2
- package/packages/core/dist/{chunk-KDDU2R5P.mjs.map → chunk-LFWZEO2L.mjs.map} +1 -1
- package/packages/core/dist/diff.mjs +3 -477
- package/packages/core/dist/diff.mjs.map +1 -1
- package/packages/core/dist/exporters.cjs.map +1 -1
- package/packages/core/dist/exporters.mjs +1 -1
- package/packages/core/dist/reporters.cjs +25 -0
- package/packages/core/dist/reporters.cjs.map +1 -1
- package/packages/core/dist/reporters.d.cts +16 -2
- package/packages/core/dist/reporters.d.ts +16 -2
- package/packages/core/dist/reporters.mjs +24 -1
- package/packages/core/dist/reporters.mjs.map +1 -1
- package/packages/cli/dist/chunk-WQ5XMFH2.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildRunWhatSummary, renderRunWhat, renderTimeline, buildRunTimeline } from './chunk-
|
|
1
|
+
import { buildRunWhatSummary, renderRunWhat, renderTimeline, buildRunTimeline } from './chunk-LFWZEO2L.mjs';
|
|
2
2
|
import { summarizeObservedOutcomes, extractOutcomesFromTraceEvents, renderObservedOutcomesMarkdown, renderObservedOutcomesHtml } from './chunk-VFO76UH3.mjs';
|
|
3
3
|
import { escapeHtml, flattenTree, safeString, compactAttributes, stableJson, escapeMarkdown, zeroKinds } from './chunk-CAWPF22J.mjs';
|
|
4
4
|
export { compactAttributes, escapeHtml, escapeMarkdown, flattenTree, safeString, stableJson, summarizeTree } from './chunk-CAWPF22J.mjs';
|
|
@@ -175,8 +175,33 @@ function slugForPathLabel(value) {
|
|
|
175
175
|
const slug = base.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^[._-]+|[._-]+$/g, "").slice(0, 80);
|
|
176
176
|
return slug.length > 0 ? slug : "artifact";
|
|
177
177
|
}
|
|
178
|
+
var EVIDENCE_CI_ARTIFACT_FILES = [
|
|
179
|
+
"evidence.html",
|
|
180
|
+
"evidence.json",
|
|
181
|
+
"check-results.json",
|
|
182
|
+
"trace.jsonl"
|
|
183
|
+
];
|
|
184
|
+
function createEvidenceCiArtifacts(options) {
|
|
185
|
+
const profile = options.redactionProfile ?? "share";
|
|
186
|
+
const prefix = options.relativeDir !== void 0 && options.relativeDir.trim() !== "" ? options.relativeDir.replace(/\\/g, "/").replace(/^\/+|\/+$/g, "") : "";
|
|
187
|
+
const join = (name) => prefix === "" ? name : path__default.default.posix.join(prefix, name);
|
|
188
|
+
const formatFor = (name) => {
|
|
189
|
+
if (name.endsWith(".html")) return "html";
|
|
190
|
+
if (name.endsWith(".jsonl")) return "jsonl";
|
|
191
|
+
return "json";
|
|
192
|
+
};
|
|
193
|
+
return EVIDENCE_CI_ARTIFACT_FILES.map((name) => ({
|
|
194
|
+
kind: "evidence",
|
|
195
|
+
path: join(name),
|
|
196
|
+
format: formatFor(name),
|
|
197
|
+
redactionProfile: profile,
|
|
198
|
+
title: `Evidence v2 ${name}`
|
|
199
|
+
}));
|
|
200
|
+
}
|
|
178
201
|
|
|
202
|
+
exports.EVIDENCE_CI_ARTIFACT_FILES = EVIDENCE_CI_ARTIFACT_FILES;
|
|
179
203
|
exports.TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION = TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION;
|
|
204
|
+
exports.createEvidenceCiArtifacts = createEvidenceCiArtifacts;
|
|
180
205
|
exports.createReporterArtifactPath = createReporterArtifactPath;
|
|
181
206
|
exports.createReporterFailureDiagnostic = createReporterFailureDiagnostic;
|
|
182
207
|
exports.createTraceArtifactManifest = createTraceArtifactManifest;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/reporters/index.ts"],"names":["path"],"mappings":"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","file":"reporters.cjs","sourcesContent":["import path from \"node:path\";\n\nexport const TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION = \"0.1\" as const;\n\n/** Experimental reporter framework identifier for local CI artifacts. */\nexport type TraceReporterFramework = \"vitest\" | \"jest\" | \"manual\";\n\n/** Experimental reporter test status normalized across supported test runners. */\nexport type TraceTestStatus = \"passed\" | \"failed\" | \"skipped\" | \"todo\";\n\n/** Experimental reporter artifact kind used in artifact manifests. */\nexport type TraceArtifactKind = \"trace\" | \"report\" | \"eval\" | \"redaction\" | \"summary\";\n\n/** Experimental reporter artifact file format used in artifact manifests. */\nexport type TraceArtifactFormat = \"json\" | \"jsonl\" | \"md\" | \"html\";\n\n/** Experimental redaction profile marker recorded with reporter artifacts. */\nexport type TraceArtifactRedactionProfile = \"local\" | \"share\" | \"strict\";\n\n/** Experimental reporter diagnostic severity. */\nexport type TraceReporterDiagnosticSeverity = \"info\" | \"warning\" | \"error\";\n\n/** Experimental reporter diagnostic code for safe, non-throwing reporter helpers. */\nexport type TraceReporterDiagnosticCode =\n | \"invalid_artifact_path\"\n | \"artifact_path_escape\"\n | \"artifact_path_empty\"\n | \"artifact_path_absolute\"\n | \"reporter_failure\";\n\n/** Experimental diagnostic emitted by reporter helpers instead of throwing. */\nexport interface TraceReporterDiagnostic {\n code: TraceReporterDiagnosticCode;\n severity: TraceReporterDiagnosticSeverity;\n message: string;\n target?: string;\n}\n\n/** Experimental manifest artifact entry shared by framework reporters. */\nexport interface TraceArtifact {\n kind: TraceArtifactKind;\n path: string;\n format: TraceArtifactFormat;\n redactionProfile: TraceArtifactRedactionProfile;\n title?: string;\n sizeBytes?: number;\n diagnostics?: TraceReporterDiagnostic[];\n}\n\n/** Experimental normalized test result entry shared by framework reporters. */\nexport interface TraceTestResult {\n testId: string;\n name: string;\n file?: string;\n status: TraceTestStatus;\n durationMs?: number;\n tracePath?: string;\n artifacts?: TraceArtifact[];\n diagnostics?: TraceReporterDiagnostic[];\n}\n\n/** Experimental reporter artifact manifest shared by framework reporters. */\nexport interface TraceArtifactManifest {\n schemaVersion: typeof TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION;\n generatedAt: string;\n framework: TraceReporterFramework;\n results: TraceTestResult[];\n artifacts: TraceArtifact[];\n diagnostics: TraceReporterDiagnostic[];\n}\n\n/** Experimental options for deterministic reporter artifact manifest creation. */\nexport interface CreateTraceArtifactManifestOptions {\n framework: TraceReporterFramework;\n generatedAt: string;\n results: TraceTestResult[];\n artifacts?: TraceArtifact[];\n diagnostics?: TraceReporterDiagnostic[];\n}\n\n/** Experimental options for deriving a safe reporter artifact path. */\nexport interface CreateReporterArtifactPathOptions {\n outputDir: string;\n testId: string;\n name: string;\n kind: TraceArtifactKind;\n format: TraceArtifactFormat;\n file?: string;\n}\n\n/** Experimental result from reporter artifact path validation/resolution. */\nexport interface ReporterArtifactPathResult {\n ok: boolean;\n outputDir: string;\n relativePath?: string;\n absolutePath?: string;\n diagnostics: TraceReporterDiagnostic[];\n}\n\nexport interface ValidateReporterArtifactPathOptions {\n outputDir: string;\n relativePath: string;\n}\n\nconst FORMAT_EXTENSIONS: Record<TraceArtifactFormat, string> = {\n json: \"json\",\n jsonl: \"jsonl\",\n md: \"md\",\n html: \"html\",\n};\n\nfunction sortDiagnostics(a: TraceReporterDiagnostic, b: TraceReporterDiagnostic): number {\n return compareStrings(a.target ?? \"\", b.target ?? \"\") ||\n compareStrings(a.code, b.code) ||\n compareStrings(a.severity, b.severity) ||\n compareStrings(a.message, b.message);\n}\n\nfunction sortArtifacts(a: TraceArtifact, b: TraceArtifact): number {\n return compareStrings(a.path, b.path) ||\n compareStrings(a.kind, b.kind) ||\n compareStrings(a.format, b.format) ||\n compareStrings(a.redactionProfile, b.redactionProfile) ||\n compareStrings(a.title ?? \"\", b.title ?? \"\");\n}\n\nfunction sortResults(a: TraceTestResult, b: TraceTestResult): number {\n return compareStrings(a.file ?? \"\", b.file ?? \"\") ||\n compareStrings(a.name, b.name) ||\n compareStrings(a.testId, b.testId);\n}\n\nfunction compareStrings(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\nfunction cloneDiagnostic(diagnostic: TraceReporterDiagnostic): TraceReporterDiagnostic {\n return {\n code: diagnostic.code,\n severity: diagnostic.severity,\n message: diagnostic.message,\n ...(diagnostic.target === undefined ? {} : { target: diagnostic.target }),\n };\n}\n\nfunction cloneArtifact(artifact: TraceArtifact): TraceArtifact {\n return {\n kind: artifact.kind,\n path: artifact.path,\n format: artifact.format,\n redactionProfile: artifact.redactionProfile,\n ...(artifact.title === undefined ? {} : { title: artifact.title }),\n ...(artifact.sizeBytes === undefined ? {} : { sizeBytes: artifact.sizeBytes }),\n diagnostics: (artifact.diagnostics ?? []).map(cloneDiagnostic).sort(sortDiagnostics),\n };\n}\n\nfunction cloneResult(result: TraceTestResult): TraceTestResult {\n return {\n testId: result.testId,\n name: result.name,\n ...(result.file === undefined ? {} : { file: result.file }),\n status: result.status,\n ...(result.durationMs === undefined ? {} : { durationMs: result.durationMs }),\n ...(result.tracePath === undefined ? {} : { tracePath: result.tracePath }),\n artifacts: (result.artifacts ?? []).map(cloneArtifact).sort(sortArtifacts),\n diagnostics: (result.diagnostics ?? []).map(cloneDiagnostic).sort(sortDiagnostics),\n };\n}\n\nfunction artifactIdentity(artifact: TraceArtifact): string {\n return `${artifact.path}\\0${artifact.kind}\\0${artifact.format}\\0${artifact.redactionProfile}`;\n}\n\nfunction dedupeArtifacts(artifacts: TraceArtifact[]): TraceArtifact[] {\n const seen = new Set<string>();\n const out: TraceArtifact[] = [];\n for (const artifact of artifacts.sort(sortArtifacts)) {\n const key = artifactIdentity(artifact);\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(artifact);\n }\n return out;\n}\n\n/** Experimental helper that creates a deterministic reporter artifact manifest. */\nexport function createTraceArtifactManifest(\n options: CreateTraceArtifactManifestOptions,\n): TraceArtifactManifest {\n const results = options.results.map(cloneResult).sort(sortResults);\n const resultArtifacts = results.flatMap((result) => result.artifacts ?? []);\n const artifacts = dedupeArtifacts([\n ...resultArtifacts,\n ...(options.artifacts ?? []).map(cloneArtifact),\n ]);\n\n return {\n schemaVersion: TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION,\n generatedAt: options.generatedAt,\n framework: options.framework,\n results,\n artifacts,\n diagnostics: (options.diagnostics ?? []).map(cloneDiagnostic).sort(sortDiagnostics),\n };\n}\n\n/** Experimental helper that creates a safe, deterministic artifact path for a test. */\nexport function createReporterArtifactPath(\n options: CreateReporterArtifactPathOptions,\n): ReporterArtifactPathResult {\n const fileSlug = slugForPathLabel(options.file ?? \"manual\");\n const testSlug = slugForPathLabel(`${options.name}-${options.testId}`);\n const relativePath = path.posix.join(\n \"tests\",\n fileSlug,\n testSlug,\n `${options.kind}.${FORMAT_EXTENSIONS[options.format]}`,\n );\n\n return validateReporterArtifactPath({\n outputDir: options.outputDir,\n relativePath,\n });\n}\n\n/** Experimental helper that validates an artifact path stays inside outputDir. */\nexport function validateReporterArtifactPath(\n options: ValidateReporterArtifactPathOptions,\n): ReporterArtifactPathResult {\n const outputDir = path.resolve(options.outputDir);\n const diagnostics: TraceReporterDiagnostic[] = [];\n const rawPath = options.relativePath;\n\n if (rawPath.length === 0) {\n diagnostics.push({\n code: \"artifact_path_empty\",\n severity: \"error\",\n message: \"Reporter artifact path must not be empty.\",\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n if (rawPath.includes(\"\\0\")) {\n diagnostics.push({\n code: \"invalid_artifact_path\",\n severity: \"error\",\n message: \"Reporter artifact path must not contain null bytes.\",\n target: rawPath,\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n if (path.isAbsolute(rawPath) || path.win32.isAbsolute(rawPath)) {\n diagnostics.push({\n code: \"artifact_path_absolute\",\n severity: \"error\",\n message: \"Reporter artifact path must be relative.\",\n target: rawPath,\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n const normalized = path.posix.normalize(rawPath.replace(/\\\\/g, \"/\"));\n const segments = normalized.split(\"/\");\n if (\n normalized === \".\" ||\n normalized.startsWith(\"../\") ||\n segments.some((segment) => segment === \"..\")\n ) {\n diagnostics.push({\n code: \"artifact_path_escape\",\n severity: \"error\",\n message: \"Reporter artifact path must stay under the output directory.\",\n target: rawPath,\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n const absolutePath = path.resolve(outputDir, normalized);\n const relFromOutput = path.relative(outputDir, absolutePath);\n if (\n relFromOutput.length === 0 ||\n relFromOutput.startsWith(\"..\") ||\n path.isAbsolute(relFromOutput)\n ) {\n diagnostics.push({\n code: \"artifact_path_escape\",\n severity: \"error\",\n message: \"Reporter artifact path resolved outside the output directory.\",\n target: rawPath,\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n return {\n ok: true,\n outputDir,\n relativePath: normalized,\n absolutePath,\n diagnostics,\n };\n}\n\n/** Experimental helper that converts an unknown reporter failure into a diagnostic. */\nexport function createReporterFailureDiagnostic(\n error: unknown,\n target?: string,\n): TraceReporterDiagnostic {\n const message = error instanceof Error\n ? error.message\n : typeof error === \"string\"\n ? error\n : \"Unknown reporter failure.\";\n\n return {\n code: \"reporter_failure\",\n severity: \"error\",\n message,\n ...(target === undefined ? {} : { target }),\n };\n}\n\nfunction slugForPathLabel(value: string): string {\n const base = path.basename(value)\n .replace(/\\.(test|spec)\\.[^.]+$/, \"\")\n .replace(/\\.[^.]+$/, \"\");\n const slug = base\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/^[._-]+|[._-]+$/g, \"\")\n .slice(0, 80);\n return slug.length > 0 ? slug : \"artifact\";\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/reporters/index.ts"],"names":["path"],"mappings":"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","file":"reporters.cjs","sourcesContent":["import path from \"node:path\";\n\nexport const TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION = \"0.1\" as const;\n\n/** Experimental reporter framework identifier for local CI artifacts. */\nexport type TraceReporterFramework = \"vitest\" | \"jest\" | \"manual\";\n\n/** Experimental reporter test status normalized across supported test runners. */\nexport type TraceTestStatus = \"passed\" | \"failed\" | \"skipped\" | \"todo\";\n\n/** Experimental reporter artifact kind used in artifact manifests. */\nexport type TraceArtifactKind = \"trace\" | \"report\" | \"eval\" | \"redaction\" | \"summary\" | \"evidence\";\n\n/** Experimental reporter artifact file format used in artifact manifests. */\nexport type TraceArtifactFormat = \"json\" | \"jsonl\" | \"md\" | \"html\";\n\n/** Experimental redaction profile marker recorded with reporter artifacts. */\nexport type TraceArtifactRedactionProfile = \"local\" | \"share\" | \"strict\";\n\n/** Experimental reporter diagnostic severity. */\nexport type TraceReporterDiagnosticSeverity = \"info\" | \"warning\" | \"error\";\n\n/** Experimental reporter diagnostic code for safe, non-throwing reporter helpers. */\nexport type TraceReporterDiagnosticCode =\n | \"invalid_artifact_path\"\n | \"artifact_path_escape\"\n | \"artifact_path_empty\"\n | \"artifact_path_absolute\"\n | \"reporter_failure\";\n\n/** Experimental diagnostic emitted by reporter helpers instead of throwing. */\nexport interface TraceReporterDiagnostic {\n code: TraceReporterDiagnosticCode;\n severity: TraceReporterDiagnosticSeverity;\n message: string;\n target?: string;\n}\n\n/** Experimental manifest artifact entry shared by framework reporters. */\nexport interface TraceArtifact {\n kind: TraceArtifactKind;\n path: string;\n format: TraceArtifactFormat;\n redactionProfile: TraceArtifactRedactionProfile;\n title?: string;\n sizeBytes?: number;\n diagnostics?: TraceReporterDiagnostic[];\n}\n\n/** Experimental normalized test result entry shared by framework reporters. */\nexport interface TraceTestResult {\n testId: string;\n name: string;\n file?: string;\n status: TraceTestStatus;\n durationMs?: number;\n tracePath?: string;\n artifacts?: TraceArtifact[];\n diagnostics?: TraceReporterDiagnostic[];\n}\n\n/** Experimental reporter artifact manifest shared by framework reporters. */\nexport interface TraceArtifactManifest {\n schemaVersion: typeof TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION;\n generatedAt: string;\n framework: TraceReporterFramework;\n results: TraceTestResult[];\n artifacts: TraceArtifact[];\n diagnostics: TraceReporterDiagnostic[];\n}\n\n/** Experimental options for deterministic reporter artifact manifest creation. */\nexport interface CreateTraceArtifactManifestOptions {\n framework: TraceReporterFramework;\n generatedAt: string;\n results: TraceTestResult[];\n artifacts?: TraceArtifact[];\n diagnostics?: TraceReporterDiagnostic[];\n}\n\n/** Experimental options for deriving a safe reporter artifact path. */\nexport interface CreateReporterArtifactPathOptions {\n outputDir: string;\n testId: string;\n name: string;\n kind: TraceArtifactKind;\n format: TraceArtifactFormat;\n file?: string;\n}\n\n/** Experimental result from reporter artifact path validation/resolution. */\nexport interface ReporterArtifactPathResult {\n ok: boolean;\n outputDir: string;\n relativePath?: string;\n absolutePath?: string;\n diagnostics: TraceReporterDiagnostic[];\n}\n\nexport interface ValidateReporterArtifactPathOptions {\n outputDir: string;\n relativePath: string;\n}\n\nconst FORMAT_EXTENSIONS: Record<TraceArtifactFormat, string> = {\n json: \"json\",\n jsonl: \"jsonl\",\n md: \"md\",\n html: \"html\",\n};\n\nfunction sortDiagnostics(a: TraceReporterDiagnostic, b: TraceReporterDiagnostic): number {\n return compareStrings(a.target ?? \"\", b.target ?? \"\") ||\n compareStrings(a.code, b.code) ||\n compareStrings(a.severity, b.severity) ||\n compareStrings(a.message, b.message);\n}\n\nfunction sortArtifacts(a: TraceArtifact, b: TraceArtifact): number {\n return compareStrings(a.path, b.path) ||\n compareStrings(a.kind, b.kind) ||\n compareStrings(a.format, b.format) ||\n compareStrings(a.redactionProfile, b.redactionProfile) ||\n compareStrings(a.title ?? \"\", b.title ?? \"\");\n}\n\nfunction sortResults(a: TraceTestResult, b: TraceTestResult): number {\n return compareStrings(a.file ?? \"\", b.file ?? \"\") ||\n compareStrings(a.name, b.name) ||\n compareStrings(a.testId, b.testId);\n}\n\nfunction compareStrings(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\nfunction cloneDiagnostic(diagnostic: TraceReporterDiagnostic): TraceReporterDiagnostic {\n return {\n code: diagnostic.code,\n severity: diagnostic.severity,\n message: diagnostic.message,\n ...(diagnostic.target === undefined ? {} : { target: diagnostic.target }),\n };\n}\n\nfunction cloneArtifact(artifact: TraceArtifact): TraceArtifact {\n return {\n kind: artifact.kind,\n path: artifact.path,\n format: artifact.format,\n redactionProfile: artifact.redactionProfile,\n ...(artifact.title === undefined ? {} : { title: artifact.title }),\n ...(artifact.sizeBytes === undefined ? {} : { sizeBytes: artifact.sizeBytes }),\n diagnostics: (artifact.diagnostics ?? []).map(cloneDiagnostic).sort(sortDiagnostics),\n };\n}\n\nfunction cloneResult(result: TraceTestResult): TraceTestResult {\n return {\n testId: result.testId,\n name: result.name,\n ...(result.file === undefined ? {} : { file: result.file }),\n status: result.status,\n ...(result.durationMs === undefined ? {} : { durationMs: result.durationMs }),\n ...(result.tracePath === undefined ? {} : { tracePath: result.tracePath }),\n artifacts: (result.artifacts ?? []).map(cloneArtifact).sort(sortArtifacts),\n diagnostics: (result.diagnostics ?? []).map(cloneDiagnostic).sort(sortDiagnostics),\n };\n}\n\nfunction artifactIdentity(artifact: TraceArtifact): string {\n return `${artifact.path}\\0${artifact.kind}\\0${artifact.format}\\0${artifact.redactionProfile}`;\n}\n\nfunction dedupeArtifacts(artifacts: TraceArtifact[]): TraceArtifact[] {\n const seen = new Set<string>();\n const out: TraceArtifact[] = [];\n for (const artifact of artifacts.sort(sortArtifacts)) {\n const key = artifactIdentity(artifact);\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(artifact);\n }\n return out;\n}\n\n/** Experimental helper that creates a deterministic reporter artifact manifest. */\nexport function createTraceArtifactManifest(\n options: CreateTraceArtifactManifestOptions,\n): TraceArtifactManifest {\n const results = options.results.map(cloneResult).sort(sortResults);\n const resultArtifacts = results.flatMap((result) => result.artifacts ?? []);\n const artifacts = dedupeArtifacts([\n ...resultArtifacts,\n ...(options.artifacts ?? []).map(cloneArtifact),\n ]);\n\n return {\n schemaVersion: TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION,\n generatedAt: options.generatedAt,\n framework: options.framework,\n results,\n artifacts,\n diagnostics: (options.diagnostics ?? []).map(cloneDiagnostic).sort(sortDiagnostics),\n };\n}\n\n/** Experimental helper that creates a safe, deterministic artifact path for a test. */\nexport function createReporterArtifactPath(\n options: CreateReporterArtifactPathOptions,\n): ReporterArtifactPathResult {\n const fileSlug = slugForPathLabel(options.file ?? \"manual\");\n const testSlug = slugForPathLabel(`${options.name}-${options.testId}`);\n const relativePath = path.posix.join(\n \"tests\",\n fileSlug,\n testSlug,\n `${options.kind}.${FORMAT_EXTENSIONS[options.format]}`,\n );\n\n return validateReporterArtifactPath({\n outputDir: options.outputDir,\n relativePath,\n });\n}\n\n/** Experimental helper that validates an artifact path stays inside outputDir. */\nexport function validateReporterArtifactPath(\n options: ValidateReporterArtifactPathOptions,\n): ReporterArtifactPathResult {\n const outputDir = path.resolve(options.outputDir);\n const diagnostics: TraceReporterDiagnostic[] = [];\n const rawPath = options.relativePath;\n\n if (rawPath.length === 0) {\n diagnostics.push({\n code: \"artifact_path_empty\",\n severity: \"error\",\n message: \"Reporter artifact path must not be empty.\",\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n if (rawPath.includes(\"\\0\")) {\n diagnostics.push({\n code: \"invalid_artifact_path\",\n severity: \"error\",\n message: \"Reporter artifact path must not contain null bytes.\",\n target: rawPath,\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n if (path.isAbsolute(rawPath) || path.win32.isAbsolute(rawPath)) {\n diagnostics.push({\n code: \"artifact_path_absolute\",\n severity: \"error\",\n message: \"Reporter artifact path must be relative.\",\n target: rawPath,\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n const normalized = path.posix.normalize(rawPath.replace(/\\\\/g, \"/\"));\n const segments = normalized.split(\"/\");\n if (\n normalized === \".\" ||\n normalized.startsWith(\"../\") ||\n segments.some((segment) => segment === \"..\")\n ) {\n diagnostics.push({\n code: \"artifact_path_escape\",\n severity: \"error\",\n message: \"Reporter artifact path must stay under the output directory.\",\n target: rawPath,\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n const absolutePath = path.resolve(outputDir, normalized);\n const relFromOutput = path.relative(outputDir, absolutePath);\n if (\n relFromOutput.length === 0 ||\n relFromOutput.startsWith(\"..\") ||\n path.isAbsolute(relFromOutput)\n ) {\n diagnostics.push({\n code: \"artifact_path_escape\",\n severity: \"error\",\n message: \"Reporter artifact path resolved outside the output directory.\",\n target: rawPath,\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n return {\n ok: true,\n outputDir,\n relativePath: normalized,\n absolutePath,\n diagnostics,\n };\n}\n\n/** Experimental helper that converts an unknown reporter failure into a diagnostic. */\nexport function createReporterFailureDiagnostic(\n error: unknown,\n target?: string,\n): TraceReporterDiagnostic {\n const message = error instanceof Error\n ? error.message\n : typeof error === \"string\"\n ? error\n : \"Unknown reporter failure.\";\n\n return {\n code: \"reporter_failure\",\n severity: \"error\",\n message,\n ...(target === undefined ? {} : { target }),\n };\n}\n\nfunction slugForPathLabel(value: string): string {\n const base = path.basename(value)\n .replace(/\\.(test|spec)\\.[^.]+$/, \"\")\n .replace(/\\.[^.]+$/, \"\");\n const slug = base\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/^[._-]+|[._-]+$/g, \"\")\n .slice(0, 80);\n return slug.length > 0 ? slug : \"artifact\";\n}\n\n/**\n * Standard Evidence v2 filenames for CI failure packages (same shape as `bundle`).\n * Success remains quiet by default — callers should emit these only on failure.\n */\nexport const EVIDENCE_CI_ARTIFACT_FILES = [\n \"evidence.html\",\n \"evidence.json\",\n \"check-results.json\",\n \"trace.jsonl\",\n] as const;\n\nexport type EvidenceCiArtifactFile = (typeof EVIDENCE_CI_ARTIFACT_FILES)[number];\n\n/**\n * Experimental helper: TraceArtifact entries for a standard Evidence v2 CI package.\n */\nexport function createEvidenceCiArtifacts(options: {\n redactionProfile?: TraceArtifactRedactionProfile;\n /** Optional subdirectory under the test artifact folder (POSIX). */\n relativeDir?: string;\n}): TraceArtifact[] {\n const profile = options.redactionProfile ?? \"share\";\n const prefix =\n options.relativeDir !== undefined && options.relativeDir.trim() !== \"\"\n ? options.relativeDir.replace(/\\\\/g, \"/\").replace(/^\\/+|\\/+$/g, \"\")\n : \"\";\n const join = (name: string): string => (prefix === \"\" ? name : path.posix.join(prefix, name));\n\n const formatFor = (name: EvidenceCiArtifactFile): TraceArtifactFormat => {\n if (name.endsWith(\".html\")) return \"html\";\n if (name.endsWith(\".jsonl\")) return \"jsonl\";\n return \"json\";\n };\n\n return EVIDENCE_CI_ARTIFACT_FILES.map((name) => ({\n kind: \"evidence\" as const,\n path: join(name),\n format: formatFor(name),\n redactionProfile: profile,\n title: `Evidence v2 ${name}`,\n }));\n}\n"]}
|
|
@@ -4,7 +4,7 @@ type TraceReporterFramework = "vitest" | "jest" | "manual";
|
|
|
4
4
|
/** Experimental reporter test status normalized across supported test runners. */
|
|
5
5
|
type TraceTestStatus = "passed" | "failed" | "skipped" | "todo";
|
|
6
6
|
/** Experimental reporter artifact kind used in artifact manifests. */
|
|
7
|
-
type TraceArtifactKind = "trace" | "report" | "eval" | "redaction" | "summary";
|
|
7
|
+
type TraceArtifactKind = "trace" | "report" | "eval" | "redaction" | "summary" | "evidence";
|
|
8
8
|
/** Experimental reporter artifact file format used in artifact manifests. */
|
|
9
9
|
type TraceArtifactFormat = "json" | "jsonl" | "md" | "html";
|
|
10
10
|
/** Experimental redaction profile marker recorded with reporter artifacts. */
|
|
@@ -87,5 +87,19 @@ declare function createReporterArtifactPath(options: CreateReporterArtifactPathO
|
|
|
87
87
|
declare function validateReporterArtifactPath(options: ValidateReporterArtifactPathOptions): ReporterArtifactPathResult;
|
|
88
88
|
/** Experimental helper that converts an unknown reporter failure into a diagnostic. */
|
|
89
89
|
declare function createReporterFailureDiagnostic(error: unknown, target?: string): TraceReporterDiagnostic;
|
|
90
|
+
/**
|
|
91
|
+
* Standard Evidence v2 filenames for CI failure packages (same shape as `bundle`).
|
|
92
|
+
* Success remains quiet by default — callers should emit these only on failure.
|
|
93
|
+
*/
|
|
94
|
+
declare const EVIDENCE_CI_ARTIFACT_FILES: readonly ["evidence.html", "evidence.json", "check-results.json", "trace.jsonl"];
|
|
95
|
+
type EvidenceCiArtifactFile = (typeof EVIDENCE_CI_ARTIFACT_FILES)[number];
|
|
96
|
+
/**
|
|
97
|
+
* Experimental helper: TraceArtifact entries for a standard Evidence v2 CI package.
|
|
98
|
+
*/
|
|
99
|
+
declare function createEvidenceCiArtifacts(options: {
|
|
100
|
+
redactionProfile?: TraceArtifactRedactionProfile;
|
|
101
|
+
/** Optional subdirectory under the test artifact folder (POSIX). */
|
|
102
|
+
relativeDir?: string;
|
|
103
|
+
}): TraceArtifact[];
|
|
90
104
|
|
|
91
|
-
export { type CreateReporterArtifactPathOptions, type CreateTraceArtifactManifestOptions, type ReporterArtifactPathResult, TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION, type TraceArtifact, type TraceArtifactFormat, type TraceArtifactKind, type TraceArtifactManifest, type TraceArtifactRedactionProfile, type TraceReporterDiagnostic, type TraceReporterDiagnosticCode, type TraceReporterDiagnosticSeverity, type TraceReporterFramework, type TraceTestResult, type TraceTestStatus, type ValidateReporterArtifactPathOptions, createReporterArtifactPath, createReporterFailureDiagnostic, createTraceArtifactManifest, validateReporterArtifactPath };
|
|
105
|
+
export { type CreateReporterArtifactPathOptions, type CreateTraceArtifactManifestOptions, EVIDENCE_CI_ARTIFACT_FILES, type EvidenceCiArtifactFile, type ReporterArtifactPathResult, TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION, type TraceArtifact, type TraceArtifactFormat, type TraceArtifactKind, type TraceArtifactManifest, type TraceArtifactRedactionProfile, type TraceReporterDiagnostic, type TraceReporterDiagnosticCode, type TraceReporterDiagnosticSeverity, type TraceReporterFramework, type TraceTestResult, type TraceTestStatus, type ValidateReporterArtifactPathOptions, createEvidenceCiArtifacts, createReporterArtifactPath, createReporterFailureDiagnostic, createTraceArtifactManifest, validateReporterArtifactPath };
|
|
@@ -4,7 +4,7 @@ type TraceReporterFramework = "vitest" | "jest" | "manual";
|
|
|
4
4
|
/** Experimental reporter test status normalized across supported test runners. */
|
|
5
5
|
type TraceTestStatus = "passed" | "failed" | "skipped" | "todo";
|
|
6
6
|
/** Experimental reporter artifact kind used in artifact manifests. */
|
|
7
|
-
type TraceArtifactKind = "trace" | "report" | "eval" | "redaction" | "summary";
|
|
7
|
+
type TraceArtifactKind = "trace" | "report" | "eval" | "redaction" | "summary" | "evidence";
|
|
8
8
|
/** Experimental reporter artifact file format used in artifact manifests. */
|
|
9
9
|
type TraceArtifactFormat = "json" | "jsonl" | "md" | "html";
|
|
10
10
|
/** Experimental redaction profile marker recorded with reporter artifacts. */
|
|
@@ -87,5 +87,19 @@ declare function createReporterArtifactPath(options: CreateReporterArtifactPathO
|
|
|
87
87
|
declare function validateReporterArtifactPath(options: ValidateReporterArtifactPathOptions): ReporterArtifactPathResult;
|
|
88
88
|
/** Experimental helper that converts an unknown reporter failure into a diagnostic. */
|
|
89
89
|
declare function createReporterFailureDiagnostic(error: unknown, target?: string): TraceReporterDiagnostic;
|
|
90
|
+
/**
|
|
91
|
+
* Standard Evidence v2 filenames for CI failure packages (same shape as `bundle`).
|
|
92
|
+
* Success remains quiet by default — callers should emit these only on failure.
|
|
93
|
+
*/
|
|
94
|
+
declare const EVIDENCE_CI_ARTIFACT_FILES: readonly ["evidence.html", "evidence.json", "check-results.json", "trace.jsonl"];
|
|
95
|
+
type EvidenceCiArtifactFile = (typeof EVIDENCE_CI_ARTIFACT_FILES)[number];
|
|
96
|
+
/**
|
|
97
|
+
* Experimental helper: TraceArtifact entries for a standard Evidence v2 CI package.
|
|
98
|
+
*/
|
|
99
|
+
declare function createEvidenceCiArtifacts(options: {
|
|
100
|
+
redactionProfile?: TraceArtifactRedactionProfile;
|
|
101
|
+
/** Optional subdirectory under the test artifact folder (POSIX). */
|
|
102
|
+
relativeDir?: string;
|
|
103
|
+
}): TraceArtifact[];
|
|
90
104
|
|
|
91
|
-
export { type CreateReporterArtifactPathOptions, type CreateTraceArtifactManifestOptions, type ReporterArtifactPathResult, TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION, type TraceArtifact, type TraceArtifactFormat, type TraceArtifactKind, type TraceArtifactManifest, type TraceArtifactRedactionProfile, type TraceReporterDiagnostic, type TraceReporterDiagnosticCode, type TraceReporterDiagnosticSeverity, type TraceReporterFramework, type TraceTestResult, type TraceTestStatus, type ValidateReporterArtifactPathOptions, createReporterArtifactPath, createReporterFailureDiagnostic, createTraceArtifactManifest, validateReporterArtifactPath };
|
|
105
|
+
export { type CreateReporterArtifactPathOptions, type CreateTraceArtifactManifestOptions, EVIDENCE_CI_ARTIFACT_FILES, type EvidenceCiArtifactFile, type ReporterArtifactPathResult, TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION, type TraceArtifact, type TraceArtifactFormat, type TraceArtifactKind, type TraceArtifactManifest, type TraceArtifactRedactionProfile, type TraceReporterDiagnostic, type TraceReporterDiagnosticCode, type TraceReporterDiagnosticSeverity, type TraceReporterFramework, type TraceTestResult, type TraceTestStatus, type ValidateReporterArtifactPathOptions, createEvidenceCiArtifacts, createReporterArtifactPath, createReporterFailureDiagnostic, createTraceArtifactManifest, validateReporterArtifactPath };
|
|
@@ -169,7 +169,30 @@ function slugForPathLabel(value) {
|
|
|
169
169
|
const slug = base.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^[._-]+|[._-]+$/g, "").slice(0, 80);
|
|
170
170
|
return slug.length > 0 ? slug : "artifact";
|
|
171
171
|
}
|
|
172
|
+
var EVIDENCE_CI_ARTIFACT_FILES = [
|
|
173
|
+
"evidence.html",
|
|
174
|
+
"evidence.json",
|
|
175
|
+
"check-results.json",
|
|
176
|
+
"trace.jsonl"
|
|
177
|
+
];
|
|
178
|
+
function createEvidenceCiArtifacts(options) {
|
|
179
|
+
const profile = options.redactionProfile ?? "share";
|
|
180
|
+
const prefix = options.relativeDir !== void 0 && options.relativeDir.trim() !== "" ? options.relativeDir.replace(/\\/g, "/").replace(/^\/+|\/+$/g, "") : "";
|
|
181
|
+
const join = (name) => prefix === "" ? name : path.posix.join(prefix, name);
|
|
182
|
+
const formatFor = (name) => {
|
|
183
|
+
if (name.endsWith(".html")) return "html";
|
|
184
|
+
if (name.endsWith(".jsonl")) return "jsonl";
|
|
185
|
+
return "json";
|
|
186
|
+
};
|
|
187
|
+
return EVIDENCE_CI_ARTIFACT_FILES.map((name) => ({
|
|
188
|
+
kind: "evidence",
|
|
189
|
+
path: join(name),
|
|
190
|
+
format: formatFor(name),
|
|
191
|
+
redactionProfile: profile,
|
|
192
|
+
title: `Evidence v2 ${name}`
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
172
195
|
|
|
173
|
-
export { TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION, createReporterArtifactPath, createReporterFailureDiagnostic, createTraceArtifactManifest, validateReporterArtifactPath };
|
|
196
|
+
export { EVIDENCE_CI_ARTIFACT_FILES, TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION, createEvidenceCiArtifacts, createReporterArtifactPath, createReporterFailureDiagnostic, createTraceArtifactManifest, validateReporterArtifactPath };
|
|
174
197
|
//# sourceMappingURL=reporters.mjs.map
|
|
175
198
|
//# sourceMappingURL=reporters.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/reporters/index.ts"],"names":[],"mappings":"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","file":"reporters.mjs","sourcesContent":["import path from \"node:path\";\n\nexport const TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION = \"0.1\" as const;\n\n/** Experimental reporter framework identifier for local CI artifacts. */\nexport type TraceReporterFramework = \"vitest\" | \"jest\" | \"manual\";\n\n/** Experimental reporter test status normalized across supported test runners. */\nexport type TraceTestStatus = \"passed\" | \"failed\" | \"skipped\" | \"todo\";\n\n/** Experimental reporter artifact kind used in artifact manifests. */\nexport type TraceArtifactKind = \"trace\" | \"report\" | \"eval\" | \"redaction\" | \"summary\";\n\n/** Experimental reporter artifact file format used in artifact manifests. */\nexport type TraceArtifactFormat = \"json\" | \"jsonl\" | \"md\" | \"html\";\n\n/** Experimental redaction profile marker recorded with reporter artifacts. */\nexport type TraceArtifactRedactionProfile = \"local\" | \"share\" | \"strict\";\n\n/** Experimental reporter diagnostic severity. */\nexport type TraceReporterDiagnosticSeverity = \"info\" | \"warning\" | \"error\";\n\n/** Experimental reporter diagnostic code for safe, non-throwing reporter helpers. */\nexport type TraceReporterDiagnosticCode =\n | \"invalid_artifact_path\"\n | \"artifact_path_escape\"\n | \"artifact_path_empty\"\n | \"artifact_path_absolute\"\n | \"reporter_failure\";\n\n/** Experimental diagnostic emitted by reporter helpers instead of throwing. */\nexport interface TraceReporterDiagnostic {\n code: TraceReporterDiagnosticCode;\n severity: TraceReporterDiagnosticSeverity;\n message: string;\n target?: string;\n}\n\n/** Experimental manifest artifact entry shared by framework reporters. */\nexport interface TraceArtifact {\n kind: TraceArtifactKind;\n path: string;\n format: TraceArtifactFormat;\n redactionProfile: TraceArtifactRedactionProfile;\n title?: string;\n sizeBytes?: number;\n diagnostics?: TraceReporterDiagnostic[];\n}\n\n/** Experimental normalized test result entry shared by framework reporters. */\nexport interface TraceTestResult {\n testId: string;\n name: string;\n file?: string;\n status: TraceTestStatus;\n durationMs?: number;\n tracePath?: string;\n artifacts?: TraceArtifact[];\n diagnostics?: TraceReporterDiagnostic[];\n}\n\n/** Experimental reporter artifact manifest shared by framework reporters. */\nexport interface TraceArtifactManifest {\n schemaVersion: typeof TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION;\n generatedAt: string;\n framework: TraceReporterFramework;\n results: TraceTestResult[];\n artifacts: TraceArtifact[];\n diagnostics: TraceReporterDiagnostic[];\n}\n\n/** Experimental options for deterministic reporter artifact manifest creation. */\nexport interface CreateTraceArtifactManifestOptions {\n framework: TraceReporterFramework;\n generatedAt: string;\n results: TraceTestResult[];\n artifacts?: TraceArtifact[];\n diagnostics?: TraceReporterDiagnostic[];\n}\n\n/** Experimental options for deriving a safe reporter artifact path. */\nexport interface CreateReporterArtifactPathOptions {\n outputDir: string;\n testId: string;\n name: string;\n kind: TraceArtifactKind;\n format: TraceArtifactFormat;\n file?: string;\n}\n\n/** Experimental result from reporter artifact path validation/resolution. */\nexport interface ReporterArtifactPathResult {\n ok: boolean;\n outputDir: string;\n relativePath?: string;\n absolutePath?: string;\n diagnostics: TraceReporterDiagnostic[];\n}\n\nexport interface ValidateReporterArtifactPathOptions {\n outputDir: string;\n relativePath: string;\n}\n\nconst FORMAT_EXTENSIONS: Record<TraceArtifactFormat, string> = {\n json: \"json\",\n jsonl: \"jsonl\",\n md: \"md\",\n html: \"html\",\n};\n\nfunction sortDiagnostics(a: TraceReporterDiagnostic, b: TraceReporterDiagnostic): number {\n return compareStrings(a.target ?? \"\", b.target ?? \"\") ||\n compareStrings(a.code, b.code) ||\n compareStrings(a.severity, b.severity) ||\n compareStrings(a.message, b.message);\n}\n\nfunction sortArtifacts(a: TraceArtifact, b: TraceArtifact): number {\n return compareStrings(a.path, b.path) ||\n compareStrings(a.kind, b.kind) ||\n compareStrings(a.format, b.format) ||\n compareStrings(a.redactionProfile, b.redactionProfile) ||\n compareStrings(a.title ?? \"\", b.title ?? \"\");\n}\n\nfunction sortResults(a: TraceTestResult, b: TraceTestResult): number {\n return compareStrings(a.file ?? \"\", b.file ?? \"\") ||\n compareStrings(a.name, b.name) ||\n compareStrings(a.testId, b.testId);\n}\n\nfunction compareStrings(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\nfunction cloneDiagnostic(diagnostic: TraceReporterDiagnostic): TraceReporterDiagnostic {\n return {\n code: diagnostic.code,\n severity: diagnostic.severity,\n message: diagnostic.message,\n ...(diagnostic.target === undefined ? {} : { target: diagnostic.target }),\n };\n}\n\nfunction cloneArtifact(artifact: TraceArtifact): TraceArtifact {\n return {\n kind: artifact.kind,\n path: artifact.path,\n format: artifact.format,\n redactionProfile: artifact.redactionProfile,\n ...(artifact.title === undefined ? {} : { title: artifact.title }),\n ...(artifact.sizeBytes === undefined ? {} : { sizeBytes: artifact.sizeBytes }),\n diagnostics: (artifact.diagnostics ?? []).map(cloneDiagnostic).sort(sortDiagnostics),\n };\n}\n\nfunction cloneResult(result: TraceTestResult): TraceTestResult {\n return {\n testId: result.testId,\n name: result.name,\n ...(result.file === undefined ? {} : { file: result.file }),\n status: result.status,\n ...(result.durationMs === undefined ? {} : { durationMs: result.durationMs }),\n ...(result.tracePath === undefined ? {} : { tracePath: result.tracePath }),\n artifacts: (result.artifacts ?? []).map(cloneArtifact).sort(sortArtifacts),\n diagnostics: (result.diagnostics ?? []).map(cloneDiagnostic).sort(sortDiagnostics),\n };\n}\n\nfunction artifactIdentity(artifact: TraceArtifact): string {\n return `${artifact.path}\\0${artifact.kind}\\0${artifact.format}\\0${artifact.redactionProfile}`;\n}\n\nfunction dedupeArtifacts(artifacts: TraceArtifact[]): TraceArtifact[] {\n const seen = new Set<string>();\n const out: TraceArtifact[] = [];\n for (const artifact of artifacts.sort(sortArtifacts)) {\n const key = artifactIdentity(artifact);\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(artifact);\n }\n return out;\n}\n\n/** Experimental helper that creates a deterministic reporter artifact manifest. */\nexport function createTraceArtifactManifest(\n options: CreateTraceArtifactManifestOptions,\n): TraceArtifactManifest {\n const results = options.results.map(cloneResult).sort(sortResults);\n const resultArtifacts = results.flatMap((result) => result.artifacts ?? []);\n const artifacts = dedupeArtifacts([\n ...resultArtifacts,\n ...(options.artifacts ?? []).map(cloneArtifact),\n ]);\n\n return {\n schemaVersion: TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION,\n generatedAt: options.generatedAt,\n framework: options.framework,\n results,\n artifacts,\n diagnostics: (options.diagnostics ?? []).map(cloneDiagnostic).sort(sortDiagnostics),\n };\n}\n\n/** Experimental helper that creates a safe, deterministic artifact path for a test. */\nexport function createReporterArtifactPath(\n options: CreateReporterArtifactPathOptions,\n): ReporterArtifactPathResult {\n const fileSlug = slugForPathLabel(options.file ?? \"manual\");\n const testSlug = slugForPathLabel(`${options.name}-${options.testId}`);\n const relativePath = path.posix.join(\n \"tests\",\n fileSlug,\n testSlug,\n `${options.kind}.${FORMAT_EXTENSIONS[options.format]}`,\n );\n\n return validateReporterArtifactPath({\n outputDir: options.outputDir,\n relativePath,\n });\n}\n\n/** Experimental helper that validates an artifact path stays inside outputDir. */\nexport function validateReporterArtifactPath(\n options: ValidateReporterArtifactPathOptions,\n): ReporterArtifactPathResult {\n const outputDir = path.resolve(options.outputDir);\n const diagnostics: TraceReporterDiagnostic[] = [];\n const rawPath = options.relativePath;\n\n if (rawPath.length === 0) {\n diagnostics.push({\n code: \"artifact_path_empty\",\n severity: \"error\",\n message: \"Reporter artifact path must not be empty.\",\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n if (rawPath.includes(\"\\0\")) {\n diagnostics.push({\n code: \"invalid_artifact_path\",\n severity: \"error\",\n message: \"Reporter artifact path must not contain null bytes.\",\n target: rawPath,\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n if (path.isAbsolute(rawPath) || path.win32.isAbsolute(rawPath)) {\n diagnostics.push({\n code: \"artifact_path_absolute\",\n severity: \"error\",\n message: \"Reporter artifact path must be relative.\",\n target: rawPath,\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n const normalized = path.posix.normalize(rawPath.replace(/\\\\/g, \"/\"));\n const segments = normalized.split(\"/\");\n if (\n normalized === \".\" ||\n normalized.startsWith(\"../\") ||\n segments.some((segment) => segment === \"..\")\n ) {\n diagnostics.push({\n code: \"artifact_path_escape\",\n severity: \"error\",\n message: \"Reporter artifact path must stay under the output directory.\",\n target: rawPath,\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n const absolutePath = path.resolve(outputDir, normalized);\n const relFromOutput = path.relative(outputDir, absolutePath);\n if (\n relFromOutput.length === 0 ||\n relFromOutput.startsWith(\"..\") ||\n path.isAbsolute(relFromOutput)\n ) {\n diagnostics.push({\n code: \"artifact_path_escape\",\n severity: \"error\",\n message: \"Reporter artifact path resolved outside the output directory.\",\n target: rawPath,\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n return {\n ok: true,\n outputDir,\n relativePath: normalized,\n absolutePath,\n diagnostics,\n };\n}\n\n/** Experimental helper that converts an unknown reporter failure into a diagnostic. */\nexport function createReporterFailureDiagnostic(\n error: unknown,\n target?: string,\n): TraceReporterDiagnostic {\n const message = error instanceof Error\n ? error.message\n : typeof error === \"string\"\n ? error\n : \"Unknown reporter failure.\";\n\n return {\n code: \"reporter_failure\",\n severity: \"error\",\n message,\n ...(target === undefined ? {} : { target }),\n };\n}\n\nfunction slugForPathLabel(value: string): string {\n const base = path.basename(value)\n .replace(/\\.(test|spec)\\.[^.]+$/, \"\")\n .replace(/\\.[^.]+$/, \"\");\n const slug = base\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/^[._-]+|[._-]+$/g, \"\")\n .slice(0, 80);\n return slug.length > 0 ? slug : \"artifact\";\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/reporters/index.ts"],"names":[],"mappings":"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","file":"reporters.mjs","sourcesContent":["import path from \"node:path\";\n\nexport const TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION = \"0.1\" as const;\n\n/** Experimental reporter framework identifier for local CI artifacts. */\nexport type TraceReporterFramework = \"vitest\" | \"jest\" | \"manual\";\n\n/** Experimental reporter test status normalized across supported test runners. */\nexport type TraceTestStatus = \"passed\" | \"failed\" | \"skipped\" | \"todo\";\n\n/** Experimental reporter artifact kind used in artifact manifests. */\nexport type TraceArtifactKind = \"trace\" | \"report\" | \"eval\" | \"redaction\" | \"summary\" | \"evidence\";\n\n/** Experimental reporter artifact file format used in artifact manifests. */\nexport type TraceArtifactFormat = \"json\" | \"jsonl\" | \"md\" | \"html\";\n\n/** Experimental redaction profile marker recorded with reporter artifacts. */\nexport type TraceArtifactRedactionProfile = \"local\" | \"share\" | \"strict\";\n\n/** Experimental reporter diagnostic severity. */\nexport type TraceReporterDiagnosticSeverity = \"info\" | \"warning\" | \"error\";\n\n/** Experimental reporter diagnostic code for safe, non-throwing reporter helpers. */\nexport type TraceReporterDiagnosticCode =\n | \"invalid_artifact_path\"\n | \"artifact_path_escape\"\n | \"artifact_path_empty\"\n | \"artifact_path_absolute\"\n | \"reporter_failure\";\n\n/** Experimental diagnostic emitted by reporter helpers instead of throwing. */\nexport interface TraceReporterDiagnostic {\n code: TraceReporterDiagnosticCode;\n severity: TraceReporterDiagnosticSeverity;\n message: string;\n target?: string;\n}\n\n/** Experimental manifest artifact entry shared by framework reporters. */\nexport interface TraceArtifact {\n kind: TraceArtifactKind;\n path: string;\n format: TraceArtifactFormat;\n redactionProfile: TraceArtifactRedactionProfile;\n title?: string;\n sizeBytes?: number;\n diagnostics?: TraceReporterDiagnostic[];\n}\n\n/** Experimental normalized test result entry shared by framework reporters. */\nexport interface TraceTestResult {\n testId: string;\n name: string;\n file?: string;\n status: TraceTestStatus;\n durationMs?: number;\n tracePath?: string;\n artifacts?: TraceArtifact[];\n diagnostics?: TraceReporterDiagnostic[];\n}\n\n/** Experimental reporter artifact manifest shared by framework reporters. */\nexport interface TraceArtifactManifest {\n schemaVersion: typeof TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION;\n generatedAt: string;\n framework: TraceReporterFramework;\n results: TraceTestResult[];\n artifacts: TraceArtifact[];\n diagnostics: TraceReporterDiagnostic[];\n}\n\n/** Experimental options for deterministic reporter artifact manifest creation. */\nexport interface CreateTraceArtifactManifestOptions {\n framework: TraceReporterFramework;\n generatedAt: string;\n results: TraceTestResult[];\n artifacts?: TraceArtifact[];\n diagnostics?: TraceReporterDiagnostic[];\n}\n\n/** Experimental options for deriving a safe reporter artifact path. */\nexport interface CreateReporterArtifactPathOptions {\n outputDir: string;\n testId: string;\n name: string;\n kind: TraceArtifactKind;\n format: TraceArtifactFormat;\n file?: string;\n}\n\n/** Experimental result from reporter artifact path validation/resolution. */\nexport interface ReporterArtifactPathResult {\n ok: boolean;\n outputDir: string;\n relativePath?: string;\n absolutePath?: string;\n diagnostics: TraceReporterDiagnostic[];\n}\n\nexport interface ValidateReporterArtifactPathOptions {\n outputDir: string;\n relativePath: string;\n}\n\nconst FORMAT_EXTENSIONS: Record<TraceArtifactFormat, string> = {\n json: \"json\",\n jsonl: \"jsonl\",\n md: \"md\",\n html: \"html\",\n};\n\nfunction sortDiagnostics(a: TraceReporterDiagnostic, b: TraceReporterDiagnostic): number {\n return compareStrings(a.target ?? \"\", b.target ?? \"\") ||\n compareStrings(a.code, b.code) ||\n compareStrings(a.severity, b.severity) ||\n compareStrings(a.message, b.message);\n}\n\nfunction sortArtifacts(a: TraceArtifact, b: TraceArtifact): number {\n return compareStrings(a.path, b.path) ||\n compareStrings(a.kind, b.kind) ||\n compareStrings(a.format, b.format) ||\n compareStrings(a.redactionProfile, b.redactionProfile) ||\n compareStrings(a.title ?? \"\", b.title ?? \"\");\n}\n\nfunction sortResults(a: TraceTestResult, b: TraceTestResult): number {\n return compareStrings(a.file ?? \"\", b.file ?? \"\") ||\n compareStrings(a.name, b.name) ||\n compareStrings(a.testId, b.testId);\n}\n\nfunction compareStrings(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\nfunction cloneDiagnostic(diagnostic: TraceReporterDiagnostic): TraceReporterDiagnostic {\n return {\n code: diagnostic.code,\n severity: diagnostic.severity,\n message: diagnostic.message,\n ...(diagnostic.target === undefined ? {} : { target: diagnostic.target }),\n };\n}\n\nfunction cloneArtifact(artifact: TraceArtifact): TraceArtifact {\n return {\n kind: artifact.kind,\n path: artifact.path,\n format: artifact.format,\n redactionProfile: artifact.redactionProfile,\n ...(artifact.title === undefined ? {} : { title: artifact.title }),\n ...(artifact.sizeBytes === undefined ? {} : { sizeBytes: artifact.sizeBytes }),\n diagnostics: (artifact.diagnostics ?? []).map(cloneDiagnostic).sort(sortDiagnostics),\n };\n}\n\nfunction cloneResult(result: TraceTestResult): TraceTestResult {\n return {\n testId: result.testId,\n name: result.name,\n ...(result.file === undefined ? {} : { file: result.file }),\n status: result.status,\n ...(result.durationMs === undefined ? {} : { durationMs: result.durationMs }),\n ...(result.tracePath === undefined ? {} : { tracePath: result.tracePath }),\n artifacts: (result.artifacts ?? []).map(cloneArtifact).sort(sortArtifacts),\n diagnostics: (result.diagnostics ?? []).map(cloneDiagnostic).sort(sortDiagnostics),\n };\n}\n\nfunction artifactIdentity(artifact: TraceArtifact): string {\n return `${artifact.path}\\0${artifact.kind}\\0${artifact.format}\\0${artifact.redactionProfile}`;\n}\n\nfunction dedupeArtifacts(artifacts: TraceArtifact[]): TraceArtifact[] {\n const seen = new Set<string>();\n const out: TraceArtifact[] = [];\n for (const artifact of artifacts.sort(sortArtifacts)) {\n const key = artifactIdentity(artifact);\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(artifact);\n }\n return out;\n}\n\n/** Experimental helper that creates a deterministic reporter artifact manifest. */\nexport function createTraceArtifactManifest(\n options: CreateTraceArtifactManifestOptions,\n): TraceArtifactManifest {\n const results = options.results.map(cloneResult).sort(sortResults);\n const resultArtifacts = results.flatMap((result) => result.artifacts ?? []);\n const artifacts = dedupeArtifacts([\n ...resultArtifacts,\n ...(options.artifacts ?? []).map(cloneArtifact),\n ]);\n\n return {\n schemaVersion: TRACE_ARTIFACT_MANIFEST_SCHEMA_VERSION,\n generatedAt: options.generatedAt,\n framework: options.framework,\n results,\n artifacts,\n diagnostics: (options.diagnostics ?? []).map(cloneDiagnostic).sort(sortDiagnostics),\n };\n}\n\n/** Experimental helper that creates a safe, deterministic artifact path for a test. */\nexport function createReporterArtifactPath(\n options: CreateReporterArtifactPathOptions,\n): ReporterArtifactPathResult {\n const fileSlug = slugForPathLabel(options.file ?? \"manual\");\n const testSlug = slugForPathLabel(`${options.name}-${options.testId}`);\n const relativePath = path.posix.join(\n \"tests\",\n fileSlug,\n testSlug,\n `${options.kind}.${FORMAT_EXTENSIONS[options.format]}`,\n );\n\n return validateReporterArtifactPath({\n outputDir: options.outputDir,\n relativePath,\n });\n}\n\n/** Experimental helper that validates an artifact path stays inside outputDir. */\nexport function validateReporterArtifactPath(\n options: ValidateReporterArtifactPathOptions,\n): ReporterArtifactPathResult {\n const outputDir = path.resolve(options.outputDir);\n const diagnostics: TraceReporterDiagnostic[] = [];\n const rawPath = options.relativePath;\n\n if (rawPath.length === 0) {\n diagnostics.push({\n code: \"artifact_path_empty\",\n severity: \"error\",\n message: \"Reporter artifact path must not be empty.\",\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n if (rawPath.includes(\"\\0\")) {\n diagnostics.push({\n code: \"invalid_artifact_path\",\n severity: \"error\",\n message: \"Reporter artifact path must not contain null bytes.\",\n target: rawPath,\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n if (path.isAbsolute(rawPath) || path.win32.isAbsolute(rawPath)) {\n diagnostics.push({\n code: \"artifact_path_absolute\",\n severity: \"error\",\n message: \"Reporter artifact path must be relative.\",\n target: rawPath,\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n const normalized = path.posix.normalize(rawPath.replace(/\\\\/g, \"/\"));\n const segments = normalized.split(\"/\");\n if (\n normalized === \".\" ||\n normalized.startsWith(\"../\") ||\n segments.some((segment) => segment === \"..\")\n ) {\n diagnostics.push({\n code: \"artifact_path_escape\",\n severity: \"error\",\n message: \"Reporter artifact path must stay under the output directory.\",\n target: rawPath,\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n const absolutePath = path.resolve(outputDir, normalized);\n const relFromOutput = path.relative(outputDir, absolutePath);\n if (\n relFromOutput.length === 0 ||\n relFromOutput.startsWith(\"..\") ||\n path.isAbsolute(relFromOutput)\n ) {\n diagnostics.push({\n code: \"artifact_path_escape\",\n severity: \"error\",\n message: \"Reporter artifact path resolved outside the output directory.\",\n target: rawPath,\n });\n return { ok: false, outputDir, diagnostics };\n }\n\n return {\n ok: true,\n outputDir,\n relativePath: normalized,\n absolutePath,\n diagnostics,\n };\n}\n\n/** Experimental helper that converts an unknown reporter failure into a diagnostic. */\nexport function createReporterFailureDiagnostic(\n error: unknown,\n target?: string,\n): TraceReporterDiagnostic {\n const message = error instanceof Error\n ? error.message\n : typeof error === \"string\"\n ? error\n : \"Unknown reporter failure.\";\n\n return {\n code: \"reporter_failure\",\n severity: \"error\",\n message,\n ...(target === undefined ? {} : { target }),\n };\n}\n\nfunction slugForPathLabel(value: string): string {\n const base = path.basename(value)\n .replace(/\\.(test|spec)\\.[^.]+$/, \"\")\n .replace(/\\.[^.]+$/, \"\");\n const slug = base\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/^[._-]+|[._-]+$/g, \"\")\n .slice(0, 80);\n return slug.length > 0 ? slug : \"artifact\";\n}\n\n/**\n * Standard Evidence v2 filenames for CI failure packages (same shape as `bundle`).\n * Success remains quiet by default — callers should emit these only on failure.\n */\nexport const EVIDENCE_CI_ARTIFACT_FILES = [\n \"evidence.html\",\n \"evidence.json\",\n \"check-results.json\",\n \"trace.jsonl\",\n] as const;\n\nexport type EvidenceCiArtifactFile = (typeof EVIDENCE_CI_ARTIFACT_FILES)[number];\n\n/**\n * Experimental helper: TraceArtifact entries for a standard Evidence v2 CI package.\n */\nexport function createEvidenceCiArtifacts(options: {\n redactionProfile?: TraceArtifactRedactionProfile;\n /** Optional subdirectory under the test artifact folder (POSIX). */\n relativeDir?: string;\n}): TraceArtifact[] {\n const profile = options.redactionProfile ?? \"share\";\n const prefix =\n options.relativeDir !== undefined && options.relativeDir.trim() !== \"\"\n ? options.relativeDir.replace(/\\\\/g, \"/\").replace(/^\\/+|\\/+$/g, \"\")\n : \"\";\n const join = (name: string): string => (prefix === \"\" ? name : path.posix.join(prefix, name));\n\n const formatFor = (name: EvidenceCiArtifactFile): TraceArtifactFormat => {\n if (name.endsWith(\".html\")) return \"html\";\n if (name.endsWith(\".jsonl\")) return \"jsonl\";\n return \"json\";\n };\n\n return EVIDENCE_CI_ARTIFACT_FILES.map((name) => ({\n kind: \"evidence\" as const,\n path: join(name),\n format: formatFor(name),\n redactionProfile: profile,\n title: `Evidence v2 ${name}`,\n }));\n}\n"]}
|