From 5b8ce440ea1c062de413c8a33c119ffce3e41c2d Mon Sep 17 00:00:00 2001 From: Alexander Farber Date: Thu, 11 Dec 2025 12:22:48 +0100 Subject: [PATCH 1/3] Show session resume command on exit --- packages/cli/src/i18n/locales/en.js | 1 + packages/cli/src/i18n/locales/zh.js | 1 + .../components/SessionSummaryDisplay.test.tsx | 8 +++++- .../ui/components/SessionSummaryDisplay.tsx | 27 ++++++++++++++----- .../SessionSummaryDisplay.test.tsx.snap | 8 +++--- 5 files changed, 35 insertions(+), 10 deletions(-) diff --git a/packages/cli/src/i18n/locales/en.js b/packages/cli/src/i18n/locales/en.js index c2217757..dec11869 100644 --- a/packages/cli/src/i18n/locales/en.js +++ b/packages/cli/src/i18n/locales/en.js @@ -867,6 +867,7 @@ export default { // Exit Screen / Stats // ============================================================================ 'Agent powering down. Goodbye!': 'Agent powering down. Goodbye!', + 'To continue this session, run': 'To continue this session, run', 'Interaction Summary': 'Interaction Summary', 'Session ID:': 'Session ID:', 'Tool Calls:': 'Tool Calls:', diff --git a/packages/cli/src/i18n/locales/zh.js b/packages/cli/src/i18n/locales/zh.js index adeb85f1..dc00d068 100644 --- a/packages/cli/src/i18n/locales/zh.js +++ b/packages/cli/src/i18n/locales/zh.js @@ -820,6 +820,7 @@ export default { // Exit Screen / Stats // ============================================================================ 'Agent powering down. Goodbye!': 'Qwen Code 正在关闭,再见!', + 'To continue this session, run': '要继续此会话,请运行', 'Interaction Summary': '交互摘要', 'Session ID:': '会话 ID:', 'Tool Calls:': '工具调用:', diff --git a/packages/cli/src/ui/components/SessionSummaryDisplay.test.tsx b/packages/cli/src/ui/components/SessionSummaryDisplay.test.tsx index 766e851a..b4527703 100644 --- a/packages/cli/src/ui/components/SessionSummaryDisplay.test.tsx +++ b/packages/cli/src/ui/components/SessionSummaryDisplay.test.tsx @@ -20,9 +20,13 @@ vi.mock('../contexts/SessionContext.js', async (importOriginal) => { const useSessionStatsMock = vi.mocked(SessionContext.useSessionStats); -const renderWithMockedStats = (metrics: SessionMetrics) => { +const renderWithMockedStats = ( + metrics: SessionMetrics, + sessionId: string = 'test-session-id-12345', +) => { useSessionStatsMock.mockReturnValue({ stats: { + sessionId, sessionStartTime: new Date(), metrics, lastPromptTokenCount: 0, @@ -70,6 +74,8 @@ describe('', () => { const output = lastFrame(); expect(output).toContain('Agent powering down. Goodbye!'); + expect(output).toContain('To continue this session, run'); + expect(output).toContain('qwen --resume test-session-id-12345'); expect(output).toMatchSnapshot(); }); }); diff --git a/packages/cli/src/ui/components/SessionSummaryDisplay.tsx b/packages/cli/src/ui/components/SessionSummaryDisplay.tsx index c8d79e0e..a5a1726e 100644 --- a/packages/cli/src/ui/components/SessionSummaryDisplay.tsx +++ b/packages/cli/src/ui/components/SessionSummaryDisplay.tsx @@ -5,7 +5,10 @@ */ import type React from 'react'; +import { Box, Text } from 'ink'; import { StatsDisplay } from './StatsDisplay.js'; +import { useSessionStats } from '../contexts/SessionContext.js'; +import { theme } from '../semantic-colors.js'; import { t } from '../../i18n/index.js'; interface SessionSummaryDisplayProps { @@ -14,9 +17,21 @@ interface SessionSummaryDisplayProps { export const SessionSummaryDisplay: React.FC = ({ duration, -}) => ( - -); +}) => { + const { stats } = useSessionStats(); + + return ( + <> + + + + {t('To continue this session, run')}{' '} + qwen --resume {stats.sessionId} + + + + ); +}; diff --git a/packages/cli/src/ui/components/__snapshots__/SessionSummaryDisplay.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/SessionSummaryDisplay.test.tsx.snap index 7c925f72..2e545631 100644 --- a/packages/cli/src/ui/components/__snapshots__/SessionSummaryDisplay.test.tsx.snap +++ b/packages/cli/src/ui/components/__snapshots__/SessionSummaryDisplay.test.tsx.snap @@ -6,7 +6,7 @@ exports[` > renders the summary display with a title 1` │ Agent powering down. Goodbye! │ │ │ │ Interaction Summary │ -│ Session ID: │ +│ Session ID: test-session-id-12345 │ │ Tool Calls: 0 ( ✓ 0 x 0 ) │ │ Success Rate: 0.0% │ │ Code Changes: +42 -15 │ @@ -20,11 +20,13 @@ exports[` > renders the summary display with a title 1` │ │ │ Model Usage Reqs Input Tokens Output Tokens │ │ ─────────────────────────────────────────────────────────────── │ -│ gemini-2.5-pro 10 1,000 2,000 │ +│ gemini-2.5-pro 10 1.000 2.000 │ │ │ │ Savings Highlight: 500 (50.0%) of input tokens were served from the cache, reducing costs. │ │ │ │ » Tip: For a full token breakdown, run \`/stats model\`. │ │ │ -╰──────────────────────────────────────────────────────────────────────────────────────────────────╯" +╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ + +To continue this session, run qwen --resume test-session-id-12345" `; From b67ee32481247d26fb86af545a1177310b89ae25 Mon Sep 17 00:00:00 2001 From: Alexander Farber Date: Thu, 11 Dec 2025 12:53:30 +0100 Subject: [PATCH 2/3] Update snapshots --- .../__snapshots__/SessionSummaryDisplay.test.tsx.snap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/ui/components/__snapshots__/SessionSummaryDisplay.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/SessionSummaryDisplay.test.tsx.snap index 2e545631..dfa39ba8 100644 --- a/packages/cli/src/ui/components/__snapshots__/SessionSummaryDisplay.test.tsx.snap +++ b/packages/cli/src/ui/components/__snapshots__/SessionSummaryDisplay.test.tsx.snap @@ -20,7 +20,7 @@ exports[` > renders the summary display with a title 1` │ │ │ Model Usage Reqs Input Tokens Output Tokens │ │ ─────────────────────────────────────────────────────────────── │ -│ gemini-2.5-pro 10 1.000 2.000 │ +│ gemini-2.5-pro 10 1,000 2,000 │ │ │ │ Savings Highlight: 500 (50.0%) of input tokens were served from the cache, reducing costs. │ │ │ From ba3b5769065b926fa79fcdb2cee12d50a1a66dbb Mon Sep 17 00:00:00 2001 From: Alexander Farber Date: Thu, 11 Dec 2025 13:10:01 +0100 Subject: [PATCH 3/3] Hide resume message when session has no messages --- .../components/SessionSummaryDisplay.test.tsx | 35 +++++++++++++++++-- .../ui/components/SessionSummaryDisplay.tsx | 19 ++++++---- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/packages/cli/src/ui/components/SessionSummaryDisplay.test.tsx b/packages/cli/src/ui/components/SessionSummaryDisplay.test.tsx index b4527703..19aa3af8 100644 --- a/packages/cli/src/ui/components/SessionSummaryDisplay.test.tsx +++ b/packages/cli/src/ui/components/SessionSummaryDisplay.test.tsx @@ -23,6 +23,7 @@ const useSessionStatsMock = vi.mocked(SessionContext.useSessionStats); const renderWithMockedStats = ( metrics: SessionMetrics, sessionId: string = 'test-session-id-12345', + promptCount: number = 5, ) => { useSessionStatsMock.mockReturnValue({ stats: { @@ -30,10 +31,10 @@ const renderWithMockedStats = ( sessionStartTime: new Date(), metrics, lastPromptTokenCount: 0, - promptCount: 5, + promptCount, }, - getPromptCount: () => 5, + getPromptCount: () => promptCount, startNewPrompt: vi.fn(), }); @@ -78,4 +79,34 @@ describe('', () => { expect(output).toContain('qwen --resume test-session-id-12345'); expect(output).toMatchSnapshot(); }); + + it('does not show resume message when there are no messages', () => { + const metrics: SessionMetrics = { + models: {}, + tools: { + totalCalls: 0, + totalSuccess: 0, + totalFail: 0, + totalDurationMs: 0, + totalDecisions: { accept: 0, reject: 0, modify: 0 }, + byName: {}, + }, + files: { + totalLinesAdded: 0, + totalLinesRemoved: 0, + }, + }; + + // Pass promptCount = 0 to simulate no messages + const { lastFrame } = renderWithMockedStats( + metrics, + 'test-session-id-12345', + 0, + ); + const output = lastFrame(); + + expect(output).toContain('Agent powering down. Goodbye!'); + expect(output).not.toContain('To continue this session, run'); + expect(output).not.toContain('qwen --resume'); + }); }); diff --git a/packages/cli/src/ui/components/SessionSummaryDisplay.tsx b/packages/cli/src/ui/components/SessionSummaryDisplay.tsx index a5a1726e..c38edc75 100644 --- a/packages/cli/src/ui/components/SessionSummaryDisplay.tsx +++ b/packages/cli/src/ui/components/SessionSummaryDisplay.tsx @@ -20,18 +20,25 @@ export const SessionSummaryDisplay: React.FC = ({ }) => { const { stats } = useSessionStats(); + // Only show the resume message if there were messages in the session + const hasMessages = stats.promptCount > 0; + return ( <> - - - {t('To continue this session, run')}{' '} - qwen --resume {stats.sessionId} - - + {hasMessages && ( + + + {t('To continue this session, run')}{' '} + + qwen --resume {stats.sessionId} + + + + )} ); };