fix(auth): update terminology to 'sign in' and 'sign out' (#20892)

Co-authored-by: Jacob Richman <jacob314@gmail.com>
This commit is contained in:
Mark McLaughlin
2026-03-10 12:10:26 -07:00
committed by GitHub
parent b00d7c88ad
commit b404fc02e7
35 changed files with 95 additions and 78 deletions

View File

@@ -147,7 +147,7 @@ Integrate Gemini CLI directly into your GitHub workflows with
Choose the authentication method that best fits your needs:
### Option 1: Login with Google (OAuth login using your Google Account)
### Option 1: Sign in with Google (OAuth login using your Google Account)
**✨ Best for:** Individual developers as well as anyone who has a Gemini Code
Assist License. (see
@@ -161,7 +161,7 @@ for details)
- **No API key management** - just sign in with your Google account
- **Automatic updates** to latest models
#### Start Gemini CLI, then choose _Login with Google_ and follow the browser authentication flow when prompted
#### Start Gemini CLI, then choose _Sign in with Google_ and follow the browser authentication flow when prompted
```bash
gemini

View File

@@ -66,7 +66,7 @@ they appear in the UI.
| Show Line Numbers | `ui.showLineNumbers` | Show line numbers in the chat. | `true` |
| Show Citations | `ui.showCitations` | Show citations for generated text in the chat. | `false` |
| Show Model Info In Chat | `ui.showModelInfoInChat` | Show the model name in the chat for each model turn. | `false` |
| Show User Identity | `ui.showUserIdentity` | Show the logged-in user's identity (e.g. email) in the UI. | `true` |
| Show User Identity | `ui.showUserIdentity` | Show the signed-in user's identity (e.g. email) in the UI. | `true` |
| Use Alternate Screen Buffer | `ui.useAlternateBuffer` | Use an alternate screen buffer for the UI, preserving shell history. | `false` |
| Use Background Color | `ui.useBackgroundColor` | Whether to use background colors in the UI. | `true` |
| Incremental Rendering | `ui.incrementalRendering` | Enable incremental rendering for the UI. This option will reduce flickering but may cause rendering artifacts. Only supported when useAlternateBuffer is enabled. | `true` |

View File

@@ -194,7 +194,7 @@ returns coordinates and element descriptions that the browser agent uses with
the `click_at` tool for precise, coordinate-based interactions.
> **Note:** The visual agent requires API key or Vertex AI authentication. It is
> not available when using Google Login.
> not available when using "Sign in with Google".
## Creating custom subagents

View File

@@ -17,8 +17,8 @@ Select the authentication method that matches your situation in the table below:
| User Type / Scenario | Recommended Authentication Method | Google Cloud Project Required |
| :--------------------------------------------------------------------- | :--------------------------------------------------------------- | :---------------------------------------------------------- |
| Individual Google accounts | [Login with Google](#login-google) | No, with exceptions |
| Organization users with a company, school, or Google Workspace account | [Login with Google](#login-google) | [Yes](#set-gcp) |
| Individual Google accounts | [Sign in with Google](#login-google) | No, with exceptions |
| Organization users with a company, school, or Google Workspace account | [Sign in with Google](#login-google) | [Yes](#set-gcp) |
| AI Studio user with a Gemini API key | [Use Gemini API Key](#gemini-api) | No |
| Google Cloud Vertex AI user | [Vertex AI](#vertex-ai) | [Yes](#set-gcp) |
| [Headless mode](#headless) | [Use Gemini API Key](#gemini-api) or<br> [Vertex AI](#vertex-ai) | No (for Gemini API Key)<br> [Yes](#set-gcp) (for Vertex AI) |
@@ -36,7 +36,7 @@ Select the authentication method that matches your situation in the table below:
[Google AI Ultra for Business](https://support.google.com/a/answer/16345165)
subscriptions.
## (Recommended) Login with Google <a id="login-google"></a>
## (Recommended) Sign in with Google <a id="login-google"></a>
If you run Gemini CLI on your local machine, the simplest authentication method
is logging in with your Google account. This method requires a web browser on a
@@ -54,9 +54,9 @@ To authenticate and use Gemini CLI:
gemini
```
2. Select **Login with Google**. Gemini CLI opens a login prompt using your web
browser. Follow the on-screen instructions. Your credentials will be cached
locally for future sessions.
2. Select **Sign in with Google**. Gemini CLI opens a sign in prompt using your
web browser. Follow the on-screen instructions. Your credentials will be
cached locally for future sessions.
### Do I need to set my Google Cloud project?
@@ -391,7 +391,7 @@ on this page.
[Headless mode](../cli/headless) will use your existing authentication method,
if an existing authentication credential is cached.
If you have not already logged in with an authentication credential, you must
If you have not already signed in with an authentication credential, you must
configure authentication using environment variables:
- [Use Gemini API Key](#gemini-api)

View File

@@ -38,7 +38,7 @@ cases, you can log in with your existing Google account:
```
2. When asked "How would you like to authenticate for this project?" select **1.
Login with Google**.
Sign in with Google**.
3. Select your Google account.

View File

@@ -297,7 +297,7 @@ their corresponding top-level category object in your `settings.json` file.
- **Default:** `false`
- **`ui.showUserIdentity`** (boolean):
- **Description:** Show the logged-in user's identity (e.g. email) in the UI.
- **Description:** Show the signed-in user's identity (e.g. email) in the UI.
- **Default:** `true`
- **`ui.useAlternateBuffer`** (boolean):

View File

@@ -79,8 +79,8 @@ manually run through this checklist.
- [ ] Verify version: `gemini --version`
- **Authentication:**
- [ ] In interactive mode run `/auth` and verify all login flows work:
- [ ] Login With Google
- [ ] In interactive mode run `/auth` and verify all sign in flows work:
- [ ] Sign in with Google
- [ ] API Key
- [ ] Vertex AI

View File

@@ -46,7 +46,7 @@ for further information.
| Gemini Developer API Key | Gemini API - Paid Services | [Gemini API Terms of Service - Paid Services](https://ai.google.dev/gemini-api/terms#paid-services) | [Google Privacy Policy](https://policies.google.com/privacy) |
| Vertex AI GenAI API Key | Vertex AI GenAI API | [Google Cloud Platform Terms of Service](https://cloud.google.com/terms/service-terms/) | [Google Cloud Privacy Notice](https://cloud.google.com/terms/cloud-privacy-notice) |
## 1. If you have logged in with your Google account to Gemini Code Assist
## 1. If you have signed in with your Google account to Gemini Code Assist
For users who use their Google account to access
[Gemini Code Assist](https://codeassist.google), these Terms of Service and
@@ -68,7 +68,7 @@ Code Assist Standard or Enterprise edition, the terms and privacy policy of
Gemini Code Assist Standard or Enterprise edition will apply to all your use of
Gemini Code Assist._
## 2. If you have logged in with a Gemini API key to the Gemini Developer API
## 2. If you have signed in with a Gemini API key to the Gemini Developer API
If you are using a Gemini API key for authentication with the
[Gemini Developer API](https://ai.google.dev/gemini-api/docs), these Terms of
@@ -84,7 +84,7 @@ Service and Privacy Notice documents apply:
- Privacy Notice: The collection and use of your data is described in the
[Google Privacy Policy](https://policies.google.com/privacy).
## 3. If you have logged in with a Gemini API key to the Vertex AI GenAI API
## 3. If you have signed in with a Gemini API key to the Vertex AI GenAI API
If you are using a Gemini API key for authentication with a
[Vertex AI GenAI API](https://cloud.google.com/vertex-ai/generative-ai/docs/reference/rest)

View File

@@ -29,13 +29,13 @@ topics on:
added to your organization's Gemini Code Assist subscription.
- **Error:
`Failed to login. Message: Your current account is not eligible... because it is not currently available in your location.`**
`Failed to sign in. Message: Your current account is not eligible... because it is not currently available in your location.`**
- **Cause:** Gemini CLI does not currently support your location. For a full
list of supported locations, see the following pages:
- Gemini Code Assist for individuals:
[Available locations](https://developers.google.com/gemini-code-assist/resources/available-locations#americas)
- **Error: `Failed to login. Message: Request contains an invalid argument`**
- **Error: `Failed to sign in. Message: Request contains an invalid argument`**
- **Cause:** Users with Google Workspace accounts or Google Cloud accounts
associated with their Gmail accounts may not be able to activate the free
tier of the Google Code Assist plan.

View File

@@ -676,7 +676,7 @@ const SETTINGS_SCHEMA = {
requiresRestart: false,
default: true,
description:
"Show the logged-in user's identity (e.g. email) in the UI.",
"Show the signed-in user's identity (e.g. email) in the UI.",
showInDialog: true,
},
useAlternateBuffer: {

View File

@@ -48,14 +48,14 @@ describe('auth', () => {
});
it('should return error message on failed auth', async () => {
const error = new Error('Auth failed');
const error = new Error('Authentication failed');
vi.mocked(mockConfig.refreshAuth).mockRejectedValue(error);
const result = await performInitialAuth(
mockConfig,
AuthType.LOGIN_WITH_GOOGLE,
);
expect(result).toEqual({
authError: 'Failed to login. Message: Auth failed',
authError: 'Failed to sign in. Message: Authentication failed',
accountSuspensionInfo: null,
});
expect(mockConfig.refreshAuth).toHaveBeenCalledWith(

View File

@@ -64,7 +64,7 @@ export async function performInitialAuth(
};
}
return {
authError: `Failed to login. Message: ${getErrorMessage(e)}`,
authError: `Failed to sign in. Message: ${getErrorMessage(e)}`,
accountSuspensionInfo: null,
};
}

View File

@@ -209,7 +209,7 @@ describe('AuthDialog', () => {
{
setup: () => {},
expected: AuthType.LOGIN_WITH_GOOGLE,
desc: 'defaults to Login with Google',
desc: 'defaults to Sign in with Google',
},
])('selects initial auth type $desc', async ({ setup, expected }) => {
setup();
@@ -351,7 +351,7 @@ describe('AuthDialog', () => {
unmount();
});
it('exits process for Login with Google when browser is suppressed', async () => {
it('exits process for Sign in with Google when browser is suppressed', async () => {
vi.useFakeTimers();
const exitSpy = vi
.spyOn(process, 'exit')

View File

@@ -44,7 +44,7 @@ export function AuthDialog({
const [exiting, setExiting] = useState(false);
let items = [
{
label: 'Login with Google',
label: 'Sign in with Google',
value: AuthType.LOGIN_WITH_GOOGLE,
key: AuthType.LOGIN_WITH_GOOGLE,
},

View File

@@ -59,8 +59,8 @@ describe('AuthInProgress', () => {
<AuthInProgress onTimeout={onTimeout} />,
);
await waitUntilReady();
expect(lastFrame()).toContain('[Spinner] Waiting for auth...');
expect(lastFrame()).toContain('Press ESC or CTRL+C to cancel');
expect(lastFrame()).toContain('[Spinner] Waiting for authentication...');
expect(lastFrame()).toContain('Press Esc or Ctrl+C to cancel');
unmount();
});

View File

@@ -53,8 +53,8 @@ export function AuthInProgress({
) : (
<Box>
<Text>
<CliSpinner type="dots" /> Waiting for auth... (Press ESC or CTRL+C
to cancel)
<CliSpinner type="dots" /> Waiting for authentication... (Press Esc
or Ctrl+C to cancel)
</Text>
</Box>
)}

View File

@@ -45,13 +45,13 @@ export const LoginWithGoogleRestartDialog = ({
);
const message =
'You have successfully logged in with Google. Gemini CLI needs to be restarted.';
"You've successfully signed in with Google. Gemini CLI needs to be restarted.";
return (
<Box borderStyle="round" borderColor={theme.status.warning} paddingX={1}>
<Text color={theme.status.warning}>
{message} Press &apos;r&apos; to restart, or &apos;escape&apos; to
choose a different auth method.
{message} Press R to restart, or Esc to choose a different
authentication method.
</Text>
</Box>
);

View File

@@ -7,7 +7,7 @@ exports[`AuthDialog > Snapshots > renders correctly with auth error 1`] = `
│ │
│ How would you like to authenticate for this project? │
│ │
│ (selected) Login with Google(not selected) Use Gemini API Key(not selected) Vertex AI
│ (selected) Sign in with Google(not selected) Use Gemini API Key(not selected) Vertex AI │
│ │
│ Something went wrong │
│ │
@@ -28,7 +28,7 @@ exports[`AuthDialog > Snapshots > renders correctly with default props 1`] = `
│ │
│ How would you like to authenticate for this project? │
│ │
│ (selected) Login with Google(not selected) Use Gemini API Key(not selected) Vertex AI
│ (selected) Sign in with Google(not selected) Use Gemini API Key(not selected) Vertex AI │
│ │
│ (Use Enter to select) │
│ │

View File

@@ -2,8 +2,8 @@
exports[`LoginWithGoogleRestartDialog > renders correctly 1`] = `
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ You have successfully logged in with Google. Gemini CLI needs to be restarted. Press 'r' to
restart, or 'escape' to choose a different auth method. │
│ You've successfully signed in with Google. Gemini CLI needs to be restarted. Press R to restart,
or Esc to choose a different authentication method.
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
"
`;

View File

@@ -288,7 +288,7 @@ describe('useAuth', () => {
);
await waitFor(() => {
expect(result.current.authError).toContain('Failed to login');
expect(result.current.authError).toContain('Failed to sign in');
expect(result.current.authState).toBe(AuthState.Updating);
});
});

View File

@@ -149,7 +149,7 @@ export const useAuthCommand = (
// Show the error message directly without "Failed to login" prefix
onAuthError(getErrorMessage(e));
} else {
onAuthError(`Failed to login. Message: ${getErrorMessage(e)}`);
onAuthError(`Failed to sign in. Message: ${getErrorMessage(e)}`);
}
}
})();

View File

@@ -34,11 +34,13 @@ describe('authCommand', () => {
vi.clearAllMocks();
});
it('should have subcommands: login and logout', () => {
it('should have subcommands: signin and signout', () => {
expect(authCommand.subCommands).toBeDefined();
expect(authCommand.subCommands).toHaveLength(2);
expect(authCommand.subCommands?.[0]?.name).toBe('login');
expect(authCommand.subCommands?.[1]?.name).toBe('logout');
expect(authCommand.subCommands?.[0]?.name).toBe('signin');
expect(authCommand.subCommands?.[0]?.altNames).toContain('login');
expect(authCommand.subCommands?.[1]?.name).toBe('signout');
expect(authCommand.subCommands?.[1]?.altNames).toContain('logout');
});
it('should return a dialog action to open the auth dialog when called with no args', () => {
@@ -59,19 +61,19 @@ describe('authCommand', () => {
expect(authCommand.description).toBe('Manage authentication');
});
describe('auth login subcommand', () => {
describe('auth signin subcommand', () => {
it('should return auth dialog action', () => {
const loginCommand = authCommand.subCommands?.[0];
expect(loginCommand?.name).toBe('login');
expect(loginCommand?.name).toBe('signin');
const result = loginCommand!.action!(mockContext, '');
expect(result).toEqual({ type: 'dialog', dialog: 'auth' });
});
});
describe('auth logout subcommand', () => {
describe('auth signout subcommand', () => {
it('should clear cached credentials', async () => {
const logoutCommand = authCommand.subCommands?.[1];
expect(logoutCommand?.name).toBe('logout');
expect(logoutCommand?.name).toBe('signout');
const { clearCachedCredentialFile } = await import(
'@google/gemini-cli-core'

View File

@@ -14,8 +14,9 @@ import { clearCachedCredentialFile } from '@google/gemini-cli-core';
import { SettingScope } from '../../config/settings.js';
const authLoginCommand: SlashCommand = {
name: 'login',
description: 'Login or change the auth method',
name: 'signin',
altNames: ['login'],
description: 'Sign in or change the authentication method',
kind: CommandKind.BUILT_IN,
autoExecute: true,
action: (_context, _args): OpenDialogActionReturn => ({
@@ -25,8 +26,9 @@ const authLoginCommand: SlashCommand = {
};
const authLogoutCommand: SlashCommand = {
name: 'logout',
description: 'Log out and clear all cached credentials',
name: 'signout',
altNames: ['logout'],
description: 'Sign out and clear all cached credentials',
kind: CommandKind.BUILT_IN,
action: async (context, _args): Promise<LogoutActionReturn> => {
await clearCachedCredentialFile();

View File

@@ -36,7 +36,7 @@ describe('AboutBox', () => {
expect(output).toContain('gemini-pro');
expect(output).toContain('default');
expect(output).toContain('macOS');
expect(output).toContain('Logged in with Google');
expect(output).toContain('Signed in with Google');
unmount();
});
@@ -63,7 +63,7 @@ describe('AboutBox', () => {
);
await waitUntilReady();
const output = lastFrame();
expect(output).toContain('Logged in with Google (test@example.com)');
expect(output).toContain('Signed in with Google (test@example.com)');
unmount();
});

View File

@@ -116,8 +116,8 @@ export const AboutBox: React.FC<AboutBoxProps> = ({
<Text color={theme.text.primary}>
{selectedAuthType.startsWith('oauth')
? userEmail
? `Logged in with Google (${userEmail})`
: 'Logged in with Google'
? `Signed in with Google (${userEmail})`
: 'Signed in with Google'
: selectedAuthType}
</Text>
</Box>

View File

@@ -28,9 +28,9 @@ describe('LogoutConfirmationDialog', () => {
);
await waitUntilReady();
expect(lastFrame()).toContain('You are now logged out.');
expect(lastFrame()).toContain('You are now signed out');
expect(lastFrame()).toContain(
'Login again to continue using Gemini CLI, or exit the application.',
'Sign in again to continue using Gemini CLI, or exit the application.',
);
expect(lastFrame()).toContain('(Use Enter to select, Esc to close)');
unmount();
@@ -45,7 +45,7 @@ describe('LogoutConfirmationDialog', () => {
expect(RadioButtonSelect).toHaveBeenCalled();
const mockCall = vi.mocked(RadioButtonSelect).mock.calls[0][0];
expect(mockCall.items).toEqual([
{ label: 'Login', value: LogoutChoice.LOGIN, key: 'login' },
{ label: 'Sign in', value: LogoutChoice.LOGIN, key: 'login' },
{ label: 'Exit', value: LogoutChoice.EXIT, key: 'exit' },
]);
expect(mockCall.isFocused).toBe(true);

View File

@@ -37,7 +37,7 @@ export const LogoutConfirmationDialog: React.FC<
const options: Array<RadioSelectItem<LogoutChoice>> = [
{
label: 'Login',
label: 'Sign in',
value: LogoutChoice.LOGIN,
key: 'login',
},
@@ -61,10 +61,10 @@ export const LogoutConfirmationDialog: React.FC<
>
<Box flexDirection="column" marginBottom={1}>
<Text bold color={theme.text.primary}>
You are now logged out.
You are now signed out
</Text>
<Text color={theme.text.secondary}>
Login again to continue using Gemini CLI, or exit the application.
Sign in again to continue using Gemini CLI, or exit the application.
</Text>
</Box>

View File

@@ -539,7 +539,7 @@ describe('<ModelStatsDisplay />', () => {
const output = lastFrame();
expect(output).toContain('Auth Method:');
expect(output).toContain('Logged in with Google');
expect(output).toContain('Signed in with Google');
expect(output).toContain('(test@example.com)');
expect(output).toContain('Tier:');
expect(output).toContain('Pro');

View File

@@ -340,8 +340,8 @@ export const ModelStatsDisplay: React.FC<ModelStatsDisplayProps> = ({
<Text color={theme.text.primary}>
{selectedAuthType.startsWith('oauth')
? userEmail
? `Logged in with Google (${userEmail})`
: 'Logged in with Google'
? `Signed in with Google (${userEmail})`
: 'Signed in with Google'
: selectedAuthType}
</Text>
</Box>

View File

@@ -616,7 +616,7 @@ describe('<StatsDisplay />', () => {
const output = lastFrame();
expect(output).toContain('Auth Method:');
expect(output).toContain('Logged in with Google (test@example.com)');
expect(output).toContain('Signed in with Google (test@example.com)');
expect(output).toContain('Tier:');
expect(output).toContain('Pro');
});

View File

@@ -589,8 +589,8 @@ export const StatsDisplay: React.FC<StatsDisplayProps> = ({
<Text color={theme.text.primary}>
{selectedAuthType.startsWith('oauth')
? userEmail
? `Logged in with Google (${userEmail})`
: 'Logged in with Google'
? `Signed in with Google (${userEmail})`
: 'Signed in with Google'
: selectedAuthType}
</Text>
</StatRow>

View File

@@ -1,6 +1,6 @@
/**
* @license
* Copyright 2025 Google LLC
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
@@ -45,7 +45,7 @@ describe('<UserIdentity />', () => {
await waitUntilReady();
const output = lastFrame();
expect(output).toContain('test@example.com');
expect(output).toContain('Signed in with Google: test@example.com');
expect(output).toContain('/auth');
expect(output).not.toContain('/upgrade');
unmount();
@@ -91,7 +91,8 @@ describe('<UserIdentity />', () => {
await waitUntilReady();
const output = lastFrame();
expect(output).toContain('Logged in with Google');
expect(output).toContain('Signed in with Google');
expect(output).not.toContain('Signed in with Google:');
expect(output).toContain('/auth');
expect(output).not.toContain('/upgrade');
unmount();
@@ -111,11 +112,20 @@ describe('<UserIdentity />', () => {
await waitUntilReady();
const output = lastFrame();
expect(output).toContain('test@example.com');
expect(output).toContain('Signed in with Google: test@example.com');
expect(output).toContain('/auth');
expect(output).toContain('Premium Plan');
expect(output).toContain('Plan: Premium Plan');
expect(output).toContain('/upgrade');
// Check for two lines (or more if wrapped, but here it should be separate)
const lines = output?.split('\n').filter((line) => line.trim().length > 0);
expect(lines?.some((line) => line.includes('Signed in with Google'))).toBe(
true,
);
expect(lines?.some((line) => line.includes('Plan: Premium Plan'))).toBe(
true,
);
unmount();
});
@@ -168,7 +178,7 @@ describe('<UserIdentity />', () => {
await waitUntilReady();
const output = lastFrame();
expect(output).toContain('Enterprise Tier');
expect(output).toContain('Plan: Enterprise Tier');
expect(output).toContain('/upgrade');
unmount();
});

View File

@@ -43,7 +43,10 @@ export const UserIdentity: React.FC<UserIdentityProps> = ({ config }) => {
<Box>
<Text color={theme.text.primary} wrap="truncate-end">
{authType === AuthType.LOGIN_WITH_GOOGLE ? (
<Text>{email ?? 'Logged in with Google'}</Text>
<Text>
<Text bold>Signed in with Google{email ? ':' : ''}</Text>
{email ? ` ${email}` : ''}
</Text>
) : (
`Authenticated with ${authType}`
)}
@@ -55,7 +58,7 @@ export const UserIdentity: React.FC<UserIdentityProps> = ({ config }) => {
{tierName && (
<Box>
<Text color={theme.text.primary} wrap="truncate-end">
{tierName}
<Text bold>Plan:</Text> {tierName}
</Text>
<Text color={theme.text.secondary}> /upgrade</Text>
</Box>

View File

@@ -136,7 +136,7 @@ export function ValidationDialog({
<CliSpinner />
<Text>
{' '}
Waiting for verification... (Press ESC or CTRL+C to cancel)
Waiting for verification... (Press Esc or Ctrl+C to cancel)
</Text>
</Box>
{errorMessage && (

View File

@@ -405,8 +405,8 @@
},
"showUserIdentity": {
"title": "Show User Identity",
"description": "Show the logged-in user's identity (e.g. email) in the UI.",
"markdownDescription": "Show the logged-in user's identity (e.g. email) in the UI.\n\n- Category: `UI`\n- Requires restart: `no`\n- Default: `true`",
"description": "Show the signed-in user's identity (e.g. email) in the UI.",
"markdownDescription": "Show the signed-in user's identity (e.g. email) in the UI.\n\n- Category: `UI`\n- Requires restart: `no`\n- Default: `true`",
"default": true,
"type": "boolean"
},