From 1fdf0732b95519c8c085a73b967e144bcf1520b7 Mon Sep 17 00:00:00 2001 From: Aarav Sareen <96787824+arvsrn@users.noreply.github.com> Date: Thu, 2 Jul 2026 19:08:37 +0530 Subject: [PATCH 1/2] align sub agent ui --- .../session-ui/src/components/basic-tool.css | 52 +++++++++++++ .../src/components/message-part.tsx | 74 +++++++++++++++++-- packages/ui/src/styles/theme.css | 18 +++++ packages/ui/src/theme/v2/mapping.ts | 26 +++++++ packages/ui/src/v2/styles/theme.css | 40 ++++++++++ 5 files changed, 202 insertions(+), 8 deletions(-) diff --git a/packages/session-ui/src/components/basic-tool.css b/packages/session-ui/src/components/basic-tool.css index 7df483afe654..bda3069351de 100644 --- a/packages/session-ui/src/components/basic-tool.css +++ b/packages/session-ui/src/components/basic-tool.css @@ -230,6 +230,7 @@ line-height: var(--line-height-large); letter-spacing: var(--letter-spacing-normal); text-transform: capitalize; + color: var(--task-agent-legacy-color, var(--text-strong)); } [data-slot="basic-tool-tool-subtitle"] { @@ -247,6 +248,57 @@ } } +body[data-new-layout] { + [data-component="task-tool-card"] { + padding: 8px 12px 8px 10px; + border-radius: 8px; + border: 0; + border-color: transparent; + background: var(--task-agent-background, light-dark(#fafafa, rgba(250, 250, 250, 0.15))); + box-shadow: inset 0 0 0 0.5px var(--task-agent-border, var(--v2-border-border-base)); + + [data-component="task-tool-spinner"], + [data-component="task-tool-title"] { + color: var(--task-agent-color, var(--text-strong)); + } + + [data-component="task-tool-title"] { + height: 20px; + font-family: var(--v2-font-family-sans, "Inter", sans-serif); + font-style: normal; + font-weight: 530; + font-size: 13px; + line-height: 20px; + letter-spacing: -0.04px; + flex: none; + flex-grow: 0; + } + + [data-slot="basic-tool-tool-subtitle"] { + font-family: var(--v2-font-family-sans, "Inter", sans-serif); + font-style: normal; + font-weight: 440; + font-size: 13px; + line-height: 20px; + letter-spacing: -0.04px; + color: light-dark(var(--v2-text-text-base), #fafafa); + font-variation-settings: "slnt" 0; + flex: none; + flex-grow: 0; + } + + [data-component="session-progress-indicator-v2"] { + color: var(--task-agent-color, light-dark(var(--v2-text-text-base), #ffffff)); + } + + &:hover, + &:focus-visible { + border-color: transparent; + background: var(--task-agent-background, light-dark(#fafafa, rgba(250, 250, 250, 0.15))); + } + } +} + body:not([data-new-layout]) { [data-component="tool-trigger"] { [data-slot="basic-tool-tool-spinner"] { diff --git a/packages/session-ui/src/components/message-part.tsx b/packages/session-ui/src/components/message-part.tsx index 67f037c9139a..10b3eeab3ae7 100644 --- a/packages/session-ui/src/components/message-part.tsx +++ b/packages/session-ui/src/components/message-part.tsx @@ -53,7 +53,6 @@ import { IconButton } from "@opencode-ai/ui/icon-button" import { Icon as IconV2 } from "@opencode-ai/ui/v2/icon" import { IconButtonV2 } from "@opencode-ai/ui/v2/icon-button-v2" import { TooltipV2 } from "@opencode-ai/ui/v2/tooltip-v2" -import { Spinner } from "@opencode-ai/ui/spinner" import { TextShimmer } from "@opencode-ai/ui/text-shimmer" import { AnimatedCountList } from "./tool-count-summary" import { ToolStatusTitle } from "./tool-status-title" @@ -62,6 +61,7 @@ import { animate } from "motion" import { useLocation } from "@solidjs/router" import { attached, inline, kind } from "./message-file" import { readPartText } from "./message-part-text" +import { SessionProgressIndicatorV2 } from "../v2/components/session-progress-indicator-v2" async function writeClipboard(text: string): Promise { const body = typeof document === "undefined" ? undefined : document.body @@ -370,6 +370,44 @@ const agentTones: Record = { plan: "var(--icon-agent-plan-base)", } +const v2AgentTones: Record = { + build: { + color: "var(--v2-agent-build-solid)", + border: "var(--v2-agent-build-border)", + background: "var(--v2-agent-build-background)", + }, + explore: { + color: "var(--v2-agent-explore-solid)", + border: "var(--v2-agent-explore-border)", + background: "var(--v2-agent-explore-background)", + }, + plan: { + color: "var(--v2-agent-plan-solid)", + border: "var(--v2-agent-plan-border)", + background: "var(--v2-agent-plan-background)", + }, +} + +const agentThemeColors: Record = { + primary: "var(--text-interactive-base)", + secondary: "var(--text-base)", + accent: "var(--icon-info-base)", + success: "var(--icon-success-base)", + warning: "var(--icon-warning-base)", + error: "var(--icon-critical-base)", + info: "var(--icon-info-base)", +} + +const v2AgentThemeColors: Record = { + primary: "var(--v2-text-text-accent)", + secondary: "var(--v2-text-text-muted)", + accent: "var(--v2-icon-icon-accent)", + success: "var(--v2-state-fg-success)", + warning: "var(--v2-state-fg-warning)", + error: "var(--v2-state-fg-danger)", + info: "var(--v2-state-fg-info)", +} + const agentPalette = [ "var(--icon-agent-ask-base)", "var(--icon-agent-build-base)", @@ -394,16 +432,27 @@ function tone(name: string) { function taskAgent( raw: unknown, list?: readonly { name: string; color?: string }[], -): { name?: string; color?: string } { +): { name?: string; color?: string; v2Color?: string; border?: string; background?: string } { if (typeof raw !== "string" || !raw) return {} const key = raw.toLowerCase() const item = list?.find((entry) => entry.name === raw || entry.name.toLowerCase() === key) + const v2Tone = item?.color ? undefined : v2AgentTones[key] + const color = agentColor(item?.color, agentThemeColors) ?? agentTones[key] ?? tone(key) + const v2Color = agentColor(item?.color, v2AgentThemeColors) ?? v2Tone?.color ?? color return { name: item?.name ?? `${raw[0]!.toUpperCase()}${raw.slice(1)}`, - color: item?.color ?? agentTones[key] ?? tone(key), + color, + v2Color, + border: v2Tone?.border ?? `color-mix(in srgb, ${v2Color} 48%, transparent)`, + background: v2Tone?.background ?? `color-mix(in srgb, ${v2Color} 12%, transparent)`, } } +function agentColor(value: string | undefined, themeColors: Record) { + if (!value) return + return themeColors[value] ?? value +} + function webSearchProviderLabel(provider: unknown) { if (provider === "parallel") return "Parallel Web Search" if (provider === "exa") return "Exa Web Search" @@ -1856,6 +1905,9 @@ ToolRegistry.register({ const agent = createMemo(() => taskAgent(props.input.subagent_type, data.store.agent)) const title = createMemo(() => agent().name ?? i18n.t("ui.tool.agent.default")) const tone = createMemo(() => agent().color) + const v2Tone = createMemo(() => agent().v2Color) + const border = createMemo(() => agent().border) + const background = createMemo(() => agent().background) const subtitle = createMemo(() => { const value = typeof props.input.description === "string" && props.input.description @@ -1889,17 +1941,23 @@ ToolRegistry.register({ } const trigger = () => ( -
+
- + - - {title()} - + {title()} {subtitle()} diff --git a/packages/ui/src/styles/theme.css b/packages/ui/src/styles/theme.css index 751036598d4e..894f65e45d86 100644 --- a/packages/ui/src/styles/theme.css +++ b/packages/ui/src/styles/theme.css @@ -281,6 +281,15 @@ --icon-agent-docs-base: #fcb239; --icon-agent-ask-base: #2090f5; --icon-agent-build-base: #034cff; + --v2-agent-plan-solid: var(--v2-pink-900); + --v2-agent-plan-border: rgba(200, 61, 139, 0.5); + --v2-agent-plan-background: rgba(253, 236, 243, 0.33); + --v2-agent-build-solid: var(--v2-blue-900); + --v2-agent-build-border: rgba(59, 92, 246, 0.5); + --v2-agent-build-background: rgba(236, 241, 254, 0.33); + --v2-agent-explore-solid: var(--v2-yellow-900); + --v2-agent-explore-border: rgba(142, 114, 49, 0.5); + --v2-agent-explore-background: rgba(254, 250, 236, 0.33); --icon-on-success-base: rgba(18, 201, 5, 0.9); --icon-on-success-hover: rgba(45, 186, 38, 0.9); --icon-on-success-selected: rgba(7, 137, 1, 0.9); @@ -541,6 +550,15 @@ --icon-agent-docs-base: #fbb73c; --icon-agent-ask-base: #2090f5; --icon-agent-build-base: #9dbefe; + --v2-agent-plan-solid: var(--v2-pink-400); + --v2-agent-plan-border: rgba(250, 188, 216, 0.5); + --v2-agent-plan-background: rgba(247, 213, 228, 0.1); + --v2-agent-build-solid: var(--v2-blue-400); + --v2-agent-build-border: rgba(215, 226, 252, 0.5); + --v2-agent-build-background: rgba(215, 226, 252, 0.1); + --v2-agent-explore-solid: var(--v2-yellow-400); + --v2-agent-explore-border: rgba(247, 229, 181, 0.5); + --v2-agent-explore-background: rgba(252, 239, 208, 0.1); --icon-on-success-base: rgba(18, 201, 5, 0.9); --icon-on-success-hover: rgba(53, 192, 45, 0.9); --icon-on-success-selected: rgba(77, 225, 68, 0.9); diff --git a/packages/ui/src/theme/v2/mapping.ts b/packages/ui/src/theme/v2/mapping.ts index 5f4be5ea1ccf..9bb29fbfa9e9 100644 --- a/packages/ui/src/theme/v2/mapping.ts +++ b/packages/ui/src/theme/v2/mapping.ts @@ -3,6 +3,30 @@ import { V2_AVATAR_DARK, V2_AVATAR_LIGHT } from "./avatar" const ref = (name: string): V2ColorValue => `var(--${name})` +const lightAgentTokens: Record = { + "v2-agent-plan-solid": ref("v2-pink-900"), + "v2-agent-plan-border": "rgba(200, 61, 139, 0.5)", + "v2-agent-plan-background": "rgba(253, 236, 243, 0.33)", + "v2-agent-build-solid": ref("v2-blue-900"), + "v2-agent-build-border": "rgba(59, 92, 246, 0.5)", + "v2-agent-build-background": "rgba(236, 241, 254, 0.33)", + "v2-agent-explore-solid": ref("v2-yellow-900"), + "v2-agent-explore-border": "rgba(142, 114, 49, 0.5)", + "v2-agent-explore-background": "rgba(254, 250, 236, 0.33)", +} + +const darkAgentTokens: Record = { + "v2-agent-plan-solid": ref("v2-pink-400"), + "v2-agent-plan-border": "rgba(250, 188, 216, 0.5)", + "v2-agent-plan-background": "rgba(247, 213, 228, 0.1)", + "v2-agent-build-solid": ref("v2-blue-400"), + "v2-agent-build-border": "rgba(215, 226, 252, 0.5)", + "v2-agent-build-background": "rgba(215, 226, 252, 0.1)", + "v2-agent-explore-solid": ref("v2-yellow-400"), + "v2-agent-explore-border": "rgba(247, 229, 181, 0.5)", + "v2-agent-explore-background": "rgba(252, 239, 208, 0.1)", +} + const light: Record = { "v2-background-bg-base": ref("v2-grey-100"), "v2-background-bg-deep": ref("v2-grey-200"), @@ -46,6 +70,7 @@ const light: Record = { "v2-state-bg-info": ref("v2-blue-100"), "v2-state-fg-info": ref("v2-blue-800"), "v2-state-border-info": ref("v2-blue-300"), + ...lightAgentTokens, ...V2_AVATAR_LIGHT, "v2-elevation-raised": "0px 2px 4px 0px var(--v2-alpha-dark-4), 0px 1px 2px -1px var(--v2-alpha-dark-8), 0px 0px 0px 0.5px var(--v2-alpha-dark-12), 0px 0px 0px 0px var(--v2-alpha-dark-0)", @@ -110,6 +135,7 @@ const dark: Record = { "v2-state-bg-info": ref("v2-blue-1200"), "v2-state-fg-info": ref("v2-blue-500"), "v2-state-border-info": ref("v2-blue-900"), + ...darkAgentTokens, ...V2_AVATAR_DARK, "v2-elevation-raised": "0px 2px 4px 0px var(--v2-alpha-dark-30), 0px 1px 2px 0px var(--v2-alpha-dark-30), 0px 0px 0px 0.5px var(--v2-alpha-light-16), 0px -0.5px 0px 0px var(--v2-alpha-light-6)", diff --git a/packages/ui/src/v2/styles/theme.css b/packages/ui/src/v2/styles/theme.css index 387ee94cbbe4..5ed135b7e9cc 100644 --- a/packages/ui/src/v2/styles/theme.css +++ b/packages/ui/src/v2/styles/theme.css @@ -77,6 +77,16 @@ --v2-state-fg-info: var(--v2-blue-800); --v2-state-border-info: var(--v2-blue-300); + --v2-agent-plan-solid: var(--v2-pink-900); + --v2-agent-plan-border: rgba(200, 61, 139, 0.5); + --v2-agent-plan-background: rgba(253, 236, 243, 0.33); + --v2-agent-build-solid: var(--v2-blue-900); + --v2-agent-build-border: rgba(59, 92, 246, 0.5); + --v2-agent-build-background: rgba(236, 241, 254, 0.33); + --v2-agent-explore-solid: var(--v2-yellow-900); + --v2-agent-explore-border: rgba(142, 114, 49, 0.5); + --v2-agent-explore-background: rgba(254, 250, 236, 0.33); + /* ── Project avatar (fixed; theme-independent) ── */ --v2-avatar-fg: #ffffffff; --v2-avatar-bg-orange: #ee7330ff; @@ -193,6 +203,16 @@ --v2-state-fg-info: var(--v2-blue-500); --v2-state-border-info: var(--v2-blue-900); + --v2-agent-plan-solid: var(--v2-pink-400); + --v2-agent-plan-border: rgba(250, 188, 216, 0.5); + --v2-agent-plan-background: rgba(247, 213, 228, 0.1); + --v2-agent-build-solid: var(--v2-blue-400); + --v2-agent-build-border: rgba(215, 226, 252, 0.5); + --v2-agent-build-background: rgba(215, 226, 252, 0.1); + --v2-agent-explore-solid: var(--v2-yellow-400); + --v2-agent-explore-border: rgba(247, 229, 181, 0.5); + --v2-agent-explore-background: rgba(252, 239, 208, 0.1); + --v2-elevation-raised: 0px 2px 4px 0px var(--v2-alpha-dark-30), 0px 1px 2px 0px var(--v2-alpha-dark-30), @@ -296,6 +316,16 @@ --v2-state-fg-info: var(--v2-blue-800); --v2-state-border-info: var(--v2-blue-300); + --v2-agent-plan-solid: var(--v2-pink-900); + --v2-agent-plan-border: rgba(200, 61, 139, 0.5); + --v2-agent-plan-background: rgba(253, 236, 243, 0.33); + --v2-agent-build-solid: var(--v2-blue-900); + --v2-agent-build-border: rgba(59, 92, 246, 0.5); + --v2-agent-build-background: rgba(236, 241, 254, 0.33); + --v2-agent-explore-solid: var(--v2-yellow-900); + --v2-agent-explore-border: rgba(142, 114, 49, 0.5); + --v2-agent-explore-background: rgba(254, 250, 236, 0.33); + --v2-elevation-raised: 0px 2px 4px 0px var(--v2-alpha-dark-4), 0px 1px 2px -1px var(--v2-alpha-dark-8), 0px 0px 0px 0.5px var(--v2-alpha-dark-12), 0px 0px 0px 0px var(--v2-alpha-dark-0); @@ -406,6 +436,16 @@ --v2-state-fg-info: var(--v2-blue-500); --v2-state-border-info: var(--v2-blue-900); + --v2-agent-plan-solid: var(--v2-pink-400); + --v2-agent-plan-border: rgba(250, 188, 216, 0.5); + --v2-agent-plan-background: rgba(247, 213, 228, 0.1); + --v2-agent-build-solid: var(--v2-blue-400); + --v2-agent-build-border: rgba(215, 226, 252, 0.5); + --v2-agent-build-background: rgba(215, 226, 252, 0.1); + --v2-agent-explore-solid: var(--v2-yellow-400); + --v2-agent-explore-border: rgba(247, 229, 181, 0.5); + --v2-agent-explore-background: rgba(252, 239, 208, 0.1); + --v2-avatar-fg: #ffffffff; --v2-avatar-bg-orange: #723d22ff; --v2-avatar-border-orange: #ff8648ff; From 0478a4cab707b22e58dbe99246a091674700aac9 Mon Sep 17 00:00:00 2001 From: Aarav Sareen <96787824+arvsrn@users.noreply.github.com> Date: Thu, 2 Jul 2026 19:18:55 +0530 Subject: [PATCH 2/2] gate new spinner to v2 only --- packages/session-ui/src/components/message-part.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/session-ui/src/components/message-part.tsx b/packages/session-ui/src/components/message-part.tsx index 10b3eeab3ae7..d6ff52b4a9cc 100644 --- a/packages/session-ui/src/components/message-part.tsx +++ b/packages/session-ui/src/components/message-part.tsx @@ -53,6 +53,7 @@ import { IconButton } from "@opencode-ai/ui/icon-button" import { Icon as IconV2 } from "@opencode-ai/ui/v2/icon" import { IconButtonV2 } from "@opencode-ai/ui/v2/icon-button-v2" import { TooltipV2 } from "@opencode-ai/ui/v2/tooltip-v2" +import { Spinner } from "@opencode-ai/ui/spinner" import { TextShimmer } from "@opencode-ai/ui/text-shimmer" import { AnimatedCountList } from "./tool-count-summary" import { ToolStatusTitle } from "./tool-status-title" @@ -453,6 +454,10 @@ function agentColor(value: string | undefined, themeColors: Record - + }> + + {title()}