From 291dd3e07dfce962f1bffef71e66d70d4a13826d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=98=BF=E6=B1=9F=28Relakkes?= =?UTF-8?q?=29?= Date: Sat, 16 May 2026 01:44:42 +0800 Subject: [PATCH] Refine goal UI around memory theme tokens Goal status needed to read like persistent agent state, not a success alert. Reuse the Memory surface language and expose goal-specific aliases so the visual treatment follows each supported desktop theme.\n\nConstraint: Must keep /goal visible in both active-session chrome and transcript events.\nRejected: Continue using success tokens | they made the UI look like a warning/success card and clashed with white/dark themes.\nConfidence: high\nScope-risk: narrow\nTested: cd desktop && bun run test -- --run src/pages/ActiveSession.test.tsx src/components/chat/MessageList.test.tsx src/theme/globals.test.ts\nTested: cd desktop && bun run lint\nTested: cd desktop && bun run build\nTested: Chrome screenshot fixture for light, white, and dark goal UI tokens. --- desktop/src/components/chat/MessageList.tsx | 27 ++++++++++----- desktop/src/pages/ActiveSession.tsx | 37 +++++++++++++++------ desktop/src/theme/globals.css | 18 ++++++++++ desktop/src/theme/globals.test.ts | 6 ++++ 4 files changed, 68 insertions(+), 20 deletions(-) diff --git a/desktop/src/components/chat/MessageList.tsx b/desktop/src/components/chat/MessageList.tsx index 1c6395c4..4f06c291 100644 --- a/desktop/src/components/chat/MessageList.tsx +++ b/desktop/src/components/chat/MessageList.tsx @@ -153,8 +153,7 @@ function GoalEventCard({ message }: { message: GoalEvent }) { const t = useTranslation() const titleKey = `chat.goalEvent.${message.action === 'status' ? 'statusTitle' : message.action}` as TranslationKey const title = t(titleKey) === titleKey ? t('chat.goalEvent.message') : t(titleKey) - const details = [ - message.objective ? t('chat.goalEvent.objective', { value: message.objective }) : null, + const metaDetails = [ message.status ? t('chat.goalEvent.statusValue', { value: message.status }) : null, message.budget ? t('chat.goalEvent.budget', { value: message.budget }) : null, message.continuations ? t('chat.goalEvent.continuations', { value: message.continuations }) : null, @@ -162,23 +161,33 @@ function GoalEventCard({ message }: { message: GoalEvent }) { return (
-
-
+
+
{title}
- {details.length > 0 ? ( -
- {details.map((detail) => ( -
{detail}
- ))} + {message.objective ? ( +
+ {t('chat.goalEvent.objective', { value: message.objective })}
) : message.message ? (
{message.message}
) : null} + {metaDetails.length > 0 && ( +
+ {metaDetails.map((detail) => ( + + {detail} + + ))} +
+ )}
diff --git a/desktop/src/pages/ActiveSession.tsx b/desktop/src/pages/ActiveSession.tsx index 1bac497a..5f35156a 100644 --- a/desktop/src/pages/ActiveSession.tsx +++ b/desktop/src/pages/ActiveSession.tsx @@ -223,31 +223,46 @@ function GoalStatusPanel({ data-testid="active-goal-panel" className={ compact - ? 'border-b border-[var(--color-success)]/20 bg-[var(--color-success)]/6 px-4 py-2' - : 'mx-auto w-full max-w-[860px] border-b border-[var(--color-success)]/20 px-8 py-2' + ? 'border-b border-[var(--color-border)] bg-[var(--color-surface-container-lowest)] px-4 py-2' + : 'mx-auto w-full max-w-[900px] px-8 py-2.5' } > -
- track_changes +
+ + track_changes +
- + {t('chat.activeGoal.title')} - + + {goal.objective && ( - + {goal.objective} )}
{(goal.budget || goal.continuations || goal.elapsed) && ( -
- {goal.budget && {t('chat.activeGoal.budget', { value: goal.budget })}} - {goal.continuations && {t('chat.activeGoal.continuations', { value: goal.continuations })}} - {goal.elapsed && {t('chat.activeGoal.elapsed', { value: goal.elapsed })}} +
+ {goal.budget && ( + + {t('chat.activeGoal.budget', { value: goal.budget })} + + )} + {goal.continuations && ( + + {t('chat.activeGoal.continuations', { value: goal.continuations })} + + )} + {goal.elapsed && ( + + {t('chat.activeGoal.elapsed', { value: goal.elapsed })} + + )}
)}
diff --git a/desktop/src/theme/globals.css b/desktop/src/theme/globals.css index 88e7a40d..97f04215 100644 --- a/desktop/src/theme/globals.css +++ b/desktop/src/theme/globals.css @@ -370,6 +370,12 @@ --color-memory-surface: #F6FAF8; --color-memory-border: #BCCDC8; --color-memory-icon-bg: #F3F8F7; + --color-goal-accent: var(--color-memory-accent); + --color-goal-surface: var(--color-memory-surface); + --color-goal-border: var(--color-memory-border); + --color-goal-icon-bg: var(--color-memory-icon-bg); + --color-goal-chip-bg: var(--color-surface); + --color-goal-chip-border: var(--color-border); --color-model-option-selected-bg: var(--color-primary-fixed); --color-model-option-selected-border: rgba(143, 72, 47, 0.2); --color-activity-heat-0: var(--color-surface-container); @@ -571,6 +577,12 @@ --color-memory-surface: #F3F8F7; --color-memory-border: #AECBC9; --color-memory-icon-bg: #EDF7F6; + --color-goal-accent: var(--color-memory-accent); + --color-goal-surface: var(--color-memory-surface); + --color-goal-border: var(--color-memory-border); + --color-goal-icon-bg: var(--color-memory-icon-bg); + --color-goal-chip-bg: var(--color-surface); + --color-goal-chip-border: var(--color-border); --color-model-option-selected-bg: #FFF0EA; --color-model-option-selected-border: rgba(143, 72, 47, 0.2); --color-activity-heat-0: #EEF2F6; @@ -749,6 +761,12 @@ --color-memory-surface: #1D2423; --color-memory-border: #334743; --color-memory-icon-bg: #22302E; + --color-goal-accent: var(--color-memory-accent); + --color-goal-surface: var(--color-memory-surface); + --color-goal-border: var(--color-memory-border); + --color-goal-icon-bg: var(--color-memory-icon-bg); + --color-goal-chip-bg: var(--color-surface-container-low); + --color-goal-chip-border: var(--color-border); --color-model-option-selected-bg: rgba(255, 181, 159, 0.13); --color-model-option-selected-border: rgba(255, 181, 159, 0.34); --color-activity-heat-0: #242322; diff --git a/desktop/src/theme/globals.test.ts b/desktop/src/theme/globals.test.ts index ca624c33..6584d978 100644 --- a/desktop/src/theme/globals.test.ts +++ b/desktop/src/theme/globals.test.ts @@ -49,6 +49,12 @@ describe('desktop theme tokens', () => { '--color-info', '--color-info-container', '--color-warning-container', + '--color-goal-accent', + '--color-goal-surface', + '--color-goal-border', + '--color-goal-icon-bg', + '--color-goal-chip-bg', + '--color-goal-chip-border', '--color-text-secondary-a72', '--color-text-secondary-a68', '--color-text-primary-a88',