Skip to content

Commit 6f97b55

Browse files
feat: disable colors if agent is detected (#9851)
Co-authored-by: Ari Perkkiö <ari.perkkio@gmail.com>
1 parent d3b7a40 commit 6f97b55

File tree

8 files changed

+47
-21
lines changed

8 files changed

+47
-21
lines changed

packages/vitest/src/node/cli/cac.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ import type { CLIOption, CLIOptions as CLIOptionsConfig } from './cli-config'
55
import { toArray } from '@vitest/utils/helpers'
66
import cac from 'cac'
77
import { normalize } from 'pathe'
8-
import c from 'tinyrainbow'
8+
import c, { disableDefaultColors } from 'tinyrainbow'
99
import { version } from '../../../package.json' with { type: 'json' }
10+
import { isAgent } from '../../utils/env'
1011
import { benchCliOptionsConfig, cliOptionsConfig, collectCliOptionsConfig } from './cli-config'
1112
import { setupTabCompletions } from './completions'
1213

@@ -74,6 +75,10 @@ function addCliOptions(cli: CAC | Command, options: CLIOptionsConfig<any>) {
7475
}
7576

7677
export function createCLI(options: CliParseOptions = {}): CAC {
78+
if (isAgent) {
79+
disableDefaultColors()
80+
}
81+
7782
const cli = cac('vitest')
7883

7984
cli.version(version)

packages/vitest/src/node/cli/cli-config.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { ApiConfig } from '../types/config'
22
import type { CliOptions } from './cli-api'
33
import { defaultBrowserPort, defaultPort } from '../../constants'
4-
import { ReportersMap } from '../reporters'
54

65
type NestedOption<T, V = Extract<T, Record<string, any>>> = V extends
76
| never
@@ -141,7 +140,7 @@ export const cliOptionsConfig: VitestCLIOptions = {
141140
},
142141
reporters: {
143142
alias: 'reporter',
144-
description: `Specify reporters (${Object.keys(ReportersMap).join(', ')})`,
143+
description: `Specify reporters (default, agent, blob, verbose, dot, json, tap, tap-flat, junit, tree, hanging-process, github-actions)`,
145144
argument: '<name>',
146145
subcommands: null, // don't support custom objects
147146
array: true,

packages/vitest/src/node/config/serializeConfig.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { TestProject } from '../project'
22
import type { ApiConfig, SerializedConfig } from '../types/config'
33
import { configDefaults } from '../../defaults'
4+
import { isAgent } from '../../utils/env'
45

56
export function serializeConfig(project: TestProject): SerializedConfig {
67
const { config, globalConfig } = project
@@ -146,5 +147,6 @@ export function serializeConfig(project: TestProject): SerializedConfig {
146147
config.slowTestThreshold
147148
?? globalConfig.slowTestThreshold
148149
?? configDefaults.slowTestThreshold,
150+
isAgent,
149151
}
150152
}

packages/vitest/src/runtime/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ export interface SerializedConfig {
146146
tagsFilter: string[] | undefined
147147
strictTags: boolean
148148
slowTestThreshold: number | undefined
149+
isAgent: boolean
149150
}
150151

151152
export interface SerializedCoverageConfig {

packages/vitest/src/runtime/workers/init.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { WorkerRequest, WorkerResponse } from '../../node/pools/types'
33
import type { WorkerSetupContext } from '../../types/worker'
44
import type { VitestWorker } from './types'
55
import { serializeError } from '@vitest/utils/error'
6+
import { disableDefaultColors } from 'tinyrainbow'
67
import { Traces } from '../../utils/traces'
78
import * as listeners from '../listeners'
89
import { createRuntimeRpc } from '../rpc'
@@ -49,6 +50,10 @@ export function init(worker: Options): void {
4950
process.env.VITEST_WORKER_ID = String(message.workerId)
5051
reportMemory = message.options.reportMemory
5152

53+
if (message.context.config.isAgent) {
54+
disableDefaultColors()
55+
}
56+
5257
traces ??= await new Traces({
5358
enabled: message.traces.enabled,
5459
sdkPath: message.traces.sdkPath,

pnpm-lock.yaml

Lines changed: 16 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ catalog:
8585
tinyexec: ^1.0.2
8686
tinyglobby: ^0.2.15
8787
tinyhighlight: ^0.3.2
88-
tinyrainbow: ^3.0.3
88+
tinyrainbow: ^3.1.0
8989
tinyspy: ^4.0.4
9090
typescript: ^5.9.3
9191
unocss: ^66.6.6

test/config/test/console-color.test.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect, test } from 'vitest'
2-
import { runVitest } from '../../test-utils'
2+
import { runVitest, runVitestCli } from '../../test-utils'
33

44
test('with color', async () => {
55
const { stdout } = await runVitest({
@@ -30,6 +30,20 @@ test('without color', async () => {
3030
expect(stdout).not.toContain('\x1B[33mtrue\x1B[39m\n')
3131
})
3232

33+
test('agent', async () => {
34+
// Agent check is done on module import, so new process is needed
35+
const { stdout } = await runVitestCli({
36+
preserveAnsi: true,
37+
nodeOptions: { env: { AI_AGENT: 'copilot' } },
38+
}, '--root', 'fixtures/console-color', '--reporter', 'default')
39+
40+
expect.soft(stdout).toContain('true\n')
41+
expect.soft(stdout).not.toContain('\x1B[33mtrue\x1B[39m\n')
42+
43+
expect.soft(stdout).toContain(' RUN')
44+
expect.soft(stdout).not.toContain('\x1B[46m RUN')
45+
})
46+
3347
test.skipIf(process.platform === 'win32')('without color, forks pool in non-TTY parent', async () => {
3448
const { stdout } = await runVitest({
3549
root: 'fixtures/console-color',

0 commit comments

Comments
 (0)