fix(tui): keep the read-only /add-dir forms session-less

The bare and `list` forms already tolerate a missing session, but the
blanket lazy-create gate forced a session (or failed with LLM-not-set)
before they could run. Only the path-adding form needs a live session, so
it now lazy-creates inside the handler instead of in the dispatch
preflight.
This commit is contained in:
liruifengv 2026-07-31 17:42:52 +08:00
parent c5e87a1ccd
commit c7392b65bf
3 changed files with 42 additions and 4 deletions

View file

@ -6,7 +6,7 @@ type AddDirChoice = 'session' | 'remember' | 'cancel';
export async function handleAddDirCommand(host: SlashCommandHost, args: string): Promise<void> {
const input = args.trim();
const session = host.session;
let session = host.session;
if (input.length === 0 || input.toLowerCase() === 'list') {
const additionalDirs = session?.summary?.additionalDirs ?? [];
@ -19,8 +19,14 @@ export async function handleAddDirCommand(host: SlashCommandHost, args: string):
}
if (session === undefined) {
host.showError(NO_ACTIVE_SESSION_MESSAGE);
return;
if (!host.engineV2) {
host.showError(NO_ACTIVE_SESSION_MESSAGE);
return;
}
// The path-adding form needs a live session; lazy-create it on first use
// (the read-only `list`/bare forms above tolerate a missing session).
session = await host.ensureSession();
if (session === undefined) return;
}
host.mountEditorReplacement(

View file

@ -310,7 +310,6 @@ async function ensureSessionForCommand(host: SlashCommandHost): Promise<Session
/** Builtin commands that need an active session; lazy-created on the v2 engine. */
const SESSION_REQUIRING_COMMANDS: ReadonlySet<BuiltinSlashCommandName> = new Set([
'add-dir',
'auto',
'btw',
'compact',

View file

@ -762,6 +762,39 @@ describe('KimiTUI message flow', () => {
expect(driver.state.appState.sessionId).toBe('');
});
it('lists additional directories without creating a session (v2 engine)', async () => {
const session = makeSession({ id: 'ses-lazy' });
const startupInput: KimiTUIStartupInput = {
...makeStartupInput(),
engineV2: true,
// No model configured: the read-only form must still work.
cliOptions: { ...makeStartupInput().cliOptions },
};
const { driver, harness } = await makeDriver(session, {}, startupInput);
driver.handleUserInput('/add-dir list');
expect(harness.createSession).not.toHaveBeenCalled();
expect(driver.state.appState.sessionId).toBe('');
});
it('lazily creates the session when adding a directory (v2 engine)', async () => {
const session = makeSession({ id: 'ses-lazy' });
const startupInput: KimiTUIStartupInput = {
...makeStartupInput(),
engineV2: true,
cliOptions: { ...makeStartupInput().cliOptions, model: 'k2' },
};
const { driver, harness } = await makeDriver(session, {}, startupInput);
driver.handleUserInput('/add-dir /tmp/extra');
await vi.waitFor(() => {
expect(driver.getCurrentSessionId()).toBe('ses-lazy');
});
expect(harness.createSession).toHaveBeenCalledTimes(1);
});
it('tracks /clear as the clear alias for /new', async () => {
const { driver, harness } = await makeDriver(makeSession({ id: 'ses-1' }));
const nextSession = makeSession({ id: 'ses-2' });