From 144368c3c62452e149f59deb029cdcebc8743169 Mon Sep 17 00:00:00 2001 From: Shaswat Raj Date: Tue, 7 Apr 2026 19:19:43 +0000 Subject: [PATCH 1/2] fix(ui): hydrate telemetry on restore to fix incorrect session ID (#24820) - Import uiTelemetryService and call hydrate when resuming via --resume - This ensures the session ID and metrics are correctly restored, so the quit summary shows the correct resume command Fixes #24820 --- packages/cli/src/ui/hooks/useSessionResume.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/cli/src/ui/hooks/useSessionResume.ts b/packages/cli/src/ui/hooks/useSessionResume.ts index 055686773bd..d43cba8fecb 100644 --- a/packages/cli/src/ui/hooks/useSessionResume.ts +++ b/packages/cli/src/ui/hooks/useSessionResume.ts @@ -10,6 +10,7 @@ import { type Config, type ResumedSessionData, convertSessionToClientHistory, + uiTelemetryService, } from '@google/gemini-cli-core'; import type { Part } from '@google/genai'; import type { HistoryItemWithoutId } from '../types.js'; @@ -109,6 +110,8 @@ export function useSessionResume({ !hasLoadedResumedSession.current ) { hasLoadedResumedSession.current = true; + // Hydrate telemetry service with the resumed conversation to restore session ID and metrics + uiTelemetryService.hydrate(resumedSessionData.conversation); const historyData = convertSessionToHistoryFormats( resumedSessionData.conversation.messages, ); From bf713834eb42d31f842c33106cb69b6d3760b5b1 Mon Sep 17 00:00:00 2001 From: SH20RAJ Date: Fri, 10 Apr 2026 22:19:31 +0530 Subject: [PATCH 2/2] fix(core): preserve shell execution config fields --- packages/core/src/config/config.test.ts | 37 +++++++++++++++++++++++++ packages/core/src/config/config.ts | 21 ++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/packages/core/src/config/config.test.ts b/packages/core/src/config/config.test.ts index 002d4da50e1..fc34994ac20 100644 --- a/packages/core/src/config/config.test.ts +++ b/packages/core/src/config/config.test.ts @@ -70,6 +70,7 @@ import { } from './models.js'; import { Storage } from './storage.js'; import type { AgentLoopContext } from './agent-loop-context.js'; +import type { ShellExecutionConfig } from '../services/shellExecutionService.js'; vi.mock('fs', async (importOriginal) => { const actual = await importOriginal(); @@ -307,6 +308,42 @@ describe('Server Config (config.ts)', () => { }); }); + describe('shell execution config', () => { + it('should preserve existing sandbox and background fields when updated', () => { + const config = new Config({ + ...baseParams, + shellBackgroundCompletionBehavior: 'notify', + }); + + const shellExecutionConfig = config.getShellExecutionConfig(); + + config.setShellExecutionConfig({ + terminalWidth: 123, + terminalHeight: 45, + pager: 'less', + showColor: true, + sanitizationConfig: shellExecutionConfig.sanitizationConfig, + sandboxManager: shellExecutionConfig.sandboxManager, + } as ShellExecutionConfig); + + const updatedShellExecutionConfig = config.getShellExecutionConfig(); + + expect(updatedShellExecutionConfig.terminalWidth).toBe(123); + expect(updatedShellExecutionConfig.terminalHeight).toBe(45); + expect(updatedShellExecutionConfig.pager).toBe('less'); + expect(updatedShellExecutionConfig.showColor).toBe(true); + expect(updatedShellExecutionConfig.sandboxConfig).toMatchObject({ + enabled: true, + command: 'docker', + image: 'gemini-cli-sandbox', + networkAccess: false, + }); + expect(updatedShellExecutionConfig.backgroundCompletionBehavior).toBe( + 'notify', + ); + }); + }); + beforeEach(() => { // Reset mocks if necessary vi.clearAllMocks(); diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts index a36d3b7a029..7a43aa57f71 100644 --- a/packages/core/src/config/config.ts +++ b/packages/core/src/config/config.ts @@ -3306,17 +3306,38 @@ export class Config implements McpContext, AgentLoopContext { setShellExecutionConfig(config: ShellExecutionConfig): void { this.shellExecutionConfig = { + ...this.shellExecutionConfig, terminalWidth: config.terminalWidth ?? this.shellExecutionConfig.terminalWidth, terminalHeight: config.terminalHeight ?? this.shellExecutionConfig.terminalHeight, showColor: config.showColor ?? this.shellExecutionConfig.showColor, pager: config.pager ?? this.shellExecutionConfig.pager, + defaultFg: config.defaultFg ?? this.shellExecutionConfig.defaultFg, + defaultBg: config.defaultBg ?? this.shellExecutionConfig.defaultBg, sanitizationConfig: config.sanitizationConfig ?? this.shellExecutionConfig.sanitizationConfig, sandboxManager: config.sandboxManager ?? this.shellExecutionConfig.sandboxManager, + sandboxConfig: + config.sandboxConfig ?? this.shellExecutionConfig.sandboxConfig, + backgroundCompletionBehavior: + config.backgroundCompletionBehavior ?? + this.shellExecutionConfig.backgroundCompletionBehavior, + additionalPermissions: + config.additionalPermissions ?? + this.shellExecutionConfig.additionalPermissions, + disableDynamicLineTrimming: + config.disableDynamicLineTrimming ?? + this.shellExecutionConfig.disableDynamicLineTrimming, + scrollback: config.scrollback ?? this.shellExecutionConfig.scrollback, + maxSerializedLines: + config.maxSerializedLines ?? + this.shellExecutionConfig.maxSerializedLines, + originalCommand: + config.originalCommand ?? this.shellExecutionConfig.originalCommand, + sessionId: config.sessionId ?? this.shellExecutionConfig.sessionId, }; } getScreenReader(): boolean {