summaryrefslogtreecommitdiff
path: root/packages/cli/src
diff options
context:
space:
mode:
authorShreya Keshive <[email protected]>2025-08-19 10:24:58 -0700
committerGitHub <[email protected]>2025-08-19 17:24:58 +0000
commit9588aa6ef971918b8acfeefdad4f6a33f93349cf (patch)
treeb72ff1f169eb88b832059cd824c58c132463771e /packages/cli/src
parentfde5511c270ace148c6328b03fa61d917850f6d3 (diff)
feat: Show /ide subcommands based on connection status instead of ideMode boolean (#6496)
Diffstat (limited to 'packages/cli/src')
-rw-r--r--packages/cli/src/ui/App.test.tsx3
-rw-r--r--packages/cli/src/ui/commands/ideCommand.test.ts25
-rw-r--r--packages/cli/src/ui/commands/ideCommand.ts12
-rw-r--r--packages/cli/src/ui/hooks/slashCommandProcessor.ts19
4 files changed, 48 insertions, 11 deletions
diff --git a/packages/cli/src/ui/App.test.tsx b/packages/cli/src/ui/App.test.tsx
index 44de1d83..9a712336 100644
--- a/packages/cli/src/ui/App.test.tsx
+++ b/packages/cli/src/ui/App.test.tsx
@@ -162,6 +162,9 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
getIdeClient: vi.fn(() => ({
getCurrentIde: vi.fn(() => 'vscode'),
getDetectedIdeDisplayName: vi.fn(() => 'VSCode'),
+ addStatusChangeListener: vi.fn(),
+ removeStatusChangeListener: vi.fn(),
+ getConnectionStatus: vi.fn(() => 'connected'),
})),
isTrustedFolder: vi.fn(() => true),
};
diff --git a/packages/cli/src/ui/commands/ideCommand.test.ts b/packages/cli/src/ui/commands/ideCommand.test.ts
index 8576320b..f61df287 100644
--- a/packages/cli/src/ui/commands/ideCommand.test.ts
+++ b/packages/cli/src/ui/commands/ideCommand.test.ts
@@ -69,16 +69,35 @@ describe('ideCommand', () => {
vi.mocked(mockConfig.getIdeClient).mockReturnValue({
getCurrentIde: () => DetectedIde.VSCode,
getDetectedIdeDisplayName: () => 'VS Code',
+ getConnectionStatus: () => ({
+ status: core.IDEConnectionStatus.Disconnected,
+ }),
} as ReturnType<Config['getIdeClient']>);
const command = ideCommand(mockConfig);
expect(command).not.toBeNull();
expect(command?.name).toBe('ide');
expect(command?.subCommands).toHaveLength(3);
- expect(command?.subCommands?.[0].name).toBe('disable');
+ expect(command?.subCommands?.[0].name).toBe('enable');
expect(command?.subCommands?.[1].name).toBe('status');
expect(command?.subCommands?.[2].name).toBe('install');
});
+ it('should show disable command when connected', () => {
+ vi.mocked(mockConfig.getIdeMode).mockReturnValue(true);
+ vi.mocked(mockConfig.getIdeClient).mockReturnValue({
+ getCurrentIde: () => DetectedIde.VSCode,
+ getDetectedIdeDisplayName: () => 'VS Code',
+ getConnectionStatus: () => ({
+ status: core.IDEConnectionStatus.Connected,
+ }),
+ } as ReturnType<Config['getIdeClient']>);
+ const command = ideCommand(mockConfig);
+ expect(command).not.toBeNull();
+ const subCommandNames = command?.subCommands?.map((cmd) => cmd.name);
+ expect(subCommandNames).toContain('disable');
+ expect(subCommandNames).not.toContain('enable');
+ });
+
describe('status subcommand', () => {
const mockGetConnectionStatus = vi.fn();
beforeEach(() => {
@@ -161,7 +180,9 @@ describe('ideCommand', () => {
vi.mocked(mockConfig.getIdeMode).mockReturnValue(true);
vi.mocked(mockConfig.getIdeClient).mockReturnValue({
getCurrentIde: () => DetectedIde.VSCode,
- getConnectionStatus: vi.fn(),
+ getConnectionStatus: () => ({
+ status: core.IDEConnectionStatus.Disconnected,
+ }),
getDetectedIdeDisplayName: () => 'VS Code',
} as unknown as ReturnType<Config['getIdeClient']>);
vi.mocked(core.getIdeInstaller).mockReturnValue({
diff --git a/packages/cli/src/ui/commands/ideCommand.ts b/packages/cli/src/ui/commands/ideCommand.ts
index b7cbea3d..49766b8d 100644
--- a/packages/cli/src/ui/commands/ideCommand.ts
+++ b/packages/cli/src/ui/commands/ideCommand.ts
@@ -237,13 +237,11 @@ export const ideCommand = (config: Config | null): SlashCommand | null => {
},
};
- const ideModeEnabled = config.getIdeMode();
- if (ideModeEnabled) {
- ideSlashCommand.subCommands = [
- disableCommand,
- statusCommand,
- installCommand,
- ];
+ const { status } = ideClient.getConnectionStatus();
+ const isConnected = status === IDEConnectionStatus.Connected;
+
+ if (isConnected) {
+ ideSlashCommand.subCommands = [statusCommand, disableCommand];
} else {
ideSlashCommand.subCommands = [
enableCommand,
diff --git a/packages/cli/src/ui/hooks/slashCommandProcessor.ts b/packages/cli/src/ui/hooks/slashCommandProcessor.ts
index d1af9964..4e70eab7 100644
--- a/packages/cli/src/ui/hooks/slashCommandProcessor.ts
+++ b/packages/cli/src/ui/hooks/slashCommandProcessor.ts
@@ -206,7 +206,22 @@ export const useSlashCommandProcessor = (
],
);
- const ideMode = config?.getIdeMode();
+ useEffect(() => {
+ if (!config) {
+ return;
+ }
+
+ const ideClient = config.getIdeClient();
+ const listener = () => {
+ reloadCommands();
+ };
+
+ ideClient.addStatusChangeListener(listener);
+
+ return () => {
+ ideClient.removeStatusChangeListener(listener);
+ };
+ }, [config, reloadCommands]);
useEffect(() => {
const controller = new AbortController();
@@ -228,7 +243,7 @@ export const useSlashCommandProcessor = (
return () => {
controller.abort();
};
- }, [config, ideMode, reloadTrigger]);
+ }, [config, reloadTrigger]);
const handleSlashCommand = useCallback(
async (