export interface TraceEventRow {
  rowId: string;
  seq: number | null;
  sequenceAuthority: TraceSequenceAuthority;
  tone: "ok" | "blocked" | "warn" | "source";
  toolState?: TraceToolState;
  statusLabel?: string;
  header: string;
  body: string | null;
  preview?: string | null;
  terminal?: boolean;
  bodyFormat?: "markdown" | "text";
}

export type TraceToolState = "running" | "success" | "failure" | "neutral";

export type TraceEvent = Record<string, unknown>;
type TraceClockFormatter = (value: string) => string;
export type TraceSequenceAuthority = "projected" | "source";
export type TraceFinalResponsePlacement = "trace" | "outer";

export interface TraceDisplayRowsOptions {
  formatClock?: TraceClockFormatter;
  finalResponsePlacement?: TraceFinalResponsePlacement;
  outerFinalResponseText?: string | null;
}

interface ResolvedTraceDisplayRowsOptions extends TraceDisplayRowsOptions {
  sequenceAuthority: TraceSequenceAuthority;
  finalResponsePlacement: TraceFinalResponsePlacement;
}

export function traceDisplayRows(trace: Record<string, unknown> = {}, events: TraceEvent[] = [], options: TraceDisplayRowsOptions = {}): TraceEventRow[] {
  const displayOptions: ResolvedTraceDisplayRowsOptions = {
    ...options,
    sequenceAuthority: traceSequenceAuthority(trace),
    finalResponsePlacement: options.finalResponsePlacement ?? "trace"
  };
  const orderedEvents = traceEventsForDisplay(
    events.filter((event) => hasTraceSequence(event, displayOptions.sequenceAuthority)),
    displayOptions.sequenceAuthority
  );
  const effectiveTrace = traceWithInferredStart(trace, orderedEvents);
  const finalResponseText = nonEmptyString(options.outerFinalResponseText) ?? traceFinalResponseText(effectiveTrace);
  const outerFinalAssistantEvent = displayOptions.finalResponsePlacement === "outer" && finalResponseText
    ? traceOuterFinalAssistantEvent(orderedEvents)
    : null;
  const hasCompletionEvent = orderedEvents.some(isCompletionTraceEvent);
  const rows: TraceEventRow[] = [];
  let completionEvent: TraceEvent | null = null;
  const renderedSourceEvents = new Set<string>();
  const renderedToolIdentities = new Set<string>();
  for (let index = 0; index < orderedEvents.length; index += 1) {
    const event = orderedEvents[index];
    const sourceEventKey = traceSourceEventKey(event);
    if (sourceEventKey) {
      if (renderedSourceEvents.has(sourceEventKey)) continue;
      renderedSourceEvents.add(sourceEventKey);
    }
    if (!event) continue;
    if (isSemanticRuntimePreparationEvent(event)) {
      rows.push(traceSemanticRuntimePreparationRow(event, displayOptions));
      continue;
    }
    if (isSemanticFailureRetryEvent(event)) {
      rows.push(traceSemanticFailureRetryRow(event, displayOptions));
      continue;
    }
    if (isNoisyTraceEvent(event)) continue;
    if (isSupersededTraceItemLifecycleEvent(event, orderedEvents, index)) continue;
    if (isToolTraceEvent(event)) {
      const identity = toolIdentity(event);
      if (identity) {
        if (renderedToolIdentities.has(identity)) continue;
        renderedToolIdentities.add(identity);
      }
      rows.push(traceToolCallRow(event, displayOptions));
      continue;
    }
    if (isDiffTraceEvent(event)) {
      rows.push(traceDiffRow(event, displayOptions));
      continue;
    }
    if (isRequestTraceEvent(event)) {
      continue;
    }
    if (isSetupTraceEvent(event)) {
      continue;
    }
    if (isTerminalAssistantTraceEvent(event)) {
      if (isOuterFinalResponseTraceEvent(event, displayOptions, outerFinalAssistantEvent)) continue;
      if (hasCompletionEvent) continue;
      if (finalResponseText) {
        rows.push(traceFinalResponseRow(event, finalResponseText, displayOptions));
      } else {
        rows.push(traceAssistantMessageRow(effectiveTrace, event, { terminal: true }, displayOptions));
      }
      continue;
    }
    if (isAssistantTraceEvent(event)) {
      if (isOuterFinalResponseTraceEvent(event, displayOptions, outerFinalAssistantEvent)) continue;
      rows.push(traceAssistantMessageRow(effectiveTrace, event, { terminal: false }, displayOptions));
      continue;
    }
    if (isCompletionTraceEvent(event)) {
      completionEvent ??= event;
      continue;
    }
    rows.push(traceDisplayRow(event, displayOptions));
  }
  if (completionEvent) rows.push(traceCompletionSummaryRow(completionEvent, displayOptions));
  const progressRow = traceBackendProgressSummaryRow(effectiveTrace, rows, orderedEvents, displayOptions);
  if (progressRow) rows.push(progressRow);
  if (rows.length > 0) return rows;
  if (orderedEvents.length === 0) return [];
  return orderedEvents
    .filter((event, index) => !isSupersededTraceItemLifecycleEvent(event, orderedEvents, index))
    .filter((event) => !isSuppressedTraceEvent(event))
    .filter((event) => !isOuterFinalResponseTraceEvent(event, displayOptions, outerFinalAssistantEvent))
    .map((event) => traceDisplayRow(event, displayOptions));
}

function isSemanticRuntimePreparationEvent(event: TraceEvent): boolean {
  const code = nonEmptyString(event.failureCode ?? event.code);
  return code === "git-mirror-fetch-in-progress" || code === "git-mirror-fetch-completed";
}

function traceSemanticRuntimePreparationRow(event: TraceEvent, options: ResolvedTraceDisplayRowsOptions): TraceEventRow {
  const eventKey = traceEventIdentityToken(event, options.sequenceAuthority);
  const code = nonEmptyString(event.failureCode ?? event.code);
  const completed = code === "git-mirror-fetch-completed";
  const attempt = numberOrNull(event.retryAttempt ?? event.attempt);
  const maxAttempts = numberOrNull(event.retryMaxAttempts ?? event.maxAttempts);
  const progress = attempt !== null && maxAttempts !== null ? `第 ${attempt}/${maxAttempts} 次` : "本次";
  const summary = nonEmptyString(event.summary ?? event.message) ?? (completed ? "Runner 源码获取完成" : "正在获取 Runner 源码");
  return {
    rowId: `event:runtime-preparation:${eventKey ?? code ?? "source-fetch"}`,
    seq: traceEventDisplaySeq(event, options.sequenceAuthority),
    sequenceAuthority: options.sequenceAuthority,
    tone: completed ? "ok" : "source",
    header: `${traceEventClock(event, options)} 运行环境准备 · ${completed ? "源码获取完成" : "源码获取中"}`.trim(),
    body: `${summary}\n${completed ? "正在启动 Runner" : `${progress}源码获取进行中`}`,
    bodyFormat: "text"
  };
}

function isSemanticFailureRetryEvent(event: TraceEvent): boolean {
  if (!nonEmptyString(event.failureDomain)) return false;
  const phase = normalizedRetryPhase(event.retryPhase);
  return phase.includes("scheduled")
    || phase.includes("exhausted")
    || phase.includes("recovered")
    || (phase.includes("retry") && phase.includes("started"));
}

function traceSemanticFailureRetryRow(event: TraceEvent, options: ResolvedTraceDisplayRowsOptions): TraceEventRow {
  const eventKey = traceEventIdentityToken(event, options.sequenceAuthority);
  const domain = nonEmptyString(event.failureDomain) === "upstream" ? "上游故障" : "基础设施故障";
  const phase = normalizedRetryPhase(event.retryPhase);
  const attempt = numberOrNull(event.retryAttempt ?? event.attempt);
  const maxAttempts = numberOrNull(event.retryMaxAttempts ?? event.maxAttempts);
  const backoffMs = numberOrNull(event.retryBackoffMs ?? event.backoffMs);
  const summary = nonEmptyString(event.summary ?? event.message) ?? "执行依赖暂时不可用";
  const retryProgress = attempt !== null && maxAttempts !== null ? `第 ${attempt}/${maxAttempts} 次` : null;
  const phaseText = phase.includes("exhausted")
    ? "有限重试已耗尽"
    : phase.includes("recovered")
      ? "故障已恢复"
      : phase.includes("started")
        ? `${retryProgress ? `${retryProgress}重试` : "重试"}已开始`
        : phase.includes("scheduled")
          ? `${retryProgress ? `${retryProgress}重试` : "重试"}已安排${backoffMs !== null ? `，退让 ${formatRetryDelay(backoffMs)}` : ""}`
          : "已观测";
  const details = [
    summary,
    nonEmptyString(event.failureComponent ?? event.component) ? `组件：${nonEmptyString(event.failureComponent ?? event.component)}` : null,
    nonEmptyString(event.failureCode ?? event.code) ? `代码：${nonEmptyString(event.failureCode ?? event.code)}` : null,
    nonEmptyString(event.nextRetryAt) ? `下次重试：${nonEmptyString(event.nextRetryAt)}` : null
  ].filter((value): value is string => Boolean(value));
  return {
    rowId: `event:semantic-retry:${eventKey ?? `${event.failureCode ?? event.code ?? "failure"}:${attempt ?? 0}:${phase}`}`,
    seq: traceEventDisplaySeq(event, options.sequenceAuthority),
    sequenceAuthority: options.sequenceAuthority,
    tone: phase.includes("exhausted") ? "blocked" : phase.includes("recovered") ? "ok" : "warn",
    header: `${traceEventClock(event, options)} ${domain} · ${phaseText}`.trim(),
    body: details.join("\n"),
    bodyFormat: "text",
    terminal: phase.includes("exhausted") ? true : undefined
  };
}

function normalizedRetryPhase(value: unknown): string {
  return String(value ?? "").trim().toLowerCase().replace(/[^a-z]/gu, "");
}

function formatRetryDelay(milliseconds: number): string {
  if (milliseconds < 1_000) return `${milliseconds} 毫秒`;
  const seconds = Math.ceil(milliseconds / 1_000);
  return seconds < 60 ? `${seconds} 秒` : `${Math.floor(seconds / 60)} 分 ${seconds % 60} 秒`;
}

function isOuterFinalResponseTraceEvent(
  event: TraceEvent,
  options: ResolvedTraceDisplayRowsOptions,
  outerFinalAssistantEvent: TraceEvent | null
): boolean {
  if (options.finalResponsePlacement !== "outer") return false;
  return event === outerFinalAssistantEvent;
}

function traceOuterFinalAssistantEvent(events: TraceEvent[]): TraceEvent | null {
  const visible = events
    .map((event, index) => ({ event, index }))
    .filter(({ event, index }) => isAssistantTraceEvent(event) && !traceAssistantLifecycleEventIsSuperseded(event, events, index));
  if (visible.length === 0) return null;
  const authoritative = [...visible].reverse().find(({ event }) => event.replyAuthority === true || event.final === true);
  if (authoritative) return authoritative.event;
  const seal = [...events].reverse().find((event) => event.finalSeal === true || nonEmptyString(event.label) === "agentrun:backend:assistant-message-final-sealed");
  if (seal) {
    const replyRef = isRecord(seal.replyRef) ? seal.replyRef : null;
    const itemId = nonEmptyString(replyRef?.itemId ?? seal.itemId);
    if (itemId) {
      const matched = [...visible].reverse().find(({ event }) => nonEmptyString(event.itemId) === itemId);
      if (matched) return matched.event;
    }
    const sealIndex = events.indexOf(seal);
    const preceding = [...visible].reverse().find(({ index }) => index < sealIndex);
    if (preceding) return preceding.event;
  }
  let terminalIndex = -1;
  for (let index = events.length - 1; index >= 0; index -= 1) {
    const event = events[index];
    if (!event || !(isCompletionTraceEvent(event) || event.terminal === true || event.eventType === "terminal" || event.type === "result")) continue;
    terminalIndex = index;
    break;
  }
  const precedingTerminal = terminalIndex >= 0 ? [...visible].reverse().find(({ index }) => index < terminalIndex) : null;
  return precedingTerminal?.event ?? visible.at(-1)?.event ?? null;
}

function traceSequenceAuthority(trace: Record<string, unknown>): TraceSequenceAuthority {
  return nonEmptyString(trace.eventSource) === "hwlab-kafka-sse" ? "source" : "projected";
}

function hasTraceSequence(event: TraceEvent | null | undefined, authority: TraceSequenceAuthority): boolean {
  return traceEventDisplaySeq(event, authority) !== null;
}

export function renderTraceRowsMarkdown(rows: TraceEventRow[] = []): string {
  if (!Array.isArray(rows) || rows.length === 0) return `_No rendered trace rows were returned._`;
  return rows.map((row, index) => renderTraceRowMarkdown(row, index + 1)).join("\n\n");
}

export function renderTraceRowMarkdown(row: TraceEventRow, index = 1): string {
  if (!isToolTraceRow(row)) return renderTraceMessageRowMarkdown(row);
  const body = renderTraceToolDetailBody(row) || row.header || `trace row ${index}`;
  const summary = traceToolSummary(row);
  const accessibleLabel = traceToolAccessibilityLabel(row);
  const visibleSummary = [
    `<code>${escapeHtml(row.header || `trace row ${index}`)}</code>`,
    summary ? escapeHtml(summary) : null
  ].filter(Boolean).join(" ");
  return [
    `- <details>`,
    `  <summary aria-label="${escapeHtmlAttribute(accessibleLabel)}" title="${escapeHtmlAttribute(accessibleLabel)}">${visibleSummary}</summary>`,
    ``,
    indentTraceMarkdownBlock(traceMarkdownFence(row.bodyFormat === "markdown" ? "markdown" : "text", body)),
    ``,
    `  </details>`
  ].join("\n");
}

function renderTraceMessageRowMarkdown(row: TraceEventRow): string {
  const body = row.body?.trimEnd();
  if (body) return traceBoldMarkdown(body);
  return traceBoldMarkdown(row.header || `_No readable trace row body._`);
}

function traceEventsForDisplay(events: TraceEvent[] = [], authority: TraceSequenceAuthority): TraceEvent[] {
  if (authority === "source") return [...events];
  return [...events].sort((left, right) => {
    const leftSeq = traceEventDisplaySeq(left, authority);
    const rightSeq = traceEventDisplaySeq(right, authority);
    if (leftSeq !== null || rightSeq !== null) {
      if (leftSeq === null) return 1;
      if (rightSeq === null) return -1;
      if (leftSeq !== rightSeq) return leftSeq - rightSeq;
    }
    const leftTime = traceEventTimestampMs(left);
    const rightTime = traceEventTimestampMs(right);
    if (leftTime !== null || rightTime !== null) {
      if (leftTime === null) return 1;
      if (rightTime === null) return -1;
      if (leftTime !== rightTime) return leftTime - rightTime;
    }
    return 0;
  });
}

function traceEventDisplaySeq(event: TraceEvent | null | undefined, authority: TraceSequenceAuthority): number | null {
  return numberOrNull(authority === "source" ? event?.sourceSeq : event?.projectedSeq);
}

function traceEventIdentityToken(event: TraceEvent, authority: TraceSequenceAuthority): string | number | null {
  if (authority === "source") {
    const sourceEventId = nonEmptyString(event.sourceEventId);
    if (sourceEventId) return sourceEventId;
    const runId = nonEmptyString(event.runId);
    const sourceSeq = traceEventDisplaySeq(event, authority);
    if (runId && sourceSeq !== null) return `${runId}:${sourceSeq}`;
    return sourceSeq;
  }
  const seq = traceEventDisplaySeq(event, authority);
  return seq ?? nonEmptyString(event.projectedSeq);
}

function isToolTraceRow(row: TraceEventRow): boolean {
  return row.rowId.startsWith("tool:") || /commandExecution/u.test(row.header);
}

export function traceToolSummary(row: TraceEventRow): string {
  if (row.preview) return compactTraceOneLine(row.preview, 140);
  const firstLine = traceMarkdownPreviewLines(row.body).find((line) => !/^(stdout|stderr|exitCode|rowId|terminal):/iu.test(line.trim()));
  return compactTraceOneLine(stripTraceToolOutputFromSummary(firstLine || row.header || "tool call"), 140);
}

export function traceToolAccessibilityLabel(row: TraceEventRow): string {
  const statusLabel = row.statusLabel ?? traceToolStatusLabel(traceToolStateFromTone(row.tone));
  return `${statusLabel}：${[row.header, traceToolSummary(row)].filter(Boolean).join("；")}`;
}

function stripTraceToolOutputFromSummary(value: string): string {
  return value.replace(/\s+(stdout:|stderr:|exitCode=).*$/isu, "").trim();
}

function traceToolCallRow(event: TraceEvent, options: ResolvedTraceDisplayRowsOptions): TraceEventRow {
  const command = cleanShellCommand(event.command);
  const toolState = traceToolState(event);
  const toolName = traceToolName(event, command);
  const fileChange = isFileChangeTraceEvent(event);
  const body = fileChange ? traceFileChangeBody(event) : traceToolCallBody(event, command);
  const eventKey = traceEventIdentityToken(event, options.sequenceAuthority);
  return {
    rowId: `tool:${event.itemId ?? eventKey ?? `${event.label ?? event.type ?? "tool"}:${event.createdAt ?? "unknown"}`}`,
    seq: traceEventDisplaySeq(event, options.sequenceAuthority),
    sequenceAuthority: options.sequenceAuthority,
    tone: traceEventTone(event),
    toolState,
    statusLabel: traceToolStatusLabel(toolState),
    header: traceEventClock(event, options),
    body,
    preview: fileChange ? traceFileChangePreview(event) : traceToolPreview(command, toolName),
    bodyFormat: fileChange && body ? "markdown" : "text"
  };
}

function isFileChangeTraceEvent(event: TraceEvent): boolean {
  return nonEmptyString(event.toolName ?? event.toolType) === "fileChange";
}

function traceFileChangePreview(event: TraceEvent): string {
  const summary = traceDiffSummary(traceDiffFiles(event));
  return compactTraceOneLine(summary ?? "fileChange", 140);
}

function traceFileChangeBody(event: TraceEvent): string | null {
  return traceDiffMarkdown(traceDiffFiles(event));
}

function isDiffTraceEvent(event: TraceEvent): boolean {
  return event.type === "diff" || event.eventType === "diff" || nonEmptyString(event.label) === "agentrun:diff";
}

function traceDiffRow(event: TraceEvent, options: ResolvedTraceDisplayRowsOptions): TraceEventRow {
  const eventKey = traceEventIdentityToken(event, options.sequenceAuthority);
  const files = traceDiffFiles(event);
  const diff = nonEmptyString(event.diff ?? event.message);
  return {
    rowId: `tool:diff:${eventKey ?? event.createdAt ?? "updated"}`,
    seq: traceEventDisplaySeq(event, options.sequenceAuthority),
    sequenceAuthority: options.sequenceAuthority,
    tone: traceEventTone(event),
    toolState: "success",
    statusLabel: "文件 diff 已更新",
    header: traceEventClock(event, options),
    body: traceDiffMarkdown(files) ?? diff,
    preview: traceDiffSummary(files) ?? "turn/diff/updated",
    bodyFormat: files.length > 0 ? "markdown" : "text"
  };
}

interface TraceDiffFile {
  path: string | null;
  kind: string | null;
  diff: string;
  additions: number;
  deletions: number;
}

function traceDiffFiles(event: TraceEvent): TraceDiffFile[] {
  const changes = (Array.isArray(event.changes) ? event.changes : []).filter(isRecord);
  if (changes.length > 0) {
    return changes.map((change) => traceDiffFile(
      traceDiffPath(nonEmptyString(change.path)),
      traceDiffKind(change.kind),
      traceDiffText(change.diff) ?? "",
      numberOrNull(change.additions),
      numberOrNull(change.deletions)
    ));
  }
  const diff = traceDiffText(event.diff ?? event.message);
  return diff ? traceUnifiedDiffFiles(diff) : [];
}

function traceDiffText(value: unknown): string | null {
  if (typeof value !== "string") return null;
  const text = value.trim();
  return text && text !== "[object Object]" ? value : null;
}

function traceUnifiedDiffFiles(diff: string): TraceDiffFile[] {
  const sections: Array<{ path: string | null; lines: string[] }> = [];
  let current: { path: string | null; lines: string[] } = { path: null, lines: [] };
  const flush = () => {
    if (current.lines.length === 0) return;
    sections.push(current);
  };
  for (const line of diff.replace(/\r\n|\r/gu, "\n").split("\n")) {
    if (line.startsWith("diff --git ") && current.lines.length > 0) {
      flush();
      current = { path: null, lines: [] };
    }
    current.lines.push(line);
    if (line.startsWith("+++ ")) current.path = traceDiffHeaderPath(line.slice(4)) ?? current.path;
    if (line.startsWith("rename to ")) current.path = line.slice("rename to ".length).trim() || current.path;
  }
  flush();
  return sections.map((section) => traceDiffFile(section.path, null, section.lines.join("\n")));
}

function traceDiffHeaderPath(value: string): string | null {
  const path = value.trim().replace(/^"|"$/gu, "");
  if (!path || path === "/dev/null") return null;
  return traceDiffPath(path.startsWith("b/") ? path.slice(2) : path);
}

function traceDiffFile(path: string | null, kind: string | null, diff: string, additionsHint: number | null = null, deletionsHint: number | null = null): TraceDiffFile {
  const normalizedDiff = traceNormalizedFileDiff(path, kind, diff);
  let additions = 0;
  let deletions = 0;
  for (const line of normalizedDiff.replace(/\r\n|\r/gu, "\n").split("\n")) {
    if (line.startsWith("+") && !line.startsWith("+++")) additions += 1;
    if (line.startsWith("-") && !line.startsWith("---")) deletions += 1;
  }
  if (!normalizedDiff) {
    additions = additionsHint ?? additions;
    deletions = deletionsHint ?? deletions;
  }
  return { path, kind, diff: normalizedDiff, additions, deletions };
}

function traceDiffKind(value: unknown): string | null {
  if (isRecord(value)) return nonEmptyString(value.type ?? value.kind);
  return nonEmptyString(value);
}

function traceDiffPath(value: string | null): string | null {
  if (!value) return null;
  const marker = "/agentrun-workspace/";
  const markerIndex = value.indexOf(marker);
  return markerIndex >= 0 ? value.slice(markerIndex + marker.length) : value;
}

function traceNormalizedFileDiff(path: string | null, kind: string | null, diff: string): string {
  const normalized = diff.replace(/\r\n|\r/gu, "\n");
  if (!normalized || /^(?:diff --git |@@ |--- |\+\+\+ )/mu.test(normalized)) return normalized;
  const lines = normalized.endsWith("\n") ? normalized.slice(0, -1).split("\n") : normalized.split("\n");
  if (kind === "add" || kind === "added" || kind === "create") {
    return [`--- /dev/null`, `+++ b/${path ?? "file"}`, `@@ -0,0 +1,${lines.length} @@`, ...lines.map((line) => `+${line}`)].join("\n");
  }
  if (kind === "delete" || kind === "deleted" || kind === "remove") {
    return [`--- a/${path ?? "file"}`, `+++ /dev/null`, `@@ -1,${lines.length} +0,0 @@`, ...lines.map((line) => `-${line}`)].join("\n");
  }
  return normalized;
}

function traceDiffSummary(files: TraceDiffFile[]): string | null {
  if (files.length === 0) return null;
  const additions = files.reduce((total, file) => total + file.additions, 0);
  const deletions = files.reduce((total, file) => total + file.deletions, 0);
  const paths = files.map((file) => file.path).filter((path): path is string => Boolean(path));
  const stats = `+${additions} -${deletions}`;
  if (files.length === 1) return `${paths[0] ?? "文件变更"} · ${stats}`;
  const visiblePaths = paths.slice(0, 2).join(", ");
  const remaining = Math.max(0, paths.length - 2);
  const pathSummary = visiblePaths ? ` · ${visiblePaths}${remaining > 0 ? ` 等 ${paths.length} 个文件` : ""}` : "";
  return `${files.length} 个文件 · ${stats}${pathSummary}`;
}

function traceDiffMarkdown(files: TraceDiffFile[]): string | null {
  if (files.length === 0) return null;
  return files.map((file, index) => {
    const title = traceMarkdownInlineCode(file.path ?? `文件变更 ${index + 1}`);
    const kind = traceDiffKindLabel(file.kind);
    const stats = `${kind} · +${file.additions} -${file.deletions}`;
    const diff = file.diff.trimEnd();
    return [`#### ${title}`, stats, diff ? traceMarkdownCodeFence("diff", diff) : "无可显示 diff"].join("\n\n");
  }).join("\n\n");
}

function traceDiffKindLabel(value: string | null): string {
  if (value === "add" || value === "added" || value === "create") return "新增";
  if (value === "delete" || value === "deleted" || value === "remove") return "删除";
  if (value === "rename" || value === "renamed") return "重命名";
  return "修改";
}

function traceMarkdownInlineCode(value: string): string {
  const text = value.replace(/\r\n|\r|\n/gu, " ").trim();
  const longestRun = Math.max(0, ...([...text.matchAll(/`+/gu)].map((match) => match[0].length)));
  const fence = "`".repeat(longestRun + 1);
  return `${fence}${text}${fence}`;
}

function traceMarkdownCodeFence(language: string, body: string): string {
  const longestRun = Math.max(0, ...([...body.matchAll(/`+/gu)].map((match) => match[0].length)));
  const fence = "`".repeat(Math.max(3, longestRun + 1));
  return `${fence}${language}\n${body}\n${fence}`;
}

function traceToolPreview(command: string | null, fallbackToolName: string): string {
  return compactTraceOneLine(command ?? fallbackToolName, 140);
}

function traceToolName(event: TraceEvent, command: string | null): string {
  const direct = nonEmptyString(event.toolName);
  if (direct && !isProtocolToolLifecycleName(direct) && !isGenericToolName(direct)) return direct;
  const label = String(event.label ?? "")
    .replace(/^agentrun:tool:/u, "")
    .replace(/^tool:/u, "")
    .replace(/^item\//u, "")
    .replace(/\/outputDelta$/iu, "")
    .replace(/:(?:started|running|completed|succeeded|failed|blocked|error|timeout|canceled|cancelled)$/iu, "");
  if (label && !isProtocolToolLifecycleName(label) && !isGenericToolName(label)) return label;
  const commandName = traceToolNameFromCommand(command);
  if (commandName) return commandName;
  if (direct && !isProtocolToolLifecycleName(direct)) return direct;
  const previewName = traceToolNameFromPreview(event);
  if (previewName) return previewName;
  return "tool call";
}

function isGenericToolName(value: unknown): boolean {
  return /^(commandExecution|tool|tool_call|tool-call|shell|command|unknown)$/iu.test(String(value ?? "").trim());
}

function isProtocolToolLifecycleName(value: unknown): boolean {
  return /^(?:item\/)?(?:started|running|completed|succeeded|failed|blocked|error|timeout|canceled|cancelled)$/iu.test(String(value ?? "").trim());
}

function traceToolNameFromCommand(command: string | null): string | null {
  const text = cleanTraceText(command);
  const segments = text.split(/\s*(?:&&|\|\||;)\s*/u).map((value) => value.trim()).filter(Boolean);
  const candidate = segments.find((value) => !/^(?:cd|export|set|source|umask)\b/u.test(value)) ?? segments[0] ?? text;
  const normalized = candidate
    .replace(/^(?:[A-Za-z_][A-Za-z0-9_]*=[^\s]+\s+)+/u, "")
    .replace(/^(?:sudo\s+|env\s+|command\s+)+/u, "")
    .replace(/^timeout\s+\S+\s+/u, "");
  const match = normalized.match(/^([A-Za-z./][A-Za-z0-9_./:-]{0,80})(?:\s|$)/u);
  return match?.[1]?.split("/").filter(Boolean).at(-1) ?? null;
}

function traceToolNameFromPreview(event: TraceEvent): string | null {
  const preview = traceEventText(event, ["output", "outputText", "outputSummary", "stdoutSummary", "message"]);
  return jsonPreviewStringField(preview, "toolName") ?? jsonPreviewStringField(preview, "type") ?? jsonPreviewStringField(preview, "name");
}

function jsonPreviewStringField(text: string | null, key: string): string | null {
  const body = String(text ?? "");
  if (!body || !/^[A-Za-z][A-Za-z0-9_]*$/u.test(key)) return null;
  const match = body.match(new RegExp(`"${key}"\\s*:\\s*"((?:\\\\.|[^"\\\\])*)"`, "u"));
  if (!match) return null;
  try {
    const parsed = JSON.parse(`"${match[1]}"`);
    return typeof parsed === "string" && parsed.trim() ? parsed.trim() : null;
  } catch {
    return match[1]?.trim() || null;
  }
}

function traceToolCallBody(event: TraceEvent, command: string | null): string | null {
  const stdout = traceEventText(event, ["stdout", "stdoutText", "stdoutSummary"]);
  const stderr = traceEventText(event, ["stderr", "stderrText", "stderrSummary"]);
  const output = traceEventText(event, ["output", "outputText", "outputSummary"]);
  const distinctOutput = output && output !== stdout && output !== stderr ? output : null;
  const outputBytes = numberOrNull(event.outputBytes);
  const lines = [
    command,
    traceDetailBlock("stdout", stdout),
    traceDetailBlock("stderr", stderr),
    traceDetailBlock("output", distinctOutput),
    event.commandTruncated === true ? "commandTruncated=true" : null,
    outputBytes !== null ? `outputBytes=${outputBytes}` : null,
    event.outputTruncated === true ? "outputTruncated=true" : null,
    event.exitCode !== undefined ? `exitCode=${event.exitCode}` : null
  ].map(cleanTraceDetailText).filter(Boolean);
  return lines.length > 0 ? lines.join("\n") : null;
}

export function traceNoiseEventCount(events: TraceEvent[] = []): number {
  return Array.isArray(events) ? events.filter((event) => isNoisyTraceEvent(event)).length : 0;
}

function traceAssistantMessageRow(trace: Record<string, unknown>, event: TraceEvent, { terminal }: { terminal: boolean }, options: ResolvedTraceDisplayRowsOptions): TraceEventRow {
  const text = traceAssistantEventText(trace, event);
  const index = Number.isInteger(event.messageIndex) ? Number(event.messageIndex) : null;
  const count = Number.isInteger(event.messageCount) ? Number(event.messageCount) : null;
  const eventKey = traceEventIdentityToken(event, options.sequenceAuthority);
  return {
    rowId: `event:${eventKey ?? `${event.label ?? event.type ?? "assistant"}:${event.createdAt ?? "unknown"}`}`,
    seq: traceEventDisplaySeq(event, options.sequenceAuthority),
    sequenceAuthority: options.sequenceAuthority,
    tone: "ok",
    header: `${traceEventClock(event, options)}  ${terminal ? "助手最终消息" : "助手消息"}${index ? ` ${index}${count ? `/${count}` : ""}` : ""}`,
    terminal: terminal ? true : undefined,
    body: text || null,
    bodyFormat: "markdown"
  };
}

function traceAssistantEventText(trace: Record<string, unknown>, event: TraceEvent): string {
  return cleanTraceDetailText(event.message ?? event.outputSummary ?? assistantStreamText(trace, event) ?? "");
}

function traceFinalResponseRow(event: TraceEvent, finalText: string, options: ResolvedTraceDisplayRowsOptions): TraceEventRow {
  const eventKey = traceEventIdentityToken(event, options.sequenceAuthority);
  return {
    rowId: `trace-final-response:${eventKey ?? "completed"}`,
    seq: traceEventDisplaySeq(event, options.sequenceAuthority),
    sequenceAuthority: options.sequenceAuthority,
    tone: "ok",
    header: `${traceEventClock(event, options)}  助手最终消息`,
    terminal: true,
    body: finalText,
    bodyFormat: "markdown"
  };
}

function traceFinalResponseText(trace: Record<string, unknown>): string | null {
  const response = trace.finalResponse && typeof trace.finalResponse === "object" ? trace.finalResponse as Record<string, unknown> : null;
  return nonEmptyString(response?.text ?? response?.content ?? response?.message);
}

function traceCompletionSummaryRow(event: TraceEvent, options: ResolvedTraceDisplayRowsOptions): TraceEventRow {
  const eventKey = traceEventIdentityToken(event, options.sequenceAuthority);
  return {
    rowId: `trace-completion:${eventKey ?? "turn"}`,
    seq: traceEventDisplaySeq(event, options.sequenceAuthority),
    sequenceAuthority: options.sequenceAuthority,
    tone: traceEventTone(event),
    header: `${traceEventClock(event, options)}  轮次完成`,
    body: null
  };
}

function traceNoiseSummaryRow(trace: Record<string, unknown>, events: TraceEvent[], options: ResolvedTraceDisplayRowsOptions): TraceEventRow {
  const lastEvent = events.at(-1);
  const status = nonEmptyString(trace.status ?? trace.traceStatus) ?? "running";
  const lastLabel = lastEvent ? readableTraceLabel(lastEvent) : "未观测";
  return {
    rowId: "trace-noise-summary",
    seq: traceEventDisplaySeq(lastEvent, options.sequenceAuthority),
    sequenceAuthority: options.sequenceAuthority,
    tone: lastEvent ? traceEventTone(lastEvent) : "source",
    header: `Trace ${status}，等待可读事件`,
    body: `已隐藏 ${events.length} 条 AgentRun backend 状态事件。最新原始事件：${lastLabel}。`,
    bodyFormat: "text"
  };
}

function traceBackendProgressSummaryRow(trace: Record<string, unknown>, rows: TraceEventRow[], events: TraceEvent[], options: ResolvedTraceDisplayRowsOptions): TraceEventRow | null {
  if (!Array.isArray(events) || events.length === 0) return null;
  if (rows.some((row) => row.rowId.startsWith("tool:") || /助手|轮次完成/u.test(row.header))) return null;
  const lastRenderedSeq = Math.max(0, ...rows.map((row) => row.seq ?? 0).filter(Number.isFinite));
  const hiddenProgress = events.filter((event) => {
    const seq = traceEventDisplaySeq(event, options.sequenceAuthority) ?? 0;
    return seq > lastRenderedSeq && (isRequestTraceEvent(event) || isSetupTraceEvent(event) || isNoisyTraceEvent(event));
  });
  return hiddenProgress.length > 0 ? traceNoiseSummaryRow(trace, hiddenProgress, options) : null;
}

function traceDisplayRow(event: TraceEvent, options: ResolvedTraceDisplayRowsOptions): TraceEventRow {
  const label = readableTraceLabel(event);
  const eventKey = traceEventIdentityToken(event, options.sequenceAuthority);
  return {
    rowId: `event:${eventKey ?? `${event.label ?? event.type ?? "event"}:${event.createdAt ?? "unknown"}`}`,
    seq: traceEventDisplaySeq(event, options.sequenceAuthority),
    sequenceAuthority: options.sequenceAuthority,
    tone: traceEventTone(event),
    header: `${traceEventClock(event, options)} ${label}`.trim(),
    body: traceDisplayBody(event)
  };
}

function assistantStreamText(trace: Record<string, unknown>, event: TraceEvent): string {
  const streams = Array.isArray(trace.assistantStreams) ? trace.assistantStreams.filter(isRecord) : [];
  const itemId = nonEmptyString(event.itemId ?? event.messageId ?? event.id);
  const matched = itemId ? streams.find((stream) => [stream.itemId, stream.messageId, stream.id].map(nonEmptyString).includes(itemId)) : null;
  return nonEmptyString(matched?.text ?? streams.at(-1)?.text) ?? "";
}

function isRequestTraceEvent(event: TraceEvent): boolean {
  const label = String(event.label ?? "");
  return label === "agentrun:request:accepted" || label === "request:accepted-short-connection" || label === "request:accepted" || label === "request:received";
}

function isSetupTraceEvent(event: TraceEvent): boolean {
  const label = String(event.label ?? "");
  return /^session:|^stdio:|^prompt:|^thread:|^turn:started|^turn:start|turn\/start|codex turn|tool:codex-app-server/iu.test(label) ||
    /^agentrun:backend:(codex-app-server-starting|initialize:completed|thread\/start|thread\/resume|thread\/started|turn\/start|turn\/started)/iu.test(label) ||
    /^agentrun:run:(reuse-skipped|reused)$/iu.test(label) ||
    /^agentrun:command:created$/iu.test(label) ||
    /^agentrun:runner-job:(created|ensured|reused)$/iu.test(label) ||
    /^agentrun:session-storage-recover-warning$/iu.test(label);
}

function isCompletionTraceEvent(event: TraceEvent): boolean {
  const label = String(event.label ?? "");
  return label.startsWith("turn:completed") || label.startsWith("result:completed") || label === "agentrun:backend:turn/completed" || label === "agentrun:terminal:completed" || label === "agentrun:result:completed";
}

function isAssistantTraceEvent(event: TraceEvent): boolean {
  const label = String(event.label ?? "");
  return label === "agentrun:assistant:message"
    || label === "agentrun:assistant:progress"
    || label === "assistant:message"
    || event.type === "assistant_progress"
    || event.eventType === "assistant_progress"
    || event.type === "assistant_message"
    || event.type === "assistant";
}

function isTerminalAssistantTraceEvent(event: TraceEvent): boolean {
  const label = String(event.label ?? "");
  if (label === "assistant:completed") return true;
  if (label === "agentrun:assistant:message") return event.replyAuthority === true || event.final === true;
  return event.type === "assistant_message" && (event.status === "completed" || event.final === true || event.terminal === true);
}

function isToolTraceEvent(event: TraceEvent): boolean {
  const label = String(event.label ?? "");
  const type = String(event.type ?? "");
  const toolName = String(event.toolName ?? "");
  return type === "tool_call" || toolName === "commandExecution" || /commandExecution|^agentrun:tool:/u.test(label);
}

function isToolStartTraceEvent(event: TraceEvent): boolean {
  const status = String(event.status ?? "").toLowerCase();
  const label = String(event.label ?? "");
  return ["started", "running", "inprogress", "in-progress", "output_chunk"].includes(status) || /:started$|\/started$/u.test(label);
}

function isToolCompleteTraceEvent(event: TraceEvent): boolean {
  const status = String(event.status ?? "").toLowerCase();
  const label = String(event.label ?? "");
  return ["completed", "succeeded", "failed", "blocked", "timeout", "canceled", "cancelled"].includes(status) || /:completed$|\/completed$/u.test(label);
}

function toolIdentity(event: TraceEvent): string | null {
  return nonEmptyString(event.itemId ?? event.id ?? event.command);
}

function traceSourceEventKey(event: TraceEvent | null | undefined): string | null {
  if (!event || typeof event !== "object") return null;
  const sourceEventId = nonEmptyString(event.sourceEventId);
  if (sourceEventId) return `source-event:${sourceEventId}`;
  const runId = nonEmptyString(event.runId);
  const sourceSeq = nonEmptyString(event.sourceSeq);
  if (runId && sourceSeq) return `run-source:${runId}:${sourceSeq}`;
  const source = nonEmptyString(event.source);
  if (!source || !sourceSeq) return null;
  return `${source}:${sourceSeq}:${nonEmptyString(event.label ?? event.type) ?? "event"}`;
}

function isSupersededTraceItemLifecycleEvent(event: TraceEvent, events: TraceEvent[], index: number): boolean {
  return isSupersededToolStart(event, events, index) || traceAssistantLifecycleEventIsSuperseded(event, events, index);
}

function isSupersededToolStart(event: TraceEvent, events: TraceEvent[], index: number): boolean {
  if (!isToolStartTraceEvent(event)) return false;
  const identity = toolIdentity(event);
  if (!identity) return false;
  return events.slice(index + 1).some((candidate) => candidate && isToolTraceEvent(candidate) && isToolCompleteTraceEvent(candidate) && toolIdentity(candidate) === identity);
}

export function traceAssistantLifecycleEventIsSuperseded(event: TraceEvent, events: TraceEvent[], index: number): boolean {
  if (!isAssistantTraceEvent(event)) return false;
  const identity = nonEmptyString(event.itemId);
  if (!identity) return false;
  const rank = traceAssistantLifecycleRank(event);
  const sequence = traceAssistantLifecycleSequence(event);
  return events.some((candidate, candidateIndex) => {
    if (candidateIndex === index || !candidate || !isAssistantTraceEvent(candidate) || nonEmptyString(candidate.itemId) !== identity) return false;
    const candidateRank = traceAssistantLifecycleRank(candidate);
    if (candidateRank !== rank) return candidateRank > rank;
    const candidateSequence = traceAssistantLifecycleSequence(candidate);
    if (sequence !== null && candidateSequence !== null && candidateSequence !== sequence) return candidateSequence > sequence;
    return candidateIndex > index;
  });
}

function traceAssistantLifecycleRank(event: TraceEvent): number {
  if (event.replyAuthority === true || event.final === true) return 3;
  if (traceAssistantLifecycleProgress(event)) return 1;
  return 2;
}

function traceAssistantLifecycleProgress(event: TraceEvent): boolean {
  return event.progress === true
    || event.type === "assistant_progress"
    || event.eventType === "assistant_progress"
    || nonEmptyString(event.label) === "agentrun:assistant:progress"
    || nonEmptyString(event.assistantSource) === "agent-message-delta-progress";
}

function traceAssistantLifecycleSequence(event: TraceEvent): number | null {
  return numberOrNull(event.sourceSeq ?? event.projectedSeq ?? event.seq);
}

function isNoisyTraceEvent(event: TraceEvent): boolean {
  const label = String(event.label ?? "");
  if (isRequestTraceEvent(event) || isSetupTraceEvent(event) || isCompletionTraceEvent(event) || isTerminalAssistantTraceEvent(event) || isAssistantTraceEvent(event)) return false;
  if (/^agentrun:backend:/u.test(label) && !event.errorCode) return true;
  if (/token_count|outputDelta:chunk/iu.test(label)) return true;
  if (/^agentrun:output:(stdout|stderr)$/u.test(label)) return true;
  if (/^agentrun:backend:(run-created|command-created|runner-job-created|thread\/status\/changed|thread\/tokenUsage\/updated|account\/rateLimits\/updated|remoteControl\/status\/changed|configWarning|codex-app-server-closed|codex-app-server-notifications-suppressed|session-updated|command-terminal|backend-turn-finished|item\/agentMessage:(started|completed)|thread\/goal\/cleared)$/u.test(label)) return true;
  return event.type === "event" && !event.outputSummary && !event.message && !event.errorCode;
}

function isSuppressedTraceEvent(event: TraceEvent): boolean {
  return isNoisyTraceEvent(event) || isRequestTraceEvent(event) || isSetupTraceEvent(event);
}

function readableTraceLabel(event: TraceEvent): string {
  const label = String(event.label ?? `${event.type ?? "event"}:${event.status ?? "observed"}`);
  if (label === "request:accepted-short-connection") return "submit short-connection";
  if (label === "request:accepted") return "request accepted";
  if (label.startsWith("turn:completed")) return "turn completed";
  if (label.startsWith("result:completed")) return "result ready";
  return label.replace(/^tool:/u, "").replace(/^assistant:/u, "assistant ").replace(/:completed$/u, " completed").replace(/:started$/u, " started");
}

function traceDisplayBody(event: TraceEvent): string | null {
  const command = cleanShellCommand(event.command);
  const lines = [
    command,
    traceDetailBlock("stdout", traceEventText(event, ["stdout", "stdoutText", "stdoutSummary"])),
    traceDetailBlock("stderr", traceEventText(event, ["stderr", "stderrText", "stderrSummary"])),
    traceEventText(event, ["output", "outputText", "outputSummary"]),
    traceEventText(event, ["prompt", "promptText", "promptSummary"]),
    traceEventText(event, ["message"]),
    traceEventText(event, ["chunk"])
  ].map(cleanTraceDetailText).filter(Boolean);
  return lines.length > 0 ? lines.join("\n") : null;
}

function traceMarkdownPreviewLines(body: string | null | undefined): string[] {
  return String(body ?? "")
    .replace(/\r\n|\r/gu, "\n")
    .trim()
    .split("\n")
    .map((line) => line.trimEnd())
    .filter((line) => Boolean(line.trim()));
}

function renderTraceRowDetailBody(row: TraceEventRow): string {
  return [
    row.body?.trimEnd() ?? "",
    row.rowId ? `rowId: ${row.rowId}` : "",
    row.terminal === true ? "terminal: true" : ""
  ].filter(Boolean).join("\n");
}

function renderTraceToolDetailBody(row: TraceEventRow): string {
  return normalizeTraceToolDetailBody(renderTraceRowDetailBody(row));
}

function normalizeTraceToolDetailBody(value: string): string {
  return String(value ?? "")
    .replace(/\r\n|\r/gu, "\n")
    .replace(/[^\S\n]+(stdout:)[^\S\n]*/giu, "\n$1\n")
    .replace(/[^\S\n]+(stderr:)[^\S\n]*/giu, "\n$1\n")
    .replace(/[^\S\n]+(exitCode=)/giu, "\n$1")
    .replace(/\n{3,}/gu, "\n\n")
    .trimEnd();
}

function traceBoldMarkdown(value: string): string {
  const body = String(value ?? "").trimEnd();
  if (!body) return "";
  return body.split("\n").map((line) => {
    if (!line.trim()) return "";
    return `**${escapeMarkdownStrongText(line)}**`;
  }).join("\n");
}

function escapeMarkdownStrongText(value: string): string {
  return escapeHtml(value).replace(/\\/gu, "\\\\").replace(/\*/gu, "\\*");
}

function indentTraceMarkdownBlock(value: string): string {
  return String(value).split("\n").map((line) => `  ${line}`).join("\n");
}

function escapeHtml(value: string): string {
  return String(value).replace(/&/gu, "&amp;").replace(/</gu, "&lt;").replace(/>/gu, "&gt;");
}

function escapeHtmlAttribute(value: string): string {
  return escapeHtml(value).replace(/"/gu, "&quot;").replace(/'/gu, "&#39;");
}

function traceMarkdownFence(language: string, body: string): string {
  const fence = body.includes("```") ? "````" : "```";
  return `${fence}${language}\n${body.trimEnd()}\n${fence}`;
}

function traceStatusToken(event: TraceEvent): string {
  const rawStatus = String(event.status ?? "");
  const status = rawStatus.toLowerCase();
  const exitCode = numberOrNull(event.exitCode);
  if (["failed", "blocked", "error", "timeout", "canceled", "cancelled"].includes(status) || event.errorCode || (exitCode !== null && exitCode !== 0)) return "fail";
  if (status === "completed" || status === "succeeded" || exitCode === 0) return "ok";
  if (["started", "running", "accepted", "inprogress", "in-progress", "output_chunk"].includes(status)) return "run";
  return rawStatus || "event";
}

function traceToolState(event: TraceEvent): TraceToolState {
  const status = traceStatusToken(event);
  if (status === "ok") return "success";
  if (status === "fail") return "failure";
  if (status === "run") return "running";
  return "neutral";
}

function traceToolStateFromTone(tone: TraceEventRow["tone"]): TraceToolState {
  if (tone === "ok") return "success";
  if (tone === "blocked") return "failure";
  if (tone === "warn") return "running";
  return "neutral";
}

function traceToolStatusLabel(state: TraceToolState): string {
  if (state === "success") return "工具调用成功";
  if (state === "failure") return "工具调用失败";
  if (state === "running") return "工具调用中";
  return "工具调用状态未知";
}

function traceEventTone(event: TraceEvent): TraceEventRow["tone"] {
  const status = traceStatusToken(event);
  if (status === "ok") return "ok";
  if (status === "fail") return "blocked";
  if (status === "run") return "warn";
  return "source";
}

function traceClock(value: unknown, options: TraceDisplayRowsOptions): string {
  const timestamp = nonEmptyString(value);
  if (timestamp && options.formatClock) return options.formatClock(timestamp);
  const date = new Date(String(value ?? ""));
  return Number.isNaN(date.getTime()) ? "--:--:--" : date.toISOString().slice(11, 19);
}

function traceEventClock(event: TraceEvent | null | undefined, options: TraceDisplayRowsOptions): string {
  return traceClock(traceEventTimestamp(event), options);
}

function traceWithInferredStart(trace: Record<string, unknown>, events: TraceEvent[]): Record<string, unknown> {
  if (nonEmptyString(trace.startedAt ?? trace.createdAt)) return trace;
  const firstTimestamp = events.map((event) => traceEventTimestamp(event)).find(Boolean);
  return firstTimestamp ? { ...trace, startedAt: firstTimestamp } : trace;
}

function traceEventTimestamp(event: TraceEvent | null | undefined): string | null {
  if (!event) return null;
  return nonEmptyString(event.createdAt ?? event.ts ?? event.timestamp ?? event.observedAt);
}

function traceEventTimestampMs(event: TraceEvent | null | undefined): number | null {
  const timestamp = traceEventTimestamp(event);
  if (!timestamp) return null;
  const parsed = Date.parse(timestamp);
  return Number.isFinite(parsed) ? parsed : null;
}

function cleanTraceText(value: unknown): string {
  return String(value ?? "").replace(/\u0000/gu, "").replace(/\r\n|\r/gu, "\n").replace(/[ \t]{2,}/gu, " ").replace(/\n{3,}/gu, "\n\n").trim();
}

function cleanTraceDetailText(value: unknown): string {
  return String(value ?? "").replace(/\u0000/gu, "").replace(/\r\n|\r/gu, "\n").replace(/\n{4,}/gu, "\n\n\n").trim();
}

function traceEventText(event: TraceEvent, keys: string[]): string | null {
  for (const key of keys) {
    const value = event[key];
    if (value === undefined || value === null) continue;
    const body = cleanTraceDetailText(value);
    if (body) return body;
  }
  return null;
}

function traceDetailBlock(label: string, value: string | null): string | null {
  return value ? `${label}:\n${value}` : null;
}

function cleanShellCommand(value: unknown): string | null {
  const raw = cleanTraceDetailText(value);
  if (!raw) return null;
  const stripped = stripShellWrapper(raw);
  const unescaped = stripped.replace(/\\(["`$\\])/gu, "$1");
  return cleanTraceDetailText(unescaped);
}

function stripShellWrapper(value: string): string {
  const match = value.match(/^\s*(?:\/usr\/bin\/env\s+)?(?:\/bin\/sh|sh|bash|\/bin\/bash)\s+-lc\s+([\s\S]*)$/u);
  if (!match) return value;
  return unwrapShellArgument(match[1] ?? "");
}

function unwrapShellArgument(value: string): string {
  const text = value.trim();
  if (text.length >= 2) {
    const quote = text[0];
    if ((quote === "'" || quote === '"') && text[text.length - 1] === quote) {
      return text.slice(1, -1);
    }
  }
  return text;
}

function compactTraceOneLine(value: unknown, limit = 220): string {
  const text = cleanTraceText(value).replace(/\s+/gu, " ");
  return text.length <= limit ? text : `${text.slice(0, Math.max(0, limit - 3))}...`;
}

function numberOrNull(value: unknown): number | null {
  if (value === null || value === undefined || value === "") return null;
  const number = Number(value);
  return Number.isInteger(number) ? number : null;
}

function nonEmptyString(value: unknown): string | null {
  const text = String(value ?? "").trim();
  return text ? text : null;
}

function isRecord(value: unknown): value is Record<string, unknown> {
  return Boolean(value && typeof value === "object");
}
