Introduce initial screen reader mode handling and flag (#6653)
This commit is contained in:
parent
679acc45b2
commit
10286934e6
|
@ -308,6 +308,20 @@ In addition to a project settings file, a project's `.gemini` directory can cont
|
||||||
"showLineNumbers": false
|
"showLineNumbers": false
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- **`accessibility`** (object):
|
||||||
|
- **Description:** Configures accessibility features for the CLI.
|
||||||
|
- **Properties:**
|
||||||
|
- **`screenReader`** (boolean): Enables screen reader mode, which adjusts the TUI for better compatibility with screen readers. This can also be enabled with the `--screen-reader` command-line flag, which will take precedence over the setting.
|
||||||
|
- **`disableLoadingPhrases`** (boolean): Disables the display of loading phrases during operations.
|
||||||
|
- **Default:** `{"screenReader": false, "disableLoadingPhrases": false}`
|
||||||
|
- **Example:**
|
||||||
|
```json
|
||||||
|
"accessibility": {
|
||||||
|
"screenReader": true,
|
||||||
|
"disableLoadingPhrases": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Example `settings.json`:
|
### Example `settings.json`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
@ -475,6 +489,8 @@ Arguments passed directly when running the CLI can override other configurations
|
||||||
- Can be specified multiple times or as comma-separated values.
|
- Can be specified multiple times or as comma-separated values.
|
||||||
- 5 directories can be added at maximum.
|
- 5 directories can be added at maximum.
|
||||||
- Example: `--include-directories /path/to/project1,/path/to/project2` or `--include-directories /path/to/project1 --include-directories /path/to/project2`
|
- Example: `--include-directories /path/to/project1,/path/to/project2` or `--include-directories /path/to/project1 --include-directories /path/to/project2`
|
||||||
|
- **`--screen-reader`**:
|
||||||
|
- Enables screen reader mode for accessibility.
|
||||||
- **`--version`**:
|
- **`--version`**:
|
||||||
- Displays the version of the CLI.
|
- Displays the version of the CLI.
|
||||||
|
|
||||||
|
|
|
@ -63,16 +63,16 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@alcalzone/ansi-tokenize": {
|
"node_modules/@alcalzone/ansi-tokenize": {
|
||||||
"version": "0.1.3",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@alcalzone/ansi-tokenize/-/ansi-tokenize-0.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/@alcalzone/ansi-tokenize/-/ansi-tokenize-0.2.0.tgz",
|
||||||
"integrity": "sha512-3yWxPTq3UQ/FY9p1ErPxIyfT64elWaMvM9lIHnaqpyft63tkxodF5aUElYHrdisWve5cETkh1+KBw1yJuW0aRw==",
|
"integrity": "sha512-qI/5TaaaCZE4yeSZ83lu0+xi1r88JSxUjnH4OP/iZF7+KKZ75u3ee5isd0LxX+6N8U0npL61YrpbthILHB6BnA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-styles": "^6.2.1",
|
"ansi-styles": "^6.2.1",
|
||||||
"is-fullwidth-code-point": "^4.0.0"
|
"is-fullwidth-code-point": "^5.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14.13.1"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@alcalzone/ansi-tokenize/node_modules/ansi-styles": {
|
"node_modules/@alcalzone/ansi-tokenize/node_modules/ansi-styles": {
|
||||||
|
@ -88,12 +88,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@alcalzone/ansi-tokenize/node_modules/is-fullwidth-code-point": {
|
"node_modules/@alcalzone/ansi-tokenize/node_modules/is-fullwidth-code-point": {
|
||||||
"version": "4.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz",
|
||||||
"integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==",
|
"integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"get-east-asian-width": "^1.0.0"
|
||||||
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=18"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
@ -5175,9 +5178,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/es-toolkit": {
|
"node_modules/es-toolkit": {
|
||||||
"version": "1.39.5",
|
"version": "1.39.10",
|
||||||
"resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.39.5.tgz",
|
"resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.39.10.tgz",
|
||||||
"integrity": "sha512-z9V0qU4lx1TBXDNFWfAASWk6RNU6c6+TJBKE+FLIg8u0XJ6Yw58Hi0yX8ftEouj6p1QARRlXLFfHbIli93BdQQ==",
|
"integrity": "sha512-E0iGnTtbDhkeczB0T+mxmoVlT4YNweEKBLq7oaU4p11mecdsZpNWOglI4895Vh4usbQ+LsJiuLuI2L0Vdmfm2w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"docs",
|
"docs",
|
||||||
|
@ -6859,26 +6862,26 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ink": {
|
"node_modules/ink": {
|
||||||
"version": "6.1.1",
|
"version": "6.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/ink/-/ink-6.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/ink/-/ink-6.2.2.tgz",
|
||||||
"integrity": "sha512-Bqw78FX+1TSIGxs6bdvohgoy6mTfqjFJVNyYzXn8HIyZyVmwLX8XdnhUtUwyaelLCqLz8uuFseCbomRZWjyo5g==",
|
"integrity": "sha512-LN1f+/D8KKqMqRux08fIfA9wsEAJ9Bu9CiI3L6ih7bnqNSDUXT/JVJ0rUIc4NkjPiPaeI3BVNREcLYLz9ePSEg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alcalzone/ansi-tokenize": "^0.1.3",
|
"@alcalzone/ansi-tokenize": "^0.2.0",
|
||||||
"ansi-escapes": "^7.0.0",
|
"ansi-escapes": "^7.0.0",
|
||||||
"ansi-styles": "^6.2.1",
|
"ansi-styles": "^6.2.1",
|
||||||
"auto-bind": "^5.0.1",
|
"auto-bind": "^5.0.1",
|
||||||
"chalk": "^5.3.0",
|
"chalk": "^5.6.0",
|
||||||
"cli-boxes": "^3.0.0",
|
"cli-boxes": "^3.0.0",
|
||||||
"cli-cursor": "^4.0.0",
|
"cli-cursor": "^4.0.0",
|
||||||
"cli-truncate": "^4.0.0",
|
"cli-truncate": "^4.0.0",
|
||||||
"code-excerpt": "^4.0.0",
|
"code-excerpt": "^4.0.0",
|
||||||
"es-toolkit": "^1.22.0",
|
"es-toolkit": "^1.39.10",
|
||||||
"indent-string": "^5.0.0",
|
"indent-string": "^5.0.0",
|
||||||
"is-in-ci": "^1.0.0",
|
"is-in-ci": "^2.0.0",
|
||||||
"patch-console": "^2.0.0",
|
"patch-console": "^2.0.0",
|
||||||
"react-reconciler": "^0.32.0",
|
"react-reconciler": "^0.32.0",
|
||||||
"scheduler": "^0.23.0",
|
"scheduler": "^0.26.0",
|
||||||
"signal-exit": "^3.0.7",
|
"signal-exit": "^3.0.7",
|
||||||
"slice-ansi": "^7.1.0",
|
"slice-ansi": "^7.1.0",
|
||||||
"stack-utils": "^2.0.6",
|
"stack-utils": "^2.0.6",
|
||||||
|
@ -7030,9 +7033,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ink/node_modules/chalk": {
|
"node_modules/ink/node_modules/chalk": {
|
||||||
"version": "5.4.1",
|
"version": "5.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz",
|
||||||
"integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
|
"integrity": "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.17.0 || ^14.13 || >=16.0.0"
|
"node": "^12.17.0 || ^14.13 || >=16.0.0"
|
||||||
|
@ -7047,6 +7050,21 @@
|
||||||
"integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==",
|
"integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/ink/node_modules/is-in-ci": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-in-ci/-/is-in-ci-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"is-in-ci": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ink/node_modules/signal-exit": {
|
"node_modules/ink/node_modules/signal-exit": {
|
||||||
"version": "3.0.7",
|
"version": "3.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||||
|
@ -9733,13 +9751,6 @@
|
||||||
"react": "^19.1.0"
|
"react": "^19.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-dom/node_modules/scheduler": {
|
|
||||||
"version": "0.26.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
|
|
||||||
"integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/react-is": {
|
"node_modules/react-is": {
|
||||||
"version": "16.13.1",
|
"version": "16.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
|
@ -9761,12 +9772,6 @@
|
||||||
"react": "^19.1.0"
|
"react": "^19.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-reconciler/node_modules/scheduler": {
|
|
||||||
"version": "0.26.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
|
|
||||||
"integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/read-package-up": {
|
"node_modules/read-package-up": {
|
||||||
"version": "11.0.0",
|
"version": "11.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz",
|
||||||
|
@ -10224,13 +10229,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/scheduler": {
|
"node_modules/scheduler": {
|
||||||
"version": "0.23.2",
|
"version": "0.26.0",
|
||||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
|
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
|
||||||
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
|
"integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
|
||||||
"license": "MIT",
|
"license": "MIT"
|
||||||
"dependencies": {
|
|
||||||
"loose-envify": "^1.1.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"node_modules/selderee": {
|
"node_modules/selderee": {
|
||||||
"version": "0.11.0",
|
"version": "0.11.0",
|
||||||
|
|
|
@ -73,6 +73,7 @@ export interface CliArgs {
|
||||||
listExtensions: boolean | undefined;
|
listExtensions: boolean | undefined;
|
||||||
proxy: string | undefined;
|
proxy: string | undefined;
|
||||||
includeDirectories: string[] | undefined;
|
includeDirectories: string[] | undefined;
|
||||||
|
screenReader: boolean | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function parseArguments(): Promise<CliArgs> {
|
export async function parseArguments(): Promise<CliArgs> {
|
||||||
|
@ -229,6 +230,11 @@ export async function parseArguments(): Promise<CliArgs> {
|
||||||
// Handle comma-separated values
|
// Handle comma-separated values
|
||||||
dirs.flatMap((dir) => dir.split(',').map((d) => d.trim())),
|
dirs.flatMap((dir) => dir.split(',').map((d) => d.trim())),
|
||||||
})
|
})
|
||||||
|
.option('screen-reader', {
|
||||||
|
type: 'boolean',
|
||||||
|
description: 'Enable screen reader mode for accessibility.',
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
|
||||||
.check((argv) => {
|
.check((argv) => {
|
||||||
if (argv.prompt && argv['promptInteractive']) {
|
if (argv.prompt && argv['promptInteractive']) {
|
||||||
|
@ -465,6 +471,9 @@ export async function loadCliConfig(
|
||||||
|
|
||||||
const sandboxConfig = await loadSandboxConfig(settings, argv);
|
const sandboxConfig = await loadSandboxConfig(settings, argv);
|
||||||
|
|
||||||
|
// The screen reader argument takes precedence over the accessibility setting.
|
||||||
|
const screenReader =
|
||||||
|
argv.screenReader ?? settings.accessibility?.screenReader ?? false;
|
||||||
return new Config({
|
return new Config({
|
||||||
sessionId,
|
sessionId,
|
||||||
embeddingModel: DEFAULT_GEMINI_EMBEDDING_MODEL,
|
embeddingModel: DEFAULT_GEMINI_EMBEDDING_MODEL,
|
||||||
|
@ -490,7 +499,10 @@ export async function loadCliConfig(
|
||||||
argv.show_memory_usage ||
|
argv.show_memory_usage ||
|
||||||
settings.showMemoryUsage ||
|
settings.showMemoryUsage ||
|
||||||
false,
|
false,
|
||||||
accessibility: settings.accessibility,
|
accessibility: {
|
||||||
|
...settings.accessibility,
|
||||||
|
screenReader,
|
||||||
|
},
|
||||||
telemetry: {
|
telemetry: {
|
||||||
enabled: argv.telemetry ?? settings.telemetry?.enabled,
|
enabled: argv.telemetry ?? settings.telemetry?.enabled,
|
||||||
target: (argv.telemetryTarget ??
|
target: (argv.telemetryTarget ??
|
||||||
|
|
|
@ -58,6 +58,7 @@ export interface SummarizeToolOutputSettings {
|
||||||
|
|
||||||
export interface AccessibilitySettings {
|
export interface AccessibilitySettings {
|
||||||
disableLoadingPhrases?: boolean;
|
disableLoadingPhrases?: boolean;
|
||||||
|
screenReader?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SettingsError {
|
export interface SettingsError {
|
||||||
|
|
|
@ -206,6 +206,16 @@ export const SETTINGS_SCHEMA = {
|
||||||
description: 'Disable loading phrases for accessibility',
|
description: 'Disable loading phrases for accessibility',
|
||||||
showInDialog: true,
|
showInDialog: true,
|
||||||
},
|
},
|
||||||
|
screenReader: {
|
||||||
|
type: 'boolean',
|
||||||
|
label: 'Screen Reader Mode',
|
||||||
|
category: 'Accessibility',
|
||||||
|
requiresRestart: true,
|
||||||
|
default: false,
|
||||||
|
description:
|
||||||
|
'Render output in plain-text to be more screen reader accessible',
|
||||||
|
showInDialog: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
checkpointing: {
|
checkpointing: {
|
||||||
|
|
|
@ -316,7 +316,7 @@ export async function main() {
|
||||||
/>
|
/>
|
||||||
</SettingsContext.Provider>
|
</SettingsContext.Provider>
|
||||||
</React.StrictMode>,
|
</React.StrictMode>,
|
||||||
{ exitOnCtrlC: false },
|
{ exitOnCtrlC: false, isScreenReaderEnabled: config.getScreenReader() },
|
||||||
);
|
);
|
||||||
|
|
||||||
checkForUpdates()
|
checkForUpdates()
|
||||||
|
|
|
@ -87,6 +87,7 @@ interface MockServerConfig {
|
||||||
getGeminiClient: Mock<() => GeminiClient | undefined>;
|
getGeminiClient: Mock<() => GeminiClient | undefined>;
|
||||||
getUserTier: Mock<() => Promise<string | undefined>>;
|
getUserTier: Mock<() => Promise<string | undefined>>;
|
||||||
getIdeClient: Mock<() => { getCurrentIde: Mock<() => string | undefined> }>;
|
getIdeClient: Mock<() => { getCurrentIde: Mock<() => string | undefined> }>;
|
||||||
|
getScreenReader: Mock<() => boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mock @google/gemini-cli-core and its Config class
|
// Mock @google/gemini-cli-core and its Config class
|
||||||
|
@ -168,6 +169,7 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
||||||
getConnectionStatus: vi.fn(() => 'connected'),
|
getConnectionStatus: vi.fn(() => 'connected'),
|
||||||
})),
|
})),
|
||||||
isTrustedFolder: vi.fn(() => true),
|
isTrustedFolder: vi.fn(() => true),
|
||||||
|
getScreenReader: vi.fn(() => false),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -923,10 +923,12 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
|
||||||
key={staticKey}
|
key={staticKey}
|
||||||
items={[
|
items={[
|
||||||
<Box flexDirection="column" key="header">
|
<Box flexDirection="column" key="header">
|
||||||
{!settings.merged.hideBanner && (
|
{!(settings.merged.hideBanner || config.getScreenReader()) && (
|
||||||
<Header version={version} nightly={nightly} />
|
<Header version={version} nightly={nightly} />
|
||||||
)}
|
)}
|
||||||
{!settings.merged.hideTips && <Tips config={config} />}
|
{!(settings.merged.hideTips || config.getScreenReader()) && (
|
||||||
|
<Tips config={config} />
|
||||||
|
)}
|
||||||
</Box>,
|
</Box>,
|
||||||
...history.map((h) => (
|
...history.map((h) => (
|
||||||
<HistoryItemDisplay
|
<HistoryItemDisplay
|
||||||
|
@ -1093,12 +1095,14 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
|
||||||
<LoadingIndicator
|
<LoadingIndicator
|
||||||
thought={
|
thought={
|
||||||
streamingState === StreamingState.WaitingForConfirmation ||
|
streamingState === StreamingState.WaitingForConfirmation ||
|
||||||
config.getAccessibility()?.disableLoadingPhrases
|
config.getAccessibility()?.disableLoadingPhrases ||
|
||||||
|
config.getScreenReader()
|
||||||
? undefined
|
? undefined
|
||||||
: thought
|
: thought
|
||||||
}
|
}
|
||||||
currentLoadingPhrase={
|
currentLoadingPhrase={
|
||||||
config.getAccessibility()?.disableLoadingPhrases
|
config.getAccessibility()?.disableLoadingPhrases ||
|
||||||
|
config.getScreenReader()
|
||||||
? undefined
|
? undefined
|
||||||
: currentLoadingPhrase
|
: currentLoadingPhrase
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import {
|
||||||
cleanupOldClipboardImages,
|
cleanupOldClipboardImages,
|
||||||
} from '../utils/clipboardUtils.js';
|
} from '../utils/clipboardUtils.js';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
import { SCREEN_READER_USER_PREFIX } from '../constants.js';
|
||||||
|
|
||||||
export interface InputPromptProps {
|
export interface InputPromptProps {
|
||||||
buffer: TextBuffer;
|
buffer: TextBuffer;
|
||||||
|
@ -688,7 +689,12 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
||||||
>
|
>
|
||||||
{shellModeActive ? (
|
{shellModeActive ? (
|
||||||
reverseSearchActive ? (
|
reverseSearchActive ? (
|
||||||
<Text color={theme.text.link}>(r:) </Text>
|
<Text
|
||||||
|
color={theme.text.link}
|
||||||
|
aria-label={SCREEN_READER_USER_PREFIX}
|
||||||
|
>
|
||||||
|
(r:){' '}
|
||||||
|
</Text>
|
||||||
) : (
|
) : (
|
||||||
'! '
|
'! '
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { Box, Text } from 'ink';
|
||||||
import { CompressionProps } from '../../types.js';
|
import { CompressionProps } from '../../types.js';
|
||||||
import Spinner from 'ink-spinner';
|
import Spinner from 'ink-spinner';
|
||||||
import { Colors } from '../../colors.js';
|
import { Colors } from '../../colors.js';
|
||||||
|
import { SCREEN_READER_MODEL_PREFIX } from '../../constants.js';
|
||||||
|
|
||||||
export interface CompressionDisplayProps {
|
export interface CompressionDisplayProps {
|
||||||
compression: CompressionProps;
|
compression: CompressionProps;
|
||||||
|
@ -40,6 +41,7 @@ export const CompressionMessage: React.FC<CompressionDisplayProps> = ({
|
||||||
color={
|
color={
|
||||||
compression.isPending ? Colors.AccentPurple : Colors.AccentGreen
|
compression.isPending ? Colors.AccentPurple : Colors.AccentGreen
|
||||||
}
|
}
|
||||||
|
aria-label={SCREEN_READER_MODEL_PREFIX}
|
||||||
>
|
>
|
||||||
{text}
|
{text}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
|
@ -8,6 +8,7 @@ import React from 'react';
|
||||||
import { Text, Box } from 'ink';
|
import { Text, Box } from 'ink';
|
||||||
import { MarkdownDisplay } from '../../utils/MarkdownDisplay.js';
|
import { MarkdownDisplay } from '../../utils/MarkdownDisplay.js';
|
||||||
import { Colors } from '../../colors.js';
|
import { Colors } from '../../colors.js';
|
||||||
|
import { SCREEN_READER_MODEL_PREFIX } from '../../constants.js';
|
||||||
|
|
||||||
interface GeminiMessageProps {
|
interface GeminiMessageProps {
|
||||||
text: string;
|
text: string;
|
||||||
|
@ -28,7 +29,12 @@ export const GeminiMessage: React.FC<GeminiMessageProps> = ({
|
||||||
return (
|
return (
|
||||||
<Box flexDirection="row">
|
<Box flexDirection="row">
|
||||||
<Box width={prefixWidth}>
|
<Box width={prefixWidth}>
|
||||||
<Text color={Colors.AccentPurple}>{prefix}</Text>
|
<Text
|
||||||
|
color={Colors.AccentPurple}
|
||||||
|
aria-label={SCREEN_READER_MODEL_PREFIX}
|
||||||
|
>
|
||||||
|
{prefix}
|
||||||
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
<Box flexGrow={1} flexDirection="column">
|
<Box flexGrow={1} flexDirection="column">
|
||||||
<MarkdownDisplay
|
<MarkdownDisplay
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Text, Box } from 'ink';
|
import { Text, Box } from 'ink';
|
||||||
import { Colors } from '../../colors.js';
|
import { Colors } from '../../colors.js';
|
||||||
|
import { SCREEN_READER_USER_PREFIX } from '../../constants.js';
|
||||||
|
|
||||||
interface UserMessageProps {
|
interface UserMessageProps {
|
||||||
text: string;
|
text: string;
|
||||||
|
@ -31,7 +32,9 @@ export const UserMessage: React.FC<UserMessageProps> = ({ text }) => {
|
||||||
alignSelf="flex-start"
|
alignSelf="flex-start"
|
||||||
>
|
>
|
||||||
<Box width={prefixWidth}>
|
<Box width={prefixWidth}>
|
||||||
<Text color={textColor}>{prefix}</Text>
|
<Text color={textColor} aria-label={SCREEN_READER_USER_PREFIX}>
|
||||||
|
{prefix}
|
||||||
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
<Box flexGrow={1}>
|
<Box flexGrow={1}>
|
||||||
<Text wrap="wrap" color={textColor}>
|
<Text wrap="wrap" color={textColor}>
|
||||||
|
|
|
@ -15,3 +15,7 @@ export const UI_WIDTH =
|
||||||
export const STREAM_DEBOUNCE_MS = 100;
|
export const STREAM_DEBOUNCE_MS = 100;
|
||||||
|
|
||||||
export const SHELL_COMMAND_NAME = 'Shell Command';
|
export const SHELL_COMMAND_NAME = 'Shell Command';
|
||||||
|
|
||||||
|
export const SCREEN_READER_USER_PREFIX = 'User: ';
|
||||||
|
|
||||||
|
export const SCREEN_READER_MODEL_PREFIX = 'Model: ';
|
||||||
|
|
|
@ -62,6 +62,7 @@ export enum ApprovalMode {
|
||||||
|
|
||||||
export interface AccessibilitySettings {
|
export interface AccessibilitySettings {
|
||||||
disableLoadingPhrases?: boolean;
|
disableLoadingPhrases?: boolean;
|
||||||
|
screenReader?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BugCommandSettings {
|
export interface BugCommandSettings {
|
||||||
|
@ -734,6 +735,10 @@ export class Config {
|
||||||
return this.skipNextSpeakerCheck;
|
return this.skipNextSpeakerCheck;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getScreenReader(): boolean {
|
||||||
|
return this.accessibility.screenReader ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
getEnablePromptCompletion(): boolean {
|
getEnablePromptCompletion(): boolean {
|
||||||
return this.enablePromptCompletion;
|
return this.enablePromptCompletion;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue