Browse documentation

Reference

TypeScript & JavaScript

Configuration

Configure each rule through its class members. Select rule files through the CLI. AI defaults also accept environment variables.

Rule locations and names

Discovery searches the project’s .coderuler/ first, then ~/.coderuler/. Rules can live directly in either directory or in subfolders. Supported suffixes are .rule.ts, .rule.mts, .rule.js, and .rule.mjs.

The filename without its rule suffix is the exact rule name. For example, policies/internal-url.rule.ts is named internal-url. A selected name must match exactly one discovered rule file across both discovery roots.

Discovery does not follow symlinks. It skips old, node_modules, and CodeRuler’s temporary installation directories. Ordinary hidden rule folders are not excluded merely because their names start with a dot.

Use validate [rule], test [rule], or check --rules <rule> to select a rule name, module path, or directory. A name filters discovered rules; an explicit path or directory replaces discovery. check --rules also accepts an HTTPS or SSH Git URL with optional #revision; this loads the whole repository like a directory. The check target stays in the current project. inspect takes one module path or exact discovered name, not a rule directory.

A shared Git repository is a good way to distribute company-wide rules across projects and maintain them in one place.

Rule members

Member Default Purpose
enabled: boolean true Disable evaluation without bypassing structural validation
files: readonly string[] ['**/*'] Nonempty root-relative glob list
exclude: readonly string[] [] Remove matching paths, even if included by files
tags?: readonly string[] Absent Labels used by check --tags and --exclude-tags
scope?: ScopeSelector<T> Absent Select parts of a file instead of its whole source
settings: RuleSettings {} AI backend, model, threshold, and token prices
group: Grouping 'scope' Decide which scopes a check sees together
comment?: string or callback Absent Nonblank Markdown override for GitHub finding bodies
when(context) Returns true Whole-rule applicability before file selection
select(context) Built-in selection Return selected scope subjects
filter(subject, context) Returns true Per-scope applicability before grouping
check: Evaluator<T> Required Decide pass or violation

Hooks and checks receive the rule instance as this. Additional class fields and methods are allowed. check must be a function-valued property rather than a method.

when and filter return boolean or { applies: boolean, reason?: string }, directly or through a promise. A false result skips the rule or scope. Invalid results and thrown errors fail execution.

files and exclude must be dense arrays of nonempty strings, including on disabled rules. tags, when present, must be a dense array of nonempty strings. An empty tags array is valid. Use class field syntax such as tags = ['go', 'security'];.

File boundaries

Paths and globs are relative to the project root, with / separators. Globs use Node.js path.matchesGlob semantics. exclude always wins.

Target traversal excludes symbolic links and directories named .git, node_modules, .coderuler, or old. Root-level dist and coverage are also excluded. Nested dist and coverage directories and regular files with reserved directory names remain eligible.

An explicit target inside an excluded directory fails. Custom selectors and project readers cannot use parent escapes or symlink traversal to bypass these boundaries. Loaded rule modules are excluded from check targets.

For check and validate, run the command from the intended project root. A check target narrows files without redefining that root. For inspect, the resolved folder argument becomes the inspected root.

Grouping

import type { Grouping } from '@alex-dbs/coderuler';

// Inside a Rule subclass:
group: Grouping = 'project';
Value One check receives
'scope' One selected scope
'file' All surviving scopes from one filepath
'folder' All surviving scopes in the same containing folder
{ by: 'folder', level: 0 } Same as 'folder'
{ by: 'folder', level: -1 } Scopes grouped one containing-folder level higher
'project' All surviving scopes, with group path .

Folder levels must be nonpositive integers. Negative levels climb toward the root and stop at .. Member order is preserved. Empty groups never reach the check.

Choose the smallest group with all evidence needed for the decision. A project-wide uniqueness policy needs a project group. A rule about one value needs only a scope.

Group checks receive subject.kind === 'group' and subject.members. One group produces one decision. Return explicit offending-member locations when you need precise findings.

AI settings and GitHub comments

RuleSettings supports backend: 'jev', model, threshold, inputCostPerMillion, and outputCostPerMillion. See AI checks for defaults and precedence.

comment can be a nonblank Markdown string or a callback. The callback receives the evaluated subject and normalized check result. It returns a string or a promise for a string, and runs once for each violating evaluation. A normal function receives the rule instance as this.

The comment replaces the generated finding body during check --diff --auto-comment or check --pr ... --auto-comment. It does not change decisions or inline locations. Omit it to keep generated text. CodeRuler strips terminal controls and redacts credentials from comments.

The class contracts are defined in rule.ts. The CLI reference lists command-level options.

Search documentation

Type to search the documentation.

Search stays in your browser. Tab to browse · Enter to open