Skip to main content

Static analysis linter for Claude Code plugins, skills, and agents

Project description

skilllint

PyPI version Python versions License CI

Static analysis linter for AI agent plugins, skills, and agents — for Claude Code, Cursor, Codex, and any agentskills.io-compatible platform.


What it does

skilllint validates the structure and content of AI agent files: plugins, skills, agents, and commands. It catches broken references, missing frontmatter, oversized skills, invalid hook configurations, and more — before they cause silent failures at runtime.

$ skilllint check plugins/my-plugin

plugins/my-plugin/skills/my-skill/SKILL.md
  SK006  Token count 14823 exceeds recommended limit of 8192

plugins/my-plugin/agents/my-agent.md
  NR001  Namespace reference 'other-plugin:some-skill' — plugin directory not found

2 errors in 2 files

Screenshots

Validation output with errors and warnings

skilllint check showing validation errors

All available rules

skilllint rules table

Rule detail

skilllint rule FM004 detail


Installation

pip install skilllint

Or with uv:

uv add skilllint          # add to a project
uv tool install skilllint # install as a global tool

Requires Python 3.11–3.14.


Quick start

# Validate a plugin directory
skilllint check plugins/my-plugin

# Validate a single skill file
skilllint check plugins/my-plugin/skills/my-skill/SKILL.md

# Validate everything and show a summary
skilllint check --show-summary plugins/

# Auto-fix issues where possible
skilllint check --fix plugins/my-plugin

# Count tokens in any markdown file
skilllint check --tokens-only .claude/CLAUDE.md

Exit codes: 0 = all checks passed · 1 = validation errors · 2 = usage error


GitHub Action

Use bitflight-devops/skilllint as a GitHub Action to validate skills, plugins, and agents in any repository:

- uses: bitflight-devops/skilllint@v1.7.0
  with:
    paths: "plugins/"          # paths to validate (default: ".")
    platform: "claude-code"   # restrict to one platform (optional)
    show-summary: "true"      # show summary panel (default: true)

Full input reference

Input Description Default
paths Space-separated paths to validate .
platform Platform adapter: claude-code, cursor, codex (all)
fix Auto-fix issues where possible false
check-only Validate only, do not auto-fix false
verbose Show detailed output including info messages false
no-color Disable color output true
tokens-only Output only the integer token count false
show-progress Show per-file PASSED/FAILED status false
show-summary Show summary panel at the end true
filter Glob pattern to restrict files within a directory (none)
filter-type File type filter: skills, agents, commands (all)
version skilllint version to install (latest or 1.2.3) latest
python-version Python version to use 3.12

Outputs

Output Description
result passed when exit code is 0; failed for any non-zero exit code
exit-code Raw exit code: 0 = pass · 1 = errors · 2 = usage error

Example: fail the CI on validation errors

name: Validate skills

on: [push, pull_request]

jobs:
  skilllint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Lint skills and plugins
        uses: bitflight-devops/skilllint@v1.7.0
        with:
          paths: "plugins/ .claude/"
          platform: "claude-code"
          show-summary: "true"
          verbose: "false"

Example: report results without blocking

- name: Lint skills and plugins
  id: lint
  uses: bitflight-devops/skilllint@v1.7.0
  with:
    paths: "plugins/"
  continue-on-error: true

- name: Print result
  run: echo "skilllint result=${{ steps.lint.outputs.result }}"

Pre-commit hook

Add to .pre-commit-config.yaml:

repos:
  - repo: https://github.com/bitflight-devops/skilllint
    rev: v1.7.0
    hooks:
      - id: skilllint

Platform support

skilllint ships with adapters for three platforms and supports third-party adapters via Python entry points:

Platform Adapter ID Bundled
Claude Code claude-code
Cursor cursor
OpenAI Codex codex
OpenCode, Gemini, and others via entry points

Restrict validation to one platform:

skilllint check --platform claude-code plugins/my-plugin

What gets validated

Code Category Description
FM001–FM010 Frontmatter Required fields, valid values, schema compliance
SK001–SK009 Skill Description quality, token limits, complexity, internal links
AS001–AS009 AgentSkills Cross-platform open standard compliance
LK001–LK002 Links Markdown link validity and broken reference detection
PD001–PD003 Progressive disclosure Directory structure for references/, examples/, scripts/
PL001–PL006 Plugin Structure, manifest correctness, marketplace layout, subprocess safety
HK001–HK005 Hook Script existence, configuration validity
NR001–NR002 Namespace refs Cross-plugin skill/agent/command references
SL001 Symlinks Symlink hygiene within plugin directory
TC001 Token count Token count reporting and threshold enforcement
PR001–PR005 Plugin registration Capability registration completeness and correctness in plugin.json
PA001 Plugin agent Plugin-packaged agents: hooks / mcpServers / permissionMode unsupported per Anthropic (ignored at load; cite sub-agents doc)
CU001–CU002 Cursor Cursor .mdc frontmatter required fields and enum values
CX001–CX002 Codex Codex AGENTS.md content non-empty and header presence

CLI reference

Usage: skilllint [OPTIONS] COMMAND [ARGS]...

Commands:
  check   Validate Claude Code plugins, skills, agents, and commands.
  docs    Fetch, query, and verify cached vendor documentation.
  rule    Show documentation for a validation rule.
  rules   List all available validation rules.

Options:
  --help  Show this message and exit.

check

Usage: skilllint check [OPTIONS] [PATHS]...

Arguments:
  paths              Paths to validate

Options:
  --check            Validate only, don't auto-fix
  --fix              Auto-fix issues where possible
  --verbose, -v      Show detailed output
  --no-color         Disable color
  --tokens-only      Output token count only
  --show-progress    Show per-file status
  --show-summary     Show summary panel
  --filter TEXT      Glob pattern to match files within a directory
  --filter-type TEXT Filter type (skills | agents | commands)
  --platform TEXT    Platform adapter
  --record PATH      Record terminal output to SVG or HTML file
  --help             Show this message and exit

rules

Usage: skilllint rules [OPTIONS]

Options:
  --platform, -p TEXT  Filter rules by platform
  --category, -c TEXT  Filter rules by category
  --severity, -s TEXT  Filter rules by severity (error, warning, info)
  --record PATH        Record terminal output to SVG or HTML file
  --help               Show this message and exit

rule

Usage: skilllint rule [OPTIONS] RULE_ID

Arguments:
  rule_id  Rule identifier (e.g., "SK001", "FM002", "AS001")  [required]

Options:
  --record PATH  Record terminal output to SVG or HTML file
  --help         Show this message and exit

docs

Cache and query vendor documentation pages for offline use.

Usage: skilllint docs [OPTIONS] COMMAND [ARGS]...

Commands:
  fetch     Fetch a documentation page or return a cached copy.
  latest    Find the most recent cached file for a page name.
  sections  Print a table of sections in a cached markdown file.
  section   Extract the text of a named section from a cached markdown file.
  verify    Verify a cached file against its .meta.json integrity sidecar.

docs fetch

Usage: skilllint docs fetch [OPTIONS] URL

Arguments:
  url                   Documentation URL to fetch or serve from cache.

Cache Options:
  --ttl FLOAT           Cache time-to-live in hours before a refresh is attempted.  [default: 4.0]
  --force               Skip the freshness check and always attempt a network fetch.

Options:
  --help                Show this message and exit.

Prints the cached file path to stdout. Status messages go to stderr. Exits 1 when no cache exists and the network is unavailable.

docs latest

Usage: skilllint docs latest [OPTIONS] PAGE_NAME

Arguments:
  page_name             Filesystem-safe page name (e.g. 'claude-code--settings').

Options:
  --help                Show this message and exit.

Prints the file path to stdout. Exits 1 when no cached file exists for that page name.

docs sections

Usage: skilllint docs sections [OPTIONS] FILE_PATH

Arguments:
  file_path             Path to the cached markdown file to index.

Options:
  --help                Show this message and exit.

Prints a table of headings with their line ranges to stdout.

docs section

Usage: skilllint docs section [OPTIONS] FILE_PATH HEADING

Arguments:
  file_path             Path to the cached markdown file.
  heading               Heading text or markdown anchor slug to locate.

Options:
  --help                Show this message and exit.

Prints the full text of the matching section to stdout. Exits 1 when the heading is not found.

Heading matching is case-insensitive and accepts two forms:

  • Heading text: "Hook input and output"
  • Markdown anchor slug: "hook-input-and-output"

Leading # characters are stripped before comparison.

docs verify

Usage: skilllint docs verify [OPTIONS] FILE_PATH

Arguments:
  file_path             Path to the cached markdown file to verify.

Options:
  --help                Show this message and exit.

Exits 0 when the file is intact. Exits 1 when the file has been modified or when no sidecar exists.

All four command names are aliases for the same tool:

skilllint   # primary
agentlint   # alias
pluginlint  # alias
skillint    # alias

Vendor documentation cache

skilllint docs provides an offline-first cache for vendor documentation pages. Pages are fetched once and stored locally; subsequent calls within the TTL window are served from disk without a network request. When the TTL has expired but the network is unavailable, the stale copy is served automatically.

Cached files are written to .claude/vendor/sources/ with filenames in the format {page-name}-{YYYY-MM-DD-HHMM}.md. Each file is accompanied by a .meta.json integrity sidecar that records the SHA-256 digest, byte count, source URL, and fetch timestamp.

# Cache a documentation page (default TTL: 4 hours)
skilllint docs fetch https://docs.anthropic.com/en/docs/claude-code/settings.md

# Force a network refresh regardless of TTL
skilllint docs fetch https://docs.anthropic.com/en/docs/claude-code/settings.md --force

# Find the most recently cached copy of a page
skilllint docs latest claude-code--settings

# List all sections with line ranges
skilllint docs sections .claude/vendor/sources/claude-code--settings-2025-01-01-1200.md

# Extract a section by heading text or markdown anchor slug
skilllint docs section .claude/vendor/sources/claude-code--settings-2025-01-01-1200.md "Hook input and output"
skilllint docs section .claude/vendor/sources/claude-code--settings-2025-01-01-1200.md "hook-input-and-output"

# Verify a cached file against its sidecar
skilllint docs verify .claude/vendor/sources/claude-code--settings-2025-01-01-1200.md

Section extraction uses marko for AST-based markdown parsing, so # characters inside fenced code blocks are never mistaken for headings.

If skilllint is not installed, use uvx to run it without a permanent install:

uvx skilllint docs fetch https://docs.anthropic.com/en/docs/claude-code/settings.md

scripts/fetch_doc_source.py is a PEP 723 standalone script that exposes the same commands via uv run --script. It is intended for contributors working directly on the skilllint source tree (where [tool.uv.sources] points the dependency at the local package), not for end users.


Third-party adapters

Register a custom platform adapter via Python entry points in your pyproject.toml:

[project.entry-points."skilllint.adapters"]
my-platform = "my_package.adapter:MyPlatformAdapter"

Your adapter must implement the AdapterProtocol interface from skilllint.adapters.protocol.


Links


License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

skilllint-1.7.1.tar.gz (313.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

skilllint-1.7.1-py3-none-any.whl (178.5 kB view details)

Uploaded Python 3

File details

Details for the file skilllint-1.7.1.tar.gz.

File metadata

  • Download URL: skilllint-1.7.1.tar.gz
  • Upload date:
  • Size: 313.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for skilllint-1.7.1.tar.gz
Algorithm Hash digest
SHA256 9f0404b8d6b8ad71a5b2206f09077bac27e278bde43423967cb5c710acc7520f
MD5 eee2a83d2c97c49c8b891c4e663c36e1
BLAKE2b-256 d859ca23942d852b8159d53008e946f15a05eb76d5dc824a07b4b5b403a85621

See more details on using hashes here.

File details

Details for the file skilllint-1.7.1-py3-none-any.whl.

File metadata

  • Download URL: skilllint-1.7.1-py3-none-any.whl
  • Upload date:
  • Size: 178.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for skilllint-1.7.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4ae44e428b38033683233c75bb54778d4555b411bd99674bb4aeb0356efc0ee4
MD5 c8a4b2044dec96f9a3c927bb8943e54f
BLAKE2b-256 671a5edc1877da3ef0f7ab9f23260305dfadda115ba044319271a9c836fc7d27

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page