Docs Packages

@procedures/vitest

packages/client-vitest/README.md on GitHub · Package map · Procedures

npm install @procedures/vitest

Vitest-specific test procedures. Run and watch tests with full coverage reporting.

October 2026: client-test is merged into this package. vitest.run also returns exitCode, stdout and stderr (the last 64 KiB) and, with coverage, the coverage percentages. The new vitest.coverage runs with coverage and takes a threshold (minimum line coverage). The sections below predate the merge.

Table of Contents#


Overview#

client-vitest provides procedures for running Vitest tests:

  • Test Execution - Run tests once with configurable patterns
  • Watch Mode - Continuous testing during development
  • Coverage Reports - Line, branch, function, and statement coverage
  • Multiple Reporters - Default, verbose, JSON, and JUnit output

Installation#

npm install github:mark1russell7/client-vitest#main

Architecture#

System Overview#

Diagram source (Mermaid). GitHub draws it on the page of the file.
graph TB
    subgraph "Application Layer"
        App[Your Application / CLI / MCP]
    end

    subgraph "client-vitest"
        Run[vitest.run<br/>Execute tests]
        Watch[vitest.watch<br/>Watch mode]
    end

    subgraph "Execution Layer"
        Shell[client-shell<br/>shell.run]
    end

    subgraph "Test Runner"
        Vitest[Vitest CLI<br/>npx vitest]
    end

    subgraph "Output"
        Results[Test Results]
        Coverage[Coverage Report]
    end

    App --> Run
    App --> Watch
    Run --> Shell
    Watch --> Shell
    Shell --> Vitest
    Vitest --> Results
    Vitest --> Coverage

Test Execution Flow#

Diagram source (Mermaid). GitHub draws it on the page of the file.
sequenceDiagram
    participant App as Application
    participant CV as client-vitest
    participant Shell as client-shell
    participant Vitest as Vitest CLI
    participant FS as File System

    App->>CV: vitest.run({ coverage: true })
    CV->>CV: Build CLI args
    CV->>Shell: shell.run("npx", ["vitest", "run", "--coverage"])
    Shell->>Vitest: Execute vitest

    loop For each test file
        Vitest->>FS: Read test file
        Vitest->>Vitest: Execute tests
    end

    Vitest->>FS: Write coverage report
    Vitest-->>Shell: Exit code + stdout
    Shell-->>CV: Command result
    CV->>CV: Parse output
    CV-->>App: { passed, failed, coverage }

Package Dependencies#

Diagram source (Mermaid). GitHub draws it on the page of the file.
graph BT
    subgraph "Test Packages"
        ClientVitest[client-vitest]
        ClientTest[client-test]
    end

    subgraph "Execution"
        Shell[client-shell]
    end

    subgraph "Core"
        Client[client]
    end

    subgraph "External"
        Vitest[vitest]
    end

    ClientVitest --> Shell
    ClientVitest --> Client
    ClientTest --> Shell
    ClientTest --> Client
    Shell --> Client
    ClientVitest -.->|executes| Vitest

Quick Start#

import { Client, LocalTransport, PROCEDURE_REGISTRY } from "@procedures/client";
import "@procedures/vitest"; // registers its procedures

const client = new Client(new LocalTransport({ registry: PROCEDURE_REGISTRY }));

// Run all tests
const result = await client.exec(["vitest", "run"], {
  cwd: "/path/to/project",
});

console.log(`Passed: ${result.passed}, Failed: ${result.failed}`);

// Run with coverage
const coverage = await client.exec(["vitest", "run"], {
  coverage: true,
});

if (coverage.coverage) {
  console.log(`Line coverage: ${coverage.coverage.lines}%`);
}

API Reference#

Procedures Summary#

PathDescription
vitest.runRun tests once
vitest.coverageRun tests once with coverage, and check a minimum line coverage
vitest.watchStart watch mode
vitest.stopStop a watch process (all of them without an id)
vitest.listList the watch processes of this host

vitest.watch, vitest.stop and vitest.list are not MCP tools. A watch process is a record of the process registry of client-shell, and it ends with the host.


vitest.run#

Run Vitest tests with configurable options.

interface VitestRunInput {
  cwd?: string;          // Working directory
  include?: string[];    // Include patterns
  exclude?: string[];    // Exclude patterns
  watch?: boolean;       // Watch mode
  coverage?: boolean;    // Enable coverage
  reporter?: "default" | "verbose" | "json" | "junit";
  passWithNoTests?: boolean;  // Pass if no tests found
}

interface VitestRunOutput {
  success: boolean;
  passed: number;
  failed: number;
  skipped: number;
  duration: number;      // ms
  coverage?: {
    lines: number;
    branches: number;
    functions: number;
    statements: number;
  };
}

Options:

OptionTypeDefaultDescription
cwdstring"."Working directory
includestring[]-Glob patterns to include
excludestring[]-Glob patterns to exclude
coveragebooleanfalseEnable coverage reporting
reporterstring"default"Output format
passWithNoTestsbooleanfalseDon't fail if no tests

Example:

// Run specific tests
const result = await client.exec(["vitest", "run"], {
  include: ["src/**/*.test.ts"],
  exclude: ["**/*.e2e.test.ts"],
  reporter: "verbose",
});

// Run with coverage threshold check
const coverage = await client.exec(["vitest", "run"], {
  coverage: true,
});

if (coverage.coverage && coverage.coverage.lines < 80) {
  console.warn("Coverage below 80%!");
  process.exit(1);
}

vitest.watch#

Start Vitest in watch mode for continuous testing.

interface VitestWatchInput {
  cwd?: string;          // Working directory
  include?: string[];    // Include patterns
}

interface VitestWatchOutput {
  id: string;            // The id for vitest.stop
  pid: number;           // Process ID
  status: "started" | "stopped";
}

Example:

// Start watch mode
const { id } = await client.exec(["vitest", "watch"], {
  include: ["src/**/*.test.ts"],
});

// The end of the output of each watch process
const { processes } = await client.exec(["vitest", "list"], { output: true });

// Stop the watch process and the processes that it started
await client.exec(["vitest", "stop"], { id });

Coverage Reporting#

Enabling Coverage#

const result = await client.exec(["vitest", "run"], {
  coverage: true,
});

Coverage Output Format#

{
  success: true,
  passed: 42,
  failed: 0,
  skipped: 2,
  duration: 5432,
  coverage: {
    lines: 87.5,      // Percentage of lines covered
    branches: 72.3,   // Percentage of branches covered
    functions: 91.2,  // Percentage of functions covered
    statements: 86.8  // Percentage of statements covered
  }
}

Coverage Visualization#

Diagram source (Mermaid). GitHub draws it on the page of the file.
graph LR
    subgraph "Coverage Metrics"
        Lines[Lines: 87.5%]
        Branches[Branches: 72.3%]
        Functions[Functions: 91.2%]
        Statements[Statements: 86.8%]
    end

    subgraph "Thresholds"
        Good[">= 80%: Good"]
        Warning["60-80%: Warning"]
        Bad["< 60%: Needs work"]
    end

    Lines --> Good
    Functions --> Good
    Statements --> Good
    Branches --> Warning

CLI Usage#

# Run tests via mark CLI
mark vitest run

# Run with coverage
mark vitest run --coverage

# Run specific patterns
mark vitest run --include "src/**/*.unit.test.ts"

# Multiple patterns
mark vitest run --include "src/**/*.test.ts" --exclude "**/*.e2e.test.ts"

# Start watch mode
mark vitest watch

# Verbose output
mark vitest run --reporter verbose

Integration#

With MCP (Claude)#

When using the MCP server, Claude can:

  • Run tests: "Run the tests for this project"
  • Check coverage: "Run tests with coverage and tell me the results"
  • Watch mode: "Start test watch mode"

With DAG Traverse#

// Run tests across all packages in dependency order
await client.exec(["dag", "traverse"], {
  visit: ["vitest", "run"],
  concurrency: 2,
});

With CI/CD#

// CI script example
const result = await client.exec(["vitest", "run"], {
  coverage: true,
  reporter: "junit",
});

if (!result.success) {
  process.exit(1);
}

if (result.coverage && result.coverage.lines < 80) {
  console.error("Coverage threshold not met");
  process.exit(1);
}

With Other Test Packages#

Diagram source (Mermaid). GitHub draws it on the page of the file.
graph TB
    subgraph "Generic Testing"
        Test[client-test<br/>test.run, test.coverage]
    end

    subgraph "Framework-Specific"
        Vitest[client-vitest<br/>vitest.run, vitest.watch]
        Jest[client-jest<br/>future]
        Mocha[client-mocha<br/>future]
    end

    subgraph "Execution"
        Shell[client-shell]
    end

    Test --> Shell
    Vitest --> Shell
    Jest --> Shell
    Mocha --> Shell

Requirements#

  • Node.js >= 22
  • Vitest >= 3.0 (peer dependency)
  • Dependencies:
    • @procedures/client
    • @procedures/shell

License#

MIT