import type { JsonRecord, RunEvent, RunnerJobRecord, TerminalStatus } from "../common/types.js"; import { runnerJobDiagnosis } from "./diagnosis.js"; export function runnerJobStatusSummary(job: RunnerJobRecord, events: RunEvent[] = []): JsonRecord { const terminalEvent = latestTerminalEvent(events, job.commandId); const runner = recordAt(job.result, "runner"); const jobIdentity = recordAt(job.result, "jobIdentity"); const kubernetes = recordAt(job.result, "kubernetes"); const retention = recordAt(job.result, "retention"); const envImage = recordAt(job.result, "envImage"); const terminalStatus = terminalEvent?.payload.terminalStatus; return { id: job.id, runId: job.runId, commandId: job.commandId, attemptId: job.attemptId, runnerId: job.runnerId, namespace: job.namespace, jobName: job.jobName, managerUrl: job.managerUrl, image: job.image, envImage, sourceCommit: job.sourceCommit, serviceAccountName: job.serviceAccountName, phase: terminalStatus ? `terminal:${terminalStatus}` : kubernetes.created === true ? "created" : "recorded", terminalStatus: isTerminalStatus(terminalStatus) ? terminalStatus : null, failureKind: typeof terminalEvent?.payload.failureKind === "string" ? terminalEvent.payload.failureKind : null, exitCode: null, startedAt: null, finishedAt: terminalEvent?.createdAt ?? null, jobIdentity, podIdentity: recordAt(job.result, "podIdentity"), logPath: typeof runner.logPath === "string" ? runner.logPath : null, retention, kubernetes, diagnosis: runnerJobDiagnosis(job, events), createdAt: job.createdAt, updatedAt: job.updatedAt, valuesPrinted: false, }; } function latestTerminalEvent(events: RunEvent[], commandId: string): RunEvent | null { for (const event of [...events].reverse()) { if (event.payload.commandId && event.payload.commandId !== commandId) continue; if (event.type === "terminal_status") return event; if (event.type === "backend_status" && event.payload.phase === "command-terminal" && event.payload.commandId === commandId) return event; } return null; } function recordAt(record: JsonRecord, key: string): JsonRecord { const value = record[key]; return typeof value === "object" && value !== null && !Array.isArray(value) ? value as JsonRecord : {}; } function isTerminalStatus(value: unknown): value is TerminalStatus { return value === "completed" || value === "failed" || value === "blocked" || value === "cancelled"; }