2026-02-18 19:01:23 -05:00
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import os from 'node:os' ;
/**
* Detects if the current OS is Windows 10.
*/
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 {
2026-03-03 06:23:26 +00:00
return (
process . env [ 'TERMINAL_EMULATOR' ] === 'JetBrains-JediTerm' ||
process . env [ 'TERM_PROGRAM' ] === 'JetBrains-JediTerm' ||
! ! process . env [ 'IDEA_INITIAL_DIRECTORY' ] ||
! ! process . env [ 'JETBRAINS_IDE' ]
) ;
2026-02-18 19:01:23 -05:00
}
2026-02-20 13:22:45 -05:00
/**
* Detects if the current terminal is the default Apple Terminal.app.
*/
export function isAppleTerminal ( ) : boolean {
return process . env [ 'TERM_PROGRAM' ] === 'Apple_Terminal' ;
}
2026-03-03 06:23:26 +00:00
/**
* Detects if the current terminal is VS Code.
*/
export function isVSCode ( ) : boolean {
return process . env [ 'TERM_PROGRAM' ] === 'vscode' ;
}
/**
* Detects if the current terminal is iTerm2.
*/
export function isITerm2 ( ) : boolean {
return process . env [ 'TERM_PROGRAM' ] === 'iTerm.app' ;
}
/**
* Detects if the current terminal is Ghostty.
*/
export function isGhostty ( ) : boolean {
return (
process . env [ 'TERM_PROGRAM' ] === 'ghostty' ||
! ! process . env [ 'GHOSTTY_BIN_DIR' ]
) ;
}
/**
* Detects if running inside tmux.
*/
export function isTmux ( ) : boolean {
return ! ! process . env [ 'TMUX' ] || ( process . env [ 'TERM' ] || '' ) . includes ( 'tmux' ) ;
}
/**
* Detects if the current terminal is Windows Terminal.
*/
export function isWindowsTerminal ( ) : boolean {
return ! ! process . env [ 'WT_SESSION' ] ;
}
2026-02-20 13:22:45 -05:00
/**
* 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 ;
}
return false ;
}
2026-02-18 19:01:23 -05:00
/**
* 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'
) {
return true ;
}
// Check if stdout supports 24-bit color depth
if ( process . stdout . getColorDepth && process . stdout . getColorDepth ( ) >= 24 ) {
return true ;
}
return false ;
}
2026-03-03 06:23:26 +00:00
/**
* Heuristic for keyboard protocol support based on terminal identity.
*/
export function supportsKeyboardProtocolHeuristic ( ) : boolean {
return isGhostty ( ) || isITerm2 ( ) || isVSCode ( ) || isWindowsTerminal ( ) ;
}
2026-02-20 13:22:45 -05:00
export enum WarningPriority {
Low = 'low' ,
High = 'high' ,
}
export interface StartupWarning {
id : string ;
message : string ;
priority : WarningPriority ;
}
2026-02-20 13:06:35 -08:00
/**
* Returns a list of compatibility warnings based on the current environment.
*/
export function getCompatibilityWarnings ( options ? : {
isAlternateBuffer? : boolean ;
2026-03-03 06:23:26 +00:00
supportsKeyboardProtocol? : boolean ;
2026-02-20 13:06:35 -08:00
} ) : StartupWarning [ ] {
2026-02-20 13:22:45 -05:00
const warnings : StartupWarning [ ] = [ ] ;
2026-02-18 19:01:23 -05:00
if ( isWindows10 ( ) ) {
2026-02-20 13:22:45 -05:00
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 ,
} ) ;
2026-02-18 19:01:23 -05:00
}
2026-02-20 13:06:35 -08:00
if ( isJetBrainsTerminal ( ) && options ? . isAlternateBuffer ) {
const platformTerminals : Partial < Record < NodeJS.Platform , string > > = {
win32 : 'Windows Terminal' ,
darwin : 'iTerm2 or Ghostty' ,
linux : 'Ghostty' ,
} ;
const suggestion = platformTerminals [ os . platform ( ) ] ;
const suggestedTerminals = suggestion ? ` (e.g., ${ suggestion } ) ` : '' ;
2026-02-20 13:22:45 -05:00
warnings . push ( {
id : 'jetbrains-terminal' ,
2026-03-03 06:23:26 +00:00
message : ` Warning: JetBrains mouse scrolling is unreliable with alternate buffer enabled. Using an external terminal ${ suggestedTerminals } or disabling alternate buffer in settings is recommended. ` ,
2026-02-20 13:22:45 -05:00
priority : WarningPriority.High ,
} ) ;
2026-02-18 19:01:23 -05:00
}
2026-03-03 06:23:26 +00:00
if ( isTmux ( ) ) {
warnings . push ( {
id : 'tmux-mouse-support' ,
message :
'Warning: Running inside tmux. For the best experience (including mouse scrolling), ensure "set -g mouse on" is enabled in your tmux configuration.' ,
priority : WarningPriority.Low ,
} ) ;
}
2026-02-20 13:22:45 -05:00
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 ,
} ) ;
2026-03-03 06:23:26 +00:00
} else if (
! supportsTrueColor ( ) &&
! isITerm2 ( ) &&
! isVSCode ( ) &&
! isGhostty ( ) &&
! isAppleTerminal ( )
) {
2026-02-20 13:22:45 -05:00
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 ,
} ) ;
2026-02-18 19:01:23 -05:00
}
2026-03-03 06:23:26 +00:00
const hasKeyboardProtocol =
options ? . supportsKeyboardProtocol ? ? supportsKeyboardProtocolHeuristic ( ) ;
if ( ! hasKeyboardProtocol ) {
const suggestion =
os . platform ( ) === 'darwin'
? 'iTerm2 or Ghostty'
: os . platform ( ) === 'win32'
? 'Windows Terminal'
: 'Ghostty' ;
warnings . push ( {
id : 'keyboard-protocol' ,
message : ` Warning: Advanced keyboard features (like Shift+Enter for newlines) are not supported in this terminal. Consider using ${ suggestion } for a better experience. ` ,
priority : WarningPriority.Low ,
} ) ;
}
2026-02-18 19:01:23 -05:00
return warnings ;
}