feat: Add markdown rendering to ask_user tool (#18211)

This commit is contained in:
Jack Wotherspoon
2026-02-03 16:04:38 -05:00
committed by GitHub
parent 3e954930f1
commit 69c0585ab2
3 changed files with 279 additions and 101 deletions
@@ -10,6 +10,7 @@ import { renderWithProviders } from '../../test-utils/render.js';
import { waitFor } from '../../test-utils/async.js';
import { AskUserDialog } from './AskUserDialog.js';
import { QuestionType, type Question } from '@google/gemini-cli-core';
import chalk from 'chalk';
import { UIStateContext, type UIState } from '../contexts/UIStateContext.js';
// Helper to write to stdin with proper act() wrapping
@@ -941,6 +942,125 @@ describe('AskUserDialog', () => {
});
});
describe('Markdown rendering', () => {
it('auto-bolds plain single-line questions', async () => {
const questions: Question[] = [
{
question: 'Which option do you prefer?',
header: 'Test',
options: [{ label: 'Yes', description: '' }],
multiSelect: false,
},
];
const { lastFrame } = renderWithProviders(
<AskUserDialog
questions={questions}
onSubmit={vi.fn()}
onCancel={vi.fn()}
width={120}
availableHeight={40}
/>,
{ width: 120 },
);
await waitFor(() => {
const frame = lastFrame();
// Plain text should be rendered as bold
expect(frame).toContain(chalk.bold('Which option do you prefer?'));
});
});
it('does not auto-bold questions that already have markdown', async () => {
const questions: Question[] = [
{
question: 'Is **this** working?',
header: 'Test',
options: [{ label: 'Yes', description: '' }],
multiSelect: false,
},
];
const { lastFrame } = renderWithProviders(
<AskUserDialog
questions={questions}
onSubmit={vi.fn()}
onCancel={vi.fn()}
width={120}
availableHeight={40}
/>,
{ width: 120 },
);
await waitFor(() => {
const frame = lastFrame();
// Should NOT have double-bold (the whole question bolded AND "this" bolded)
// "Is " should not be bold, only "this" should be bold
expect(frame).toContain('Is ');
expect(frame).toContain(chalk.bold('this'));
expect(frame).not.toContain('**this**');
});
});
it('renders bold markdown in question', async () => {
const questions: Question[] = [
{
question: 'Is **this** working?',
header: 'Test',
options: [{ label: 'Yes', description: '' }],
multiSelect: false,
},
];
const { lastFrame } = renderWithProviders(
<AskUserDialog
questions={questions}
onSubmit={vi.fn()}
onCancel={vi.fn()}
width={120}
availableHeight={40}
/>,
{ width: 120 },
);
await waitFor(() => {
const frame = lastFrame();
// Check for chalk.bold('this') - asterisks should be gone, text should be bold
expect(frame).toContain(chalk.bold('this'));
expect(frame).not.toContain('**this**');
});
});
it('renders inline code markdown in question', async () => {
const questions: Question[] = [
{
question: 'Run `npm start`?',
header: 'Test',
options: [{ label: 'Yes', description: '' }],
multiSelect: false,
},
];
const { lastFrame } = renderWithProviders(
<AskUserDialog
questions={questions}
onSubmit={vi.fn()}
onCancel={vi.fn()}
width={120}
availableHeight={40}
/>,
{ width: 120 },
);
await waitFor(() => {
const frame = lastFrame();
// Backticks should be removed
expect(frame).toContain('npm start');
expect(frame).not.toContain('`npm start`');
});
});
});
it('uses availableTerminalHeight from UIStateContext if availableHeight prop is missing', () => {
const questions: Question[] = [
{