Skip to content

Pre-commit

skillsaw ships a Pre-commit hook so every contributor to your repository runs the linter on commit, at a pinned version, with no install instructions.

Setup

Add skillsaw to your repository's .pre-commit-config.yaml:

repos:
  - repo: https://github.com/stbenjam/skillsaw
    rev: v0.18.0
    hooks:
      - id: skillsaw

Then install the git hook once per clone:

pre-commit install

From now on, every commit runs the linter first. Violations at error severity (or warnings, with strict: true in .skillsaw.yaml) block the commit.

You can also run it on demand across the whole repository:

pre-commit run skillsaw --all-files

How the hook works

Most Pre-commit hooks receive the list of staged filenames and lint each file independently. skillsaw is a repo-level linter: it detects your repository type, validates marketplace registration, and runs cross-file rules, none of which map to per-file invocation. The hook therefore declares pass_filenames: false and lints the whole repository.

The published hook declares files: . — any staged file triggers a full repository lint. Codex plugin manifests can declare skills, hooks, MCP configs, and assets at arbitrary paths, so no narrower filename pattern can cover every lint input; matching everything keeps cross-file validation complete while still letting pre-commit skip commits that stage nothing (an --allow-empty commit, a message-only amend). One known gap: pre-commit does not count deleted files toward files matching, so a commit that only deletes files skips the hook — a deletion that leaves a manifest path dangling surfaces on the next non-deletion commit, or immediately via pre-commit run skillsaw --all-files.

Because the whole repository is linted, a pre-existing violation in a file you didn't touch can block your commit. If you're adopting skillsaw on a repo with existing violations, create a baseline first — baselined violations don't fail the lint, so the hook only flags new problems.

Pinning

The rev: field pins the skillsaw version. Git tags are mutable; if your threat model includes a compromised upstream re-pointing a tag, pin a full commit SHA instead:

  - repo: https://github.com/stbenjam/skillsaw
    rev: 3e1188f446413e6d6818c98644d2d6a84e4038e7  # v0.14.1
    hooks:
      - id: skillsaw

pre-commit autoupdate bumps rev: to the latest tag as an explicit, reviewable diff. See Supply Chain Protection for the broader trust model, including the release attestations that let you verify what you're pinning.

Configuration

The hook needs no configuration of its own — it respects your repository's .skillsaw.yaml exactly like a manual skillsaw lint run, including rule overrides, excludes, strict mode, inline suppressions, and the baseline.

To pass extra CLI flags, override args in your config:

    hooks:
      - id: skillsaw
        args: [--skip-rule, content-weak-language]

Troubleshooting

Can I run the hook only for selected paths? Override the files filter in your own config:

    hooks:
      - id: skillsaw
        files: ^(CLAUDE\.md|\.claude/|\.claude-plugin/)

This trades completeness for speed: a Codex component declared at a custom path, or a change that leaves a manifest path dangling, may no longer trigger the hook.

The hook fails on files I didn't change. That's the repo-level lint working as intended — see the baseline note above.

Environment is stale after a skillsaw release. Pre-commit caches the hook environment per rev. Run pre-commit autoupdate to move to a new release, or pre-commit clean to rebuild environments.