From afb6e2794f2c870802d13e1a95ccb108d5363e36 Mon Sep 17 00:00:00 2001 From: iliya Date: Mon, 9 Mar 2026 18:15:00 +0200 Subject: [PATCH] feat: refine team provisioning and UI components for improved user experience - Updated TeamProvisioningService to prevent duplicate display of provisioning narration in the Activity timeline. - Enhanced CompactBoundary component with a cleaner design and improved interaction for expanding/collapsing content. - Added new CSS variables for compact phase badge styling to enhance visual consistency. - Modified TeamDetailView to include a collapsible status block for better organization of team information. - Improved MessageComposer to reflect provisioning status in placeholders and notifications, enhancing user awareness during team launches. - Updated ActivityTimeline to suppress session separators for reconnects within the same team, streamlining the user experience. --- .../services/team/TeamProvisioningService.ts | 11 +- .../components/chat/CompactBoundary.tsx | 125 +++++++++--------- .../components/team/TeamDetailView.tsx | 53 +++++--- .../team/TeamProvisioningBanner.tsx | 4 +- .../team/activity/ActivityTimeline.tsx | 39 ++++-- .../team/messages/MessageComposer.tsx | 22 ++- src/renderer/index.css | 8 ++ src/renderer/utils/groupTransformer.ts | 4 - 8 files changed, 157 insertions(+), 109 deletions(-) diff --git a/src/main/services/team/TeamProvisioningService.ts b/src/main/services/team/TeamProvisioningService.ts index b508e867..3a15f284 100644 --- a/src/main/services/team/TeamProvisioningService.ts +++ b/src/main/services/team/TeamProvisioningService.ts @@ -3154,14 +3154,9 @@ export class TeamProvisioningService { } } } else { - // Pre-ready: also push to live cache so Messages shows early narration - // once team:getData becomes readable. The banner still uses provisioningOutputParts. - if (!run.silentUserDmForward && !hasCapturedSendMessage) { - const cleanText = stripAgentBlocks(text).trim(); - if (cleanText.length > 0) { - this.pushLiveLeadTextMessage(run, cleanText); - } - } + // Pre-ready: provisioning narration is shown in the ProvisioningProgressBlock banner + // (via provisioningOutputParts). Do NOT push to live cache to avoid duplicate display + // and leaking internal provisioning monologue into the Activity timeline. } } diff --git a/src/renderer/components/chat/CompactBoundary.tsx b/src/renderer/components/chat/CompactBoundary.tsx index 8fb8d4b8..d23dc752 100644 --- a/src/renderer/components/chat/CompactBoundary.tsx +++ b/src/renderer/components/chat/CompactBoundary.tsx @@ -6,8 +6,6 @@ import { CODE_BORDER, COLOR_TEXT_MUTED, COLOR_TEXT_SECONDARY, - TOOL_CALL_BG, - TOOL_CALL_BORDER, TOOL_CALL_TEXT, } from '@renderer/constants/cssVariables'; import { REHYPE_PLUGINS } from '@renderer/utils/markdownPlugins'; @@ -27,14 +25,8 @@ interface CompactBoundaryProps { } /** - * CompactBoundary displays an interactive, collapsible marker indicating where - * the conversation was compacted. - * - * Features: - * - Minimalist design with subtle border and hover states - * - Click to expand/collapse compacted content - * - Scrollable content area with enforced max-height - * - Linear/Notion-inspired aesthetics + * CompactBoundary displays a horizontal divider indicating where + * the conversation was compacted. Click to expand the compacted summary. */ export const CompactBoundary = ({ compactGroup, @@ -64,70 +56,71 @@ export const CompactBoundary = ({ const compactContent = getCompactContent(); return ( -
- {/* Collapsible Header - Amber/orange accent for distinction */} +
+ {/* Divider with centered label */} {/* Expanded Content */} @@ -144,7 +137,7 @@ export const CompactBoundary = ({ {/* Content - scrollable with left accent bar */}
{compactContent ? ( s.editorPendingRevealFile); @@ -523,7 +525,7 @@ export const TeamDetailView = ({ teamName }: TeamDetailViewProps): React.JSX.Ele ); // Filter sessions to team-only using sessionHistory + leadSessionId - const teamSessions = useMemo(() => { + const teamSessionIds = useMemo(() => { const sessionIds = new Set(); if (data?.config.leadSessionId) { sessionIds.add(data.config.leadSessionId); @@ -533,10 +535,14 @@ export const TeamDetailView = ({ teamName }: TeamDetailViewProps): React.JSX.Ele sessionIds.add(id); } } + return sessionIds; + }, [data?.config.leadSessionId, data?.config.sessionHistory]); + + const teamSessions = useMemo(() => { // If no session IDs known (backward compat), show all sessions - if (sessionIds.size === 0) return sessions; - return sessions.filter((s) => sessionIds.has(s.id)); - }, [sessions, data?.config.leadSessionId, data?.config.sessionHistory]); + if (teamSessionIds.size === 0) return sessions; + return sessions.filter((s) => teamSessionIds.has(s.id)); + }, [sessions, teamSessionIds]); // Auto-reset session filter if the selected session is no longer in teamSessions useEffect(() => { @@ -1563,17 +1569,33 @@ export const TeamDetailView = ({ teamName }: TeamDetailViewProps): React.JSX.Ele }} />
- - + + {!statusBlockCollapsed && ( + <> + + + + )}
{ openCreateTaskDialog(subject, description); diff --git a/src/renderer/components/team/TeamProvisioningBanner.tsx b/src/renderer/components/team/TeamProvisioningBanner.tsx index 20006dae..fc435550 100644 --- a/src/renderer/components/team/TeamProvisioningBanner.tsx +++ b/src/renderer/components/team/TeamProvisioningBanner.tsx @@ -110,7 +110,9 @@ export const TeamProvisioningBanner = ({
-

Team launched — process alive

+

+ Team launched — teammates may still be starting +