Skip to main content

A configurable linter for agent skills, plugins, and AI coding assistant context

Project description

PyPI version PyPI Downloads Tests codecov License Python Versions

skillsaw logo

skillsaw

Lint your skills before they cut someone. A configurable linter, doc generator, and CI companion for agentskills.io skills, Claude Code plugins, and plugin marketplaces.

Formerly named claudelint. If you're migrating, see Migrating from claudelint.

Features

  • ๐Ÿ” Context-Aware โ€” Automatically detects agentskills repos, single plugins, and marketplaces and enables the right rules
  • ๐Ÿ“ Rule-Based โ€” Enable/disable individual rules with configurable severity levels
  • ๐Ÿ“ Doc Generation โ€” Generate HTML or Markdown documentation for your plugins and skills with skillsaw docs
  • ๐Ÿ”Œ Extensible โ€” Load custom rules from Python files
  • โœ… Comprehensive โ€” Validates skill format, plugin structure, metadata, command format, and cross-file consistency
  • ๐Ÿค– CI-Ready โ€” GitHub Action posts inline PR comments with automatic deduplication and thread resolution
  • ๐Ÿณ Containerized โ€” Run via Docker for consistent, isolated linting
  • โšก Fast โ€” Efficient validation with clear, actionable output

Table of Contents

Quick Start

# Lint current directory (no install required)
uvx skillsaw

# Lint specific directory
skillsaw /path/to/skills

# Verbose output
skillsaw -v

# Strict mode (warnings as errors)
skillsaw --strict

# Generate default config
skillsaw --init

# List all available rules
skillsaw --list-rules

# Generate documentation
skillsaw docs

Installation

Via uvx (easiest โ€” no install required)

uvx skillsaw
uvx skillsaw /path/to/skills

Via pip

pip install skillsaw

From source

git clone https://github.com/stbenjam/skillsaw.git
cd skillsaw
pip install -e .

Using Docker

docker pull ghcr.io/stbenjam/skillsaw:latest
docker run -v $(pwd):/workspace ghcr.io/stbenjam/skillsaw

GitHub Action

The built-in GitHub Action installs skillsaw, runs it, and posts violations as inline PR comments with automatic deduplication. Fixed violations have their comment threads resolved.

name: Lint

on: [pull_request]

permissions:
  contents: read
  pull-requests: write

jobs:
  skillsaw:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: stbenjam/skillsaw@v0
        with:
          strict: true

Inputs

Input Description Default
path Path to lint .
version Specific skillsaw version to install latest
strict Treat warnings as errors false
verbose Include info-level violations false
token GitHub token for posting PR comments ${{ github.token }}

Outputs

Output Description
exit-code skillsaw exit code (0=pass, 1=errors, 2=strict+warnings)
errors Number of errors found
warnings Number of warnings found
report Full JSON report

PR comment behavior

  • Each violation gets its own inline comment on the relevant line or file
  • Comments are deduplicated across re-runs using content fingerprinting
  • When a violation is fixed, its comment thread is automatically resolved
  • Comments with human replies are preserved

Permissions: contents: read is required for checkout. pull-requests: write is required for posting comments.

Repository Types

skillsaw automatically detects your repository structure:

agentskills.io Skills

Standalone skill repositories following the agentskills.io specification:

my-skill/
โ”œโ”€โ”€ SKILL.md              # Required: metadata + instructions
โ”œโ”€โ”€ scripts/              # Optional: executable code
โ”œโ”€โ”€ references/           # Optional: documentation
โ”œโ”€โ”€ assets/               # Optional: templates, resources
โ”œโ”€โ”€ evals/                # Optional: evaluation tests
โ”‚   โ””โ”€โ”€ evals.json
โ””โ”€โ”€ <any-dir>/            # Arbitrary directories allowed per spec

Skill collections (multiple skills in subdirectories) are also supported:

skills-repo/
โ”œโ”€โ”€ skill-one/
โ”‚   โ””โ”€โ”€ SKILL.md
โ””โ”€โ”€ skill-two/
    โ””โ”€โ”€ SKILL.md

Standard discovery paths (.claude/skills/, .github/skills/, .agents/skills/) are checked automatically.

Single Plugin

my-plugin/
โ”œโ”€โ”€ .claude-plugin/
โ”‚   โ””โ”€โ”€ plugin.json
โ”œโ”€โ”€ commands/
โ”‚   โ””โ”€โ”€ my-command.md
โ”œโ”€โ”€ skills/
โ”‚   โ””โ”€โ”€ my-skill/
โ”‚       โ””โ”€โ”€ SKILL.md
โ””โ”€โ”€ README.md

Marketplace (Multiple Plugins)

skillsaw supports multiple marketplace structures per the Claude Code specification:

Traditional Structure (plugins/ directory)

marketplace/
โ”œโ”€โ”€ .claude-plugin/
โ”‚   โ””โ”€โ”€ marketplace.json
โ””โ”€โ”€ plugins/
    โ”œโ”€โ”€ plugin-one/
    โ”‚   โ”œโ”€โ”€ .claude-plugin/
    โ”‚   โ””โ”€โ”€ commands/
    โ””โ”€โ”€ plugin-two/
        โ”œโ”€โ”€ .claude-plugin/
        โ””โ”€โ”€ commands/

Flat Structure (root-level plugin)

marketplace/
โ”œโ”€โ”€ .claude-plugin/
โ”‚   โ””โ”€โ”€ marketplace.json    # source: "./"
โ”œโ”€โ”€ commands/
โ”‚   โ””โ”€โ”€ my-command.md
โ””โ”€โ”€ skills/
    โ””โ”€โ”€ my-skill/

Custom Paths and Mixed Structures

Plugins from plugins/, custom paths, and remote sources can coexist in one marketplace. Only local sources are validated.

Configuration

Generate a default .skillsaw.yaml in your repository root:

skillsaw --init

This creates a config file with all builtin rules, their defaults, and descriptions. Edit it to enable, disable, or customize rules for your project. See .skillsaw.yaml.example for a complete example.

Builtin Rules

agentskills.io

These rules validate skills against the agentskills.io specification. They auto-enable for agentskills repos, single plugins, and marketplaces whenever skills are detected.

Rule ID Description Default Severity
agentskill-valid SKILL.md must have valid frontmatter with name and description error (auto)
agentskill-name Skill name must be lowercase with hyphens and match directory name error (auto)
agentskill-description Skill description should be meaningful and within length limits warning (auto)
agentskill-structure Skill directories should only contain recognized subdirectories (stricter than spec) warning (disabled)
agentskill-evals Validate evals/evals.json format when present error (auto)
agentskill-evals-required Require evals/evals.json for each skill (opt-in) error (disabled)

agentskill-structure parameters:

Parameter Description Default
allowed_dirs Directory names allowed in the skill root ["assets", "evals", "references", "scripts"]

Plugin Structure

Rule ID Description Default Severity
plugin-json-required Plugin must have .claude-plugin/plugin.json error (auto)
plugin-json-valid Plugin.json must be valid JSON with required fields error (auto)
plugin-naming Plugin names should use kebab-case warning (auto)
plugin-readme Plugin should have a README.md file warning (auto)

plugin-json-valid parameters:

Parameter Description Default
recommended-fields Fields that trigger a warning if missing from plugin.json ["description", "version", "author"]

Command Format

Rule ID Description Default Severity
command-naming Command files should use kebab-case naming warning
command-frontmatter Command files must have valid frontmatter with description error
command-sections Command files should have Name, Synopsis, Description, and Implementation sections warning
command-name-format Command Name section should be 'plugin-name:command-name' warning

Marketplace

Rule ID Description Default Severity
marketplace-json-valid Marketplace.json must be valid JSON with required fields error (auto)
marketplace-registration Plugins must be registered in marketplace.json error (auto)

Skills, Agents, Hooks

Rule ID Description Default Severity
skill-frontmatter SKILL.md files should have frontmatter with name and description warning
agent-frontmatter Agent files must have valid frontmatter with name and description error
hooks-json-valid hooks.json must be valid JSON with proper hook configuration structure error

MCP (Model Context Protocol)

Rule ID Description Default Severity
mcp-valid-json MCP configuration must be valid JSON with proper mcpServers structure error
mcp-prohibited Plugins should not enable non-allowlisted MCP servers error (disabled)

mcp-prohibited parameters:

Parameter Description Default
allowlist MCP server names that are permitted []

Rules Directory

Rule ID Description Default Severity
rules-valid .claude/rules/ files must be markdown with valid optional paths frontmatter error (auto)

Openclaw

Validates metadata.openclaw in SKILL.md frontmatter against the openclaw spec. Only fires when metadata.openclaw is present.

Rule ID Description Default Severity
openclaw-metadata Validate metadata.openclaw fields against the openclaw spec warning (auto)

Custom Rules

Create custom validation rules by extending the Rule base class:

from pathlib import Path
from typing import List
from skillsaw import Rule, RuleViolation, Severity, RepositoryContext

class NoTodoCommentsRule(Rule):
    @property
    def rule_id(self) -> str:
        return "no-todo-comments"

    @property
    def description(self) -> str:
        return "Command files should not contain TODO comments"

    def default_severity(self) -> Severity:
        return Severity.WARNING

    def check(self, context: RepositoryContext) -> List[RuleViolation]:
        violations = []
        for plugin_path in context.plugins:
            commands_dir = plugin_path / "commands"
            if not commands_dir.exists():
                continue
            for cmd_file in commands_dir.glob("*.md"):
                content = cmd_file.read_text()
                if "TODO" in content:
                    violations.append(
                        self.violation("Found TODO comment", file_path=cmd_file)
                    )
        return violations

Then reference it in .skillsaw.yaml:

custom-rules:
  - ./my_custom_rules.py

rules:
  no-todo-comments:
    enabled: true
    severity: warning

Documentation Generation

skillsaw can generate documentation for your plugins, skills, and marketplaces:

# Generate HTML docs (default)
skillsaw docs

# Generate Markdown
skillsaw docs --format markdown

# Write to a specific file
skillsaw docs --format markdown -o docs/README.md

# Write to a directory
skillsaw docs -o my-docs/

# Custom title
skillsaw docs --title "My Plugin Docs"

The generated documentation includes plugin metadata, command descriptions, skill summaries, and configuration details extracted from your repository.

Exit Codes

  • 0 - Success (no errors, or warnings only in non-strict mode)
  • 1 - Failure (errors found, or warnings in strict mode)

Example Output

Linting: /path/to/skills-repo

Errors:
  โœ— ERROR [skills/my-skill/SKILL.md]: Name 'My Skill' must contain only lowercase letters, numbers, and hyphens
  โœ— ERROR [plugins/git/.claude-plugin/plugin.json]: Missing plugin.json

Warnings:
  โš  WARNING [skills/helper/SKILL.md]: Description exceeds 1024 characters (1087)
  โš  WARNING [plugins/utils]: Missing README.md (recommended)

Summary:
  Errors:   2
  Warnings: 2

Migrating from claudelint

This project was renamed from claudelint to skillsaw. To migrate:

  1. Update your package: pip install skillsaw (instead of pip install claudelint)
  2. Rename .claudelint.yaml to .skillsaw.yaml (the old name is still discovered as a fallback)
  3. Update CLI usage: skillsaw (instead of claudelint)
  4. Update imports in custom rules: from skillsaw import ... (the old from claudelint import ... still works)

The claudelint command still works as a shim but prints a deprecation warning.

Removed rules

The following rules from claudelint have been removed in skillsaw:

Rule ID Reason
commands-dir-required Claude Code now treats skills/ and commands/ as the same mechanism; requiring a commands/ directory is no longer meaningful
commands-exist Same as above โ€” plugins don't need to have commands

If your .skillsaw.yaml references these rule IDs, skillsaw will emit a warning about the unknown rule.

Development

# Run tests
pytest tests/ -v

# Format code
black src/ tests/

# Build Docker image
docker build -t skillsaw .

Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass
  5. Submit a pull request

License

Apache 2.0 - See LICENSE for details.

See Also

Support

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

skillsaw-0.6.0.tar.gz (83.8 kB view details)

Uploaded Source

Built Distribution

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

skillsaw-0.6.0-py3-none-any.whl (65.3 kB view details)

Uploaded Python 3

File details

Details for the file skillsaw-0.6.0.tar.gz.

File metadata

  • Download URL: skillsaw-0.6.0.tar.gz
  • Upload date:
  • Size: 83.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for skillsaw-0.6.0.tar.gz
Algorithm Hash digest
SHA256 48bae1cda78eb034df683f7cad03469540f99d9d521e50165c7f678bf024ac0a
MD5 fbd9904047173ca02e0fa93f31780cdd
BLAKE2b-256 f32bf3414387759ba5ac00932905eeed2ed1c8ff00a9ae573390a4fc4e91672f

See more details on using hashes here.

Provenance

The following attestation bundles were made for skillsaw-0.6.0.tar.gz:

Publisher: release.yml on stbenjam/skillsaw

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file skillsaw-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: skillsaw-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 65.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for skillsaw-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 684ec245df22eccdb8775aa25c017a4355244b0f7ff35f811b241ff8ea5e55ce
MD5 de0215abc564ed1232d49794cecbf1ff
BLAKE2b-256 2e8621f2ec7ebf44ac7cee693e95ec94733138f8059942eb445c5b4e851a06a7

See more details on using hashes here.

Provenance

The following attestation bundles were made for skillsaw-0.6.0-py3-none-any.whl:

Publisher: release.yml on stbenjam/skillsaw

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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