# Configuration Reference
Complete reference for all linthis configuration options.
## Configuration Hierarchy
Configuration is loaded from multiple sources with the following precedence (highest to lowest):
1. **CLI arguments** - Command-line flags override all config files
2. **Project config** - `.linthis/config.toml` in project root
3. **User config** - `~/.linthis/config.toml` for global settings
4. **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.
```toml
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.
```toml
includes = ["src/**", "lib/**"]
```
**Type:** Array of strings (glob patterns)
**Default:** `[]` (all files)
---
### `excludes`
File patterns to exclude (glob patterns). Added to built-in excludes.
```toml
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.
```toml
max_complexity = 20
```
**Type:** Integer
**Default:** `20`
---
### `preset`
Code style preset to use.
```toml
preset = "google"
```
**Type:** String
**Default:** `null` (none)
**Valid values:** `google`, `standard`, `airbnb`
---
### `verbose`
Enable verbose output with additional details.
```toml
verbose = true
```
**Type:** Boolean
**Default:** `false`
---
## Checks Configuration
Control which checks run and their settings. By default, `lint`, `security`, and `complexity` all run.
```toml
[checks]
# Which checks to run (default: ["lint", "security", "complexity"])
run = ["lint", "security", "complexity"]
```
### `[checks.security]`
| `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 |
```toml
[checks.security]
scan_type = "sast"
fail_on = "high"
```
### `[checks.complexity]`
| `threshold` | integer | `10` | Cyclomatic complexity threshold per function |
| `fail_on_high` | boolean | `false` | Exit with error if any function exceeds threshold |
```toml
[checks.complexity]
threshold = 15
fail_on_high = true
```
### Secrets Scanner Configuration
Custom secrets patterns via `.linthis/secrets.toml`:
```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.
```toml
[plugins]
sources = [
{ name = "official" },
{ name = "custom-rules", url = "https://github.com/user/lts-plugin.git", ref = "main" }
]
```
### Plugin Source Fields
| `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.
```toml
[rules]
disable = ["E501", "whitespace/*"]
[rules.severity]
"W0612" = "error"
"E0001" = "info"
```
### `rules.disable`
Disable specific rule codes. Supports exact codes and prefix patterns.
```toml
[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.
```toml
[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.
```toml
[[rules.custom]]
code = "custom/no-fixme"
severity = "warning"
suggestion = "Address the issue or convert to TODO"
languages = ["rust", "python"]
extensions = ["rs", "py"]
enabled = true
```
### Custom Rule Fields
| `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.
```toml
[performance]
large_file_threshold = 1048576 # 1MB
skip_large_files = false
cache_max_age_days = 7
```
| `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.
```toml
[hook]
timeout = 60
parallel = true
output_width = 0 # 0 = auto-detect terminal width
```
| `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 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:
```toml
# 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" }
```
| `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.
```toml
[hook.marketplaces]
default = "https://github.com/linthis-group/marketplace.git"
corp = "https://github.com/mycompany/linthis-marketplace.git"
```
| `<name>` | String | Git URL of the marketplace repository |
---
### `[hook.git]`
Override the hook script for git hooks (Tier 2). Key is the event name.
```toml
[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" } }
```
| `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.
```toml
[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>`.
```toml
[hook.agent.stop]
"claude.settings" = { source = { plugin = "my-plugin", file = "hooks/agent/hook/stop/claude/settings.json" } }
```
| `<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.
```toml
[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.)
| `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`.
```toml
[cmsg]
ticket_pattern = "\\[\\w+-\\d+\\]"
```
| `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.
```toml
[rust]
enabled = true
max_complexity = 15
excludes = ["target/**"]
[rust.rules]
disable = ["clippy::needless_return"]
```
| `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.
```toml
[python]
enabled = true
max_complexity = 10
excludes = ["*_test.py", "test_*.py"]
```
Same fields as `[rust]`.
---
### `[cpp]`
C++ specific options with cpplint/clang-tidy support.
```toml
[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
```
| `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.
```toml
[oc]
linelength = 150
cpplint_filter = "-build/header_guard"
fn_length = 80 # Max method SLOC (non-blank, non-comment lines). Default: 80
```
| `fn_length` | Integer | `80` | Max Objective-C method SLOC (non-blank, non-comment lines) |
All other fields same as `[cpp]`.
---
### `[typescript]`
TypeScript-specific options.
```toml
[typescript]
enabled = true
excludes = ["*.d.ts"]
```
Same fields as `[rust]`.
---
### `[javascript]`
JavaScript-specific options.
```toml
[javascript]
enabled = true
excludes = ["*.min.js"]
```
Same fields as `[rust]`.
---
### `[go]`
Go-specific options.
```toml
[go]
enabled = true
max_complexity = 15
```
Same fields as `[rust]`.
---
### `[java]`
Java-specific options.
```toml
[java]
enabled = true
excludes = ["*Test.java"]
```
Same fields as `[rust]`.
---
### `[c]`
C-specific options.
```toml
[c]
enabled = true
linelength = 120
```
Same fields as `[cpp]`.
---
### `[swift]`
Swift-specific options.
```toml
[swift]
enabled = true
excludes = ["Pods/**"]
```
Same fields as `[rust]`.
---
### `[kotlin]`
Kotlin-specific options.
```toml
[kotlin]
enabled = true
excludes = ["*Test.kt"]
```
Same fields as `[rust]`.
---
### `[lua]`
Lua-specific options.
```toml
[lua]
enabled = true
```
Same fields as `[rust]`.
---
### `[dart]`
Dart-specific options.
```toml
[dart]
enabled = true
excludes = [".dart_tool/**"]
```
Same fields as `[rust]`.
---
### `[shell]`
Shell/Bash-specific options.
```toml
[shell]
enabled = true
excludes = ["*.bak.sh"]
```
Same fields as `[rust]`.
---
### `[ruby]`
Ruby-specific options.
```toml
[ruby]
enabled = true
excludes = ["vendor/**"]
```
Same fields as `[rust]`.
---
### `[php]`
PHP-specific options.
```toml
[php]
enabled = true
excludes = ["vendor/**"]
```
Same fields as `[rust]`.
---
### `[scala]`
Scala-specific options.
```toml
[scala]
enabled = true
excludes = ["target/**"]
```
Same fields as `[rust]`.
---
### `[csharp]`
C#-specific options.
```toml
[csharp]
enabled = true
excludes = ["bin/**", "obj/**"]
```
Same fields as `[rust]`.
---
## Source Configuration (CodeCC Compatibility)
### `[source]`
Configure source path exclusions (compatible with CodeCC `.code.yml`).
```toml
[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.
```toml
[review]
enabled = true
auto_fix = false
provider = "claude-cli"
retention_days = 30
[review.reviewers]
default = ["alice", "bob"]
```
| `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]`
| `default` | Array | `[]` | Default reviewers (platform usernames) |
### `[review.platforms.<name>]`
Configure custom Git platforms for PR/MR creation.
```toml
[review.platforms.my-gitlab]
pr_create = "glab mr create --title '{title}' --description '{body}'"
pr_list = "glab mr list"
reviewer_flag = "--reviewer"
```
| `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.
```toml
[plugin_auto_sync]
enabled = true
interval_hours = 24
```
See [Auto Sync Documentation](../features/auto-sync.md) for details.
---
### `[self_auto_update]`
Configure automatic self-updates.
```toml
[self_auto_update]
enabled = false
check_interval_hours = 24
```
See [Self Update Documentation](../features/self-update.md) for details.
---
## Complete Example
```toml
# .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"
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"
```