cmux NEXT: lanes show each session's harness and current step (hq#2509)
On the Lanes view (Agent Activity, behind Labs > Show Preview Features), each lane now has a second, muted line under its title. It shows the harness that runs the lane (claude, codex) and the step it's on: the running turn's prompt, or else the agent's last message. A failed lane keeps its error on that line instead.
This is the first slice of the chief view, manaflow-ai/cmuxterm-hq#2509. It uses only data the view already gets: harness, turn.prompt and lastMessage are on every acpmux summary. The native snapshot (AgentActivityLane.of) and the watch-event path (priority.ts) both project the same fields, with whitespace folded to one line and the text capped at 240 characters. A person's own last message isn't a step, so it doesn't show. The filter now matches the step too.
.lane was picking up a 12px row gap from the page's button styles, which pushed the second line (and the existing error line) closer to the next row than to its own title. It's 1px now.
No new strings and no new motion. The PR, head and CI verdict per lane need a new acpmux summary field, so they're the next step in #2509, not part of this PR.
Screenshots
The pages.agent-activity gallery entry, lanes variant, 1000 px wide at 2x, rendered from this branch.
The Claude reference on the left groups sessions by what they need. On the right is this branch's Lanes view:

The Codex reference on top shows a title with a muted line under it. Below it are this branch's rows with the same structure, plus the harness and the step:

References: cmux-design-references apps/claude/web/october-status-sidebar.png and apps/codex/live/grouped-priority-and-chat-rows.png.
Testing
bun test test/agent-activity-priority.test.ts test/agent-activity-lanes.test.tsx: 3 fail on the test commit 5865ea1521 and 16 pass on c6a8df66b6. The new tests cover the projection from a summary (prompt, last agent message, and the user-message case), the rendered second line, the error case, and filtering by step.AgentLanesTests.aLaneCarriesItsHarnessAndCurrentStepcovers the Swift parse. I didn't compile or run it locally (no native builds on this Mac); CI runs it.swiftc -parsepasses on the changed Swift files.vp fmt --checkandvp lintpass on the changed files.vp check(typecheck) finds no errors in the changed files. It reports one error in an unrelated test whose fixture isn't in my sparse checkout.
Changelog
none (Labs preview feature)
🤖 Generated with Claude Code