import type { TaskListItem, TaskStatus } from "./types"; /** * Statuses that represent an actively executing assignment, where live * in-progress step information is meaningful to surface. */ const ACTIVE_STATUSES: ReadonlySet = new Set([ "assigned", "dispatched", ]); /** * Format a task's latest in-progress step snapshot for inline display. * * Returns `null` when: * - the task is not actively executing (queued, done, failed) — terminal/queued * status always wins over a stale progress snapshot; or * - no progress has been reported yet (`progress_step_index` is null/undefined * or `progress_step_status` is missing). * * Otherwise returns a compact string like `"step 2 — running: tapping button"`. * The summary is truncated to a display-friendly length with a Unicode ellipsis * when it exceeds the limit. */ export function formatTaskProgress( task: Pick< TaskListItem, | "status" | "progress_step_index" | "progress_step_status" | "progress_summary" >, maxSummaryLength = 120, ): string | null { if (!ACTIVE_STATUSES.has(task.status)) return null; if ( task.progress_step_index === null || task.progress_step_index === undefined || !task.progress_step_status ) { return null; } const summary = task.progress_summary ?? ""; const trimmed = summary.trim(); const display = trimmed.length > maxSummaryLength ? `${trimmed.slice(0, maxSummaryLength - 1).trimEnd()}\u2026` : trimmed; return `step ${task.progress_step_index} \u2014 ${task.progress_step_status}${ display ? `: ${display}` : "" }`; }