or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

built-in-rules.mdcli-interface.mdcommit-reading.mdconfiguration-presets.mdconfiguration-system.mdindex.mdlinting-engine.mdoutput-formatting.md
tile.json

linting-engine.mddocs/

Linting Engine

Core message validation against configurable rules with detailed error reporting and rule outcome tracking.

Capabilities

Lint Function

Main function for validating commit messages against a set of rules.

/**
 * Lint a commit message against provided rules
 * @param message - Commit message string to validate
 * @param rawRulesConfig - Rule configuration object (optional)
 * @param rawOpts - Linting options (optional)
 * @returns Promise resolving to detailed validation results
 */
function lint(
  message: string,
  rawRulesConfig?: QualifiedRules,
  rawOpts?: LintOptions
): Promise<LintOutcome>;

Linting Options

Configuration options for customizing the linting process.

interface LintOptions {
  /** Whether to use default ignore patterns (default: true) */
  defaultIgnores?: boolean;
  /** Custom ignore functions to skip certain commits */
  ignores?: ((commit: string) => boolean)[];
  /** Parser options for conventional-commits-parser */
  parserOpts?: Options;
  /** Plugin objects providing additional rules */
  plugins?: PluginRecords;
  /** Help URL to include in error messages */
  helpUrl?: string;
}

Lint Outcome

Comprehensive result object containing validation status and detailed rule outcomes.

interface LintOutcome {
  /** Original input commit message */
  input: string;
  /** Overall validation result (true if no errors) */
  valid: boolean;
  /** Array of error-level rule violations */
  errors: LintRuleOutcome[];
  /** Array of warning-level rule violations */
  warnings: LintRuleOutcome[];
}

Rule Outcome Details

Individual rule validation result with detailed information.

interface LintRuleOutcome {
  /** Whether this specific rule passed validation */
  valid: boolean;
  /** Severity level of the rule (0=disabled, 1=warning, 2=error) */
  level: RuleConfigSeverity;
  /** Name of the rule that was executed */
  name: string;
  /** Human-readable message describing the violation or success */
  message: string;
}

Rule Configuration Types

Types for configuring individual rules with severity, condition, and values.

type QualifiedRules = {
  [ruleName: string]: QualifiedRuleConfig;
};

type QualifiedRuleConfig = 
  | QualifiedRuleConfigTuple<void>
  | QualifiedRuleConfigTuple<any>;

type QualifiedRuleConfigTuple<T> = T extends void
  ? Readonly<[RuleConfigSeverity.Disabled]> | 
    Readonly<[RuleConfigSeverity, RuleConfigCondition]>
  : Readonly<[RuleConfigSeverity.Disabled]> | 
    Readonly<[RuleConfigSeverity, RuleConfigCondition, T]>;

enum RuleConfigSeverity {
  Disabled = 0,
  Warning = 1,
  Error = 2
}

type RuleConfigCondition = "always" | "never";

Parsed Commit Structure

Structure representing a parsed commit message used by rules for validation.

interface Commit {
  /** Original raw commit message */
  raw: string;
  /** Commit header (first line) */
  header: string;
  /** Commit type (e.g., 'feat', 'fix') */
  type: string | null;
  /** Commit scope (e.g., 'api', 'ui') */
  scope: string | null;
  /** Commit subject (description) */
  subject: string | null;
  /** Commit body (detailed description) */
  body: string | null;
  /** Commit footer (metadata, references) */
  footer: string | null;
  /** Breaking change notes and other notable information */
  notes: CommitNote[];
  /** Issue and PR references */
  references: CommitReference[];
  /** User mentions (@username) */
  mentions: string[];
  /** Revert commit information */
  revert: CommitRevert | null;
  /** Merge commit information */
  merge: string | null;
}

interface CommitNote {
  title: string;
  text: string;
}

interface CommitReference {
  action: string;
  owner: string | null;
  repository: string | null;
  issue: string;
  raw: string;
  prefix: string;
}

interface CommitRevert {
  header: string;
  hash: string | null;
}

Rule Function Interface

Interface for implementing custom rules that validate parsed commits.

type Rule<Value = never> = (
  parsed: Commit,
  when?: RuleConfigCondition,
  value?: Value
) => RuleOutcome | Promise<RuleOutcome>;

type AsyncRule<Value = never> = BaseRule<Value, "async">;
type SyncRule<Value = never> = BaseRule<Value, "sync">;

type RuleOutcome = Readonly<[boolean, string?]>;

Usage Examples

Basic Linting

import lint from "@commitlint/lint";

// Simple message validation
const result = await lint("feat: add user authentication");

console.log(result.valid); // true
console.log(result.errors); // []
console.log(result.warnings); // []

Linting with Rules

import lint from "@commitlint/lint";

const rules = {
  "type-enum": [2, "always", ["feat", "fix", "docs", "style"]],
  "subject-case": [2, "always", "lower-case"],
  "header-max-length": [2, "always", 72]
};

const result = await lint("FEAT: Add New Feature", rules);

console.log(result.valid); // false
console.log(result.errors); // Array of validation errors

Linting with Options

import lint from "@commitlint/lint";

const rules = {
  "type-enum": [2, "always", ["feat", "fix", "docs"]],
  "subject-empty": [2, "never"]
};

const options = {
  defaultIgnores: true,
  ignores: [
    (commit) => commit.includes("WIP"),
    (commit) => commit.startsWith("fixup!")
  ],
  parserOpts: {
    commentChar: "#",
    headerPattern: /^(\w*)(?:\((.*)\))?: (.*)$/,
    headerCorrespondence: ["type", "scope", "subject"]
  },
  helpUrl: "https://example.com/commit-help"
};

const result = await lint("feat(api): add user endpoint", rules, options);

Processing Results

import lint from "@commitlint/lint";

const result = await lint("invalid commit message", rules);

if (!result.valid) {
  console.log(`Validation failed for: ${result.input}`);
  
  // Process errors
  result.errors.forEach(error => {
    console.log(`❌ ${error.name}: ${error.message}`);
  });
  
  // Process warnings
  result.warnings.forEach(warning => {
    console.log(`⚠️  ${warning.name}: ${warning.message}`);
  });
}

Custom Rule Implementation

// Custom rule function
const customRule = (parsed, when = "always", value) => {
  const { subject } = parsed;
  const negated = when === "never";
  const hasValue = subject && subject.includes(value);
  
  return [
    negated ? !hasValue : hasValue,
    `Subject ${negated ? "must not" : "must"} contain "${value}"`
  ];
};

// Use custom rule
const rules = {
  "subject-contains-ticket": [2, "always", "JIRA-"]
};

const plugins = {
  "local": {
    rules: {
      "subject-contains-ticket": customRule
    }
  }
};

const result = await lint(
  "feat: add feature without ticket",
  rules,
  { plugins }
);

Integration with Configuration

import { load } from "@commitlint/load";
import lint from "@commitlint/lint";

// Load configuration and lint message
const config = await load();
const result = await lint("feat: new feature", config.rules, {
  parserOpts: config.parserPreset?.parserOpts,
  plugins: config.plugins,
  ignores: config.ignores,
  defaultIgnores: config.defaultIgnores,
  helpUrl: config.helpUrl
});

Batch Processing

import lint from "@commitlint/lint";

const messages = [
  "feat: add authentication",
  "fix: resolve login bug", 
  "invalid message format"
];

const rules = {
  "type-enum": [2, "always", ["feat", "fix", "docs"]],
  "subject-empty": [2, "never"]
};

// Process multiple messages
const results = await Promise.all(
  messages.map(message => lint(message, rules))
);

// Summary
const totalErrors = results.reduce((sum, result) => sum + result.errors.length, 0);
const totalWarnings = results.reduce((sum, result) => sum + result.warnings.length, 0);
const validCount = results.filter(result => result.valid).length;

console.log(`Processed ${messages.length} commits`);
console.log(`Valid: ${validCount}, Errors: ${totalErrors}, Warnings: ${totalWarnings}`);