From 1f1fc8ceedd41a68d925fe095fdfb76cf9e0c15d Mon Sep 17 00:00:00 2001 From: Matthew Chisolm <39521893+mchisolm0@users.noreply.github.com> Date: Sun, 23 Feb 2025 19:37:26 -0600 Subject: [PATCH 1/2] fix: use environment variables to check for terminal Issue #2278 finds CLibrary.isatty gives an error unless both the --no-color and --no-ansi flags are given. This fix switches to environment variables because on CachyOS Linux and Fedora Linux users consistently got those errors. --- maestro-cli/src/main/java/maestro/cli/DisableAnsiMixin.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/maestro-cli/src/main/java/maestro/cli/DisableAnsiMixin.kt b/maestro-cli/src/main/java/maestro/cli/DisableAnsiMixin.kt index 3a6de1b244..f3ee1dca94 100644 --- a/maestro-cli/src/main/java/maestro/cli/DisableAnsiMixin.kt +++ b/maestro-cli/src/main/java/maestro/cli/DisableAnsiMixin.kt @@ -40,9 +40,12 @@ class DisableAnsiMixin { val parserWithANSIOption = findFirstParserWithMatchedParamLabel(parseResult, "") val mixin = parserWithANSIOption?.commandSpec()?.mixins()?.values?.firstNotNullOfOrNull { it.userObject() as? DisableAnsiMixin } - val stdoutIsTTY = CLibrary.isatty(CLibrary.STDOUT_FILENO) != 0 + // Instead of using CLibrary.isatty, use environment variables to detect terminal + val forceDisable = System.getenv("MAESTRO_DISABLE_ANSI")?.toBoolean() ?: false + val isTTY = !forceDisable && System.getenv("TERM") != null + ansiEnabled = mixin?.enableANSIOutput // Use the param value if it was specified - ?: stdoutIsTTY // Otherwise fall back to checking if output is a tty + ?: isTTY // Otherwise fall back to checking environment Ansi.setEnabled(ansiEnabled) From ae49d1ef04e0383f0b63f897e0c26b79343cdc5e Mon Sep 17 00:00:00 2001 From: Matthew Chisolm <39521893+mchisolm0@users.noreply.github.com> Date: Mon, 24 Feb 2025 17:57:19 -0600 Subject: [PATCH 2/2] Add conditional checking for Windows terminals --- .../main/java/maestro/cli/DisableAnsiMixin.kt | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/maestro-cli/src/main/java/maestro/cli/DisableAnsiMixin.kt b/maestro-cli/src/main/java/maestro/cli/DisableAnsiMixin.kt index f3ee1dca94..8af8b9b925 100644 --- a/maestro-cli/src/main/java/maestro/cli/DisableAnsiMixin.kt +++ b/maestro-cli/src/main/java/maestro/cli/DisableAnsiMixin.kt @@ -35,6 +35,13 @@ class DisableAnsiMixin { return null } + private fun isWindowsTerminalColorCapable(): Boolean { + // Check for modern Windows terminals that support ANSI + return System.getenv("PSVersionTable") != null || // PowerShell + System.getenv("WT_SESSION") != null || // Windows Terminal + System.getenv("TERM_PROGRAM") == "vscode" // VS Code terminal + } + private fun applyCLIMixin(parseResult: CommandLine.ParseResult) { // Find the first mixin for which of the enable-ansi parameter was specified val parserWithANSIOption = findFirstParserWithMatchedParamLabel(parseResult, "") @@ -42,7 +49,15 @@ class DisableAnsiMixin { // Instead of using CLibrary.isatty, use environment variables to detect terminal val forceDisable = System.getenv("MAESTRO_DISABLE_ANSI")?.toBoolean() ?: false - val isTTY = !forceDisable && System.getenv("TERM") != null + val forceEnable = System.getenv("MAESTRO_FORCE_ANSI")?.toBoolean() ?: false + + val isWindows = System.getProperty("os.name").lowercase().contains("windows") + val isTTY = when { + forceEnable -> true + forceDisable -> false + isWindows -> isWindowsTerminalColorCapable() + else -> System.getenv("TERM") != null + } ansiEnabled = mixin?.enableANSIOutput // Use the param value if it was specified ?: isTTY // Otherwise fall back to checking environment