diff --git a/.changeset/hide-empty-current-session.md b/.changeset/hide-empty-current-session.md new file mode 100644 index 000000000..5f490925a --- /dev/null +++ b/.changeset/hide-empty-current-session.md @@ -0,0 +1,5 @@ +--- +"@moonshot-ai/kimi-code": patch +--- + +Hide the empty current session from the sessions picker while keeping other empty sessions visible. diff --git a/apps/kimi-code/src/tui/kimi-tui.ts b/apps/kimi-code/src/tui/kimi-tui.ts index 92021068f..ada55d506 100644 --- a/apps/kimi-code/src/tui/kimi-tui.ts +++ b/apps/kimi-code/src/tui/kimi-tui.ts @@ -227,6 +227,7 @@ import { } from './utils/mcp-server-status'; import { openUrl } from './utils/open-url'; import { setProcessTitle } from './utils/proctitle'; +import { sessionRowsForPicker } from './utils/session-picker-rows'; import { installTerminalFocusTracking } from './utils/terminal-focus'; import { notifyTerminalOnce } from './utils/terminal-notification'; import { createTerminalState, type TerminalState } from './utils/terminal-state'; @@ -1866,14 +1867,11 @@ export class KimiTUI { this.state.loadingSessions = true; try { const sessions = await this.harness.listSessions({ workDir: this.state.appState.workDir }); - this.state.sessions = sessions.map((session) => ({ - id: session.id, - title: session.title ?? null, - last_prompt: session.lastPrompt ?? null, - work_dir: session.workDir, - updated_at: session.updatedAt ?? session.createdAt ?? 0, - metadata: session.metadata, - })); + this.state.sessions = sessionRowsForPicker( + sessions, + this.state.appState.sessionId, + this.hasSessionContent(), + ); } catch { /* silently ignore */ } finally { diff --git a/apps/kimi-code/src/tui/utils/session-picker-rows.ts b/apps/kimi-code/src/tui/utils/session-picker-rows.ts new file mode 100644 index 000000000..55e063246 --- /dev/null +++ b/apps/kimi-code/src/tui/utils/session-picker-rows.ts @@ -0,0 +1,20 @@ +import type { SessionSummary } from '@moonshot-ai/kimi-code-sdk'; + +import type { SessionRow } from '#/tui/components/dialogs/session-picker'; + +export function sessionRowsForPicker( + sessions: readonly SessionSummary[], + currentSessionId: string, + currentSessionHasContent: boolean, +): SessionRow[] { + return sessions + .filter((session) => currentSessionHasContent || session.id !== currentSessionId) + .map((session) => ({ + id: session.id, + title: session.title ?? null, + last_prompt: session.lastPrompt ?? null, + work_dir: session.workDir, + updated_at: session.updatedAt ?? session.createdAt ?? 0, + metadata: session.metadata, + })); +} diff --git a/apps/kimi-code/test/tui/utils/session-picker-rows.test.ts b/apps/kimi-code/test/tui/utils/session-picker-rows.test.ts new file mode 100644 index 000000000..30d56969c --- /dev/null +++ b/apps/kimi-code/test/tui/utils/session-picker-rows.test.ts @@ -0,0 +1,64 @@ +import type { SessionSummary } from '@moonshot-ai/kimi-code-sdk'; +import { describe, expect, it } from 'vitest'; + +import { sessionRowsForPicker } from '#/tui/utils/session-picker-rows'; + +function summary(input: { + readonly id: string; + readonly title?: string; + readonly lastPrompt?: string; +}): SessionSummary { + return { + id: input.id, + title: input.title, + lastPrompt: input.lastPrompt, + workDir: '/tmp/project', + sessionDir: `/tmp/home/sessions/${input.id}`, + createdAt: 1, + updatedAt: 2, + }; +} + +describe('sessionRowsForPicker', () => { + it('omits the current session when the TUI session has no content', () => { + const rows = sessionRowsForPicker( + [ + summary({ id: 'ses_current', title: 'New Session' }), + summary({ id: 'ses_previous', title: 'New Session' }), + ], + 'ses_current', + false, + ); + + expect(rows.map((row) => row.id)).toEqual(['ses_previous']); + }); + + it('keeps the current session when the TUI session has content', () => { + const rows = sessionRowsForPicker( + [ + summary({ + id: 'ses_current', + title: 'Implement feature', + lastPrompt: 'Implement feature', + }), + ], + 'ses_current', + true, + ); + + expect(rows.map((row) => row.id)).toEqual(['ses_current']); + }); + + it('does not filter empty historical sessions', () => { + const rows = sessionRowsForPicker( + [ + summary({ id: 'ses_current', title: 'New Session' }), + summary({ id: 'ses_previous_empty', title: 'New Session' }), + ], + 'ses_current', + false, + ); + + expect(rows.map((row) => row.id)).toEqual(['ses_previous_empty']); + }); +});