File size: 5,572 Bytes
7a1ad33 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | /**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import os from 'node:os';
/**
* Detects if the current OS is Windows 10.
* Windows 11 also reports as version 10.0, but with build numbers >= 22000.
*/
export function isWindows10(): boolean {
if (os.platform() !== 'win32') {
return false;
}
const release = os.release();
const parts = release.split('.');
if (parts.length >= 3 && parts[0] === '10' && parts[1] === '0') {
const build = parseInt(parts[2], 10);
return build < 22000;
}
return false;
}
/**
* Detects if the current terminal is a JetBrains-based IDE terminal.
*/
export function isJetBrainsTerminal(): boolean {
const env = process.env;
return !!(
env['TERMINAL_EMULATOR']?.startsWith('JetBrains') || env['JETBRAINS_IDE']
);
}
/**
* Detects if the current terminal is running inside tmux.
*/
export function isTmux(): boolean {
return !!process.env['TMUX'];
}
/**
* Detects if the current terminal is running inside GNU screen.
*/
export function isGnuScreen(): boolean {
return !!process.env['STY'];
}
/**
* Detects if the terminal is low-color mode (TERM=screen* with no COLORTERM).
*/
export function isLowColorTmux(): boolean {
const term = process.env['TERM'] || '';
return isTmux() && term.startsWith('screen') && !process.env['COLORTERM'];
}
/**
* Detects if the terminal is a "dumb" terminal.
*/
export function isDumbTerminal(): boolean {
const term = process.env['TERM'] || '';
return term === 'dumb' || term === 'vt100';
}
/**
* Detects if the current terminal is the default Apple Terminal.app.
*/
export function isAppleTerminal(): boolean {
return process.env['TERM_PROGRAM'] === 'Apple_Terminal';
}
/**
* Detects if the current terminal supports 256 colors (8-bit).
*/
export function supports256Colors(): boolean {
// Check if stdout supports at least 8-bit color depth
if (process.stdout.getColorDepth && process.stdout.getColorDepth() >= 8) {
return true;
}
// Check TERM environment variable
const term = process.env['TERM'] || '';
if (term.includes('256color')) {
return true;
}
// Terminals supporting true color (like kmscon) also support 256 colors
if (supportsTrueColor()) {
return true;
}
return false;
}
/**
* Detects if the current terminal supports true color (24-bit).
*/
export function supportsTrueColor(): boolean {
// Check COLORTERM environment variable
if (
process.env['COLORTERM'] === 'truecolor' ||
process.env['COLORTERM'] === '24bit' ||
process.env['COLORTERM'] === 'kmscon'
) {
return true;
}
// Check if stdout supports 24-bit color depth
if (process.stdout.getColorDepth && process.stdout.getColorDepth() >= 24) {
return true;
}
return false;
}
export enum WarningPriority {
Low = 'low',
High = 'high',
}
export interface StartupWarning {
id: string;
message: string;
priority: WarningPriority;
}
/**
* Returns a list of compatibility warnings based on the current environment.
*/
export function getCompatibilityWarnings(options?: {
isAlternateBuffer?: boolean;
}): StartupWarning[] {
const warnings: StartupWarning[] = [];
if (isWindows10()) {
warnings.push({
id: 'windows-10',
message:
'Warning: Windows 10 detected. Some UI features like smooth scrolling may be degraded. Windows 11 is recommended for the best experience.',
priority: WarningPriority.High,
});
}
if (isJetBrainsTerminal() && options?.isAlternateBuffer) {
warnings.push({
id: 'jetbrains-terminal',
message:
'Warning: JetBrains terminal detected — alternate buffer mode may cause scroll wheel issues and rendering artifacts. If you experience problems, disable it in /settings → "Use Alternate Screen Buffer".',
priority: WarningPriority.High,
});
}
if (isLowColorTmux()) {
warnings.push({
id: 'low-color-tmux',
message:
'Warning: Limited color support detected (TERM=screen). Some visual elements may not render correctly. For better color support in tmux, add to ~/.tmux.conf:\n set -g default-terminal "tmux-256color"\n set -ga terminal-overrides ",*256col*:Tc"',
priority: WarningPriority.High,
});
}
if (isGnuScreen()) {
warnings.push({
id: 'gnu-screen',
message:
'Warning: GNU screen detected. Some keyboard shortcuts and visual features may behave unexpectedly. For the best experience, consider using tmux or running Gemini CLI directly in your terminal.',
priority: WarningPriority.Low,
});
}
if (isDumbTerminal()) {
const term = process.env['TERM'] || 'dumb';
warnings.push({
id: 'dumb-terminal',
message: `Warning: Basic terminal detected (TERM=${term}). Visual rendering will be limited. For the best experience, use a terminal emulator with truecolor support.`,
priority: WarningPriority.High,
});
}
if (!supports256Colors()) {
warnings.push({
id: '256-color',
message:
'Warning: 256-color support not detected. Using a terminal with at least 256-color support is recommended for a better visual experience.',
priority: WarningPriority.High,
});
} else if (!supportsTrueColor() && !isAppleTerminal()) {
warnings.push({
id: 'true-color',
message:
'Warning: True color (24-bit) support not detected. Using a terminal with true color enabled will result in a better visual experience.',
priority: WarningPriority.Low,
});
}
return warnings;
}
|