@@ -33,6 +33,7 @@ const IDE_THEME_INFERENCE = {
3333 'tokyo' ,
3434 'abyss' ,
3535 'zed dark' ,
36+ 'vs dark' ,
3637 ] ,
3738 light : [
3839 'light' ,
@@ -48,6 +49,7 @@ const IDE_THEME_INFERENCE = {
4849 'pastel' ,
4950 'cream' ,
5051 'zed light' ,
52+ 'vs light' ,
5153 ] ,
5254} as const
5355
@@ -236,6 +238,7 @@ const resolveZedSettingsPaths = (): string[] => {
236238}
237239
238240const extractVSCodeTheme = ( content : string ) : ThemeName | null => {
241+ // Try standard colorTheme setting
239242 const colorThemeMatch = content . match (
240243 / " w o r k b e n c h \. c o l o r T h e m e " \s * : \s * " ( [ ^ " ] + ) " / i,
241244 )
@@ -244,12 +247,29 @@ const extractVSCodeTheme = (content: string): ThemeName | null => {
244247 if ( inferred ) return inferred
245248 }
246249
247- const themeKindEnv =
248- process . env . VSCODE_THEME_KIND ?? process . env . VSCODE_COLOR_THEME_KIND
249- if ( themeKindEnv ) {
250- const normalized = themeKindEnv . trim ( ) . toLowerCase ( )
251- if ( normalized === 'dark' || normalized === 'hc' ) return 'dark'
252- if ( normalized === 'light' ) return 'light'
250+ // Check if auto-detect is enabled and try preferred themes
251+ const autoDetectMatch = content . match (
252+ / " w i n d o w \. a u t o D e t e c t C o l o r S c h e m e " \s * : \s * ( t r u e | f a l s e ) / i,
253+ )
254+ const autoDetectEnabled = autoDetectMatch ?. [ 1 ] ?. toLowerCase ( ) === 'true'
255+
256+ if ( autoDetectEnabled ) {
257+ // Try to extract both preferred themes and infer from their names
258+ const preferredDarkMatch = content . match (
259+ / " w o r k b e n c h \. p r e f e r r e d D a r k C o l o r T h e m e " \s * : \s * " ( [ ^ " ] + ) " / i,
260+ )
261+ if ( preferredDarkMatch ) {
262+ const inferred = inferThemeFromName ( preferredDarkMatch [ 1 ] )
263+ if ( inferred ) return inferred
264+ }
265+
266+ const preferredLightMatch = content . match (
267+ / " w o r k b e n c h \. p r e f e r r e d L i g h t C o l o r T h e m e " \s * : \s * " ( [ ^ " ] + ) " / i,
268+ )
269+ if ( preferredLightMatch ) {
270+ const inferred = inferThemeFromName ( preferredLightMatch [ 1 ] )
271+ if ( inferred ) return inferred
272+ }
253273 }
254274
255275 return null
@@ -315,6 +335,15 @@ const detectVSCodeTheme = (): ThemeName | null => {
315335 if ( theme ) {
316336 return theme
317337 }
338+
339+ // If extractVSCodeTheme returned null but auto-detect is enabled,
340+ // use platform theme as fallback
341+ const autoDetectMatch = content . match (
342+ / " w i n d o w \. a u t o D e t e c t C o l o r S c h e m e " \s * : \s * ( t r u e | f a l s e ) / i,
343+ )
344+ if ( autoDetectMatch ?. [ 1 ] ?. toLowerCase ( ) === 'true' ) {
345+ return detectPlatformTheme ( )
346+ }
318347 }
319348
320349 const themeKindEnv =
@@ -367,13 +396,6 @@ const extractZedTheme = (content: string): ThemeName | null => {
367396 if ( typeof modeTheme === 'string' ) {
368397 candidates . push ( modeTheme )
369398 }
370- } else if ( mode === 'system' ) {
371- const platformTheme = detectPlatformTheme ( )
372- candidates . push ( platformTheme )
373- const platformThemeName = themeConfig [ platformTheme ]
374- if ( typeof platformThemeName === 'string' ) {
375- candidates . push ( platformThemeName )
376- }
377399 }
378400 }
379401
@@ -435,6 +457,23 @@ const detectZedTheme = (): ThemeName | null => {
435457 if ( theme ) {
436458 return theme
437459 }
460+
461+ // If extractZedTheme returned null, check if theme mode is 'system'
462+ // and fall back to platform detection
463+ try {
464+ const sanitized = stripJsonStyleComments ( content )
465+ const parsed = JSON . parse ( sanitized ) as Record < string , unknown >
466+ const themeSetting = parsed . theme
467+ if ( themeSetting && typeof themeSetting === 'object' ) {
468+ const themeConfig = themeSetting as Record < string , unknown >
469+ const modeRaw = themeConfig . mode
470+ if ( typeof modeRaw === 'string' && modeRaw . toLowerCase ( ) === 'system' ) {
471+ return detectPlatformTheme ( )
472+ }
473+ }
474+ } catch {
475+ // Ignore parsing errors
476+ }
438477 }
439478
440479 return null
@@ -473,11 +512,6 @@ type ThemeOverrideConfig = Partial<Record<ThemeName, ChatThemeOverrides>> & {
473512 all ?: ChatThemeOverrides
474513}
475514
476- const CHAT_THEME_ENV_KEYS = [
477- 'OPEN_TUI_CHAT_THEME_OVERRIDES' ,
478- 'OPENTUI_CHAT_THEME_OVERRIDES' ,
479- ] as const
480-
481515const mergeMarkdownOverrides = (
482516 base : MarkdownThemeOverrides | undefined ,
483517 override : MarkdownThemeOverrides | undefined ,
@@ -571,18 +605,6 @@ const parseThemeOverrides = (
571605 }
572606}
573607
574- const loadThemeOverrides = ( ) : Partial <
575- Record < ThemeName , ChatThemeOverrides >
576- > => {
577- for ( const key of CHAT_THEME_ENV_KEYS ) {
578- const raw = process . env [ key ]
579- if ( raw && raw . trim ( ) . length > 0 ) {
580- return parseThemeOverrides ( raw )
581- }
582- }
583- return { }
584- }
585-
586608const textDecoder = new TextDecoder ( )
587609
588610const readSpawnOutput = ( output : unknown ) : string => {
@@ -686,7 +708,11 @@ export const detectSystemTheme = (): ThemeName => {
686708 const ideTheme = detectIDETheme ( )
687709 const platformTheme = detectPlatformTheme ( )
688710 const preferredTheme =
689- terminalOverrideTheme ?? ideTheme ?? oscDetectedTheme ?? platformTheme ?? 'dark'
711+ terminalOverrideTheme ??
712+ ideTheme ??
713+ oscDetectedTheme ??
714+ platformTheme ??
715+ 'dark'
690716
691717 if ( normalizedEnv === 'opposite' ) {
692718 return preferredTheme === 'dark' ? 'light' : 'dark'
@@ -824,13 +850,10 @@ const DEFAULT_CHAT_THEMES: Record<ThemeName, ChatTheme> = {
824850 } ,
825851}
826852
827- export const chatThemes = ( ( ) => {
828- const overrides = loadThemeOverrides ( )
829- return {
830- dark : mergeTheme ( DEFAULT_CHAT_THEMES . dark , overrides . dark ) ,
831- light : mergeTheme ( DEFAULT_CHAT_THEMES . light , overrides . light ) ,
832- }
833- } ) ( )
853+ export const chatThemes = {
854+ dark : DEFAULT_CHAT_THEMES . dark ,
855+ light : DEFAULT_CHAT_THEMES . light ,
856+ }
834857
835858export const createMarkdownPalette = ( theme : ChatTheme ) : MarkdownPalette => {
836859 const headingDefaults : Record < MarkdownHeadingLevel , string > = {
0 commit comments