fix(patch): cherry-pick f08b4af to release/v0.45.2-pr-27749 to patch version v0.45.2 and create version 0.45.3 (#27769)

Co-authored-by: David Pierce <davidapierce@google.com>
Co-authored-by: Gal Zahavi <38544478+galz10@users.noreply.github.com>
This commit is contained in:
gemini-cli-robot
2026-06-09 14:29:16 -07:00
committed by GitHub
parent dfa8394cad
commit 7e87af9cf2
17 changed files with 884 additions and 25 deletions
@@ -12,7 +12,12 @@ import { MessageType } from '../types.js';
describe('helpCommand', () => {
let mockContext: CommandContext;
const originalEnv = { ...process.env };
const originalPlatform = process.platform;
const action = helpCommand.action;
if (!action) {
throw new Error('Help command has no action');
}
beforeEach(() => {
mockContext = createMockCommandContext({
@@ -23,16 +28,13 @@ describe('helpCommand', () => {
});
afterEach(() => {
process.env = { ...originalEnv };
Object.defineProperty(process, 'platform', { value: originalPlatform });
vi.unstubAllEnvs();
vi.clearAllMocks();
});
it('should add a help message to the UI history', async () => {
if (!helpCommand.action) {
throw new Error('Help command has no action');
}
await helpCommand.action(mockContext, '');
it('should add a help message to the UI history by default', async () => {
await action(mockContext, '');
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
expect.objectContaining({
@@ -47,4 +49,85 @@ describe('helpCommand', () => {
expect(helpCommand.kind).toBe(CommandKind.BUILT_IN);
expect(helpCommand.description).toBe('For help on gemini-cli');
});
describe('Antigravity installer commands help', () => {
it('should output macOS installation command on darwin platform', async () => {
Object.defineProperty(process, 'platform', { value: 'darwin' });
await action(mockContext, 'install antigravity cli');
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
expect.objectContaining({
type: MessageType.INFO,
text: `To install the Antigravity CLI on macOS, run the following command:\n\n'curl -fsSL https://antigravity.google/cli/install.sh | bash'`,
}),
);
});
it('should output Linux installation command on linux platform', async () => {
Object.defineProperty(process, 'platform', { value: 'linux' });
await action(mockContext, 'how do I install antigravity CLI');
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
expect.objectContaining({
type: MessageType.INFO,
text: `To install the Antigravity CLI on Linux, run the following command:\n\n'curl -fsSL https://antigravity.google/cli/install.sh | bash'`,
}),
);
});
it('should output Windows PowerShell installation command on win32 when PSModulePath is set', async () => {
Object.defineProperty(process, 'platform', { value: 'win32' });
vi.stubEnv('PSModulePath', 'C:\\some\\path');
await action(mockContext, 'how do I migrate to antigravity CLI');
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
expect.objectContaining({
type: MessageType.INFO,
text: `To install the Antigravity CLI on Windows (PowerShell), run the following command:\n\n'irm https://antigravity.google/cli/install.ps1 | iex'`,
}),
);
});
it('should output Windows CMD installation command on win32 when PSModulePath is not set', async () => {
Object.defineProperty(process, 'platform', { value: 'win32' });
vi.stubEnv('PSModulePath', '');
await action(mockContext, 'install antigravity cli');
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
expect.objectContaining({
type: MessageType.INFO,
text: `To install the Antigravity CLI on Windows (Command Prompt), run the following command:\n\n'curl -fsSL https://antigravity.google/cli/install.cmd -o install.cmd && install.cmd && del install.cmd'`,
}),
);
});
it('should learn more message on unsupported platform', async () => {
Object.defineProperty(process, 'platform', { value: 'freebsd' });
await action(mockContext, 'install antigravity cli');
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
expect.objectContaining({
type: MessageType.INFO,
text: 'Learn more about Antigravity CLI at https://antigravity.google/docs/cli-getting-started',
}),
);
});
it('should fall back to default help if query does not contain install or migrate', async () => {
Object.defineProperty(process, 'platform', { value: 'darwin' });
await action(mockContext, 'antigravity cli');
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
expect.objectContaining({
type: MessageType.HELP,
}),
);
});
});
});
+24 -1
View File
@@ -6,13 +6,36 @@
import { CommandKind, type SlashCommand } from './types.js';
import { MessageType, type HistoryItemHelp } from '../types.js';
import { getAntigravityInstallInfo } from '../utils/antigravityUtils.js';
export const helpCommand: SlashCommand = {
name: 'help',
kind: CommandKind.BUILT_IN,
description: 'For help on gemini-cli',
autoExecute: true,
action: async (context) => {
action: async (context, args) => {
const lowerArgs = args?.toLowerCase() || '';
const hasAntigravity = lowerArgs.includes('antigravity');
const hasInstallOrMigrate =
lowerArgs.includes('install') || lowerArgs.includes('migrate');
if (hasAntigravity && hasInstallOrMigrate) {
const info = getAntigravityInstallInfo();
if (info) {
context.ui.addItem({
type: MessageType.INFO,
text: `To install the Antigravity CLI on ${info.platformName}, run the following command:\n\n'${info.installCmd}'`,
});
} else {
context.ui.addItem({
type: MessageType.INFO,
text: `Learn more about Antigravity CLI at https://antigravity.google/docs/cli-getting-started`,
});
}
return;
}
const helpItem: Omit<HistoryItemHelp, 'id'> = {
type: MessageType.HELP,
timestamp: new Date(),
+78 -1
View File
@@ -10,12 +10,14 @@ import {
expect,
vi,
beforeEach,
afterEach,
type MockedFunction,
} from 'vitest';
import { renderHook } from '../../test-utils/render.js';
import { useBanner, _clearSessionBannersForTest } from './useBanner.js';
import { persistentState } from '../../utils/persistentState.js';
import crypto from 'node:crypto';
import chalk from 'chalk';
vi.mock('../../utils/persistentState.js', () => ({
persistentState: {
@@ -94,7 +96,9 @@ describe('useBanner', () => {
const { result } = await renderHook(() => useBanner(antigravityBannerData));
expect(result.current.bannerText).toBe('Antigravity is coming to town!');
expect(result.current.bannerText).toContain(
'Antigravity is coming to town!',
);
});
it('should increment the persistent count when banner is shown', async () => {
@@ -137,4 +141,77 @@ describe('useBanner', () => {
expect(result.current.bannerText).toBe('Line1\nLine2');
});
describe('Antigravity installation commands', () => {
const originalPlatform = process.platform;
afterEach(() => {
Object.defineProperty(process, 'platform', { value: originalPlatform });
vi.unstubAllEnvs();
});
it('should append macOS & Linux install command when on darwin', async () => {
Object.defineProperty(process, 'platform', { value: 'darwin' });
const data = { defaultText: 'Welcome to Antigravity!', warningText: '' };
const { result } = await renderHook(() => useBanner(data));
expect(result.current.bannerText).toBe(
`Welcome to Antigravity!\n \nTo install run "${chalk.bold('curl -fsSL https://antigravity.google/cli/install.sh | bash')}"`,
);
});
it('should append macOS & Linux install command when on linux', async () => {
Object.defineProperty(process, 'platform', { value: 'linux' });
const data = { defaultText: 'Welcome to Antigravity!', warningText: '' };
const { result } = await renderHook(() => useBanner(data));
expect(result.current.bannerText).toBe(
`Welcome to Antigravity!\n \nTo install run "${chalk.bold('curl -fsSL https://antigravity.google/cli/install.sh | bash')}"`,
);
});
it('should append Windows PowerShell install command when on win32 and PSModulePath is set', async () => {
Object.defineProperty(process, 'platform', { value: 'win32' });
vi.stubEnv('PSModulePath', 'C:\\some\\path');
const data = { defaultText: 'Welcome to Antigravity!', warningText: '' };
const { result } = await renderHook(() => useBanner(data));
expect(result.current.bannerText).toBe(
`Welcome to Antigravity!\n \nTo install run "${chalk.bold('irm https://antigravity.google/cli/install.ps1 | iex')}"`,
);
});
it('should append Windows CMD install command when on win32 and PSModulePath is not set', async () => {
Object.defineProperty(process, 'platform', { value: 'win32' });
vi.stubEnv('PSModulePath', '');
const data = { defaultText: 'Welcome to Antigravity!', warningText: '' };
const { result } = await renderHook(() => useBanner(data));
expect(result.current.bannerText).toBe(
`Welcome to Antigravity!\n \nTo install run "${chalk.bold('curl -fsSL https://antigravity.google/cli/install.cmd -o install.cmd && install.cmd && del install.cmd')}"`,
);
});
it('should not append install command if banner text does not contain Antigravity', async () => {
Object.defineProperty(process, 'platform', { value: 'darwin' });
const data = { defaultText: 'Regular Banner', warningText: '' };
const { result } = await renderHook(() => useBanner(data));
expect(result.current.bannerText).toBe('Regular Banner');
});
it('should not append install command if process.platform is an unsupported platform', async () => {
Object.defineProperty(process, 'platform', { value: 'freebsd' });
const data = { defaultText: 'Welcome to Antigravity!', warningText: '' };
const { result } = await renderHook(() => useBanner(data));
expect(result.current.bannerText).toBe('Welcome to Antigravity!');
});
});
});
+10 -1
View File
@@ -7,6 +7,8 @@
import { useState, useEffect } from 'react';
import { persistentState } from '../../utils/persistentState.js';
import crypto from 'node:crypto';
import chalk from 'chalk';
import { getAntigravityInstallInfo } from '../utils/antigravityUtils.js';
const DEFAULT_MAX_BANNER_SHOWN_COUNT = 5;
@@ -46,7 +48,14 @@ export function useBanner(bannerData: BannerData) {
activeText.includes('Antigravity'));
const rawBannerText = showBanner ? activeText : '';
const bannerText = rawBannerText.replace(/\\n/g, '\n');
let bannerText = rawBannerText.replace(/\\n/g, '\n');
if (showBanner && activeText.includes('Antigravity')) {
const info = getAntigravityInstallInfo();
if (info) {
bannerText += `\n \nTo install run "${chalk.bold(info.installCmd)}"`;
}
}
useEffect(() => {
if (showBanner && activeText) {
@@ -0,0 +1,72 @@
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { describe, it, expect, vi, afterEach } from 'vitest';
import { getAntigravityInstallInfo } from './antigravityUtils.js';
describe('antigravityUtils', () => {
const originalPlatform = process.platform;
afterEach(() => {
Object.defineProperty(process, 'platform', { value: originalPlatform });
vi.unstubAllEnvs();
});
it('should return macOS installation info on darwin platform', () => {
Object.defineProperty(process, 'platform', { value: 'darwin' });
const info = getAntigravityInstallInfo();
expect(info).toEqual({
platformName: 'macOS',
installCmd: 'curl -fsSL https://antigravity.google/cli/install.sh | bash',
});
});
it('should return Linux installation info on linux platform', () => {
Object.defineProperty(process, 'platform', { value: 'linux' });
const info = getAntigravityInstallInfo();
expect(info).toEqual({
platformName: 'Linux',
installCmd: 'curl -fsSL https://antigravity.google/cli/install.sh | bash',
});
});
it('should return Windows PowerShell installation info on win32 when PSModulePath is set', () => {
Object.defineProperty(process, 'platform', { value: 'win32' });
vi.stubEnv('PSModulePath', 'C:\\some\\path');
const info = getAntigravityInstallInfo();
expect(info).toEqual({
platformName: 'Windows (PowerShell)',
installCmd: 'irm https://antigravity.google/cli/install.ps1 | iex',
});
});
it('should return Windows CMD installation info on win32 when PSModulePath is not set', () => {
Object.defineProperty(process, 'platform', { value: 'win32' });
vi.stubEnv('PSModulePath', '');
const info = getAntigravityInstallInfo();
expect(info).toEqual({
platformName: 'Windows (Command Prompt)',
installCmd:
'curl -fsSL https://antigravity.google/cli/install.cmd -o install.cmd && install.cmd && del install.cmd',
});
});
it('should return null on unsupported platform', () => {
Object.defineProperty(process, 'platform', { value: 'freebsd' });
const info = getAntigravityInstallInfo();
expect(info).toBeNull();
});
});
@@ -0,0 +1,47 @@
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import process from 'node:process';
const ANTIGRAVITY_SH_INSTALL =
'curl -fsSL https://antigravity.google/cli/install.sh | bash';
export interface AntigravityInstallInfo {
platformName: string;
installCmd: string;
}
/**
* Gets the platform-specific installation details for the Antigravity CLI.
* Returns null if the current platform is unsupported.
*/
export function getAntigravityInstallInfo(): AntigravityInstallInfo | null {
if (process.platform === 'win32') {
if (process.env['PSModulePath']) {
return {
platformName: 'Windows (PowerShell)',
installCmd: 'irm https://antigravity.google/cli/install.ps1 | iex',
};
} else {
return {
platformName: 'Windows (Command Prompt)',
installCmd:
'curl -fsSL https://antigravity.google/cli/install.cmd -o install.cmd && install.cmd && del install.cmd',
};
}
} else if (process.platform === 'darwin') {
return {
platformName: 'macOS',
installCmd: ANTIGRAVITY_SH_INSTALL,
};
} else if (process.platform === 'linux') {
return {
platformName: 'Linux',
installCmd: ANTIGRAVITY_SH_INSTALL,
};
}
return null;
}