From mr-sparkle
Universal polyglot linting and per-project config management. Use when you need to lint files, understand tool selection logic, invoke linting from commands/agents, or manage mr-sparkle config.
How this skill is triggered — by the user, by Claude, or both
Slash command
/mr-sparkle:lintThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill provides universal polyglot linting through a CLI script that detects file types, finds project configuration, and runs appropriate linters.
defaults/default-biome.jsondefaults/default-editorconfigdefaults/default-eslint.config.jsdefaults/default-markdownlint.jsoncdefaults/default-prettier.jsondefaults/default-prettier.json5defaults/default-prettierignoredefaults/default-rubocop.ymldefaults/default-ruff.tomldefaults/default-shellcheckrcdefaults/default-standard.ymlscripts/lint.pyThis skill provides universal polyglot linting through a CLI script that detects file types, finds project configuration, and runs appropriate linters.
| Language | Tool Groups (priority order) | Config Detection |
|---|---|---|
| Python | ruff OR pylint+isort+black | pyproject.toml, ruff.toml, setup.cfg |
| JavaScript/TypeScript | biome OR eslint+prettier | biome.json, eslint.config.*, package.json |
| Markdown | markdownlint-cli2 | .markdownlint-cli2.*, ~/.markdownlint-cli2.jsonc |
| Shell | shfmt+shellcheck | .editorconfig, .shellcheckrc |
| Ruby | standard OR rubocop | .standard.yml, .rubocop.yml, Gemfile |
| YAML | prettier | .prettierrc*, ~/.prettierrc.json5 |
| JSON/JSON5/JSONC | prettier | .prettierrc*, ~/.prettierrc.json5 |
The script uses group-based priority selection:
[ruff] vs [pylint, isort, black])Example for Python:
pyproject.toml has [tool.ruff] → runs ruff check --fix then ruff formatsetup.cfg has [isort] section → runs pylint, isort, blackruff (first group default)The universal linting script is at scripts/lint.py.
# Lint a file (auto-detects type, applies fixes)
${CLAUDE_SKILL_DIR}/scripts/lint.py /path/to/file.py
# JSON output for programmatic use
${CLAUDE_SKILL_DIR}/scripts/lint.py /path/to/file.py --format json
# Text output (default, human-readable)
${CLAUDE_SKILL_DIR}/scripts/lint.py /path/to/file.py --format text
--format text (default):
✓ ruff file.py: OK
or
⚠ ruff file.py: Lint errors!
<detailed output>
--format json:
{
"file": "/path/to/file.py",
"toolset": "python",
"tools_run": ["ruff"],
"status": "ok",
"results": [
{"tool": "ruff", "status": "ok", "output": ""}
]
}
0: Success (file clean or fixed)1: Lint errors found (non-blocking)2: Tool execution errorThe script finds project root by walking up from the file looking for:
package.jsonpyproject.tomlGemfile.git directoryConfig detection happens relative to project root.
| Tool | Config Files | pyproject.toml | INI Files |
|---|---|---|---|
| ruff | ruff.toml, .ruff.toml | [tool.ruff] | - |
| black | - | [tool.black] | - |
| isort | .isort.cfg | [tool.isort] | setup.cfg [isort] |
| pylint | .pylintrc, pylintrc | [tool.pylint] | setup.cfg [pylint] |
| Tool | Config Files | package.json |
|---|---|---|
| biome | biome.json, biome.jsonc | @biomejs/biome in deps |
| eslint | eslint.config.*, .eslintrc.* | eslint in deps |
| prettier | .prettierrc*, prettier.config.* | prettier in deps |
| Tool | Config Files | Global Fallback |
|---|---|---|
| markdownlint-cli2 | .markdownlint-cli2.* | ~/.markdownlint-cli2.jsonc |
If no config found, uses defaults/default-markdownlint.jsonc.
| Tool | Config Files |
|---|---|
| shfmt | .editorconfig |
| shellcheck | .shellcheckrc |
| Tool | Config Files | Gemfile |
|---|---|---|
| standard | .standard.yml | gem "standard" or gem "standardrb" |
| rubocop | .rubocop.yml, .rubocop_todo.yml | gem "rubocop" |
Tool selection:
standardrb --fixrubocop -a (safe auto-correct only)| Tool | Config Files | Global Fallback |
|---|---|---|
| prettier | .prettierrc*, prettier.config.* | ~/.prettierrc.json5 |
If no config found, uses defaults/default-prettier.json5.
Supported extensions:
.yaml, .yml.json, .json5, .jsoncRun the linting script:
`${CLAUDE_SKILL_DIR}/scripts/lint.py <file_path>`
For linting results, run:
`${CLAUDE_SKILL_DIR}/scripts/lint.py <file> --format json`
Parse the JSON output to understand lint status.
The script supports --stdin-hook mode for hook integration:
# Reads hook JSON from stdin, outputs hook-compatible JSON
echo '{"tool_input":{"file_path":"/path/to/file.py"}}' | ${CLAUDE_SKILL_DIR}/scripts/lint.py --stdin-hook
Output visibility (systemMessage vs additionalContext) is controlled by the output section in .claude/mr-sparkle.config.yml.
All mr-sparkle settings live in .claude/mr-sparkle.config.yml in the project root.
# Use autodetection (default behavior when no config file exists)
lint_on_write:
tools:
- default
output:
user: true
claude: false
# Explicit tools per extension — bypasses autodetection entirely
lint_on_write:
tools:
- file_ext: [.py]
commands:
- ruff check --fix
- ruff format
- file_ext: [.js, .ts, .tsx]
commands:
- eslint --fix
output:
user: false
claude: true
# Disable linting entirely
lint_on_write:
tools: []
# Disable direct invocation blocking (markdownlint without --config, etc.)
block_direct: []
Key behaviors:
tools: [default])tools: [default] is all-or-nothing — cannot mix with explicit entriesoutput.user controls the systemMessage (shown to user)output.claude controls additionalContext (fed to Claude)If invoked as config or config show: Read .claude/mr-sparkle.config.yml and display resolved settings.
If config init: Run --detect on representative files to generate .claude/mr-sparkle.config.yml with explicit tool commands based on what autodetection found.
If config set: Update a config value. Examples:
config set output.user falseconfig set output.claude trueconfig set tools defaultconfig set tools noneWhen creating or modifying the config file:
.claude/ directory if it doesn't exist.claude/*.config.yml to .gitignore if not already there${CLAUDE_SKILL_DIR}/scripts/lint.py --detect /path/to/file.py
Shows what autodetection finds: project root, toolset, selected tools, installed binaries, and config status. Useful for debugging why the wrong tools are running.
The script silently exits (code 0, no output) when:
tools: [] (linting disabled)npx claudepluginhub racurry/neat-little-package --plugin mr-sparkleAutomates format-lint-resolve pipelines for code editing tasks. Discovers linters from pyproject.toml/.pre-commit-config.yaml/package.json, fixes ruff/mypy/bandit issues, ensures quality before completion.
Guides markdown linting with markdownlint-cli2: run checks, fix MD0XX errors, configure .markdownlint-cli2.jsonc rules/ignores, set up VS Code extension and GitHub Actions. Supports GFM/CommonMark for validation and workflows.
Configures modern linting: Biome for JavaScript/TypeScript, Ruff for Python, Clippy for Rust. Detects projects, migrates from ESLint/Flake8, checks versions, adds pre-commit integration.