mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-10 22:21:22 -07:00
Allow ask headers longer than 16 chars (#20041)
This commit is contained in:
committed by
GitHub
parent
3f6cec22e6
commit
813e0c18ac
@@ -173,6 +173,28 @@ describe('TabHeader', () => {
|
|||||||
unmount();
|
unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('truncates long headers when not selected', async () => {
|
||||||
|
const longTabs: Tab[] = [
|
||||||
|
{ key: '0', header: 'ThisIsAVeryLongHeaderThatShouldBeTruncated' },
|
||||||
|
{ key: '1', header: 'AnotherVeryLongHeader' },
|
||||||
|
];
|
||||||
|
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||||
|
<TabHeader tabs={longTabs} currentIndex={0} />,
|
||||||
|
);
|
||||||
|
await waitUntilReady();
|
||||||
|
const frame = lastFrame();
|
||||||
|
|
||||||
|
// Current tab (index 0) should NOT be truncated
|
||||||
|
expect(frame).toContain('ThisIsAVeryLongHeaderThatShouldBeTruncated');
|
||||||
|
|
||||||
|
// Inactive tab (index 1) SHOULD be truncated to 16 chars (15 chars + …)
|
||||||
|
const expectedTruncated = 'AnotherVeryLong…';
|
||||||
|
expect(frame).toContain(expectedTruncated);
|
||||||
|
expect(frame).not.toContain('AnotherVeryLongHeader');
|
||||||
|
|
||||||
|
unmount();
|
||||||
|
});
|
||||||
|
|
||||||
it('falls back to default when renderStatusIcon returns undefined', async () => {
|
it('falls back to default when renderStatusIcon returns undefined', async () => {
|
||||||
const renderStatusIcon = () => undefined;
|
const renderStatusIcon = () => undefined;
|
||||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||||
|
|||||||
@@ -94,16 +94,19 @@ export function TabHeader({
|
|||||||
{showStatusIcons && (
|
{showStatusIcons && (
|
||||||
<Text color={theme.text.secondary}>{getStatusIcon(tab, i)} </Text>
|
<Text color={theme.text.secondary}>{getStatusIcon(tab, i)} </Text>
|
||||||
)}
|
)}
|
||||||
<Text
|
<Box maxWidth={i !== currentIndex ? 16 : 100}>
|
||||||
color={
|
<Text
|
||||||
i === currentIndex ? theme.status.success : theme.text.secondary
|
color={
|
||||||
}
|
i === currentIndex ? theme.status.success : theme.text.secondary
|
||||||
bold={i === currentIndex}
|
}
|
||||||
underline={i === currentIndex}
|
bold={i === currentIndex}
|
||||||
aria-current={i === currentIndex ? 'step' : undefined}
|
underline={i === currentIndex}
|
||||||
>
|
aria-current={i === currentIndex ? 'step' : undefined}
|
||||||
{tab.header}
|
wrap="truncate"
|
||||||
</Text>
|
>
|
||||||
|
{tab.header}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
))}
|
))}
|
||||||
{showArrows && <Text color={theme.text.secondary}>{' →'}</Text>}
|
{showArrows && <Text color={theme.text.secondary}>{' →'}</Text>}
|
||||||
|
|||||||
@@ -103,19 +103,6 @@ describe('AskUserTool', () => {
|
|||||||
expect(result).toContain("must have required property 'header'");
|
expect(result).toContain("must have required property 'header'");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return error if header exceeds max length', () => {
|
|
||||||
const result = tool.validateToolParams({
|
|
||||||
questions: [
|
|
||||||
{
|
|
||||||
question: 'Test?',
|
|
||||||
header: 'This is way too long',
|
|
||||||
type: QuestionType.CHOICE,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
expect(result).toContain('must NOT have more than 16 characters');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return error if options has fewer than 2 items', () => {
|
it('should return error if options has fewer than 2 items', () => {
|
||||||
const result = tool.validateToolParams({
|
const result = tool.validateToolParams({
|
||||||
questions: [
|
questions: [
|
||||||
@@ -276,13 +263,7 @@ describe('AskUserTool', () => {
|
|||||||
describe('validateBuildAndExecute', () => {
|
describe('validateBuildAndExecute', () => {
|
||||||
it('should hide validation errors from returnDisplay', async () => {
|
it('should hide validation errors from returnDisplay', async () => {
|
||||||
const params = {
|
const params = {
|
||||||
questions: [
|
questions: [],
|
||||||
{
|
|
||||||
question: 'Test?',
|
|
||||||
header: 'This is way too long',
|
|
||||||
type: QuestionType.TEXT,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = await tool.validateBuildAndExecute(
|
const result = await tool.validateBuildAndExecute(
|
||||||
|
|||||||
@@ -80,8 +80,7 @@ exports[`coreTools snapshots for specific models > Model: gemini-2.5-pro > snaps
|
|||||||
"items": {
|
"items": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"header": {
|
"header": {
|
||||||
"description": "MUST be 16 characters or fewer or the call will fail. Very short label displayed as a chip/tag. Use abbreviations: "Auth" not "Authentication", "Config" not "Configuration". Examples: "Auth method", "Library", "Approach", "Database".",
|
"description": "Very short label displayed as a chip/tag. Use abbreviations: "Auth" not "Authentication", "Config" not "Configuration". Examples: "Auth method", "Library", "Approach", "Database".",
|
||||||
"maxLength": 16,
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
},
|
},
|
||||||
"multiSelect": {
|
"multiSelect": {
|
||||||
@@ -869,8 +868,7 @@ exports[`coreTools snapshots for specific models > Model: gemini-3-pro-preview >
|
|||||||
"items": {
|
"items": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"header": {
|
"header": {
|
||||||
"description": "MUST be 16 characters or fewer or the call will fail. Very short label displayed as a chip/tag. Use abbreviations: "Auth" not "Authentication", "Config" not "Configuration". Examples: "Auth method", "Library", "Approach", "Database".",
|
"description": "Very short label displayed as a chip/tag. Use abbreviations: "Auth" not "Authentication", "Config" not "Configuration". Examples: "Auth method", "Library", "Approach", "Database".",
|
||||||
"maxLength": 16,
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
},
|
},
|
||||||
"multiSelect": {
|
"multiSelect": {
|
||||||
|
|||||||
@@ -609,9 +609,8 @@ The agent did not use the todo list because this task could be completed by a ti
|
|||||||
},
|
},
|
||||||
header: {
|
header: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
maxLength: 16,
|
|
||||||
description:
|
description:
|
||||||
'MUST be 16 characters or fewer or the call will fail. Very short label displayed as a chip/tag. Use abbreviations: "Auth" not "Authentication", "Config" not "Configuration". Examples: "Auth method", "Library", "Approach", "Database".',
|
'Very short label displayed as a chip/tag. Use abbreviations: "Auth" not "Authentication", "Config" not "Configuration". Examples: "Auth method", "Library", "Approach", "Database".',
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
|||||||
@@ -587,9 +587,8 @@ The agent did not use the todo list because this task could be completed by a ti
|
|||||||
},
|
},
|
||||||
header: {
|
header: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
maxLength: 16,
|
|
||||||
description:
|
description:
|
||||||
'MUST be 16 characters or fewer or the call will fail. Very short label displayed as a chip/tag. Use abbreviations: "Auth" not "Authentication", "Config" not "Configuration". Examples: "Auth method", "Library", "Approach", "Database".',
|
'Very short label displayed as a chip/tag. Use abbreviations: "Auth" not "Authentication", "Config" not "Configuration". Examples: "Auth method", "Library", "Approach", "Database".',
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
|||||||
Reference in New Issue
Block a user