// SPEC: PJ2026-01060703 CI/CD TaskRun summaries. // Responsibility: shared bounded TaskRun prioritization for branch-follower status/debug visibility. export type TaskRunMode = "failed" | "active" | "slow"; export function taskRunItems(taskRuns: Record, mode: TaskRunMode, limit = 5): Record[] { const explicit = mode === "failed" ? taskRuns.failedItems : mode === "active" ? taskRuns.activeItems : taskRuns.slowItems; const explicitItems = arrayRecords(explicit); if (explicitItems.length > 0) return explicitItems.slice(0, limit).map(compactTaskRunItem); const items = arrayRecords(taskRuns.items); if (mode === "failed") return items.filter((item) => item.status === "False").slice(0, limit).map(compactTaskRunItem); if (mode === "active") return items.filter((item) => item.status !== "True" && item.status !== "False").slice(0, limit).map(compactTaskRunItem); const slowItems = arrayRecords(asOptionalRecord(taskRuns.performance)?.slowTaskRuns); if (slowItems.length > 0) return slowItems.slice(0, limit).map(compactTaskRunItem); return items.filter((item) => { const seconds = numberOrNull(item.durationSeconds); return seconds !== null && seconds > 60; }).slice(0, limit).map(compactTaskRunItem); } export function prioritizedTaskRunItems(taskRuns: Record, limit = 16): Record[] { const prioritized = [ ...taskRunItems(taskRuns, "failed", limit), ...taskRunItems(taskRuns, "active", limit), ...taskRunItems(taskRuns, "slow", limit), ...arrayRecords(taskRuns.items).map(compactTaskRunItem), ]; const seen = new Set(); const out: Record[] = []; for (const item of prioritized) { const key = taskRunKey(item); if (seen.has(key)) continue; seen.add(key); out.push(item); if (out.length >= limit) break; } return out; } export function compactTaskRunItem(item: Record): Record { return { name: stringOrNull(item.name), pipelineTask: stringOrNull(item.pipelineTask), status: stringOrNull(item.status), reason: stringOrNull(item.reason), durationSeconds: numberOrNull(item.durationSeconds), }; } function taskRunKey(item: Record): string { const key = [ stringOrNull(item.name), stringOrNull(item.pipelineTask), stringOrNull(item.status), stringOrNull(item.reason), ].filter((value) => value !== null).join("|"); return key.length > 0 ? key : JSON.stringify(item); } function asOptionalRecord(value: unknown): Record | null { return typeof value === "object" && value !== null && !Array.isArray(value) ? value as Record : null; } function arrayRecords(value: unknown): Record[] { return Array.isArray(value) ? value.filter((item): item is Record => typeof item === "object" && item !== null && !Array.isArray(item)) : []; } function stringOrNull(value: unknown): string | null { return typeof value === "string" && value.length > 0 ? value : null; } function numberOrNull(value: unknown): number | null { return typeof value === "number" && Number.isFinite(value) ? value : null; }