refactor(cli): keyboard handling and AskUserDialog (#17414)

This commit is contained in:
Jacob Richman
2026-01-27 14:26:00 -08:00
committed by GitHub
parent 3103697ea7
commit b51323b40c
46 changed files with 1220 additions and 385 deletions
@@ -5,6 +5,7 @@
*/
import { render } from '../../test-utils/render.js';
import { waitFor } from '../../test-utils/async.js';
import { describe, it, expect, vi, beforeEach, type Mock } from 'vitest';
import { ApiAuthDialog } from './ApiAuthDialog.js';
import { useKeypress } from '../hooks/useKeypress.js';
@@ -132,17 +133,20 @@ describe('ApiAuthDialog', () => {
it('calls clearApiKey and clears buffer when Ctrl+C is pressed', async () => {
render(<ApiAuthDialog onSubmit={onSubmit} onCancel={onCancel} />);
// calls[0] is the ApiAuthDialog's useKeypress (Ctrl+C handler)
// Call 0 is ApiAuthDialog (isActive: true)
// Call 1 is TextInput (isActive: true, priority: true)
const keypressHandler = mockedUseKeypress.mock.calls[0][0];
await keypressHandler({
keypressHandler({
name: 'c',
shift: false,
ctrl: true,
cmd: false,
});
expect(clearApiKey).toHaveBeenCalled();
expect(mockBuffer.setText).toHaveBeenCalledWith('');
await waitFor(() => {
expect(clearApiKey).toHaveBeenCalled();
expect(mockBuffer.setText).toHaveBeenCalledWith('');
});
});
});
+4 -2
View File
@@ -86,10 +86,12 @@ export function ApiAuthDialog({
};
useKeypress(
async (key) => {
(key) => {
if (keyMatchers[Command.CLEAR_INPUT](key)) {
await handleClear();
void handleClear();
return true;
}
return false;
},
{ isActive: true },
);
+4 -2
View File
@@ -169,18 +169,20 @@ export function AuthDialog({
// Prevent exit if there is an error message.
// This means they user is not authenticated yet.
if (authError) {
return;
return true;
}
if (settings.merged.security.auth.selectedType === undefined) {
// Prevent exiting if no auth method is set
onAuthError(
'You must select an auth method to proceed. Press Ctrl+C twice to exit.',
);
return;
return true;
}
// eslint-disable-next-line @typescript-eslint/no-floating-promises
onSelect(undefined, SettingScope.User);
return true;
}
return false;
},
{ isActive: true },
);
@@ -24,6 +24,7 @@ export const LoginWithGoogleRestartDialog = ({
(key) => {
if (key.name === 'escape') {
onDismiss();
return true;
} else if (key.name === 'r' || key.name === 'R') {
setTimeout(async () => {
if (process.send) {
@@ -38,7 +39,9 @@ export const LoginWithGoogleRestartDialog = ({
await runExitCleanup();
process.exit(RELAUNCH_EXIT_CODE);
}, 100);
return true;
}
return false;
},
{ isActive: true },
);