| name | lint |
| description | Run linting and formatting on files or discover project linters. Usage with /lint path or /lint init with optional --force flag |
| color | orange |
Linting Command
This command provides manual control over linting workflows. It can run linters on specific files/directories or discover and document project linters.
Usage Modes
1. Lint Files
Lint one or more files or directories:
/lint path/to/file.py
/lint path/to/directory/
/lint file1.py file2.py file3.py
Behavior:
- Read
## LINTERS section from project's CLAUDE.md to identify configured linters
- Run formatters first (auto-fix trivial issues)
- Run linters second (report substantive issues)
- If errors found, use linting-root-cause-resolver agent to fix systematically
- Re-run linters to verify resolution
2. Discover Project Linters
Scan the project and generate the ## LINTERS section for CLAUDE.md:
/lint init
/lint init --force
Behavior:
- Scan for linting configuration files:
.pre-commit-config.yaml
pyproject.toml (ruff, mypy, pyright, bandit)
package.json (eslint, prettier)
.husky/ directory
- Root
.eslintrc*, .prettierrc*, .markdownlint* files
- Identify configured formatters and linters
- Generate
## LINTERS section in standard format
- Append to
CLAUDE.md (or update if --force provided)
Implementation
When this command is invoked, perform the following steps based on the arguments:
For /lint <path> (Lint Mode)
-
Read project linting configuration:
Grep(pattern="^## LINTERS", path="CLAUDE.md", output_mode="content", -A=50)
-
If LINTERS section not found:
- Inform user: "No ## LINTERS section found in CLAUDE.md. Run
/lint init first to discover project linters."
- Exit
-
Parse LINTERS section to identify:
- Formatters list with file patterns
- Linters list with file patterns
-
Match file paths to tools:
- For each provided path, determine which formatters/linters apply based on file extension
- Example:
*.py files → ruff format, ruff check, mypy, pyright
-
Run formatters first (auto-fix phase):
uv run ruff format <file.py>
npx prettier --write <file.ts>
npx markdownlint-cli2 --fix <file.md>
shfmt -w <script.sh>
-
Run linters second (validation phase):
uv run ruff check <file.py>
uv run mypy <file.py>
uv run pyright <file.py>
npx eslint <file.ts>
shellcheck <script.sh>
-
If linting errors found:
-
Verify resolution:
- Re-run linters on all files
- Confirm all issues resolved
For /lint init (Discovery Mode)
-
Check for existing LINTERS section:
Grep(pattern="^## LINTERS", path="CLAUDE.md", output_mode="content")
-
If section exists and --force not provided:
- Inform user: "## LINTERS section already exists in CLAUDE.md. Use
/lint init --force to overwrite."
- Show existing configuration
- Exit
-
Scan for git pre-commit hooks:
test -d .git && echo "Git repository: yes" || echo "Git repository: no"
test -f .pre-commit-config.yaml && echo "pre-commit config: found" || echo "pre-commit config: not found"
test -d .husky && echo "husky: found" || echo "husky: not found"
-
Scan for Python linting config (pyproject.toml):
Read(file_path="pyproject.toml")
- Look for
[tool.ruff], [tool.mypy], [tool.pyright], [tool.bandit] sections
- Identify which tools are configured
-
Scan for JavaScript/TypeScript config (package.json):
Read(file_path="package.json")
- Look for
eslint, prettier, @typescript-eslint/* in devDependencies
- Check for
.eslintrc*, .prettierrc* config files
-
Scan for Markdown linting:
test -f .markdownlint.json && echo "markdownlint config: found"
-f .markdownlint.yaml &&
File Pattern Matching
When determining which linters apply to files, use these standard patterns:
- Python:
*.py → ruff format, ruff check, mypy, pyright, bandit
- JavaScript/TypeScript:
*.{js,ts,jsx,tsx} → prettier, eslint
- Markdown:
*.{md,markdown} → markdownlint-cli2
- Shell:
*.{sh,bash,zsh,fish} → shfmt, shellcheck
- JSON:
*.json → prettier
- YAML:
*.{yml,yaml} → prettier (if configured)
Error Handling
If CLAUDE.md doesn't exist:
- In lint mode: Warn and suggest running
/lint init
- In init mode: Create CLAUDE.md with LINTERS section
If tools aren't installed:
- Show which tools are missing
- Suggest installation commands (e.g.,
uv add --dev ruff mypy pyright)
If linting errors persist after agent resolution:
- Show remaining errors
- Ask user if they want to continue investigation or accept current state
Examples
Example 1: Lint a single file
User: /lint src/auth.py
Claude:
1. Reading ## LINTERS section from CLAUDE.md...
2. Found formatters: ruff format [*.py]
3. Found linters: ruff check [*.py], mypy [*.py], pyright [*.py]
4. Running formatter: uv run ruff format src/auth.py
✓ Formatted 1 file
5. Running linters:
- uv run ruff check src/auth.py
✗ Found 2 errors (E501, F401)
- uv run mypy src/auth.py
✗ Found 1 error (arg-type)
6. Launching linting-root-cause-resolver agent for src/auth.py...
7. Agent resolved all 3 issues
8. Re-running linters:
- uv run ruff check src/auth.py ✓
- uv run mypy src/auth.py ✓
- uv run pyright src/auth.py ✓
9. All linting errors resolved ✓
Example 2: Lint multiple files
User: /lint src/auth.py src/models.py tests/test_auth.py
Claude:
1. Reading ## LINTERS section from CLAUDE.md...
2. Running formatters on 3 files...
✓ All files formatted
3. Running linters on 3 files...
✗ src/auth.py: 2 errors
✗ src/models.py: 5 errors
✓ tests/test_auth.py: no errors
4. Launching concurrent linting-root-cause-resolver agents:
- Agent 1: Resolving src/auth.py
- Agent 2: Resolving src/models.py
5. Both agents completed successfully
6. Re-running linters: All files clean ✓
Example 3: Discover project linters
User: /lint init
Claude:
1. Checking for existing ## LINTERS section in CLAUDE.md...
Not found - proceeding with discovery
2. Scanning project configuration:
✓ Git repository detected
✓ Found .pre-commit-config.yaml (6 hooks)
✓ Found pyproject.toml with [tool.ruff], [tool.mypy], [tool.pyright]
✓ Found package.json with prettier, eslint
✓ Found .markdownlint.json
3. Generating LINTERS section...
## LINTERS
git pre-commit hooks: enabled
pre-commit tool: pre-commit
### Formatters
- ruff format [*.py]
- prettier [*.{ts,tsx,json,md}]
- markdownlint-cli2 [*.md]
### Static Checking and Linting
- ruff check [*.py]
- mypy [*.py]
- pyright [*.py]
- eslint [*.{ts,tsx}]
- markdownlint-cli2 [*.md]
4. Appended to CLAUDE.md ✓
Example 4: Re-discover linters (force mode)
User: /lint init --force
Claude:
1. Checking for existing ## LINTERS section in CLAUDE.md...
Found existing section
2. --force flag provided, removing existing section
3. Re-scanning project configuration...
[Same discovery process as Example 3]
4. Updated CLAUDE.md with new configuration ✓
Notes
- The
/lint command respects the holistic-linting skill philosophy: format first (auto-fix trivial issues), lint second (report substantive issues), resolve systematically (understand root causes)
- Orchestrators should launch concurrent linting-root-cause-resolver agents when multiple files have errors
- Sub-agents should use this command on their touched files before completing tasks
- The init mode creates a "cache" in CLAUDE.md to avoid repeated configuration discovery overhead