mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-05-18 23:42:43 +00:00
feat(cli): warn users that rewind is disabled in IDE mode (#4122)
Some checks are pending
Qwen Code CI / Classify PR (push) Waiting to run
Qwen Code CI / Lint (push) Blocked by required conditions
Qwen Code CI / Test (macos-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Test (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Test (windows-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Post Coverage Comment (push) Blocked by required conditions
Qwen Code CI / CodeQL (push) Blocked by required conditions
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
Some checks are pending
Qwen Code CI / Classify PR (push) Waiting to run
Qwen Code CI / Lint (push) Blocked by required conditions
Qwen Code CI / Test (macos-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Test (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Test (windows-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Post Coverage Comment (push) Blocked by required conditions
Qwen Code CI / CodeQL (push) Blocked by required conditions
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
This commit is contained in:
parent
df32345d05
commit
435f711e33
2 changed files with 94 additions and 3 deletions
|
|
@ -3077,6 +3077,85 @@ describe('AppContainer State Management', () => {
|
|||
expect(trigger.activeCount()).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('IDE mode rewind guard', () => {
|
||||
it('shows info message instead of opening rewind selector when IDE mode is enabled', () => {
|
||||
const mockAddItem = vi.fn();
|
||||
mockedUseHistory.mockReturnValue({
|
||||
history: [{ id: 1, type: 'user', text: 'hello' }],
|
||||
addItem: mockAddItem,
|
||||
updateItem: vi.fn(),
|
||||
clearItems: vi.fn(),
|
||||
loadHistory: vi.fn(),
|
||||
truncateToItem: vi.fn(),
|
||||
});
|
||||
mockedUseGeminiStream.mockReturnValue({
|
||||
streamingState: 'idle',
|
||||
submitQuery: vi.fn(),
|
||||
initError: null,
|
||||
pendingHistoryItems: [],
|
||||
thought: null,
|
||||
cancelOngoingRequest: vi.fn(),
|
||||
retryLastPrompt: vi.fn(),
|
||||
});
|
||||
vi.spyOn(mockConfig, 'getIdeMode').mockReturnValue(true);
|
||||
|
||||
render(
|
||||
<AppContainer
|
||||
config={mockConfig}
|
||||
settings={mockSettings}
|
||||
version="1.0.0"
|
||||
initializationResult={mockInitResult}
|
||||
/>,
|
||||
);
|
||||
|
||||
capturedUIActions.openRewindSelector();
|
||||
|
||||
expect(mockAddItem).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
type: 'info',
|
||||
text: expect.stringMatching(/rewind.*disabled.*IDE/i),
|
||||
}),
|
||||
expect.any(Number),
|
||||
);
|
||||
expect(capturedUIState.isRewindSelectorOpen).toBeFalsy();
|
||||
});
|
||||
|
||||
it('opens rewind selector normally when IDE mode is disabled', () => {
|
||||
const mockAddItemDisabled = vi.fn();
|
||||
mockedUseHistory.mockReturnValue({
|
||||
history: [{ id: 1, type: 'user', text: 'hello' }],
|
||||
addItem: mockAddItemDisabled,
|
||||
updateItem: vi.fn(),
|
||||
clearItems: vi.fn(),
|
||||
loadHistory: vi.fn(),
|
||||
truncateToItem: vi.fn(),
|
||||
});
|
||||
mockedUseGeminiStream.mockReturnValue({
|
||||
streamingState: 'idle',
|
||||
submitQuery: vi.fn(),
|
||||
initError: null,
|
||||
pendingHistoryItems: [],
|
||||
thought: null,
|
||||
cancelOngoingRequest: vi.fn(),
|
||||
retryLastPrompt: vi.fn(),
|
||||
});
|
||||
vi.spyOn(mockConfig, 'getIdeMode').mockReturnValue(false);
|
||||
|
||||
render(
|
||||
<AppContainer
|
||||
config={mockConfig}
|
||||
settings={mockSettings}
|
||||
version="1.0.0"
|
||||
initializationResult={mockInitResult}
|
||||
/>,
|
||||
);
|
||||
|
||||
capturedUIActions.openRewindSelector();
|
||||
|
||||
expect(mockAddItemDisabled).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('dedupeNewestFirst', () => {
|
||||
|
|
|
|||
|
|
@ -2160,14 +2160,25 @@ export const AppContainer = (props: AppContainerProps) => {
|
|||
}, []);
|
||||
|
||||
// --- Rewind selector callbacks ---
|
||||
// IDE guard here is NOT redundant with the keyboard handler guard (line ~2375):
|
||||
// /rewind calls openRewindSelector directly, bypassing the keyboard handler.
|
||||
const openRewindSelector = useCallback(() => {
|
||||
if (streamingState !== StreamingState.Idle) return;
|
||||
if (config.getIdeMode()) return;
|
||||
if (dialogsVisibleRef.current) return;
|
||||
if (config.getIdeMode()) {
|
||||
historyManager.addItem(
|
||||
{
|
||||
type: 'info',
|
||||
text: 'Rewind is disabled in IDE mode.',
|
||||
},
|
||||
Date.now(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
const hasUserTurns = historyManager.history.some((h) => h.type === 'user');
|
||||
if (!hasUserTurns) return;
|
||||
setIsRewindSelectorOpen(true);
|
||||
}, [streamingState, config, historyManager.history]);
|
||||
}, [streamingState, config, historyManager]);
|
||||
openRewindSelectorRef.current = openRewindSelector;
|
||||
|
||||
const closeRewindSelector = useCallback(() => {
|
||||
|
|
@ -2559,7 +2570,8 @@ export const AppContainer = (props: AppContainerProps) => {
|
|||
// Input is empty and idle — double-ESC opens rewind selector
|
||||
if (
|
||||
streamingState === StreamingState.Idle &&
|
||||
!dialogsVisibleRef.current
|
||||
!dialogsVisibleRef.current &&
|
||||
!config.getIdeMode()
|
||||
) {
|
||||
if (escapeTimerRef.current) {
|
||||
clearTimeout(escapeTimerRef.current);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue