This project has been archived by its maintainers, and is no longer receiving any updates.
skillscan-lint
Quality linter for AI agent skill files. Catches weasel words, ambiguous instructions, missing metadata, and skill graph problems (cycles, dangling references, broken file links) before they reach production.
Works with skills from skills.sh, ClawHub, and any SKILL.md-based skill package.
Install
pip install skillscan-lint
Or run without installing:
docker run --rm -v "$PWD:/work" kurtpayne/skillscan-lint scan /work/skills/
Quick Start
# Lint a single skill file
skillscan-lint scan SKILL.md
# Lint an entire skills directory (including graph checks)
skillscan-lint scan ./skills/ --graph
# Output as JSON for CI integration
skillscan-lint scan ./skills/ --format json
# List all rules
skillscan-lint rules
Example output
SKILL.md
QL-004 WARNING Weasel intensifier "basically" weakens the instruction.
QL-009 ERROR Description too short (8 words). Minimum is 10.
QL-015 WARNING TODO marker found — remove before publishing.
GR-002 ERROR Skill "data-fetcher" references "parser" which does not exist.
GR-006 WARNING Broken file reference: "references/auth.md" does not exist.
2 errors, 3 warnings
Rules
skillscan-lint ships with two rule families:
Quality rules (QL-*)
| Rule | Severity | What it catches |
|---|---|---|
| QL-001 | WARNING | Passive voice in instructions |
| QL-004 | WARNING | Weasel intensifiers (basically, very, essentially) |
| QL-008 | WARNING | Vague verbs (handle, manage, deal with) |
| QL-009 | ERROR | Description too short (< 10 words) |
| QL-010 | WARNING | Description too long (> 150 words) |
| QL-011 | ERROR | Missing description field |
| QL-012 | ERROR | Missing name field |
| QL-013 | WARNING | Name not in snake_case |
| QL-014 | WARNING | Missing version field |
| QL-015 | WARNING | TODO/FIXME marker in body |
| QL-016 | WARNING | Superlatives (best, perfect, ultimate) |
| QL-017 | WARNING | Nominalisations (optimization → optimize) |
| QL-018 | WARNING | Redundant phrases (end result, past history) |
| QL-019 | WARNING | Buzzwords (leverage, synergy, paradigm) |
| QL-020 | WARNING | Hedging language (might, could possibly) |
| QL-021 | ERROR | Sentence too long (> 35 words) |
| QL-022 | WARNING | Instruction body too long (> 500 lines) |
| QL-023 | WARNING | Missing ## Usage or ## Overview section |
| QL-024 | WARNING | Missing ## Examples section |
Run skillscan-lint rules for the full list with descriptions.
Graph rules (GR-*, requires --graph)
Graph rules analyze the invocation graph across a skills directory — which skills call which, what files they reference, and whether the dependency structure is sound.
| Rule | Severity | What it catches |
|---|---|---|
| GR-001 | ERROR | Cycle in skill invocation graph (A → B → A) |
| GR-002 | ERROR | Dangling reference (skill invokes a skill that doesn't exist) |
| GR-003 | WARNING | Orphan entry-point (invokes others but is never invoked — add entry_point: true if intentional) |
| GR-004 | WARNING | Hub skill (unusually high in-degree — single point of failure) |
| GR-005 | WARNING | Undocumented dependency (referenced skill has no ## Usage or ## Overview section) |
| GR-006 | WARNING | Broken intra-skill file reference (Markdown link points to a .md file that doesn't exist) |
Graph edges are resolved from three sources, in order of reliability:
- Front-matter keys —
invoke:,calls:,depends_on:,uses:,requires:with skill names or file paths - Markdown links to
SKILL.mdfiles —[skill name](../other-skill/SKILL.md) - Path resolution — front-matter values containing
/or ending in.mdare resolved relative to the skill file
Reference docs, README files, and other supporting .md files within a skill package are not treated as graph nodes — they are checked by GR-006 for broken links instead.
CI Integration
GitHub Actions
- name: Lint skills
run: |
pip install skillscan-lint
skillscan-lint scan ./skills/ --graph --format json > report.json
Pre-commit hook
# .pre-commit-config.yaml
repos:
- repo: https://github.com/kurtpayne/skillscan-lint
rev: v0.3.0
hooks:
- id: skillscan-lint
args: [--graph]
Docker in CI
- name: Lint skills
run: |
docker run --rm -v "${{ github.workspace }}:/work" \
kurtpayne/skillscan-lint scan /work/skills/ --graph --format json \
> skillscan-lint-report.json
Skill Graph Example
Given a skills directory:
skills/
data-fetcher/SKILL.md (invoke: parser)
parser/SKILL.md (invoke: data-fetcher) ← cycle!
formatter/SKILL.md (invoke: missing-skill) ← dangling ref
Running skillscan-lint scan ./skills/ --graph will report:
GR-001 ERROR Cycle detected: data-fetcher → parser → data-fetcher
GR-002 ERROR Skill "formatter" references "missing-skill" which does not exist.
Related
- skillscan-security — Security scanner for AI skills: prompt injection, IOC matching, malware detection, ML-based classifier
- skills.sh — Community registry of AI agent skills
- ClawHub — MCP skill marketplace
License
Apache-2.0. See LICENSE.
Metadata
Release files for skillscan-lint 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| skillscan_lint-1.0.0.tar.gz | 47.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| skillscan_lint-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 86.2 kB
Release files / skillscan_lint-1.0.0.tar.gz
| Download URL | skillscan_lint-1.0.0.tar.gz |
|---|---|
| Size | 47.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
62135791721c0876aaab03aa13405f8452e7e55931ab98d6a5f3d7b8f3344f65
|
|
BLAKE2b-256 checksum How to use checksums |
ea172c7ef87bd4255f52bf1989cc6fb944a0a152ac70afde43992e02bf1fc288
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 20, 2026.
Transparency logRelease files / skillscan_lint-1.0.0-py3-none-any.whl
| Download URL | skillscan_lint-1.0.0-py3-none-any.whl |
|---|---|
| Size | 38.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ba88abd088e95eced8b18509188fc989953f9d176ab76884cd48d0c43736fc98
|
|
BLAKE2b-256 checksum How to use checksums |
eb0566b99eeafd4f494483a22c88c339e101e03397e81bcd458718949602d5b4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 20, 2026.
Transparency log