Skip to content

Commit 6ebe284

Browse files
sharzikiclaude
andauthored
fix(cli): /clear dismisses active /btw side-question dialog (#3431)
The /clear command cleared the history log but left an active /btw side-question dialog visible in the fixed bottom area, because /btw stores state in dedicated btwItem state (via setBtwItem) rather than in history items. The ui.clear callback only called clearItems() and clearScreen(), never cancelBtw(), so the pending-btw dialog survived. Call cancelBtw() from ui.clear so /clear (and /reset, /new) abort any in-flight btw request and null out the btwItem state. Fixes #3334 Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
1 parent f7ebc37 commit 6ebe284

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

packages/cli/src/ui/hooks/slashCommandProcessor.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type {
1414
} from '../commands/types.js';
1515
import { CommandKind } from '../commands/types.js';
1616
import type { LoadedSettings } from '../../config/settings.js';
17+
import type { HistoryItemBtw } from '../types.js';
1718
import { MessageType } from '../types.js';
1819
import { BuiltinCommandLoader } from '../../services/BuiltinCommandLoader.js';
1920
import { FileCommandLoader } from '../../services/FileCommandLoader.js';
@@ -1124,4 +1125,53 @@ describe('useSlashCommandProcessor', () => {
11241125
expect(logSlashCommand).not.toHaveBeenCalled();
11251126
});
11261127
});
1128+
1129+
describe('ui.clear and /btw dialog', () => {
1130+
it('should dismiss an active btw dialog when ui.clear is called', async () => {
1131+
const result = setupProcessorHook();
1132+
await waitFor(() => expect(result.current.commandContext).toBeDefined());
1133+
1134+
const btwItem: HistoryItemBtw = {
1135+
type: MessageType.BTW,
1136+
btw: { question: 'why?', answer: '', isPending: true },
1137+
};
1138+
1139+
act(() => {
1140+
result.current.commandContext.ui.setBtwItem(btwItem);
1141+
});
1142+
await waitFor(() => {
1143+
expect(result.current.commandContext.ui.btwItem).toEqual(btwItem);
1144+
});
1145+
1146+
act(() => {
1147+
result.current.commandContext.ui.clear();
1148+
});
1149+
1150+
await waitFor(() => {
1151+
expect(result.current.commandContext.ui.btwItem).toBeNull();
1152+
});
1153+
});
1154+
1155+
it('should abort the in-flight btw request when ui.clear is called', async () => {
1156+
const result = setupProcessorHook();
1157+
await waitFor(() => expect(result.current.commandContext).toBeDefined());
1158+
1159+
const abortController = new AbortController();
1160+
const abortSpy = vi.spyOn(abortController, 'abort');
1161+
1162+
act(() => {
1163+
result.current.commandContext.ui.btwAbortControllerRef.current =
1164+
abortController;
1165+
});
1166+
1167+
act(() => {
1168+
result.current.commandContext.ui.clear();
1169+
});
1170+
1171+
expect(abortSpy).toHaveBeenCalledTimes(1);
1172+
expect(
1173+
result.current.commandContext.ui.btwAbortControllerRef.current,
1174+
).toBeNull();
1175+
});
1176+
});
11271177
});

packages/cli/src/ui/hooks/slashCommandProcessor.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ export const useSlashCommandProcessor = (
259259
ui: {
260260
addItem,
261261
clear: () => {
262+
cancelBtw();
262263
clearItems();
263264
clearScreen();
264265
refreshStatic();

0 commit comments

Comments
 (0)