import { createHash } from "node:crypto"; import type { FailureFingerprint } from "../types.js"; const pathNoise = /(?:\/Users\/|\/home\/|[A-Za-z]:\\)[^\s:]+/g; const lineNoise = /:\d+(?::\d+)?/g; const uuidNoise = /\b[0-9a-f]{8}-[0-9a-f-]{27}\b/gi; export function failureFingerprint(command: string, stdout: string, stderr: string): FailureFingerprint { const text = `${stdout}\n${stderr}`.replace(pathNoise, "").replace(lineNoise, ":").replace(uuidNoise, ""); const diagnostic = text.match(/(?:TS|ERR_|E)[A-Z0-9_]+\d+|AssertionError|TypeError|ReferenceError|SyntaxError|Error: [^\n]+/i)?.[0] ?? "command-failure"; const lines = text.split("\n").map((line) => line.trim()).filter((line) => line && !/^(?:#\s*)?duration_ms\s*:/i.test(line)).slice(0, 20); const components = [command.replace(/\s+/g, " ").trim(), diagnostic, ...lines]; return { hash: createHash("sha256").update(components.join("\n")).digest("hex"), class: diagnostic, components }; }