diff --git a/packages/vitest/src/node/cli/cac.ts b/packages/vitest/src/node/cli/cac.ts index a16e044d257f..9c9fdb2c3eeb 100644 --- a/packages/vitest/src/node/cli/cac.ts +++ b/packages/vitest/src/node/cli/cac.ts @@ -5,8 +5,9 @@ import type { CLIOption, CLIOptions as CLIOptionsConfig } from './cli-config' import { toArray } from '@vitest/utils/helpers' import cac from 'cac' import { normalize } from 'pathe' -import c from 'tinyrainbow' +import c, { disableDefaultColors } from 'tinyrainbow' import { version } from '../../../package.json' with { type: 'json' } +import { isAgent } from '../../utils/env' import { benchCliOptionsConfig, cliOptionsConfig, collectCliOptionsConfig } from './cli-config' import { setupTabCompletions } from './completions' @@ -74,6 +75,10 @@ function addCliOptions(cli: CAC | Command, options: CLIOptionsConfig) { } export function createCLI(options: CliParseOptions = {}): CAC { + if (isAgent) { + disableDefaultColors() + } + const cli = cac('vitest') cli.version(version) diff --git a/packages/vitest/src/node/cli/cli-config.ts b/packages/vitest/src/node/cli/cli-config.ts index ddf7641096b2..1393d39f5acc 100644 --- a/packages/vitest/src/node/cli/cli-config.ts +++ b/packages/vitest/src/node/cli/cli-config.ts @@ -1,7 +1,6 @@ import type { ApiConfig } from '../types/config' import type { CliOptions } from './cli-api' import { defaultBrowserPort, defaultPort } from '../../constants' -import { ReportersMap } from '../reporters' type NestedOption>> = V extends | never @@ -141,7 +140,7 @@ export const cliOptionsConfig: VitestCLIOptions = { }, reporters: { alias: 'reporter', - description: `Specify reporters (${Object.keys(ReportersMap).join(', ')})`, + description: `Specify reporters (default, agent, blob, verbose, dot, json, tap, tap-flat, junit, tree, hanging-process, github-actions)`, argument: '', subcommands: null, // don't support custom objects array: true, diff --git a/packages/vitest/src/node/config/serializeConfig.ts b/packages/vitest/src/node/config/serializeConfig.ts index 7be23a3cb071..ca0115c32eb8 100644 --- a/packages/vitest/src/node/config/serializeConfig.ts +++ b/packages/vitest/src/node/config/serializeConfig.ts @@ -1,6 +1,7 @@ import type { TestProject } from '../project' import type { ApiConfig, SerializedConfig } from '../types/config' import { configDefaults } from '../../defaults' +import { isAgent } from '../../utils/env' export function serializeConfig(project: TestProject): SerializedConfig { const { config, globalConfig } = project @@ -146,5 +147,6 @@ export function serializeConfig(project: TestProject): SerializedConfig { config.slowTestThreshold ?? globalConfig.slowTestThreshold ?? configDefaults.slowTestThreshold, + isAgent, } } diff --git a/packages/vitest/src/runtime/config.ts b/packages/vitest/src/runtime/config.ts index a50b5c0aa83d..f2e2cbbf8304 100644 --- a/packages/vitest/src/runtime/config.ts +++ b/packages/vitest/src/runtime/config.ts @@ -146,6 +146,7 @@ export interface SerializedConfig { tagsFilter: string[] | undefined strictTags: boolean slowTestThreshold: number | undefined + isAgent: boolean } export interface SerializedCoverageConfig { diff --git a/packages/vitest/src/runtime/workers/init.ts b/packages/vitest/src/runtime/workers/init.ts index b225fda7ff79..431d8da79332 100644 --- a/packages/vitest/src/runtime/workers/init.ts +++ b/packages/vitest/src/runtime/workers/init.ts @@ -3,6 +3,7 @@ import type { WorkerRequest, WorkerResponse } from '../../node/pools/types' import type { WorkerSetupContext } from '../../types/worker' import type { VitestWorker } from './types' import { serializeError } from '@vitest/utils/error' +import { disableDefaultColors } from 'tinyrainbow' import { Traces } from '../../utils/traces' import * as listeners from '../listeners' import { createRuntimeRpc } from '../rpc' @@ -49,6 +50,10 @@ export function init(worker: Options): void { process.env.VITEST_WORKER_ID = String(message.workerId) reportMemory = message.options.reportMemory + if (message.context.config.isAgent) { + disableDefaultColors() + } + traces ??= await new Traces({ enabled: message.traces.enabled, sdkPath: message.traces.sdkPath, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a907a964e130..d69a57151df9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -127,8 +127,8 @@ catalogs: specifier: ^0.3.2 version: 0.3.2 tinyrainbow: - specifier: ^3.0.3 - version: 3.0.3 + specifier: ^3.1.0 + version: 3.1.0 tinyspy: specifier: ^4.0.4 version: 4.0.4 @@ -531,7 +531,7 @@ importers: version: 3.0.2 tinyrainbow: specifier: 'catalog:' - version: 3.0.3 + version: 3.1.0 ws: specifier: 'catalog:' version: 8.19.0 @@ -580,7 +580,7 @@ importers: version: link:../mocker tinyrainbow: specifier: 'catalog:' - version: 3.0.3 + version: 3.1.0 devDependencies: playwright: specifier: ^1.58.2 @@ -652,7 +652,7 @@ importers: version: 2.1.1 tinyrainbow: specifier: 'catalog:' - version: 3.0.3 + version: 3.1.0 devDependencies: '@types/istanbul-lib-coverage': specifier: 'catalog:' @@ -713,7 +713,7 @@ importers: version: 4.0.0-rc.1 tinyrainbow: specifier: 'catalog:' - version: 3.0.3 + version: 3.1.0 devDependencies: '@types/istanbul-lib-coverage': specifier: 'catalog:' @@ -756,7 +756,7 @@ importers: version: 6.2.2 tinyrainbow: specifier: 'catalog:' - version: 3.0.3 + version: 3.1.0 devDependencies: '@vitest/runner': specifier: workspace:* @@ -803,7 +803,7 @@ importers: dependencies: tinyrainbow: specifier: 'catalog:' - version: 3.0.3 + version: 3.1.0 devDependencies: '@types/react-is': specifier: ^19.2.0 @@ -870,7 +870,7 @@ importers: version: 0.2.15 tinyrainbow: specifier: 'catalog:' - version: 3.0.3 + version: 3.1.0 vitest: specifier: workspace:* version: link:../vitest @@ -982,7 +982,7 @@ importers: version: 2.0.0 tinyrainbow: specifier: 'catalog:' - version: 3.0.3 + version: 3.1.0 devDependencies: '@jridgewell/trace-mapping': specifier: 'catalog:' @@ -1067,7 +1067,7 @@ importers: version: 0.2.15 tinyrainbow: specifier: 'catalog:' - version: 3.0.3 + version: 3.1.0 vite: specifier: 7.1.5 version: 7.1.5(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) @@ -1496,7 +1496,7 @@ importers: version: 0.3.0 tinyrainbow: specifier: 'catalog:' - version: 3.0.3 + version: 3.1.0 tinyspy: specifier: ^4.0.4 version: 4.0.4 @@ -1601,7 +1601,7 @@ importers: version: 1.0.2 tinyrainbow: specifier: 'catalog:' - version: 3.0.3 + version: 3.1.0 vite: specifier: 7.1.5 version: 7.1.5(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.31.1)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) @@ -9823,8 +9823,8 @@ packages: picocolors: optional: true - tinyrainbow@3.0.3: - resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} + tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} engines: {node: '>=14.0.0'} tinyspy@4.0.4: @@ -19200,7 +19200,7 @@ snapshots: optionalDependencies: picocolors: 1.1.1 - tinyrainbow@3.0.3: {} + tinyrainbow@3.1.0: {} tinyspy@4.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 2264f9ae99bc..adf5cb50143a 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -81,7 +81,7 @@ catalog: tinyexec: ^1.0.2 tinyglobby: ^0.2.15 tinyhighlight: ^0.3.2 - tinyrainbow: ^3.0.3 + tinyrainbow: ^3.1.0 tinyspy: ^4.0.4 typescript: ^5.9.3 unocss: ^66.6.6 diff --git a/test/config/test/console-color.test.ts b/test/config/test/console-color.test.ts index b552908a199a..29a8b54c3fb0 100644 --- a/test/config/test/console-color.test.ts +++ b/test/config/test/console-color.test.ts @@ -1,5 +1,5 @@ import { expect, test } from 'vitest' -import { runVitest } from '../../test-utils' +import { runVitest, runVitestCli } from '../../test-utils' test('with color', async () => { const { stdout } = await runVitest({ @@ -30,6 +30,20 @@ test('without color', async () => { expect(stdout).not.toContain('\x1B[33mtrue\x1B[39m\n') }) +test('agent', async () => { + // Agent check is done on module import, so new process is needed + const { stdout } = await runVitestCli({ + preserveAnsi: true, + nodeOptions: { env: { AI_AGENT: 'copilot' } }, + }, '--root', 'fixtures/console-color', '--reporter', 'default') + + expect.soft(stdout).toContain('true\n') + expect.soft(stdout).not.toContain('\x1B[33mtrue\x1B[39m\n') + + expect.soft(stdout).toContain(' RUN') + expect.soft(stdout).not.toContain('\x1B[46m RUN') +}) + test.skipIf(process.platform === 'win32')('without color, forks pool in non-TTY parent', async () => { const { stdout } = await runVitest({ root: 'fixtures/console-color',