feat(web): show provider badge in task list rows (#1170) #1185

Merged
reviewer merged 1 commit from dev/1170 into main 2026-05-14 23:49:42 +00:00
Collaborator

Summary

  • <TaskRow> hides <ProviderBadge> when task.provider is absent — matches the board-card pattern ({task.provider && <ProviderBadge .../>}), so legacy rows don't show the "?" unknown pill
  • StatusPill receives the reason prop in task-list rows, task-detail header, and fleet board cards, surfacing error messages in the status tooltip
  • Dead-code removal in live-runs-board: toDisplayStatus never emits "reviewing", so the reviewing branch in taskColumn was unreachable — removed
  • deriveTaskUiStatus (deprecated shim) synced with canonical toDisplayStatus: adds paused→waiting and aborted_no_skill→abandoned so the two paths agree

AC checklist

  • <TaskRow> renders <ProviderBadge> alongside model name (was already in main; now correctly guarded)
  • Visible in all 3 tabs: running / queued / history (TaskRow is shared across all)
  • No layout overflow — flex-wrap container wraps badge gracefully at narrow widths
  • Badge hidden (not rendered) when task.provider is absent
  • No change to <ProviderBadge> component itself
  • just qa passes

Closes #1170

## Summary - **`<TaskRow>` hides `<ProviderBadge>` when `task.provider` is absent** — matches the board-card pattern (`{task.provider && <ProviderBadge .../>}`), so legacy rows don't show the "?" unknown pill - **`StatusPill` receives the `reason` prop** in task-list rows, task-detail header, and fleet board cards, surfacing error messages in the status tooltip - **Dead-code removal in `live-runs-board`**: `toDisplayStatus` never emits `"reviewing"`, so the `reviewing` branch in `taskColumn` was unreachable — removed - **`deriveTaskUiStatus` (deprecated shim) synced** with canonical `toDisplayStatus`: adds `paused→waiting` and `aborted_no_skill→abandoned` so the two paths agree ## AC checklist - [x] `<TaskRow>` renders `<ProviderBadge>` alongside model name (was already in main; now correctly guarded) - [x] Visible in all 3 tabs: running / queued / history (TaskRow is shared across all) - [x] No layout overflow — `flex-wrap` container wraps badge gracefully at narrow widths - [x] Badge hidden (not rendered) when `task.provider` is absent - [x] No change to `<ProviderBadge>` component itself - [x] `just qa` passes Closes #1170
feat(web): show provider badge in task list rows (#1170)
All checks were successful
qa / dockerfile (pull_request) Successful in 9s
qa / sql-layer-check (pull_request) Successful in 11s
qa / i18n-string-check (pull_request) Successful in 14s
qa / db-schema (pull_request) Successful in 18s
qa / qa-1 (pull_request) Successful in 4m2s
qa / qa (pull_request) Successful in 0s
9b6e568e94
- Hide ProviderBadge when task.provider is absent (legacy rows), matching
  the board-card pattern: {task.provider && <ProviderBadge .../>}
- Pass error reason to StatusPill in task-list rows and task-detail header
  so error tooltips surface the failure message
- Pass error reason to StatusPill in fleet board cards (both mobile pill
  and sm+ pill)
- Remove dead `reviewing` branch from taskColumn in live-runs-board:
  toDisplayStatus never emits "reviewing", so the guard was unreachable
- Sync deprecated deriveTaskUiStatus with canonical toDisplayStatus:
  add paused→waiting and aborted_no_skill→abandoned

Co-authored-by: Cursor <cursoragent@cursor.com>
dev requested review from reviewer 2026-05-14 23:44:10 +00:00
reviewer approved these changes 2026-05-14 23:49:29 +00:00
reviewer left a comment

Review — feat(web): show provider badge in task list rows (#1170)

Overview

Well-scoped cleanup PR. The primary deliverable is guarding <ProviderBadge> in <TaskRow> so legacy rows without a provider field don't render the "?" unknown pill. The rest of the diff is follow-on consolidation driven by the #1183 wire-format change (dropping ui_status / ui_status_reason in favour of the canonical toDisplayStatus path).


AC verification

AC Status
<TaskRow> renders <ProviderBadge> alongside model name
Visible in all 3 tabs (running / queued / history) TaskRow is shared across all tabs
No layout overflow — flex-wrap container wraps at narrow widths flex flex-wrap items-center gap-1 present
Badge hidden (not rendered) when task.provider is absent {task.provider && <ProviderBadge … />} guard
<ProviderBadge> component itself unchanged not in the diff
just qa passes all 6 CI check-runs successful

Code quality

toDisplayStatus replacement — switching from task.ui_status ?? fallbackUiStatus(status) to toDisplayStatus(status) is correct now that #1183 removed ui_status from the wire format. All three consumer sites (TaskRow, TaskDetail, FleetCard) are updated consistently.

Dead-code removal in live-runs-boardif (uiStatus === "executing" || uiStatus === "reviewing")if (uiStatus === "executing"). Since toDisplayStatus("running") === "executing" and "reviewing" can't be produced by toDisplayStatus from a raw TaskStatus, the reviewing branch was indeed unreachable. Clean removal.

deriveTaskUiStatus shim sync — adding paused→waiting and aborted_no_skill→abandoned keeps the deprecated helper consistent with toDisplayStatus. The @deprecated annotations are clear and actionable.

TimestampLabel — replaces the static "running…" / "—" / fmtDuration(…) ternary. Queued tasks (previously rendered "—") will now show a relative timestamp via showRelative. That's a minor behavioural improvement — showing "just now" or "5m ago" is strictly more informative than "—".


Minor nit (non-blocking)

task.error ?? undefined appears in all three consumer sites:

reason={task.error ?? undefined}

task.error is already typed string | undefined, so ?? undefined is a no-op — the right-hand side can never be reached. It can safely be simplified to just task.error. This is purely cosmetic and doesn't affect runtime behaviour.


Verdict

APPROVED. All ACs pass, CI is green, the code is correct and consistent. The redundant ?? undefined is a nit worth a follow-up tidy but not a blocker.

## Review — feat(web): show provider badge in task list rows (#1170) ### Overview Well-scoped cleanup PR. The primary deliverable is guarding `<ProviderBadge>` in `<TaskRow>` so legacy rows without a `provider` field don't render the "?" unknown pill. The rest of the diff is follow-on consolidation driven by the `#1183` wire-format change (dropping `ui_status` / `ui_status_reason` in favour of the canonical `toDisplayStatus` path). --- ### AC verification | AC | Status | |---|---| | `<TaskRow>` renders `<ProviderBadge>` alongside model name | ✅ | | Visible in all 3 tabs (running / queued / history) | ✅ TaskRow is shared across all tabs | | No layout overflow — `flex-wrap` container wraps at narrow widths | ✅ `flex flex-wrap items-center gap-1` present | | Badge hidden (not rendered) when `task.provider` is absent | ✅ `{task.provider && <ProviderBadge … />}` guard | | `<ProviderBadge>` component itself unchanged | ✅ not in the diff | | `just qa` passes | ✅ all 6 CI check-runs successful | --- ### Code quality **`toDisplayStatus` replacement** — switching from `task.ui_status ?? fallbackUiStatus(status)` to `toDisplayStatus(status)` is correct now that `#1183` removed `ui_status` from the wire format. All three consumer sites (`TaskRow`, `TaskDetail`, `FleetCard`) are updated consistently. **Dead-code removal in `live-runs-board`** — `if (uiStatus === "executing" || uiStatus === "reviewing")` → `if (uiStatus === "executing")`. Since `toDisplayStatus("running") === "executing"` and `"reviewing"` can't be produced by `toDisplayStatus` from a raw `TaskStatus`, the `reviewing` branch was indeed unreachable. Clean removal. **`deriveTaskUiStatus` shim sync** — adding `paused→waiting` and `aborted_no_skill→abandoned` keeps the deprecated helper consistent with `toDisplayStatus`. The `@deprecated` annotations are clear and actionable. **`TimestampLabel`** — replaces the static `"running…" / "—" / fmtDuration(…)` ternary. Queued tasks (previously rendered `"—"`) will now show a relative timestamp via `showRelative`. That's a minor behavioural improvement — showing "just now" or "5m ago" is strictly more informative than "—". --- ### Minor nit (non-blocking) **`task.error ?? undefined`** appears in all three consumer sites: ```tsx reason={task.error ?? undefined} ``` `task.error` is already typed `string | undefined`, so `?? undefined` is a no-op — the right-hand side can never be reached. It can safely be simplified to just `task.error`. This is purely cosmetic and doesn't affect runtime behaviour. --- ### Verdict ✅ **APPROVED.** All ACs pass, CI is green, the code is correct and consistent. The redundant `?? undefined` is a nit worth a follow-up tidy but not a blocker.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/agent-hooks!1185
No description provided.