* fix(frontend): truncate long subtask card titles to a single line
The subtask card header rendered task.description without any width
constraint; when a provider omits the optional description, the full
task prompt becomes the title and overflows the card.
Wrap the title in a truncating span (full text remains available via
the title tooltip and the expanded card body), give the step min-w-0
flex-1, and pin the status cluster with shrink-0 so overflow resolves
at the title.
Add an e2e test asserting a long prompt renders with the truncate
class, a real ellipsis (scrollWidth > clientWidth), and single-line
height.
* fix(frontend): keep subtask card status cluster shrinkable on narrow viewports
The shrink-0 status cluster could not shrink below its max-content (model
label + usage + status pill, up to ~456px with a long tool-call
description), so on narrow viewports it overflowed the header row while the
title collapsed to zero. Drop shrink-0 and add min-w-0 to both the cluster
and the pill (the pill's min-content is the status text's longest
unbreakable word, so one min-w-0 was not enough), and floor the title at
min-w-24 so it stays visible.
Also extend the e2e spec per review: an in_progress shimmer truncation test
(held-open SSE stream keeps the card running), a 375px no-overflow
assertion for both the resting and running card, and a pixel-budget
single-line check instead of parseFloat(lineHeight) which NaNs on the
'normal' keyword.
* test(frontend): honest fixture text and explicit visibility timeout in subtask spec
Review nits: the long-title fixture lifted the stopped test's human turn
whose text narrates the stop scenario; give it its own LONG_TASK_USER_TEXT
and override content alongside id and tool_calls. Add the missing 15s
timeout on the running-375px title visibility assertion so a future
reorder doesn't turn the 5s default into a cold-start flake.
* fix(frontend): resolve stale subagent running state after stop
Subtask cards were recreated from task tool calls as in_progress whenever
the thread was loading. If a user stopped a run before the task tool returned
a ToolMessage, the card could remain running after reload, and could flip back
to running when a later user turn started streaming.
Derive pending subtask state from the current assistant turn instead of the
global thread loading flag. A task now stays in progress only while its own
turn is loading or while a matching ToolMessage exists for result parsing;
otherwise it is marked failed.
Add unit coverage for task ToolMessage matching and for the later-turn loading
regression.
* fix(frontend): refresh subagent card on terminal status transition
- notify React via a ref + post-render effect when a subtask flips to
completed/failed, so SubtaskCard updates without relying on an
unrelated MessageList re-render
- tighten the current-turn heuristic to `groupIndex === lastGroupIndex`
(precomputed once) — fixes the rare case where an earlier subagent
group in the same turn was kept in_progress, and drops the per-group
slice+some scan to O(1)
- rename `getPendingSubtaskStatus` → `derivePendingSubtaskStatus`
- narrow `toolCall.id` at MessageList call sites; skip task tool calls
without an id instead of `id!`
- add Playwright e2e covering reload-after-stop showing `Subtask failed`