From dcd4b2d38b186f31467361614c6d49d7a1f0907f Mon Sep 17 00:00:00 2001 From: Ryan Bahan Date: Fri, 3 Apr 2026 17:21:58 -0600 Subject: [PATCH] Remove is-interactive, inline the check The package was a 6-line function checking process.stdout.isTTY, TERM !== 'dumb', and absence of CI env var. Inline the logic directly in isTerminalInteractive(). Added 5 tests covering all branches: TTY + normal term, non-TTY, dumb terminal, CI set, CI empty string. Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/cli-kit/package.json | 1 - .../src/public/node/context/local.test.ts | 53 ++++++++++++++++++- .../cli-kit/src/public/node/context/local.ts | 3 +- pnpm-lock.yaml | 9 ---- 4 files changed, 53 insertions(+), 13 deletions(-) diff --git a/packages/cli-kit/package.json b/packages/cli-kit/package.json index 5f9f78b016b..575df410f86 100644 --- a/packages/cli-kit/package.json +++ b/packages/cli-kit/package.json @@ -137,7 +137,6 @@ "ignore": "6.0.2", "ink": "6.8.0", "is-executable": "2.0.1", - "is-interactive": "2.0.0", "is-wsl": "3.1.0", "jose": "5.9.6", "latest-version": "7.0.0", diff --git a/packages/cli-kit/src/public/node/context/local.test.ts b/packages/cli-kit/src/public/node/context/local.test.ts index abd5c523a6a..a4116f8cea9 100644 --- a/packages/cli-kit/src/public/node/context/local.test.ts +++ b/packages/cli-kit/src/public/node/context/local.test.ts @@ -4,6 +4,7 @@ import { isDevelopment, isHostedAppsMode, isShopify, + isTerminalInteractive, isUnitTest, analyticsDisabled, cloudEnvironment, @@ -14,12 +15,62 @@ import { import {fileExists} from '../fs.js' import {exec} from '../system.js' -import {expect, describe, vi, test} from 'vitest' +import {afterEach, expect, describe, vi, test} from 'vitest' vi.mock('../fs.js') vi.mock('../system.js') vi.mock('../environment.js') +describe('isTerminalInteractive', () => { + const originalIsTTY = process.stdout.isTTY + const originalEnv = {...process.env} + + afterEach(() => { + process.stdout.isTTY = originalIsTTY + process.env.TERM = originalEnv.TERM + if (originalEnv.CI === undefined) { + delete process.env.CI + } else { + process.env.CI = originalEnv.CI + } + }) + + test('returns true when stdout is a TTY, TERM is not dumb, and not in CI', () => { + process.stdout.isTTY = true + delete process.env.CI + process.env.TERM = 'xterm-256color' + expect(isTerminalInteractive()).toBe(true) + }) + + test('returns false when stdout is not a TTY', () => { + process.stdout.isTTY = false + delete process.env.CI + process.env.TERM = 'xterm-256color' + expect(isTerminalInteractive()).toBe(false) + }) + + test('returns false when TERM is dumb', () => { + process.stdout.isTTY = true + delete process.env.CI + process.env.TERM = 'dumb' + expect(isTerminalInteractive()).toBe(false) + }) + + test('returns false when CI env var is set', () => { + process.stdout.isTTY = true + process.env.CI = 'true' + process.env.TERM = 'xterm-256color' + expect(isTerminalInteractive()).toBe(false) + }) + + test('returns false when CI env var is empty string (still set)', () => { + process.stdout.isTTY = true + process.env.CI = '' + process.env.TERM = 'xterm-256color' + expect(isTerminalInteractive()).toBe(false) + }) +}) + describe('isUnitTest', () => { test('returns true when SHOPIFY_UNIT_TEST is truthy', () => { // Given diff --git a/packages/cli-kit/src/public/node/context/local.ts b/packages/cli-kit/src/public/node/context/local.ts index 116ff50257a..34fddf6791f 100644 --- a/packages/cli-kit/src/public/node/context/local.ts +++ b/packages/cli-kit/src/public/node/context/local.ts @@ -4,7 +4,6 @@ import {defaultThemeKitAccessDomain, environmentVariables, pathConstants} from ' import {fileExists} from '../fs.js' import {exec} from '../system.js' -import isInteractive from 'is-interactive' import macaddress from 'macaddress' import {homedir} from 'os' @@ -15,7 +14,7 @@ import {homedir} from 'os' * @returns True if the terminal is interactive. */ export function isTerminalInteractive(): boolean { - return isInteractive() + return Boolean(process.stdout.isTTY && process.env.TERM !== 'dumb' && !('CI' in process.env)) } /** diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 43ce79abff3..5160366dfc7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -393,9 +393,6 @@ importers: is-executable: specifier: 2.0.1 version: 2.0.1 - is-interactive: - specifier: 2.0.0 - version: 2.0.0 is-wsl: specifier: 3.1.0 version: 3.1.0 @@ -6238,10 +6235,6 @@ packages: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} - is-interactive@2.0.0: - resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} - engines: {node: '>=12'} - is-lower-case@2.0.2: resolution: {integrity: sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ==} @@ -15853,8 +15846,6 @@ snapshots: is-interactive@1.0.0: {} - is-interactive@2.0.0: {} - is-lower-case@2.0.2: dependencies: tslib: 2.6.3