feat(desktop): an agent's tab hovers a card with its whole name, when it last moved, and its latest step
What
Dean: "Hovering over an agent tab should show a richer tooltip/preview. I want the full name, last updated timestamp in top right, and a max 1 line preview of the last message/tool call."
Builds on #2069 (merged), the service half: it gives subagents a short title from the coding agents' title step and carries it on the wire.
Dean's follow-up: "Subagent cards are unreadable because the name is the whole task. Use a short title. … Show model and effort on both subagent and coding agent cards, e.g. 'Opus 5.5 High', via the shared ModelLabel … Subagent and coding agent cards use the same layout."
Coding agent and subagent tabs now show a small hover card where the plain Tooltip used to be. It has the same delay, warm window, and ways of closing as the Tooltip (it is the Tooltip, given a card). It opens below the tab, lined up with the tab's left edge, and stays clear of the strip.
-
One layout for both agents and subagents.
-
Top row: the full name (at most 2 lines) on the left, and a muted time on the right.
-
Under the name: the model and effort through the shared
ModelLabel(#2012), e.g. "Opus 5.5 High" with the effort dimmed.- An agent's comes from its summary.
- A delegated worker's comes from the
delegatecall that started it, in the transcript its agent's tab holds. - Luke's planning workers show none: the service doesn't know their effort, and has their model only as a bare OpenAI id (#2069 explains why).
-
A subagent's name: its title from #2069 when it has one, for coder workers and planning workers alike.
- A coder worker's title comes from its own page or its agent's page; a planning worker's from its session.
- Until a title exists, the task's first line stands in, on one line with a fade (#1979) instead of wrapping.
- The tab label and the "+" menu row use the same name.
- While running: the live "Working… 1m 12s", the same words and count the transcript's last line uses (#1986/#2038). I picked this over "now" because it says both that the agent is busy and for how long.
- Once ended: how it ended, wherever the tab's glyph doesn't show it, then how long ago it last moved (e.g. "Stopped · 3m", "Failed · 12m"). The state words are the ones #2067's hint used to say; the card replaces that hint on these tabs.
- The time itself: how long ago it last moved, in the sidebar's letters (
sinceTextfrom #2001, e.g. "3m"). If the tab holds the last turn, that's the turn'sfinishedAt(#2038). If not, it's the newest run's start, which is the latest time the summary knows. - Subagents: the same, counted from the session's start and end (Luke's planning workers) or the worker's run start (an agent's delegated workers), wherever these are known.
-
Preview: one line, faded at its end like a long tab label (#1979). It shows the latest step: the agent's last words with markdown stripped to plain text, or its last tool call in the concise transcript's own words ("Ran
pnpm test", "Editedsrc/x.ts", "Asked the worker: …"). It reusestranscript-copy.ts's concise reading (#1991) through a newlatestActivity, so there is no new formatter. Reasoning and the developer's own messages are skipped. -
Where the data comes from (no fetch on hover): an agent's tab or delegated worker's tab now hands up the transcript it holds (
onHeld), and the panel keeps it after another tab is chosen. Each held transcript is tied to the page it was read from: that page's own status andrunStartedAt, which changes with every turn. A card shows it only while it belongs to the run the agent is on now, and either:- the tab is the chosen one, so it is live; or
- it was read after that run ended.
A new turn whose first read is still out or failed shows nothing from the previous turn, even on the chosen tab (Devin's review caught this).
Otherwise the card shows only the name and time from the summary. Two cases where that happens: a running agent in a background tab, and a tab never opened this session. Luke's planning workers always have a preview, because the plan holds their whole session.
-
Unchanged: fixed tabs (Board/Code/Transcript/Work/History) and file tabs keep the plain Tooltip. The draft "New agent" tab has nothing to preview, so it gets no card.
-
Session replay: the card is text like the rest, so the recording masks it, and it also carries
ph-no-capturelike an agent's tab body. -
The agent tab's old tooltip showed the model name. The model is still on the composer's model chip, and an untitled tab is named by its model anyway.
-
Small fix in the shared Tooltip: it now measures the pill's layout size (
offsetWidth/offsetHeight) instead of its box. The box is still scaled to 0.96 by the waiting fade, so a wide card near the window's right edge was clamped about 11px short.
Screenshots
Rendered from the real TabStrip/Tab/AgentTabCard and the app's stylesheet in headless Chrome on Linux, not the Mac app (so the fonts are Linux fallbacks).
| Light | Dark | |
|---|---|---|
| Finished agent: long name wraps, model and effort, "12m", last words as plain text, faded | ![]() | ![]() |
| Running agent: live count, latest tool call in the transcript's words | ![]() | ![]() |
| Subagent with its title, model and effort, live count, latest call | ![]() | ![]() |
| Subagent before its title lands: the task on one faded line | ![]() | ![]() |
Tests
desktop-plans.test.ts(through the real side panel, onTestClock):- Hovering an agent's tab shows its full name, "3m" from the last turn's
finishedAt, and a one-line plain-text preview. The card carriesph-no-captureand describes the tab. - The preview is still there after another tab is chosen.
- A running tab that was never opened shows "Working… 1m 12s" and no preview, and reads no transcript.
- An agent that starts a new turn shows nothing from the previous turn, even on its chosen tab whose read failed.
- The Board tab still shows no tooltip.
- A tool call reads "Ran
pnpm test", with the subject as code. - A subagent's card counts while it works and shows "2m" once it has ended.
- A delegated worker's card has the same layout as its agent's: the task on one line while untitled, plus the model and effort from its call.
- A delegated worker named on its agent's page is drawn by that title.
- A planning worker whose session carries a title is drawn by it.
- Hovering an agent's tab shows its full name, "3m" from the last turn's
transcript-copy.test.ts:latestActivitygives the last words as plain text and a call worded as the concise copy words it, skipping reasoning and the developer.tooltip.test.ts: a card opens from its control's left edge, describes the control, and is left out of the recording. A card too wide for the room is placed using its pre-fade size.- I updated the two existing hover assertions on agent and subagent tabs (model name, or job only) to the card.
Mac validation
This was built on a Linux cloud VM. CI could not verify the Mac UI, and ./scripts/verify.sh was not run. LUKE-159 is the manual Mac pass. ./scripts/check.sh passes locally.
🤖 Generated with Claude Code







