diff --git a/packages/cli/src/ui/components/messages/HintMessage.test.tsx b/packages/cli/src/ui/components/messages/HintMessage.test.tsx
new file mode 100644
index 0000000000..528b2211b6
--- /dev/null
+++ b/packages/cli/src/ui/components/messages/HintMessage.test.tsx
@@ -0,0 +1,56 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { renderWithProviders } from '../../../test-utils/render.js';
+import { HintMessage } from './HintMessage.js';
+import { describe, it, expect, vi } from 'vitest';
+import { makeFakeConfig } from '@google/gemini-cli-core';
+
+describe('HintMessage', () => {
+ afterEach(() => {
+ vi.unstubAllEnvs();
+ vi.restoreAllMocks();
+ });
+
+ it('renders normal hint message with correct prefix', async () => {
+ const { lastFrame, unmount } = await renderWithProviders(
+ ,
+ { width: 80 },
+ );
+ const output = lastFrame();
+
+ expect(output).toContain('💡');
+ expect(output).toContain('Steering Hint: Try this instead');
+ unmount();
+ });
+
+ describe('with NO_COLOR set', () => {
+ beforeEach(() => {
+ vi.stubEnv('NO_COLOR', '1');
+ });
+
+ it('uses margins instead of background blocks when NO_COLOR is set', async () => {
+ const { lastFrame, unmount } = await renderWithProviders(
+ ,
+ { width: 80, config: makeFakeConfig({ useBackgroundColor: true }) },
+ );
+ const output = lastFrame();
+
+ // In NO_COLOR mode, the block characters (â–„/â–€) should NOT be present.
+ expect(output).not.toContain('â–„');
+ expect(output).not.toContain('â–€');
+
+ const lines = output.split('\n').filter((l) => l.trim() !== '');
+ expect(lines).toHaveLength(1);
+ expect(lines[0]).toContain('💡');
+ expect(lines[0]).toContain('Steering Hint: Try this instead');
+
+ expect(output).toMatchSnapshot();
+
+ unmount();
+ });
+ });
+});
diff --git a/packages/cli/src/ui/components/messages/HintMessage.tsx b/packages/cli/src/ui/components/messages/HintMessage.tsx
index a19847dd34..e0b8699d6b 100644
--- a/packages/cli/src/ui/components/messages/HintMessage.tsx
+++ b/packages/cli/src/ui/components/messages/HintMessage.tsx
@@ -19,7 +19,9 @@ export const HintMessage: React.FC = ({ text }) => {
const prefix = '💡 ';
const prefixWidth = prefix.length;
const config = useConfig();
- const useBackgroundColor = config.getUseBackgroundColor();
+ const useBackgroundColorSetting = config.getUseBackgroundColor();
+ const useBackgroundColor =
+ useBackgroundColorSetting && !!theme.background.message;
return (
({
@@ -14,6 +15,11 @@ vi.mock('../../utils/commandUtils.js', () => ({
}));
describe('UserMessage', () => {
+ afterEach(() => {
+ vi.unstubAllEnvs();
+ vi.restoreAllMocks();
+ });
+
it('renders normal user message with correct prefix', async () => {
const { lastFrame, unmount } = await renderWithProviders(
,
@@ -60,4 +66,32 @@ describe('UserMessage', () => {
expect(output).toMatchSnapshot();
unmount();
});
+
+ describe('with NO_COLOR set', () => {
+ beforeEach(() => {
+ vi.stubEnv('NO_COLOR', '1');
+ });
+
+ it('uses margins instead of background blocks when NO_COLOR is set', async () => {
+ const { lastFrame, unmount } = await renderWithProviders(
+ ,
+ { width: 80, config: makeFakeConfig({ useBackgroundColor: true }) },
+ );
+ const output = lastFrame();
+
+ // In NO_COLOR mode, the block characters (â–„/â–€) should NOT be present.
+ expect(output).not.toContain('â–„');
+ expect(output).not.toContain('â–€');
+
+ // There should be empty lines above and below the message due to marginY={1}.
+ // lastFrame() returns the full buffer, so we can check for leading/trailing newlines or empty lines.
+ const lines = output.split('\n').filter((l) => l.trim() !== '');
+ expect(lines).toHaveLength(1);
+ expect(lines[0]).toContain('> Hello Gemini');
+
+ expect(output).toMatchSnapshot();
+
+ unmount();
+ });
+ });
});
diff --git a/packages/cli/src/ui/components/messages/UserMessage.tsx b/packages/cli/src/ui/components/messages/UserMessage.tsx
index 6609a7d1c4..2a0d094c7f 100644
--- a/packages/cli/src/ui/components/messages/UserMessage.tsx
+++ b/packages/cli/src/ui/components/messages/UserMessage.tsx
@@ -27,7 +27,9 @@ export const UserMessage: React.FC = ({ text, width }) => {
const prefixWidth = prefix.length;
const isSlashCommand = checkIsSlashCommand(text);
const config = useConfig();
- const useBackgroundColor = config.getUseBackgroundColor();
+ const useBackgroundColorSetting = config.getUseBackgroundColor();
+ const useBackgroundColor =
+ useBackgroundColorSetting && !!theme.background.message;
const textColor = isSlashCommand ? theme.text.accent : theme.text.primary;
diff --git a/packages/cli/src/ui/components/messages/UserShellMessage.test.tsx b/packages/cli/src/ui/components/messages/UserShellMessage.test.tsx
new file mode 100644
index 0000000000..ef9d9f7737
--- /dev/null
+++ b/packages/cli/src/ui/components/messages/UserShellMessage.test.tsx
@@ -0,0 +1,54 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { renderWithProviders } from '../../../test-utils/render.js';
+import { UserShellMessage } from './UserShellMessage.js';
+import { describe, it, expect, vi } from 'vitest';
+import { makeFakeConfig } from '@google/gemini-cli-core';
+
+describe('UserShellMessage', () => {
+ afterEach(() => {
+ vi.unstubAllEnvs();
+ vi.restoreAllMocks();
+ });
+
+ it('renders normal shell message with correct prefix', async () => {
+ const { lastFrame, unmount } = await renderWithProviders(
+ ,
+ { width: 80 },
+ );
+ const output = lastFrame();
+
+ expect(output).toContain('$ ls -la');
+ unmount();
+ });
+
+ describe('with NO_COLOR set', () => {
+ beforeEach(() => {
+ vi.stubEnv('NO_COLOR', '1');
+ });
+
+ it('uses margins instead of background blocks when NO_COLOR is set', async () => {
+ const { lastFrame, unmount } = await renderWithProviders(
+ ,
+ { width: 80, config: makeFakeConfig({ useBackgroundColor: true }) },
+ );
+ const output = lastFrame();
+
+ // In NO_COLOR mode, the block characters (â–„/â–€) should NOT be present.
+ expect(output).not.toContain('â–„');
+ expect(output).not.toContain('â–€');
+
+ const lines = output.split('\n').filter((l) => l.trim() !== '');
+ expect(lines).toHaveLength(1);
+ expect(lines[0]).toContain('$ ls -la');
+
+ expect(output).toMatchSnapshot();
+
+ unmount();
+ });
+ });
+});
diff --git a/packages/cli/src/ui/components/messages/UserShellMessage.tsx b/packages/cli/src/ui/components/messages/UserShellMessage.tsx
index 872fb6ed41..1fe733acca 100644
--- a/packages/cli/src/ui/components/messages/UserShellMessage.tsx
+++ b/packages/cli/src/ui/components/messages/UserShellMessage.tsx
@@ -20,7 +20,9 @@ export const UserShellMessage: React.FC = ({
width,
}) => {
const config = useConfig();
- const useBackgroundColor = config.getUseBackgroundColor();
+ const useBackgroundColorSetting = config.getUseBackgroundColor();
+ const useBackgroundColor =
+ useBackgroundColorSetting && !!theme.background.message;
// Remove leading '!' if present, as App.tsx adds it for the processor.
const commandToDisplay = text.startsWith('!') ? text.substring(1) : text;
diff --git a/packages/cli/src/ui/components/messages/__snapshots__/HintMessage.test.tsx.snap b/packages/cli/src/ui/components/messages/__snapshots__/HintMessage.test.tsx.snap
new file mode 100644
index 0000000000..044c45aba8
--- /dev/null
+++ b/packages/cli/src/ui/components/messages/__snapshots__/HintMessage.test.tsx.snap
@@ -0,0 +1,7 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`HintMessage > with NO_COLOR set > uses margins instead of background blocks when NO_COLOR is set 1`] = `
+"
+💡 Steering Hint: Try this instead
+"
+`;
diff --git a/packages/cli/src/ui/components/messages/__snapshots__/UserMessage.test.tsx.snap b/packages/cli/src/ui/components/messages/__snapshots__/UserMessage.test.tsx.snap
index 5e44687fdd..0459cae90e 100644
--- a/packages/cli/src/ui/components/messages/__snapshots__/UserMessage.test.tsx.snap
+++ b/packages/cli/src/ui/components/messages/__snapshots__/UserMessage.test.tsx.snap
@@ -28,3 +28,9 @@ exports[`UserMessage > transforms image paths in user message 1`] = `
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
"
`;
+
+exports[`UserMessage > with NO_COLOR set > uses margins instead of background blocks when NO_COLOR is set 1`] = `
+"
+> Hello Gemini
+"
+`;
diff --git a/packages/cli/src/ui/components/messages/__snapshots__/UserShellMessage.test.tsx.snap b/packages/cli/src/ui/components/messages/__snapshots__/UserShellMessage.test.tsx.snap
new file mode 100644
index 0000000000..4886f6cc26
--- /dev/null
+++ b/packages/cli/src/ui/components/messages/__snapshots__/UserShellMessage.test.tsx.snap
@@ -0,0 +1,7 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`UserShellMessage > with NO_COLOR set > uses margins instead of background blocks when NO_COLOR is set 1`] = `
+"
+$ ls -la
+"
+`;