From 40fe7dce092392ea4091923c2838eac6e27af451 Mon Sep 17 00:00:00 2001 From: maria-rcks Date: Mon, 3 Aug 2026 19:07:28 -0400 Subject: [PATCH 1/2] feat(chat): refine V2 conversation UI --- README.md | 1 + .../settings/DesktopClientSettings.test.ts | 1 + apps/mobile/src/lib/threadActivity.test.ts | 41 +++++ apps/mobile/src/lib/threadActivity.ts | 7 + .../BranchToolbarBranchSelector.tsx | 16 +- .../web/src/components/ChatView.logic.test.ts | 24 ++- apps/web/src/components/ChatView.logic.ts | 9 +- apps/web/src/components/ChatView.tsx | 99 +++++++----- .../components/ProjectScriptsControl.test.tsx | 34 ++++ .../src/components/ProjectScriptsControl.tsx | 92 ++++++++--- .../chat/MessagesTimeline.logic.test.ts | 8 +- .../components/chat/MessagesTimeline.logic.ts | 9 ++ .../components/chat/MessagesTimeline.test.tsx | 62 ++++++- .../src/components/chat/MessagesTimeline.tsx | 152 ++++++++++++++---- .../components/chat/ThreadDetailsPanel.tsx | 2 +- .../components/chat/TimelineSystemDivider.tsx | 8 +- .../src/components/chat/V2LifecycleRow.tsx | 20 ++- .../src/components/chat/providerIconUtils.ts | 53 ++++++ .../components/settings/SettingsPanels.tsx | 34 ++++ .../settings/settingsSearch.test.ts | 4 + .../src/components/settings/settingsSearch.ts | 5 + apps/web/src/index.css | 26 +-- apps/web/src/session-logic.test.ts | 9 ++ apps/web/src/session-logic.ts | 2 + docs/README.md | 1 + docs/user/appearance.md | 11 ++ packages/client-runtime/package.json | 4 + .../src/state/turnItemPresentation.test.ts | 36 +++++ .../src/state/turnItemPresentation.ts | 8 + packages/contracts/src/settings.test.ts | 9 ++ packages/contracts/src/settings.ts | 4 + 31 files changed, 642 insertions(+), 149 deletions(-) create mode 100644 docs/user/appearance.md create mode 100644 packages/client-runtime/src/state/turnItemPresentation.test.ts create mode 100644 packages/client-runtime/src/state/turnItemPresentation.ts diff --git a/README.md b/README.md index 1e9b0517945..6364f6eac3f 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,7 @@ Full docs live in [docs/](./docs). There's no docs site yet. - [Install and first run](./docs/user/install.md) - [Permission modes](./docs/user/permission-modes.md) - [Keyboard shortcuts](./docs/user/keybindings.md) +- [Appearance preferences](./docs/user/appearance.md) - [Remote access from a phone or another machine](./docs/user/remote-access.md) - [Keeping app and server in sync](./docs/user/updating.md) - [Source control integrations](./docs/user/source-control.md) diff --git a/apps/desktop/src/settings/DesktopClientSettings.test.ts b/apps/desktop/src/settings/DesktopClientSettings.test.ts index 8d76ea83a33..34097d3688f 100644 --- a/apps/desktop/src/settings/DesktopClientSettings.test.ts +++ b/apps/desktop/src/settings/DesktopClientSettings.test.ts @@ -21,6 +21,7 @@ const clientSettings: ClientSettings = { environmentIdentificationMode: "artwork", favorites: [], glassOpacity: 80, + persistComposerContextStrip: true, providerModelPreferences: {}, sidebarAutoSettleAfterDays: 3, sidebarProjectGroupingMode: "repository_path", diff --git a/apps/mobile/src/lib/threadActivity.test.ts b/apps/mobile/src/lib/threadActivity.test.ts index 4d5f258a285..38e15e46197 100644 --- a/apps/mobile/src/lib/threadActivity.test.ts +++ b/apps/mobile/src/lib/threadActivity.test.ts @@ -89,6 +89,20 @@ function assistantMessage(updatedAt = "2026-06-20T00:00:03.000Z") { } describe("buildThreadFeed", () => { + it("hides synthetic workspace preparation activity", () => { + const workspacePreparation = projected( + { + ...command(), + title: "Workspace ready", + input: "Preparing workspace", + output: "Workspace preparation completed.", + }, + 0, + ); + + expect(buildThreadFeed([workspacePreparation])).toEqual([]); + }); + it("does not treat a queued-only run as live feed activity", () => { expect( threadFeedRunIsUnsettled({ @@ -131,6 +145,33 @@ describe("buildThreadFeed", () => { ).toBe("turn_start"); }); + it("hides the interruption request and keeps the terminal result", () => { + const request = projected( + { + ...base("item-interrupt-request", "2026-06-20T00:00:02.000Z", 1), + type: "run_interrupt_request", + message: "Interrupt requested", + }, + 0, + ); + const result = projected( + { + ...base("item-interrupt-result", "2026-06-20T00:00:03.000Z", 2), + type: "run_interrupt_result", + message: "Run interrupted before provider start", + }, + 1, + ); + + const activities = buildThreadFeed([request, result]).flatMap((entry) => + entry.type === "activity-group" ? entry.activities : [], + ); + + expect(activities).toHaveLength(1); + expect(activities[0]?.summary).toBe("Run interrupted"); + expect(activities[0]?.detail).toBe("Run interrupted before provider start"); + }); + it("preserves authoritative V2 order instead of sorting reconstructed collections", () => { const rows = [ projected(userMessage("2026-06-20T00:00:03.000Z"), 0), diff --git a/apps/mobile/src/lib/threadActivity.ts b/apps/mobile/src/lib/threadActivity.ts index e5729d85776..6742b60bf06 100644 --- a/apps/mobile/src/lib/threadActivity.ts +++ b/apps/mobile/src/lib/threadActivity.ts @@ -3,6 +3,7 @@ import type { ThreadPendingUserInput, ThreadUserInputQuestion, } from "@t3tools/client-runtime/state/thread-requests"; +import { turnItemIsWorkspacePreparation } from "@t3tools/client-runtime/state/turn-item-presentation"; import { resolveT3McpToolPresentation, type T3McpToolLogo, @@ -683,6 +684,12 @@ export function buildThreadFeed( const entries: RawThreadFeedEntry[] = []; for (const row of visibleTurnItems) { const item = row.item; + if (turnItemIsWorkspacePreparation(item)) continue; + // Match the web timeline: only the terminal interrupt result is useful to + // users; the preceding request is transient bookkeeping. + if (item.type === "run_interrupt_request") { + continue; + } const createdAt = DateTime.formatIso(item.startedAt ?? item.updatedAt); if (item.type === "user_message" || item.type === "assistant_message") { const updatedAt = DateTime.formatIso(item.updatedAt); diff --git a/apps/web/src/components/BranchToolbarBranchSelector.tsx b/apps/web/src/components/BranchToolbarBranchSelector.tsx index 77f8ffd49ec..f578cd9af32 100644 --- a/apps/web/src/components/BranchToolbarBranchSelector.tsx +++ b/apps/web/src/components/BranchToolbarBranchSelector.tsx @@ -37,6 +37,7 @@ import { THREAD_DETAILS_PANEL_ICON_CLASS, THREAD_DETAILS_PANEL_ROW_POPUP_CLASS, THREAD_DETAILS_PANEL_ROW_CLASS, + THREAD_DETAILS_PANEL_SELECT_ROW_CLASS, } from "./chat/threadDetailsPanelStyles"; import { parsePullRequestReference } from "../pullRequestReference"; import { getSourceControlPresentation } from "../sourceControlPresentation"; @@ -761,7 +762,7 @@ export function BranchToolbarBranchSelector({ render={ +