mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
Patch 0.3.0 preview.4 (#7713)
Co-authored-by: gemini-cli-robot <gemini-cli-robot@google.com> Co-authored-by: christine betts <chrstn@uw.edu> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Bryan Morgan <bryanmorgan@google.com> Co-authored-by: anthony bushong <agmsb@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@google/gemini-cli",
|
||||
"version": "0.3.0-preview.1",
|
||||
"version": "0.3.0-preview.3",
|
||||
"description": "Gemini CLI",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -25,7 +25,7 @@
|
||||
"dist"
|
||||
],
|
||||
"config": {
|
||||
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.3.0-preview.1"
|
||||
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.3.0-preview.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@google/gemini-cli-core": "file:../core",
|
||||
@@ -36,9 +36,10 @@
|
||||
"command-exists": "^1.2.9",
|
||||
"diff": "^7.0.0",
|
||||
"dotenv": "^17.1.0",
|
||||
"fzf": "^0.5.2",
|
||||
"glob": "^10.4.1",
|
||||
"highlight.js": "^11.11.1",
|
||||
"ink": "^6.1.1",
|
||||
"ink": "^6.2.3",
|
||||
"ink-gradient": "^3.0.0",
|
||||
"ink-spinner": "^5.0.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
|
||||
@@ -482,10 +482,10 @@ export async function loadCliConfig(
|
||||
}
|
||||
|
||||
const sandboxConfig = await loadSandboxConfig(settings, argv);
|
||||
|
||||
// The screen reader argument takes precedence over the accessibility setting.
|
||||
const screenReader =
|
||||
argv.screenReader ?? settings.ui?.accessibility?.screenReader ?? false;
|
||||
argv.screenReader !== undefined
|
||||
? argv.screenReader
|
||||
: (settings.ui?.accessibility?.screenReader ?? false);
|
||||
return new Config({
|
||||
sessionId,
|
||||
embeddingModel: DEFAULT_GEMINI_EMBEDDING_MODEL,
|
||||
|
||||
@@ -242,7 +242,7 @@ export const SETTINGS_SCHEMA = {
|
||||
label: 'Screen Reader Mode',
|
||||
category: 'UI',
|
||||
requiresRestart: true,
|
||||
default: false,
|
||||
default: undefined as boolean | undefined,
|
||||
description:
|
||||
'Render output in plain-text to be more screen reader accessible',
|
||||
showInDialog: true,
|
||||
|
||||
@@ -5,11 +5,15 @@
|
||||
*/
|
||||
|
||||
import type React from 'react';
|
||||
import { Text } from 'ink';
|
||||
import { Text, useIsScreenReaderEnabled } from 'ink';
|
||||
import Spinner from 'ink-spinner';
|
||||
import type { SpinnerName } from 'cli-spinners';
|
||||
import { useStreamingContext } from '../contexts/StreamingContext.js';
|
||||
import { StreamingState } from '../types.js';
|
||||
import {
|
||||
SCREEN_READER_LOADING,
|
||||
SCREEN_READER_RESPONDING,
|
||||
} from '../textConstants.js';
|
||||
|
||||
interface GeminiRespondingSpinnerProps {
|
||||
/**
|
||||
@@ -24,11 +28,19 @@ export const GeminiRespondingSpinner: React.FC<
|
||||
GeminiRespondingSpinnerProps
|
||||
> = ({ nonRespondingDisplay, spinnerType = 'dots' }) => {
|
||||
const streamingState = useStreamingContext();
|
||||
|
||||
const isScreenReaderEnabled = useIsScreenReaderEnabled();
|
||||
if (streamingState === StreamingState.Responding) {
|
||||
return <Spinner type={spinnerType} />;
|
||||
return isScreenReaderEnabled ? (
|
||||
<Text>{SCREEN_READER_RESPONDING}</Text>
|
||||
) : (
|
||||
<Spinner type={spinnerType} />
|
||||
);
|
||||
} else if (nonRespondingDisplay) {
|
||||
return <Text>{nonRespondingDisplay}</Text>;
|
||||
return isScreenReaderEnabled ? (
|
||||
<Text>{SCREEN_READER_LOADING}</Text>
|
||||
) : (
|
||||
<Text>{nonRespondingDisplay}</Text>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
cleanupOldClipboardImages,
|
||||
} from '../utils/clipboardUtils.js';
|
||||
import * as path from 'node:path';
|
||||
import { SCREEN_READER_USER_PREFIX } from '../constants.js';
|
||||
import { SCREEN_READER_USER_PREFIX } from '../textConstants.js';
|
||||
|
||||
export interface InputPromptProps {
|
||||
buffer: TextBuffer;
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Box, Text } from 'ink';
|
||||
import type { CompressionProps } from '../../types.js';
|
||||
import Spinner from 'ink-spinner';
|
||||
import { Colors } from '../../colors.js';
|
||||
import { SCREEN_READER_MODEL_PREFIX } from '../../constants.js';
|
||||
import { SCREEN_READER_MODEL_PREFIX } from '../../textConstants.js';
|
||||
|
||||
export interface CompressionDisplayProps {
|
||||
compression: CompressionProps;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import type React from 'react';
|
||||
import { Box, Text } from 'ink';
|
||||
import { Box, Text, useIsScreenReaderEnabled } from 'ink';
|
||||
import { Colors } from '../../colors.js';
|
||||
import crypto from 'node:crypto';
|
||||
import { colorizeCode, colorizeLine } from '../../utils/CodeColorizer.js';
|
||||
@@ -107,6 +107,7 @@ export const DiffRenderer: React.FC<DiffRendererProps> = ({
|
||||
terminalWidth,
|
||||
theme,
|
||||
}) => {
|
||||
const screenReaderEnabled = useIsScreenReaderEnabled();
|
||||
if (!diffContent || typeof diffContent !== 'string') {
|
||||
return <Text color={Colors.AccentYellow}>No diff content.</Text>;
|
||||
}
|
||||
@@ -120,6 +121,17 @@ export const DiffRenderer: React.FC<DiffRendererProps> = ({
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
if (screenReaderEnabled) {
|
||||
return (
|
||||
<Box flexDirection="column">
|
||||
{parsedLines.map((line, index) => (
|
||||
<Text key={index}>
|
||||
{line.type}: {line.content}
|
||||
</Text>
|
||||
))}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
// Check if the diff represents a new file (only additions and header lines)
|
||||
const isNewFile = parsedLines.every(
|
||||
|
||||
@@ -8,7 +8,7 @@ import type React from 'react';
|
||||
import { Text, Box } from 'ink';
|
||||
import { MarkdownDisplay } from '../../utils/MarkdownDisplay.js';
|
||||
import { Colors } from '../../colors.js';
|
||||
import { SCREEN_READER_MODEL_PREFIX } from '../../constants.js';
|
||||
import { SCREEN_READER_MODEL_PREFIX } from '../../textConstants.js';
|
||||
|
||||
interface GeminiMessageProps {
|
||||
text: string;
|
||||
|
||||
@@ -129,18 +129,22 @@ const ToolStatusIndicator: React.FC<ToolStatusIndicatorProps> = ({
|
||||
/>
|
||||
)}
|
||||
{status === ToolCallStatus.Success && (
|
||||
<Text color={Colors.AccentGreen}>{TOOL_STATUS.SUCCESS}</Text>
|
||||
<Text color={Colors.AccentGreen} aria-label={'Success:'}>
|
||||
{TOOL_STATUS.SUCCESS}
|
||||
</Text>
|
||||
)}
|
||||
{status === ToolCallStatus.Confirming && (
|
||||
<Text color={Colors.AccentYellow}>{TOOL_STATUS.CONFIRMING}</Text>
|
||||
<Text color={Colors.AccentYellow} aria-label={'Confirming:'}>
|
||||
{TOOL_STATUS.CONFIRMING}
|
||||
</Text>
|
||||
)}
|
||||
{status === ToolCallStatus.Canceled && (
|
||||
<Text color={Colors.AccentYellow} bold>
|
||||
<Text color={Colors.AccentYellow} aria-label={'Canceled:'} bold>
|
||||
{TOOL_STATUS.CANCELED}
|
||||
</Text>
|
||||
)}
|
||||
{status === ToolCallStatus.Error && (
|
||||
<Text color={Colors.AccentRed} bold>
|
||||
<Text color={Colors.AccentRed} aria-label={'Error:'} bold>
|
||||
{TOOL_STATUS.ERROR}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import type React from 'react';
|
||||
import { Text, Box } from 'ink';
|
||||
import { Colors } from '../../colors.js';
|
||||
import { SCREEN_READER_USER_PREFIX } from '../../constants.js';
|
||||
import { SCREEN_READER_USER_PREFIX } from '../../textConstants.js';
|
||||
import { isSlashCommand as checkIsSlashCommand } from '../../utils/commandUtils.js';
|
||||
|
||||
interface UserMessageProps {
|
||||
|
||||
@@ -65,7 +65,6 @@ export function RadioButtonSelect<T>({
|
||||
const [scrollOffset, setScrollOffset] = useState(0);
|
||||
const [numberInput, setNumberInput] = useState('');
|
||||
const numberInputTimer = useRef<NodeJS.Timeout | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const newScrollOffset = Math.max(
|
||||
0,
|
||||
@@ -195,7 +194,10 @@ export function RadioButtonSelect<T>({
|
||||
return (
|
||||
<Box key={item.label} alignItems="center">
|
||||
<Box minWidth={2} flexShrink={0}>
|
||||
<Text color={isSelected ? Colors.AccentGreen : Colors.Foreground}>
|
||||
<Text
|
||||
color={isSelected ? Colors.AccentGreen : Colors.Foreground}
|
||||
aria-hidden
|
||||
>
|
||||
{isSelected ? '●' : ' '}
|
||||
</Text>
|
||||
</Box>
|
||||
@@ -203,6 +205,7 @@ export function RadioButtonSelect<T>({
|
||||
marginRight={1}
|
||||
flexShrink={0}
|
||||
minWidth={itemNumberText.length}
|
||||
aria-state={{ checked: isSelected }}
|
||||
>
|
||||
<Text color={numberColor}>{itemNumberText}</Text>
|
||||
</Box>
|
||||
|
||||
@@ -16,10 +16,6 @@ export const STREAM_DEBOUNCE_MS = 100;
|
||||
|
||||
export const SHELL_COMMAND_NAME = 'Shell Command';
|
||||
|
||||
export const SCREEN_READER_USER_PREFIX = 'User: ';
|
||||
|
||||
export const SCREEN_READER_MODEL_PREFIX = 'Model: ';
|
||||
|
||||
// Tool status symbols used in ToolMessage component
|
||||
export const TOOL_STATUS = {
|
||||
SUCCESS: '✓',
|
||||
|
||||
13
packages/cli/src/ui/textConstants.ts
Normal file
13
packages/cli/src/ui/textConstants.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
export const SCREEN_READER_USER_PREFIX = 'User: ';
|
||||
|
||||
export const SCREEN_READER_MODEL_PREFIX = 'Model: ';
|
||||
|
||||
export const SCREEN_READER_LOADING = 'loading';
|
||||
|
||||
export const SCREEN_READER_RESPONDING = 'responding';
|
||||
Reference in New Issue
Block a user