feat(core): implement automatic terminal detection and capability warnings (#14426)

This commit is contained in:
Spencer
2026-03-03 06:23:26 +00:00
parent e43b1cff58
commit 3f7181c6da
7 changed files with 224 additions and 240 deletions

View File

@@ -106,6 +106,30 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
enterAlternateScreen: vi.fn(),
disableLineWrapping: vi.fn(),
getVersion: vi.fn(() => Promise.resolve('1.0.0')),
detectTerminalEnvironment: vi.fn().mockReturnValue({
isTmux: false,
isJetBrains: false,
isWindowsTerminal: false,
isVSCode: false,
isITerm2: false,
isGhostty: false,
isAppleTerminal: false,
isWindows10: false,
supports256Colors: true,
supportsTrueColor: true,
supportsKeyboardProtocol: true,
}),
getTerminalCapabilities: vi.fn().mockReturnValue({
capabilities: {
supportsAltBuffer: true,
supportsMouse: true,
supportsReliableBackbufferClear: true,
supportsKeyboardProtocol: true,
},
warnings: [],
reasons: {},
}),
supportsKeyboardProtocolHeuristic: vi.fn().mockReturnValue(true),
startupProfiler: {
start: vi.fn(() => ({
end: vi.fn(),
@@ -184,6 +208,7 @@ vi.mock('./ui/utils/terminalCapabilityManager.js', () => ({
terminalCapabilityManager: {
detectCapabilities: vi.fn(),
getTerminalBackgroundColor: vi.fn(),
isKeyboardProtocolSupported: vi.fn().mockReturnValue(false),
},
}));

View File

@@ -15,6 +15,7 @@ import { createHash } from 'node:crypto';
import v8 from 'node:v8';
import os from 'node:os';
import dns from 'node:dns';
import { terminalCapabilityManager } from './ui/utils/terminalCapabilityManager.js';
import { start_sandbox } from './utils/sandbox.js';
import type { DnsResolutionOrder, LoadedSettings } from './config/settings.js';
import {
@@ -690,6 +691,8 @@ export async function main() {
})),
...(await getUserStartupWarnings(settings.merged, undefined, {
isAlternateBuffer: useAlternateBuffer,
supportsKeyboardProtocol:
terminalCapabilityManager.isKeyboardProtocolSupported(),
})),
];

View File

@@ -270,6 +270,10 @@ export class TerminalCapabilityManager {
return this.kittyEnabled;
}
isKeyboardProtocolSupported(): boolean {
return this.kittySupported || this.modifyOtherKeysSupported;
}
supportsOsc9Notifications(env: NodeJS.ProcessEnv = process.env): boolean {
if (env['WT_SESSION']) {
return false;

View File

@@ -174,5 +174,20 @@ describe('getUserStartupWarnings', () => {
);
expect(warnings).not.toContainEqual(compWarning);
});
it('should pass options to getCompatibilityWarnings', async () => {
const projectDir = path.join(testRootDir, 'project');
await fs.mkdir(projectDir);
await getUserStartupWarnings({}, projectDir, {
isAlternateBuffer: true,
supportsKeyboardProtocol: true,
});
expect(getCompatibilityWarnings).toHaveBeenCalledWith({
isAlternateBuffer: true,
supportsKeyboardProtocol: true,
});
});
});
});

View File

@@ -88,7 +88,10 @@ const WARNING_CHECKS: readonly WarningCheck[] = [
export async function getUserStartupWarnings(
settings: Settings,
workspaceRoot: string = process.cwd(),
options?: { isAlternateBuffer?: boolean },
options?: {
isAlternateBuffer?: boolean;
supportsKeyboardProtocol?: boolean;
},
): Promise<StartupWarning[]> {
const results = await Promise.all(
WARNING_CHECKS.map(async (check) => {
@@ -109,6 +112,7 @@ export async function getUserStartupWarnings(
warnings.push(
...getCompatibilityWarnings({
isAlternateBuffer: options?.isAlternateBuffer,
supportsKeyboardProtocol: options?.supportsKeyboardProtocol,
}),
);
}