qwen-code/packages/web-shell/client/components
Shaojin Wen 9f2168f78e
feat(web-shell): collapsible TodoWrite history with status diff (#5109)
* feat(web-shell): collapsible TodoWrite history with status diff

Inline todo_write updates rendered as a generic, non-collapsible tool row
crammed in with surrounding tool calls — the todo-specific renderer was
effectively dead code because the detector matched the literal "todowrite"
while the wire name is "todo_write" (kind "think").

- Detect the todo tool by name (todo_write / todowrite) instead of relying
  on the unrelated tool kind, reviving the rich rendering and also
  populating the floating todo panel that was empty on the daemon path.
- Render each update as its own standalone group, collapsed by default to
  the per-snapshot diff (just-completed / just-started items) or the current
  step, expanding to the full checklist; the header shows completed/total.
- Use consistent status glyphs (●/◐/○) in both collapsed and expanded views
  via a shared TodoView component used by ToolGroup and PlanMessage.

* fix(web-shell): scope todo diff per task identity; address review

- [Critical] computeTodoTimeline keyed its running state on todo.id alone, but
  ids aren't globally unique (ACP assigns positional ids, models renumber per
  plan), so a later plan diffed against a previous plan's stale terminal status
  and silently dropped events in the collapsed view. Key on id+content so
  distinct tasks stay separate; add an id-reuse regression test.
- Stabilize the TodoTimelineContext value with a signature-cached Map so
  streaming ticks that don't touch a todo snapshot no longer re-render every
  todo/plan row.
- Drop the unused completed/total from TodoSnapshotDiff (consumers compute the
  count locally — single source of truth).
- Fall back to the raw result summary when a todo_write payload is unparseable.
- Add PlanMessage rendering tests and extractTodosFromToolCall coverage; remove
  stale "step time" comments left after dropping per-step timing.

* test(web-shell): document todo-diff keying limits; cover signature

Follow-up to review on the id+content keying in computeTodoTimeline:
- Document the two rare trade-offs in the todoStateKey doc (a mid-task reword on
  a stable id, and unrelated plans reusing both id and content), both degrading
  to "the collapsed diff omits one event" while the expanded list stays correct.
- Pin behavior with tests: an item carried over and completed in a later turn
  (which id+content handles but a user-turn reset would drop), plus the two
  documented gaps.
- Add todoTimelineSignature tests: stable across non-todo edits; changes on any
  id/status/content change.

* refactor(web-shell): isolate plan context read; expand todo test coverage

Address follow-up review:
- Extract PlanEventSummary as the sole TodoTimelineContext consumer, mirroring
  ToolGroup's TodoToolBody so the memo-shielded PlanMessage stays stable when
  the timeline Map reference changes.
- Note the spurious-`started` axis of the reword trade-off in the todoStateKey
  doc (a reword can drop a completion or emit a stray start).
- Add direct isTodoWriteToolName tests (incl. the `todowrite` ACP variant) and
  a todoTimelineSignature empty-transcript test.
2026-06-15 00:44:15 +08:00
..
dialogs feat(cli,web-shell): persist goal status in daemon transcript events (#5098) 2026-06-14 21:08:06 +08:00
messages feat(web-shell): collapsible TodoWrite history with status diff (#5109) 2026-06-15 00:44:15 +08:00
panels feat(web-shell): revamp floating todo panel interactions (#5069) 2026-06-13 11:51:03 +08:00
Editor.keymap.test.ts feat(web-shell): add Option+Enter and Cmd+Enter newline shortcuts (#5005) 2026-06-12 13:07:56 +08:00
Editor.module.css feat(web-shell): make input shortcuts discoverable and clickable (#5096) 2026-06-14 16:41:37 +08:00
Editor.test.ts feat(daemon): merge daemon-mode feature batch into main (#4490) 2026-06-12 00:34:49 +08:00
Editor.tsx feat(web-shell): make input shortcuts discoverable and clickable (#5096) 2026-06-14 16:41:37 +08:00
InsightProgress.module.css feat(daemon): merge daemon-mode feature batch into main (#4490) 2026-06-12 00:34:49 +08:00
InsightProgress.tsx feat(daemon): merge daemon-mode feature batch into main (#4490) 2026-06-12 00:34:49 +08:00
InsightReady.tsx feat(daemon): merge daemon-mode feature batch into main (#4490) 2026-06-12 00:34:49 +08:00
MessageItem.tsx feat(web-shell): collapsible TodoWrite history with status diff (#5109) 2026-06-15 00:44:15 +08:00
MessageList.module.css feat(web-shell): revamp floating todo panel interactions (#5069) 2026-06-13 11:51:03 +08:00
MessageList.test.ts feat(web-shell): show time on parallel-agents box and sub-agent tools (#5084) 2026-06-14 00:46:42 +08:00
MessageList.tsx feat(web-shell): show time on parallel-agents box and sub-agent tools (#5084) 2026-06-14 00:46:42 +08:00
MessageTimestamp.module.css feat(web-shell): show message time on hover (#5079) 2026-06-13 15:30:44 +08:00
MessageTimestamp.test.tsx feat(web-shell): show message time on hover (#5079) 2026-06-13 15:30:44 +08:00
MessageTimestamp.tsx feat(web-shell): show message time on hover (#5079) 2026-06-13 15:30:44 +08:00
PromptChevron.tsx feat(daemon): merge daemon-mode feature batch into main (#4490) 2026-06-12 00:34:49 +08:00
ShortcutsPanel.module.css feat(daemon): merge daemon-mode feature batch into main (#4490) 2026-06-12 00:34:49 +08:00
ShortcutsPanel.tsx feat(web-shell): make input shortcuts discoverable and clickable (#5096) 2026-06-14 16:41:37 +08:00
StatusBar.module.css feat(web-shell): make input shortcuts discoverable and clickable (#5096) 2026-06-14 16:41:37 +08:00
StatusBar.tsx feat(web-shell): make input shortcuts discoverable and clickable (#5096) 2026-06-14 16:41:37 +08:00
StreamingStatus.module.css feat(web-shell): daemon web-shell improvements — token usage, settings, retry, streaming metrics, hidden commands (#5066) 2026-06-13 02:58:08 +00:00
StreamingStatus.tsx feat(web-shell): daemon web-shell improvements — token usage, settings, retry, streaming metrics, hidden commands (#5066) 2026-06-13 02:58:08 +00:00
Tips.module.css feat(daemon): merge daemon-mode feature batch into main (#4490) 2026-06-12 00:34:49 +08:00
Tips.tsx feat(daemon): merge daemon-mode feature batch into main (#4490) 2026-06-12 00:34:49 +08:00
ToastHost.module.css feat(daemon): merge daemon-mode feature batch into main (#4490) 2026-06-12 00:34:49 +08:00
ToastHost.tsx feat(daemon): merge daemon-mode feature batch into main (#4490) 2026-06-12 00:34:49 +08:00
WelcomeHeader.module.css feat(daemon): merge daemon-mode feature batch into main (#4490) 2026-06-12 00:34:49 +08:00
WelcomeHeader.tsx feat(web-shell): daemon web-shell improvements — token usage, settings, retry, streaming metrics, hidden commands (#5066) 2026-06-13 02:58:08 +00:00