or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cli-commands.mdconfiguration.mdindex.mdprogrammatic-api.mdreporters.md
tile.json

reporters.mddocs/

Reporter System

Extensible reporting system with built-in reporters and support for custom reporter modules, template-based output formatting, and color styling for presenting spell checking results.

Capabilities

Default Reporter

Get the built-in CLI reporter with comprehensive formatting and color support.

/**
 * Get the default CLI reporter with formatting and color support
 * @param options - Reporter configuration options
 * @param config - Optional additional reporter configuration
 * @returns CSpellReporter instance configured for CLI output
 */
function getDefaultReporter(options: ReporterOptions, config?: CSpellReporterConfiguration): CSpellReporter;

interface ReporterOptions {
  fileGlobs: string[];
  color?: boolean;
  debug?: boolean;
  issues?: boolean;
  issuesSummaryReport?: boolean;
  legacy?: boolean;
  progress?: boolean;
  relative?: boolean;
  root?: string;
  showContext?: boolean | number;
  showPerfSummary?: boolean;
  showSuggestions?: boolean;
  silent?: boolean;
  summary?: boolean;
  verbose?: boolean;
  wordsOnly?: boolean;
}

interface CSpellReporter {
  /** Report when spell checking begins */
  onBegin?: (settings: CSpellSettings, emitter: Emitter) => void;
  /** Report when a file begins processing */
  onFileBegin?: (filename: string) => void;
  /** Report when a file completes processing */
  onFileEnd?: (filename: string, result: FileResult) => void;
  /** Report spelling issues found */
  onIssue?: (issue: Issue) => void;
  /** Report errors encountered during processing */
  onError?: (message: string, error: Error) => void;
  /** Report when spell checking completes */
  onResult?: (result: RunResult) => void;
}

interface Issue {
  /** The misspelled text */
  text: string;
  /** Start offset in the file */
  offset: number;
  /** Length of the misspelled text */
  length: number;
  /** Line number (1-based) */
  line: number;
  /** Column number (1-based) */
  col: number;
  /** File path */
  filename: string;
  /** Issue context */
  context: IssueContext;
  /** Suggested corrections */
  suggestions?: string[];
}

interface FileResult {
  /** File path */
  filename: string;
  /** Number of issues found */
  issues: number;
  /** Whether file was processed successfully */
  success: boolean;
  /** Time taken to process file */
  elapsedTime?: number;
}

Usage Examples:

import { lint, getDefaultReporter } from "cspell";

// Use default reporter
const reporter = getDefaultReporter({
  fileGlobs: ["src/**/*.js"],
  verbose: true,
  showSuggestions: true,
  color: true
});
const result = await lint(
  ["src/**/*.js"], 
  { verbose: true },
  reporter  
);

// Custom reporter extending default behavior
class CustomReporter implements CSpellReporter {
  private defaultReporter = getDefaultReporter({
    fileGlobs: ["src/**/*.js"],
    verbose: true
  });
  
  onBegin = (settings: CSpellSettings, emitter: Emitter) => {
    console.log("πŸ” Starting spell check...");
    this.defaultReporter.onBegin?.(settings, emitter);
  };
  
  onIssue = (issue: Issue) => {
    // Custom issue logging
    console.log(`❌ ${issue.filename}:${issue.line}:${issue.col} - "${issue.text}"`);
    
    // Still use default formatting
    this.defaultReporter.onIssue?.(issue);
  };
  
  onResult = (result: RunResult) => {
    console.log(`βœ… Checked ${result.files} files, found ${result.issues} issues`);
    this.defaultReporter.onResult?.(result);
  };
}

Reporter Configuration

Configure reporter behavior with comprehensive options for output formatting and styling.

interface CSpellReporterConfiguration extends ReporterConfiguration, LinterCliOptions {
  /** Console interface for output */
  readonly console?: ReporterConsole;
}

interface ReporterConfiguration {
  /** Built-in reporter names or custom reporter module paths */
  reporter?: string[];
  /** Custom issue output template with placeholder variables */
  issueTemplate?: string;
  /** Show suggestions for misspelled words */
  showSuggestions?: boolean;
  /** Show context around issues */
  showContext?: boolean | number;
  /** Only show words without file/line information */
  wordsOnly?: boolean;
  /** Show unique errors only */
  unique?: boolean;
  /** Verbose output mode */
  verbose?: boolean;
  /** Enable color output */
  color?: boolean;
}

interface ReporterConsole {
  /** Standard output logging */
  log: (text: string) => void;
  /** Error output logging */
  error: (text: string) => void;
  /** Warning output logging */
  warn: (text: string) => void;
  /** Information output logging */
  info: (text: string) => void;
}

Usage Examples:

import { lint } from "cspell";

// Built-in reporter configuration
const result = await lint(
  ["src/**/*.ts"],
  {
    reporter: ["default"],        // Use default reporter explicitly
    showSuggestions: true,       // Show spelling suggestions  
    showContext: 10,             // Show 10 characters of context
    verbose: true,               // Verbose output
    color: true                  // Enable color output
  }
);

// JSON reporter for CI/CD
const result = await lint(
  ["**/*.md"],
  {
    reporter: ["@cspell/cspell-json-reporter"],
    verbose: false,
    color: false
  }
);

// Multiple reporters
const result = await lint(
  ["docs/**/*.md"],
  {
    reporter: [
      "default",                              // Console output
      "@cspell/cspell-json-reporter",        // JSON output  
      "./custom-reporters/slack-reporter.js" // Custom Slack reporter
    ]
  }
);

Custom Reporter Modules

Create custom reporter modules for specialized output formats and integrations.

interface CSpellReporterModule {
  /**
   * Get reporter instance with configuration
   * @param settings - Reporter settings object
   * @param config - Reporter configuration options
   * @returns Configured CSpellReporter instance
   */
  getReporter: <T>(settings: T, config: CSpellReporterConfiguration) => CSpellReporter;
}

// Example custom reporter module structure
interface CustomReporterSettings {
  /** Custom setting for reporter behavior */
  customOption?: string;
  /** Output file path for custom reporter */
  outputFile?: string;
}

Usage Examples:

// custom-reporter.js - Custom reporter module
export function getReporter(settings, config) {
  return {
    issues: [],
    
    onBegin(cspellSettings, emitter) {
      console.log(`Starting spell check with ${config.reporter?.length || 1} reporters`);
    },
    
    onIssue(issue) {
      this.issues.push({
        file: issue.filename,
        line: issue.line,
        column: issue.col,
        word: issue.text,
        suggestions: issue.suggestions || []
      });
    },
    
    onResult(result) {
      // Generate custom report format
      const report = {
        summary: {
          totalFiles: result.files,
          filesWithIssues: result.filesWithIssues.size,  
          totalIssues: result.issues,
          timestamp: new Date().toISOString()
        },
        issues: this.issues
      };
      
      if (settings.outputFile) {
        require('fs').writeFileSync(settings.outputFile, JSON.stringify(report, null, 2));
      } else {
        console.log(JSON.stringify(report, null, 2));
      }
    }
  };
}

// Using the custom reporter
import { lint } from "cspell";

const result = await lint(
  ["src/**/*.js"],
  {
    reporter: ["./custom-reporter.js"],
    customReporterSettings: {
      outputFile: "./spell-check-report.json"
    }
  }
);

Template-Based Output

Use customizable templates for issue output formatting with placeholder variable substitution.

interface TemplateSubstitutions {
  /** Column number */
  $col: string;
  /** Full context around the issue */
  $contextFull: string;
  /** Context text before the issue */
  $contextLeft: string;
  /** Context text after the issue */
  $contextRight: string;
  /** File name */
  $filename: string;
  /** Padding for context alignment */
  $padContext: string;
  /** Padding for row/column alignment */
  $padRowCol: string;
  /** Row (line) number */
  $row: string;
  /** Comma-separated suggestions */
  $suggestions: string;
  /** The misspelled text */
  $text: string;
  /** Quick fix suggestion (first suggestion) */
  $quickFix: string;
  /** Issue message */
  $message: string;
  /** Issue message with color formatting applied */
  $messageColored: string;
  /** Full URI of the file being checked */
  $uri: string;
}

// Predefined templates
type IssueTemplate = 
  | "default"           // Standard format with colors
  | "legacy"            // Legacy bracket format
  | "wordsOnly"         // Just the misspelled words
  | "withContext"       // Include surrounding text context
  | "withSuggestions"   // Include spelling suggestions
  | string;             // Custom template string

Usage Examples:

import { lint } from "cspell";

// Custom issue template
const result = await lint(
  ["src/**/*.ts"],
  {
    issueTemplate: "{green $filename}:{yellow $row:$col} - {red $text} -> {blue $suggestions}"
  }
);

// Context-aware template
const result = await lint(
  ["docs/**/*.md"],
  {
    issueTemplate: `
File: $filename (Line $row)
Issue: "$text" 
Context: ...$contextLeft{$text}$contextRight...
Suggestions: [$suggestions]
---`,
    showContext: 20
  }
);

// Minimal template for CI
const result = await lint(
  ["**/*.js"],
  {
    issueTemplate: "$filename:$row:$col:$text",
    color: false
  }
);

// Rich template with colors and suggestions
const result = await lint(
  ["src/**"],
  {
    issueTemplate: "{bgRed  ERROR } {green $filename}:{yellow $row}:{yellow $col} - {red {underline $text}} {gray (suggestions: {cyan $suggestions})}",
    showSuggestions: true
  }
);

Color and Styling

Control color output and styling in reporter output using Chalk color templates.

// Color template syntax (using Chalk template strings)
type ColorTemplate = 
  | "{green text}"          // Green text
  | "{red {underline text}}" // Red underlined text  
  | "{bgBlue {white text}}"  // White text on blue background
  | "{yellow text}"          // Yellow text
  | "{gray text}"            // Gray text
  | "{cyan text}"            // Cyan text
  | "{magenta text}"         // Magenta text
  | string;                  // Plain text

interface ColorConfiguration {
  /** Enable/disable color output */
  color?: boolean;
  /** Color support detection */
  colorSupport?: 'auto' | 'always' | 'never';
}

Usage Examples:

import { lint } from "cspell";

// Colorful output template  
const result = await lint(
  ["src/**/*.js"],
  {
    issueTemplate: "{bgRed {white  ERROR }} {green $filename}:{yellow $row:$col} - {red {bold $text}}",
    color: true
  }
);

// Disable colors for CI/automated environments
const result = await lint(
  ["**/*.ts"],
  {
    issueTemplate: "ERROR: $filename:$row:$col - $text (suggestions: $suggestions)",
    color: false,
    showSuggestions: true
  }
);

// Conditional color based on environment
const isCI = process.env.CI === 'true';
const result = await lint(
  ["docs/**/*.md"],
  {
    issueTemplate: isCI 
      ? "$filename:$row:$col - $text"  // Plain for CI
      : "{red ●} {green $filename}:{yellow $row:$col} - {red $text}", // Colorful for local
    color: !isCI
  }
);

Built-in Reporters

CSpell includes several built-in reporters for different output formats and use cases.

// Built-in reporter identifiers
type BuiltinReporter = 
  | "default"                           // Standard CLI reporter with colors
  | "@cspell/cspell-json-reporter"     // JSON format output
  | "@cspell/cspell-junit-reporter"    // JUnit XML format
  | "@cspell/cspell-github-actions"    // GitHub Actions annotations
  | string;                            // Path to custom reporter module

Usage Examples:

import { lint } from "cspell";

// Default console reporter
const result = await lint(["src/**/*.js"], {
  reporter: ["default"]
});

// JSON reporter for programmatic consumption
const result = await lint(["**/*.ts"], {
  reporter: ["@cspell/cspell-json-reporter"]
});

// JUnit XML for test result integration
const result = await lint(["tests/**/*.js"], {
  reporter: ["@cspell/cspell-junit-reporter"]
});

// GitHub Actions integration  
const result = await lint(["**/*.md"], {
  reporter: ["@cspell/cspell-github-actions"]
});

// Multiple reporters for comprehensive output
const result = await lint(["src/**"], {
  reporter: [
    "default",                          // Console output for developers
    "@cspell/cspell-json-reporter",    // JSON for automation
    "./reporters/slack-reporter.js"    // Custom Slack notifications
  ]
});

Reporter Error Handling

Handle errors and edge cases in custom reporters with proper error propagation.

interface ReporterErrorHandling {
  /** Handle errors during reporting */
  onError?: (message: string, error: Error) => void;
  /** Handle reporter initialization failures */
  onReporterError?: (reporterName: string, error: Error) => void;
}

// Error scenarios in reporters
type ReporterError = 
  | "REPORTER_NOT_FOUND"      // Reporter module not found
  | "REPORTER_INVALID"        // Reporter doesn't implement interface
  | "OUTPUT_WRITE_FAILED"     // Failed to write output file
  | "TEMPLATE_PARSE_ERROR"    // Invalid template syntax
  | "COLOR_SUPPORT_ERROR";    // Color support detection failed

Usage Examples:

// Robust reporter with error handling
class RobustReporter implements CSpellReporter {
  onError = (message: string, error: Error) => {
    console.error(`Reporter Error: ${message}`);
    console.error(`Details: ${error.message}`);
    
    // Continue processing instead of failing completely
    return;
  };
  
  onIssue = (issue: Issue) => {
    try {
      // Custom issue processing
      this.processIssue(issue);
    } catch (error) {
      this.onError?.("Failed to process issue", error as Error);
    }
  };
  
  private processIssue(issue: Issue) {
    // Safe issue processing with fallbacks
    const safeFilename = issue.filename || '<unknown>';
    const safeText = issue.text || '<empty>';
    
    console.log(`${safeFilename}:${issue.line}:${issue.col} - ${safeText}`);
  }
}

// Using reporter with error handling
try {
  const result = await lint(["src/**/*.js"], {
    reporter: ["./potentially-failing-reporter.js"]
  });
} catch (error) {
  console.error("Spell check failed:", error.message);
  
  // Fallback to default reporter
  const fallbackResult = await lint(["src/**/*.js"], {
    reporter: ["default"]
  });
}

Integration Examples

CI/CD Pipeline Integration

// ci-reporter.js - Optimized for CI environments
export function getReporter(settings, config) {
  return {
    onResult(result) {
      if (result.issues > 0) {
        console.log(`::error::Found ${result.issues} spelling issues in ${result.filesWithIssues.size} files`);
        process.exitCode = 1;
      } else {
        console.log(`::notice::Spell check passed - ${result.files} files checked`);
      }
    }
  };
}

Slack Integration

// slack-reporter.js - Send results to Slack
export function getReporter(settings, config) {
  return {
    issues: [],
    
    onIssue(issue) {
      this.issues.push(issue);
    },
    
    async onResult(result) {
      if (result.issues > 0 && settings.slackWebhook) {
        const message = {
          text: `Spell check found ${result.issues} issues`,
          attachments: [{
            color: 'warning',
            fields: [
              { title: 'Files Checked', value: result.files, short: true },
              { title: 'Issues Found', value: result.issues, short: true }
            ]
          }]
        };
        
        await fetch(settings.slackWebhook, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(message)
        });
      }
    }
  };
}