From adbc5af95f145c157dbc3a21a5b5ec19d0100649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E5=B7=85=E5=B3=B0?= <44549369+iyangdianfeng@users.noreply.github.com> Date: Mon, 26 Jan 2026 01:09:31 +0800 Subject: [PATCH] feat(ui): add configurable text justification activity setting (#212) * fix(server): improve external server and error handling - Skip OpenCode shutdown when using external server (OPENCODE_SKIP_START=true) - Return 404 status for non-existent directories instead of empty array - Move error logging before response handling * feat(ui): add configurable text justification activity setting - Replace hardcoded ENABLE_TEXT_JUSTIFICATION_ACTIVITY constant with dynamic showTextJustificationActivity setting in useUIStore - Add toggle UI in Chat settings section (Settings > Chat) - Add setting to DesktopSettings type for cross-runtime persistence - Default value is false (matching original constant behavior) --------- Co-authored-by: iiyangdianfeng --- .../components/chat/hooks/useTurnGrouping.ts | 7 ++-- .../sections/openchamber/OpenChamberPage.tsx | 2 +- .../openchamber/OpenChamberVisualSettings.tsx | 18 ++++++++++- packages/ui/src/lib/desktop.ts | 1 + packages/ui/src/stores/useUIStore.ts | 8 +++++ packages/web/server/index.js | 32 ++++++++++--------- 6 files changed, 47 insertions(+), 21 deletions(-) diff --git a/packages/ui/src/components/chat/hooks/useTurnGrouping.ts b/packages/ui/src/components/chat/hooks/useTurnGrouping.ts index 8b0dda43..2d46fdee 100644 --- a/packages/ui/src/components/chat/hooks/useTurnGrouping.ts +++ b/packages/ui/src/components/chat/hooks/useTurnGrouping.ts @@ -73,8 +73,6 @@ interface TurnActivityInfo { diffStats?: TurnDiffStats; } -const ENABLE_TEXT_JUSTIFICATION_ACTIVITY = false; - const ACTIVITY_STANDALONE_TOOL_NAMES = new Set(['task']); const isActivityStandaloneTool = (toolName: unknown): boolean => { @@ -123,6 +121,7 @@ const extractFinalAssistantText = (turn: Turn): string | undefined => { }; const getTurnActivityInfo = (turn: Turn): TurnActivityInfo => { + const showTextJustificationActivity = useUIStore.getState().showTextJustificationActivity; interface SummaryDiff { additions?: number | null | undefined; deletions?: number | null | undefined; @@ -186,7 +185,7 @@ const getTurnActivityInfo = (turn: Turn): TurnActivityInfo => { turn.assistantMessages.forEach((msg) => { const messageId = msg.info.id; const infoFinish = (msg.info as { finish?: string | null | undefined }).finish; - const hasStopFinishInMessage = ENABLE_TEXT_JUSTIFICATION_ACTIVITY + const hasStopFinishInMessage = showTextJustificationActivity ? infoFinish === 'stop' : false; @@ -233,7 +232,7 @@ const getTurnActivityInfo = (turn: Turn): TurnActivityInfo => { } if ( - ENABLE_TEXT_JUSTIFICATION_ACTIVITY && + showTextJustificationActivity && part.type === 'text' && (hasTools || hasReasoning) && !hasStopFinishInMessage diff --git a/packages/ui/src/components/sections/openchamber/OpenChamberPage.tsx b/packages/ui/src/components/sections/openchamber/OpenChamberPage.tsx index c216a62e..44b0b825 100644 --- a/packages/ui/src/components/sections/openchamber/OpenChamberPage.tsx +++ b/packages/ui/src/components/sections/openchamber/OpenChamberPage.tsx @@ -84,7 +84,7 @@ const VisualSectionContent: React.FC = () => { // Chat section: Default Tool Output, Diff layout, Show reasoning traces, Queue mode const ChatSectionContent: React.FC = () => { - return ; + return ; }; // Sessions section: Default model & agent, Session retention, Memory limits diff --git a/packages/ui/src/components/sections/openchamber/OpenChamberVisualSettings.tsx b/packages/ui/src/components/sections/openchamber/OpenChamberVisualSettings.tsx index afdaec2e..9849c3e1 100644 --- a/packages/ui/src/components/sections/openchamber/OpenChamberVisualSettings.tsx +++ b/packages/ui/src/components/sections/openchamber/OpenChamberVisualSettings.tsx @@ -73,7 +73,7 @@ const DIFF_VIEW_MODE_OPTIONS: Option<'single' | 'stacked'>[] = [ }, ]; -export type VisibleSetting = 'theme' | 'fontSize' | 'spacing' | 'cornerRadius' | 'inputBarOffset' | 'toolOutput' | 'diffLayout' | 'dotfiles' | 'reasoning' | 'queueMode'; +export type VisibleSetting = 'theme' | 'fontSize' | 'spacing' | 'cornerRadius' | 'inputBarOffset' | 'toolOutput' | 'diffLayout' | 'dotfiles' | 'reasoning' | 'queueMode' | 'textJustificationActivity'; interface OpenChamberVisualSettingsProps { /** Which settings to show. If undefined, shows all. */ @@ -85,6 +85,8 @@ export const OpenChamberVisualSettings: React.FC const directoryShowHidden = useDirectoryShowHidden(); const showReasoningTraces = useUIStore(state => state.showReasoningTraces); const setShowReasoningTraces = useUIStore(state => state.setShowReasoningTraces); + const showTextJustificationActivity = useUIStore(state => state.showTextJustificationActivity); + const setShowTextJustificationActivity = useUIStore(state => state.setShowTextJustificationActivity); const toolCallExpansion = useUIStore(state => state.toolCallExpansion); const setToolCallExpansion = useUIStore(state => state.setToolCallExpansion); const fontSize = useUIStore(state => state.fontSize); @@ -528,6 +530,20 @@ export const OpenChamberVisualSettings: React.FC )} + {shouldShow('textJustificationActivity') && ( + + )} + {shouldShow('queueMode') && (