diff --git a/desktop/src/__tests__/generalSettings.test.tsx b/desktop/src/__tests__/generalSettings.test.tsx index 872f1208..1e484376 100644 --- a/desktop/src/__tests__/generalSettings.test.tsx +++ b/desktop/src/__tests__/generalSettings.test.tsx @@ -1379,6 +1379,13 @@ describe('Settings > About tab', () => { }) }) + it('shows the current product name', async () => { + render() + + expect(await screen.findByRole('heading', { name: 'Code Council' })).toBeInTheDocument() + expect(screen.getByAltText('Code Council')).toBeInTheDocument() + }) + it('renders release notes with markdown formatting', async () => { render() diff --git a/desktop/src/pages/Settings.tsx b/desktop/src/pages/Settings.tsx index ec15292d..02393e86 100644 --- a/desktop/src/pages/Settings.tsx +++ b/desktop/src/pages/Settings.tsx @@ -4142,8 +4142,8 @@ function AboutSettings() { return (
{/* Logo + App Name + Version */} - Claude Code Haha -

Claude Code Haha

+ Code Council +

Code Council

{version && (
{t('settings.about.version')} {version} diff --git a/desktop/src/stores/chatStore.test.ts b/desktop/src/stores/chatStore.test.ts index 014da03b..52ae5877 100644 --- a/desktop/src/stores/chatStore.test.ts +++ b/desktop/src/stores/chatStore.test.ts @@ -186,7 +186,7 @@ describe('chatStore history mapping', () => { sessionStoreSnapshot.sessions = [] cliTaskStoreSnapshot.tasks = [] cliTaskStoreSnapshot.sessionId = null - useSessionRuntimeStore.setState({ selections: {} }) + useSessionRuntimeStore.setState({ selections: {}, coordinatorModes: {}, soloPipelineModes: {} }) localStorage.clear() useChatStore.setState({ ...initialState, @@ -1606,6 +1606,31 @@ describe('chatStore history mapping', () => { ) }) + it('replays Solo Pipeline mode immediately before sending a user turn', () => { + useSessionRuntimeStore.setState({ coordinatorModes: {}, soloPipelineModes: { [TEST_SESSION_ID]: true } }) + useChatStore.setState({ + sessions: { + [TEST_SESSION_ID]: makeSession({ chatState: 'idle' }), + }, + }) + + useChatStore.getState().sendMessage(TEST_SESSION_ID, '继续 solo') + + expect(sendMock).toHaveBeenNthCalledWith(1, TEST_SESSION_ID, { + type: 'set_coordinator_mode', + enabled: false, + }) + expect(sendMock).toHaveBeenNthCalledWith(2, TEST_SESSION_ID, { + type: 'set_pipeline_mode', + flavor: 'solo', + }) + expect(sendMock).toHaveBeenNthCalledWith(3, TEST_SESSION_ID, { + type: 'user_message', + content: '继续 solo', + attachments: undefined, + }) + }) + it('can send a visual selection turn without rendering the full model prompt as user text', () => { useChatStore.setState({ sessions: { @@ -4460,7 +4485,7 @@ describe('chatStore context-exhausted suggestion (方案3)', () => { sendMock.mockReset() getMemberBySessionIdMock.mockReset() getMemberBySessionIdMock.mockReturnValue(null) - useSessionRuntimeStore.setState({ selections: {} }) + useSessionRuntimeStore.setState({ selections: {}, coordinatorModes: {}, soloPipelineModes: {} }) useChatStore.setState({ ...initialState, sessions: {} }) // Reset the module-level compaction-thrash tracking for this session id. useChatStore.getState().clearMessages(SID) @@ -4521,7 +4546,7 @@ describe('chatStore message queue', () => { sendMock.mockReset() getMemberBySessionIdMock.mockReset() getMemberBySessionIdMock.mockReturnValue(null) - useSessionRuntimeStore.setState({ selections: {} }) + useSessionRuntimeStore.setState({ selections: {}, coordinatorModes: {}, soloPipelineModes: {} }) useChatStore.setState({ ...initialState, sessions: {} }) }) diff --git a/desktop/src/stores/chatStore.ts b/desktop/src/stores/chatStore.ts index a19c2980..bbd9fb6c 100644 --- a/desktop/src/stores/chatStore.ts +++ b/desktop/src/stores/chatStore.ts @@ -1176,6 +1176,23 @@ export const useChatStore = create((set, get) => ({ // 方案3: count this as a real user turn so rapid re-compaction (thrash) // can be told apart from compactions spread across genuine work. noteUserTurnForCompactionThrash(sessionId) + + // 每次真实用户回合前都把服务端运行模式对齐一次。 + // 这样即使 renderer 重连或服务端清理了内存标记,UI 里仍开启的 + // Solo/协调模式也会在本轮消息前重新生效。 + const runtimeModes = useSessionRuntimeStore.getState() + const coordinatorEnabled = runtimeModes.coordinatorModes[sessionId] ?? false + const soloPipelineEnabled = runtimeModes.soloPipelineModes[sessionId] ?? false + if (soloPipelineEnabled) { + wsManager.send(sessionId, { type: 'set_coordinator_mode', enabled: false }) + wsManager.send(sessionId, { type: 'set_pipeline_mode', flavor: 'solo' }) + } else if (coordinatorEnabled) { + wsManager.send(sessionId, { type: 'set_pipeline_mode', flavor: 'normal' }) + wsManager.send(sessionId, { type: 'set_coordinator_mode', enabled: true }) + } else { + wsManager.send(sessionId, { type: 'set_coordinator_mode', enabled: false }) + wsManager.send(sessionId, { type: 'set_pipeline_mode', flavor: 'normal' }) + } wsManager.send(sessionId, { type: 'user_message', content, attachments: serverAttachments }) },