From 9516424cae487a57b51ebf1c344a9603d23dfa3b Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Wed, 10 Dec 2025 20:41:45 +0100 Subject: [PATCH] fixes #161: disable theme watcher in print mode The theme file watcher was keeping the Node.js process alive indefinitely even in print mode where hot-reload is unnecessary. This fix adds an enableWatcher parameter to initTheme() and setTheme() functions, and only enables watchers in interactive mode. - Modified initTheme() to accept enableWatcher parameter (default: false) - Modified setTheme() to accept enableWatcher parameter (default: false) - Updated main.ts to only enable watchers in interactive mode - Updated InteractiveMode to enable watchers when changing themes --- packages/coding-agent/src/main.ts | 6 ++++-- .../src/modes/interactive/interactive-mode.ts | 4 ++-- .../src/modes/interactive/theme/theme.ts | 12 ++++++++---- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/packages/coding-agent/src/main.ts b/packages/coding-agent/src/main.ts index 7f484c4c..6e06cb25 100644 --- a/packages/coding-agent/src/main.ts +++ b/packages/coding-agent/src/main.ts @@ -167,10 +167,13 @@ export async function main(args: string[]) { // Process @file arguments const { initialMessage, initialAttachments } = prepareInitialMessage(parsed); + // Determine if we're in interactive mode (needed for theme watcher) + const isInteractive = !parsed.print && parsed.mode === undefined; + // Initialize theme (before any TUI rendering) const settingsManager = new SettingsManager(); const themeName = settingsManager.getTheme(); - initTheme(themeName); + initTheme(themeName, isInteractive); // Setup session manager const sessionManager = new SessionManager(parsed.continue && !parsed.resume, parsed.session); @@ -196,7 +199,6 @@ export async function main(args: string[]) { } // Determine mode and output behavior - const isInteractive = !parsed.print && parsed.mode === undefined; const mode = parsed.mode || "text"; const shouldPrintMessages = isInteractive; diff --git a/packages/coding-agent/src/modes/interactive/interactive-mode.ts b/packages/coding-agent/src/modes/interactive/interactive-mode.ts index 946130a6..097b9d78 100644 --- a/packages/coding-agent/src/modes/interactive/interactive-mode.ts +++ b/packages/coding-agent/src/modes/interactive/interactive-mode.ts @@ -1164,7 +1164,7 @@ export class InteractiveMode { const selector = new ThemeSelectorComponent( currentTheme, (themeName) => { - const result = setTheme(themeName); + const result = setTheme(themeName, true); this.settingsManager.setTheme(themeName); this.ui.invalidate(); done(); @@ -1179,7 +1179,7 @@ export class InteractiveMode { this.ui.requestRender(); }, (themeName) => { - const result = setTheme(themeName); + const result = setTheme(themeName, true); if (result.success) { this.ui.invalidate(); this.ui.requestRender(); diff --git a/packages/coding-agent/src/modes/interactive/theme/theme.ts b/packages/coding-agent/src/modes/interactive/theme/theme.ts index 3b0787d8..4ce6304d 100644 --- a/packages/coding-agent/src/modes/interactive/theme/theme.ts +++ b/packages/coding-agent/src/modes/interactive/theme/theme.ts @@ -455,12 +455,14 @@ let currentThemeName: string | undefined; let themeWatcher: fs.FSWatcher | undefined; let onThemeChangeCallback: (() => void) | undefined; -export function initTheme(themeName?: string): void { +export function initTheme(themeName?: string, enableWatcher: boolean = false): void { const name = themeName ?? getDefaultTheme(); currentThemeName = name; try { theme = loadTheme(name); - startThemeWatcher(); + if (enableWatcher) { + startThemeWatcher(); + } } catch (error) { // Theme is invalid - fall back to dark theme silently currentThemeName = "dark"; @@ -469,11 +471,13 @@ export function initTheme(themeName?: string): void { } } -export function setTheme(name: string): { success: boolean; error?: string } { +export function setTheme(name: string, enableWatcher: boolean = false): { success: boolean; error?: string } { currentThemeName = name; try { theme = loadTheme(name); - startThemeWatcher(); + if (enableWatcher) { + startThemeWatcher(); + } return { success: true }; } catch (error) { // Theme is invalid - fall back to dark theme