fix(gui): keep the parallel-active count outside the ellipsized hint

Both todo one-line surfaces truncate the active hint with overflow: hidden
and text-overflow: ellipsis. A "+N" appended to the first active task's name
therefore sat at the far end of the truncatable text, so a long task name or a
narrow viewport clipped exactly the part that reports the other running tasks,
leaving a parallel plan indistinguishable from a sequential one.

planSummary now returns activeContent and activeExtra as separate fields
instead of one joined activeHint, and each surface renders the count in its own
flex: none span beside the ellipsized name: .activeExtra in the collapsed plan
strip header, .extra in the todo_write row. Putting the count in front of the
name was rejected — the task name is what the reader looks for first.

The parallel-plan cases in todo-panel.spec.tsx now assert the count is a
separate element from the name, and both fail if the two are rejoined. The
assembled web snapshot re-records: the flex gap supplies the visual space, so
the transcript reads "实现 fixture 样本+1" with no space in the text nodes.
This commit is contained in:
Chinesezjc
2026-07-27 15:07:43 +08:00
parent f8b0bd31d3
commit 07f9959d55
13 changed files with 116 additions and 54 deletions

View File

@@ -8,7 +8,10 @@
// by the tail history page), including the collapse interaction. The sample
// plan runs two items in_progress at once, so both surfaces are pinned against
// a parallel plan — the collapsed one-line hint must account for the second
// active item instead of naming the first and dropping it.
// active item instead of naming the first and dropping it. The `+1` reads
// against the task name with no space because it is a separate non-shrinking
// span (spaced by the flex `gap`), kept outside the ellipsized text so a narrow
// viewport clips the task name rather than the count.
import { readFileSync } from 'node:fs'
import { join } from 'node:path'
import { act, cleanup, fireEvent, screen, waitFor, within } from '@testing-library/react'
@@ -165,7 +168,7 @@ it('renders the todo_write turn: dedicated tool row + the dock plan strip', asyn
"text": "○浏览器验收",
},
],
"row": "☰更新任务清单1/4 已完成 · 实现 fixture 样本 +1",
"row": "☰更新任务清单1/4 已完成 · 实现 fixture 样本+1",
"rowState": "ok",
}
`)
@@ -186,7 +189,7 @@ it('collapses the plan strip to the in-progress hint and restores it', async ()
listGone: panel.querySelector('ul') === null,
}).toMatchInlineSnapshot(`
{
"collapsedHeader": "Plan1/4实现 fixture 样本 +1",
"collapsedHeader": "Plan1/4实现 fixture 样本+1",
"listGone": true,
}
`)