fix: hide empty current session from sessions list (#13)

* fix: hide empty current session from sessions list

* chore: add changeset for session picker fix

* fix: use TUI content state for session picker filtering

---------

Co-authored-by: qer <wbxl2000@outlook.com>
This commit is contained in:
liruifengv 2026-05-25 14:50:29 +08:00 committed by GitHub
parent 89ea8959eb
commit 35726d7a41
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 95 additions and 8 deletions

View file

@ -0,0 +1,5 @@
---
"@moonshot-ai/kimi-code": patch
---
Hide the empty current session from the sessions picker while keeping other empty sessions visible.

View file

@ -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 {

View file

@ -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,
}));
}

View file

@ -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']);
});
});