Configuration Reference¶
Complete reference for all linthis configuration options.
Configuration Hierarchy¶
Configuration is loaded from multiple sources with the following precedence (highest to lowest):
- CLI arguments - Command-line flags override all config files
- Project config -
.linthis/config.tomlin project root - User config -
~/.linthis/config.tomlfor global settings - Built-in defaults - Sensible defaults for all options
Configuration File Formats¶
Supported formats:
- TOML (.toml) - Recommended
- YAML (.yml, .yaml)
- JSON (.json)
Top-Level Options¶
languages¶
Languages to check. If empty, auto-detects based on file extensions.
languages = ["rust", "python", "typescript"]
Type: Array of strings
Default: [] (auto-detect)
Valid values: rust, python, typescript, javascript, go, java, c, cpp, oc (Objective-C), swift, kotlin, lua, dart, shell, ruby, php, scala, csharp
includes¶
File patterns to include (glob patterns). If empty, checks all files.
includes = ["src/**", "lib/**"]
Type: Array of strings (glob patterns)
Default: [] (all files)
excludes¶
File patterns to exclude (glob patterns). Added to built-in excludes.
excludes = ["*.generated.rs", "vendor/**"]
Type: Array of strings (glob patterns)
Default: []
Alias: exclude
Built-in excludes (always applied):
- **/node_modules/**
- **/target/**
- **/.git/**
- **/vendor/**
- **/__pycache__/**
max_complexity¶
Maximum cyclomatic complexity allowed per function.
max_complexity = 20
Type: Integer
Default: 20
preset¶
Code style preset to use.
preset = "google"
Type: String
Default: null (none)
Valid values: google, standard, airbnb
verbose¶
Enable verbose output with additional details.
verbose = true
Type: Boolean
Default: false
Checks Configuration¶
Control which checks run and their settings. By default, lint, security, and complexity all run.
[checks]
# Which checks to run (default: ["lint", "security", "complexity"])
run = ["lint", "security", "complexity"]
[checks.security]¶
| Key | Type | Default | Description |
|---|---|---|---|
scan_type |
string | "all" |
"sca" (dependencies), "sast" (source code), "all" |
fail_on |
string | Minimum severity to fail: "critical", "high", "medium", "low" |
|
sast_config |
string | Path to custom SAST rules file |
[checks.security]
scan_type = "sast"
fail_on = "high"
[checks.complexity]¶
| Key | Type | Default | Description |
|---|---|---|---|
threshold |
integer | 10 |
Cyclomatic complexity threshold per function |
fail_on_high |
boolean | false |
Exit with error if any function exceeds threshold |
[checks.complexity]
threshold = 15
fail_on_high = true
Secrets Scanner Configuration¶
Custom secrets patterns via .linthis/secrets.toml:
# Add custom patterns
[[patterns]]
id = "secrets/internal-token"
description = "Internal service token detected"
regex = '"tok_[A-Za-z0-9]{32,}"'
severity = "high"
cwe = "CWE-798"
# Disable built-in patterns
[disabled]
rules = ["secrets/jwt-token"]
Config resolution priority: --sast-config > secrets.toml in project root > .linthis/secrets.toml > ~/.linthis/secrets.toml > built-in patterns.
Plugin Configuration¶
[plugins]¶
Configure external plugins for additional linters or rules.
[plugins]
sources = [
{ name = "official" },
{ name = "custom-rules", url = "https://github.com/user/lts-plugin.git", ref = "main" }
]
Plugin Source Fields¶
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name |
String | Yes | - | Plugin name (for registry lookup) |
url |
String | No | - | Git repository URL |
ref |
String | No | main |
Git ref (tag, branch, commit) |
enabled |
Boolean | No | true |
Enable/disable this plugin |
Rules Configuration¶
[rules]¶
Configure rule disabling, severity overrides, and custom rules.
[rules]
disable = ["E501", "whitespace/*"]
[rules.severity]
"W0612" = "error"
"E0001" = "info"
rules.disable¶
Disable specific rule codes. Supports exact codes and prefix patterns.
[rules]
disable = [
"E501", # Exact rule code
"whitespace/*", # All rules starting with "whitespace"
"clippy::needless_*" # All clippy needless_* rules
]
Type: Array of strings
Default: []
[rules.severity]¶
Override severity level for specific rules.
[rules.severity]
"W0612" = "error" # Upgrade warning to error
"E0001" = "info" # Downgrade error to info
"todo" = "off" # Disable rule entirely
Type: Map of string to severity
Valid severities: error, warning, info, off
[[rules.custom]]¶
Define custom regex-based lint rules.
[[rules.custom]]
code = "custom/no-fixme"
pattern = "FIXME|XXX"
message = "Found FIXME/XXX comment that needs attention"
severity = "warning"
suggestion = "Address the issue or convert to TODO"
languages = ["rust", "python"]
extensions = ["rs", "py"]
enabled = true
Custom Rule Fields¶
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
code |
String | Yes | - | Unique rule code (e.g., custom/no-print) |
pattern |
String | Yes | - | Regex pattern to match |
message |
String | Yes | - | Error message to display |
severity |
String | No | warning |
Severity level (error, warning, info) |
suggestion |
String | No | - | Fix suggestion text |
extensions |
Array | No | [] |
File extensions filter (empty = all) |
languages |
Array | No | [] |
Language filter (empty = all) |
enabled |
Boolean | No | true |
Enable/disable this rule |
Performance Configuration¶
[performance]¶
Tune performance-related settings.
[performance]
large_file_threshold = 1048576 # 1MB
skip_large_files = false
cache_max_age_days = 7
| Field | Type | Default | Description |
|---|---|---|---|
large_file_threshold |
Integer | 1048576 (1MB) |
File size threshold in bytes |
skip_large_files |
Boolean | false |
Skip (instead of warn) for large files |
cache_max_age_days |
Integer | 7 |
Plugin cache expiry in days |
Git Hooks Configuration¶
[hook]¶
Configure git hook behavior and source overrides.
[hook]
timeout = 60
parallel = true
output_width = 0 # 0 = auto-detect terminal width
| Field | Type | Default | Description |
|---|---|---|---|
timeout |
Integer | 60 |
Hook timeout in seconds |
parallel |
Boolean | true |
Enable parallel execution |
output_width |
Integer | 0 |
Output box width (0 = auto, min 50, max 120) |
Three-Tier Hook Resolution¶
When linthis hook install generates or resolves a hook, it applies a three-tier resolution system (highest → lowest priority):
| Tier | Description |
|---|---|
| Tier 1 | Fixed-path auto-discovery — hooks/<type>/<event> in project root (for git hooks) or hooks/agent/plugins/<id>/ (for agent plugins) |
| Tier 2 | TOML source mapping — [hook.git], [hook.agent.plugins._default], [hook.agent.stop] entries in .linthis/config.toml |
| Tier 3 | Built-in generator — the default generated script or rules content (unchanged fallback) |
Tier 1 takes effect automatically without any configuration — just place a file at the expected path. Tier 2 allows fine-grained source overrides via TOML. Tier 3 is always the fallback.
HookSource — Source Specification¶
All [hook.*] override entries use a source = { ... } field with one of five variants:
# Variant 1 — File: local path relative to project root
source = { file = "hooks/git/pre-commit" }
# Variant 2 — Plugin: path inside an installed plugin cache
source = { plugin = "my-plugin", file = "hooks/git/pre-commit" }
# Variant 3 — Marketplace: file inside a plugin from a named marketplace repo
source = { marketplace = "corp", plugin = "linthis-official", file = "hooks/agent/plugins/lt/lint" }
# Variant 4 — Url: direct HTTP/HTTPS download (files only)
source = { url = "https://example.com/hooks/pre-commit" }
# Variant 5 — Git: clone a git repo and use the given path
source = { git = "https://github.com/org/repo.git", ref = "v1.0", path = "hooks/git/pre-commit" }
| Variant | Required fields | Optional fields | Notes |
|---|---|---|---|
File |
file |
— | Path relative to project root |
Plugin |
plugin, file |
— | Plugin must be added via linthis plugin add |
Marketplace |
marketplace, plugin, file |
— | Marketplace URL defined in [hook.marketplaces] |
Url |
url |
— | Files only, not directories |
Git |
git, path |
ref |
Clones on first use, cached locally |
[hook.marketplaces]¶
Named marketplace repositories used by HookSource::Marketplace. The key "default" is used when no marketplace field is given.
[hook.marketplaces]
default = "https://github.com/linthis-group/marketplace.git"
corp = "https://github.com/mycompany/linthis-marketplace.git"
| Field | Type | Description |
|---|---|---|
<name> |
String | Git URL of the marketplace repository |
[hook.git]¶
Override the hook script for git hooks (Tier 2). Key is the event name.
[hook.git]
pre-commit = { source = { plugin = "my-plugin", file = "hooks/git/pre-commit" } }
pre-push = { source = { file = "hooks/git/pre-push" } }
commit-msg = { source = { url = "https://example.com/hooks/commit-msg" } }
| Key | Description |
|---|---|
pre-commit |
Script to run for the pre-commit event |
pre-push |
Script to run for the pre-push event |
commit-msg |
Script to run for the commit-msg event |
Similar override sections exist for other hook types:
- [hook.git-with-agent] — git hooks with AI fix fallback
- [hook.prek] — prek hook scripts
- [hook.prek-with-agent] — prek hooks with AI fix fallback
[hook.agent.plugins._default]¶
Override agent plugin bundles (Tier 2). Each entry points to a directory containing skill, command, memory, and hook subdirectories. Key is the plugin ID.
[hook.agent.plugins._default]
"lt.lint" = { source = { plugin = "my-plugin", file = "hooks/agent/plugins/lt/lint" } }
"lt.cmsg" = { source = { plugin = "my-plugin", file = "hooks/agent/plugins/lt/cmsg" } }
"lt.review" = { source = { plugin = "my-plugin", file = "hooks/agent/plugins/lt/review" } }
The resolved directory must contain one or more of:
<plugin-dir>/
├── skills/<skill_name>/SKILL.md — skill instruction file (e.g., skills/lt-lint/SKILL.md)
├── commands/ — slash command files (optional)
├── memories/TOPLEVEL.md — memory section injected into CLAUDE.md etc. (optional)
└── hooks/hooks.json — stop hook settings (optional)
[hook.agent.stop]¶
Override the agent Stop Hook settings file (Tier 2). Key format is <provider>.<filename-stem>.
[hook.agent.stop]
"claude.settings" = { source = { plugin = "my-plugin", file = "hooks/agent/hook/stop/claude/settings.json" } }
| Key format | Example | Description |
|---|---|---|
<provider>.<stem> |
claude.settings |
Overrides .claude/settings.json for the Claude provider |
[hook.agent.skill-names]¶
Configure custom skill directory names for each hook event. This allows teams with existing skill directories to map linthis events to their custom names instead of the defaults.
[hook.agent.skill-names]
pre-commit = "my-team-lint" # default: "lt-lint"
commit-msg = "my-team-cmsg" # default: "lt-cmsg"
pre-push = "my-team-review" # default: "lt-review"
The values are used as:
- Directory names under .claude/skills/ and .codebuddy/skills/ (e.g., .claude/skills/my-team-lint/SKILL.md)
- Base file names for flat-file providers (Gemini: my-team-lint.md, Cursor: my-team-lint.mdc, etc.)
| Field | Type | Default | Description |
|---|---|---|---|
pre-commit |
String | "lt-lint" |
Skill name for the pre-commit (lint) event |
commit-msg |
String | "lt-cmsg" |
Skill name for the commit-msg event |
pre-push |
String | "lt-review" |
Skill name for the pre-push (review) event |
Without this config, the defaults are used (backward compatible).
Commit Message Validation ([cmsg])¶
Configure commit message validation rules used by linthis cmsg.
[cmsg]
commit_msg_pattern = "^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\\(.+\\))?: .{1,72}"
require_ticket = false
ticket_pattern = "\\[\\w+-\\d+\\]"
| Field | Type | Default | Description |
|---|---|---|---|
commit_msg_pattern |
String | Conventional Commits | Regex for valid commit messages |
require_ticket |
Boolean | false |
Require ticket reference |
ticket_pattern |
String | - | Regex for ticket format (e.g., [JIRA-123]) |
Language-Specific Configuration¶
[rust]¶
Rust-specific options.
[rust]
enabled = true
max_complexity = 15
excludes = ["target/**"]
[rust.rules]
disable = ["clippy::needless_return"]
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
Boolean | true |
Enable/disable Rust linting |
max_complexity |
Integer | Global | Override max complexity |
excludes |
Array | [] |
Additional exclude patterns |
rules |
RulesConfig | - | Language-specific rule overrides |
[python]¶
Python-specific options.
[python]
enabled = true
max_complexity = 10
excludes = ["*_test.py", "test_*.py"]
Same fields as [rust].
[cpp]¶
C++ specific options with cpplint/clang-tidy support.
[cpp]
enabled = true
max_complexity = 25
linelength = 120
cpplint_filter = "-build/c++11,-whitespace/tab"
clang_tidy_ignored_checks = ["clang-analyzer-osx.cocoa.RetainCount"]
fn_length = 80
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
Boolean | true |
Enable/disable C++ linting |
max_complexity |
Integer | Global | Override max complexity |
excludes |
Array | [] |
Additional exclude patterns |
linelength |
Integer | 80 |
Line length for cpplint |
cpplint_filter |
String | - | Cpplint filter rules |
clang_tidy_ignored_checks |
Array | [] |
Clang-tidy checks to ignore |
fn_length |
Integer | 80 |
Max Objective-C method SLOC (non-blank, non-comment lines) |
rules |
RulesConfig | - | Language-specific rule overrides |
[oc] / [objectivec]¶
Objective-C specific options. Includes all fields from [cpp], plus fn_length for method length checking.
[oc]
linelength = 150
cpplint_filter = "-build/header_guard"
fn_length = 80 # Max method SLOC (non-blank, non-comment lines). Default: 80
| Field | Type | Default | Description |
|---|---|---|---|
fn_length |
Integer | 80 |
Max Objective-C method SLOC (non-blank, non-comment lines) |
All other fields same as [cpp].
[typescript]¶
TypeScript-specific options.
[typescript]
enabled = true
excludes = ["*.d.ts"]
Same fields as [rust].
[javascript]¶
JavaScript-specific options.
[javascript]
enabled = true
excludes = ["*.min.js"]
Same fields as [rust].
[go]¶
Go-specific options.
[go]
enabled = true
max_complexity = 15
Same fields as [rust].
[java]¶
Java-specific options.
[java]
enabled = true
excludes = ["*Test.java"]
Same fields as [rust].
[c]¶
C-specific options.
[c]
enabled = true
linelength = 120
Same fields as [cpp].
[swift]¶
Swift-specific options.
[swift]
enabled = true
excludes = ["Pods/**"]
Same fields as [rust].
[kotlin]¶
Kotlin-specific options.
[kotlin]
enabled = true
excludes = ["*Test.kt"]
Same fields as [rust].
[lua]¶
Lua-specific options.
[lua]
enabled = true
Same fields as [rust].
[dart]¶
Dart-specific options.
[dart]
enabled = true
excludes = [".dart_tool/**"]
Same fields as [rust].
[shell]¶
Shell/Bash-specific options.
[shell]
enabled = true
excludes = ["*.bak.sh"]
Same fields as [rust].
[ruby]¶
Ruby-specific options.
[ruby]
enabled = true
excludes = ["vendor/**"]
Same fields as [rust].
[php]¶
PHP-specific options.
[php]
enabled = true
excludes = ["vendor/**"]
Same fields as [rust].
[scala]¶
Scala-specific options.
[scala]
enabled = true
excludes = ["target/**"]
Same fields as [rust].
[csharp]¶
C#-specific options.
[csharp]
enabled = true
excludes = ["bin/**", "obj/**"]
Same fields as [rust].
Source Configuration (CodeCC Compatibility)¶
[source]¶
Configure source path exclusions (compatible with CodeCC .code.yml).
[source.test_source]
filepath_regex = [".*_test\\.py$", "test_.*\\.py$"]
[source.auto_generate_source]
filepath_regex = ["generated/.*"]
[source.third_party_source]
filepath_regex = ["vendor/.*", "third_party/.*"]
Review Configuration¶
[review]¶
Configure the AI-powered code review feature.
[review]
enabled = true
auto_fix = false
provider = "claude-cli"
retention_days = 30
[review.reviewers]
default = ["alice", "bob"]
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
Boolean | true |
Enable/disable review feature |
auto_fix |
Boolean | false |
Enable auto-fix mode (create fix branch + PR/MR) |
provider |
String | - | AI provider override for review |
retention_days |
Integer | 30 |
Retention days for review artifacts |
[review.reviewers]¶
| Field | Type | Default | Description |
|---|---|---|---|
default |
Array | [] |
Default reviewers (platform usernames) |
[review.platforms.<name>]¶
Configure custom Git platforms for PR/MR creation.
[review.platforms.my-gitlab]
pr_create = "glab mr create --title '{title}' --description '{body}'"
pr_list = "glab mr list"
reviewer_flag = "--reviewer"
| Field | Type | Required | Description |
|---|---|---|---|
pr_create |
String | Yes | Command template for creating PR/MR |
pr_list |
String | No | Command template for listing PRs/MRs |
reviewer_flag |
String | No | Flag name for specifying reviewers (default: --reviewer) |
install_cmd |
String | No | Install command for the CLI tool |
install_hint |
String | No | Human-readable install hint shown when tool is missing |
Auto-Sync Configuration¶
[plugin_auto_sync]¶
Configure automatic plugin synchronization.
[plugin_auto_sync]
enabled = true
interval_hours = 24
See Auto Sync Documentation for details.
[self_auto_update]¶
Configure automatic self-updates.
[self_auto_update]
enabled = false
check_interval_hours = 24
See Self Update Documentation for details.
Complete Example¶
# .linthis/config.toml
# Global settings
languages = ["rust", "python", "typescript"]
excludes = ["*.generated.*", "vendor/**"]
max_complexity = 20
preset = "google"
# Plugin configuration
[plugins]
sources = [
{ name = "official" },
{ name = "company-rules", url = "https://github.com/company/linthis-plugin.git" }
]
# Rules configuration
[rules]
disable = ["E501", "whitespace/*"]
[rules.severity]
"W0612" = "error"
"todo" = "warning"
[[rules.custom]]
code = "custom/no-console"
pattern = "console\\.(log|warn|error)"
message = "console.log found in code"
severity = "warning"
languages = ["typescript", "javascript"]
# Performance tuning
[performance]
large_file_threshold = 2097152 # 2MB
skip_large_files = true
# Git hooks
[hook]
timeout = 120
# Hook source overrides (Tier 2)
[hook.git]
pre-commit = { source = { plugin = "company", file = "hooks/git/pre-commit" } }
[hook.agent.plugins._default]
"lt.lint" = { source = { plugin = "company", file = "hooks/agent/plugins/lt/lint" } }
[hook.agent.stop]
"claude.settings" = { source = { plugin = "company", file = "hooks/agent/hook/stop/claude/settings.json" } }
# Custom skill directory names (optional)
[hook.agent.skill-names]
pre-commit = "custom-lint"
# Language-specific overrides
[rust]
max_complexity = 15
[python]
excludes = ["*_test.py"]
[cpp]
linelength = 120
cpplint_filter = "-build/c++11"