skilllint checks agent skills, agents, commands, plugins, and platform files.
This page is the canonical guide for installation, the CLI, configuration,
GitHub Actions, and pre-commit.
python -m pip install skilllint
skilllint --versionFor an isolated executable, use uv tool install skilllint; for a project
dependency use uv add skilllint. Supported Python versions are 3.11–3.14.
The default route scans the supplied paths using the compatible validators. Platform selection is explicit when a scan must be limited:
uv run skilllint check --no-color --show-summary plugins/my-plugin
uv run skilllint check --platform claude-code plugins/my-plugin
uv run skilllint check --platform cursor .cursor/rules
uv run skilllint check --platform codex AGENTS.md--platform agentskills is not a check namespace. Use the concrete adapter
for a check; agentskills is the shared rule taxonomy used by rules:
uv run skilllint rules --platform agentskillsFixes are applied in place and the files are checked again. Fixing is not coverage proof: a zero exit means no remaining error-severity findings, not that every adapter or file was selected.
uv run skilllint check --fix plugins/my-plugin
uv run skilllint check --tokens-only skills/my-skill/SKILL.mdDo not combine --fix with --platform; fixing always uses the default
compatibility route. A second --fix run should make no further changes.
Exit status is stable for scripts and CI: 0 means no error-severity findings
(warnings and info findings may still be printed), 1 means an
error-severity validation finding,
and 2 means invalid CLI usage. Invalid policy entries are diagnosed on
stderr and the documented defaults are used; they do not turn a normal scan
into exit 2. File counts in the summary describe files selected, not adapter
coverage.
Use --no-color for logs, --verbose for info findings, --show-progress for
per-file status, and --show-summary for the final counts. --filter limits
paths within a directory and --filter-type accepts skills, agents, or
commands. Gitignored paths are skipped by default; add
--include-gitignore when those files are intentionally in scope.
$ uv run skilllint check --no-color --show-progress --show-summary \
--filter-type skills plugins/my-plugin
$ uv run skilllint check --include-gitignore generated/SKILL.mdskilllint rules is the compact catalog; skilllint rule FM007 explains one
rule. The optional .skilllint.json config is discovered from the file's
directory upward. Inside a plugin, .claude-plugin/validator.json takes
priority. Configurations do not merge: the nearest applicable file wins.
{
"ignore": {
"": ["AS008"],
"skills/legacy": ["FM007"]
},
"thresholds": {"SK006": 4400, "SK007": 8800},
"severity": {"SK006": "warning"}
}Ignore keys are path prefixes relative to their config root. An empty prefix
matches every file below it; skills/legacy does not match a sibling such as
skills/legacy-old. Invalid thresholds and severity values are diagnosed
and the documented defaults are used; fix the config rather than relying on a
fallback.
Pin the Action ref and the package version independently. Replace X.Y.Z in the examples with the release you intend to pin. The Action exposes
result (passed or failed) and exit-code (0, 1, or 2).
- uses: bitflight-devops/skilllint@vX.Y.Z
id: skilllint
with:
paths: "plugins/"
version: "X.Y.Z"
platform: "claude-code"
show-summary: "true"
no-color: "true"To observe a failure without blocking a later step, use
continue-on-error: true and inspect both outputs:
- uses: bitflight-devops/skilllint@vX.Y.Z
id: lint
continue-on-error: true
with:
paths: "plugins/"
version: "X.Y.Z"
- run: echo "skilllint result=${{ steps.lint.outputs.result }} exit=${{ steps.lint.outputs.exit-code }}"The retained hooks run on staged files. Pin a release (or commit SHA), and
append supported CLI arguments under args:
repos:
- repo: https://github.com/bitflight-devops/skilllint
rev: v1.7.0
hooks:
- id: skilllint
- id: skilllint-fixskilllint checks without mutating files; skilllint-fix applies supported
fixes and is idempotent. Use the hook's exclude for generated or vendored
trees. The broad by-file-type hook is intentionally omitted from this guide.
From a checkout, run the same gates used by the project:
uv run prek run --all-files
uv run pytestThe examples above are source-coupled by
tests/test_usage_examples.py; keep commands and their
documented context executable when changing this page.