skills_lint 0.5.1
skills_lint: ^0.5.1 copied to clipboard
A static analysis linter for Agent Skills (SKILL.md) written in Dart. Validates frontmatter, naming, paths, and structure for use in CI and pre-commit hooks.
skills_lint #
This is not an officially supported Google product. This project is not eligible for the Google Open Source Software Vulnerability Rewards Program.
A static analysis linter for Agent Skills to ensure they meet the specification in presubmit checks. This project is a Dart package and can be run as a CLI tool to validate your skills directory before committing.
Table of Contents #
Overview #
An Agent Skill is a portable, self-contained directory that extends an AI agent's capabilities. Pre-submit linting ensures that your skill definitions are valid and ready for consumption by agent platforms.
skills_lint validates:
- Presence of mandatory
SKILL.mdfile. - YAML frontmatter constraints (naming, length, etc.).
- Directory structure (flat, no deep nesting).
- Relative path integrity.
For a full definition of the skill standard, see the Agent Skills Specification.
Installation #
skills_lint ships as both a standalone native binary (no Dart
SDK required) and as a Dart package on pub.dev. Pick the path that
matches your environment.
Homebrew note. A
brew install dart-skills-lintpath is on the roadmap; it will land afterskills_lintmigrates to its own dedicated repository. Until then, the install paths below cover all supported platforms.
1. Dart developers — pub.dev #
If you already have the Dart SDK installed, the standard pub.dev paths still work and are unchanged.
As a project dev_dependency
Add to your pubspec.yaml:
dev_dependencies:
skills_lint: ^0.5.0
Then:
dart pub get
Globally installed
For multiple projects without per-project pubspec entries:
dart install skills_lint
2. install.sh — Linux + macOS, no Dart required #
The recommended path for CI runners and laptops without the Dart SDK
on PATH. Downloads the matching prebuilt binary from the latest GitHub
Release, verifies its SHA256, and installs to /usr/local/bin (with a
sudo fallback). Supports macOS arm64 + x64 and Linux x64 + arm64.
curl -fsSL https://github.com/google/skills_lint.dart/releases/latest/download/install.sh | bash
Optional env vars (set before the bash part):
INSTALL_DIR— install destination (default/usr/local/bin).VERSION— pin a specific release like0.4.0(defaultlatest).REPO— alternate source repo (defaultgoogle/skills_lint.dart).
macOS first-launch note
macOS binaries are not yet code-signed. The first time you run the binary, macOS Gatekeeper will block it ("cannot be opened because the developer cannot be verified"). Remove the quarantine flag once:
xattr -d com.apple.quarantine "$(which skills_lint)"
This step goes away once notarized builds ship.
3. Direct download — Linux + macOS, no install script #
For environments where piping a script to bash isn't acceptable.
Grab the tarball for your platform from
the latest GitHub Release
and verify its SHA256 against the release's SHA256SUMS asset.
TARGET="linux-x64" # or: macos-arm64, macos-x64, linux-arm64
VERSION="0.5.0"
BASE="https://github.com/google/skills_lint.dart/releases/download/skills_lint-v${VERSION}"
curl -fsSLO "${BASE}/skills_lint-${TARGET}.tar.gz"
curl -fsSLO "${BASE}/SHA256SUMS"
grep " skills_lint-${TARGET}.tar.gz$" SHA256SUMS | sha256sum -c -
tar -xzf "skills_lint-${TARGET}.tar.gz"
sudo install -m 0755 "skills_lint-${TARGET}" /usr/local/bin/skills_lint
On macOS, replace sha256sum -c - with shasum -a 256 -c -.
Usage #
skills_lint runs as a command-line tool, configured by flags or by
a skills_lint.yaml file. The CLI is the user-facing surface; it
also has a programmatic API for contributors who need to embed the
linter in their own test suite — see
CONTRIBUTING.md.
1. As a Command Line Tool with Arguments #
Run the linter against your skills or root skills directories by passing arguments.
dart run skills_lint --skills-directory ./path/to/skills-root
Multiple root directories can be specified:
dart run skills_lint --skills-directory ./path/to/root-a --skills-directory ./path/to/root-b
Validate Individual Skills directly using --skill or -s:
dart run skills_lint --skill ./path/to/my-single-skill
If no directory is specified, it automatically checks .claude/skills and .agents/skills relative to your workspace root.
Flags #
-d,--skills-directory: Specifies a root directory containing sub-folders of skills to validate. Can be passed multiple times. Can use home tilde expansion (ex:~/.agents/skills).-s,--skill: Specifies an individual skill directory to validate directly. Can be passed multiple times.-q,--quiet: Hide non-error validation output.-w,--print-warnings: Enable printing of warning messages.--fast-fail: Halt execution immediately on the error.--ignore-config: Ignore the YAML configuration file entirely.--[no-]check-trailing-whitespace: Enable/disable checking for trailing whitespace. (Disabled by default).--fix: Write fixes for failing lints to disk.--dry-run: When combined with--fix, prints the proposed diff without writing.--fix-apply: Deprecated alias for--fix. Prints a deprecation notice on use.
2. As a Command Line Tool with a YAML Configuration File #
You can configure the linter using a configuration file (defaulting to skills_lint.yaml in the current directory).
Create skills_lint.yaml in the root of your repository:
# skills_lint.yaml
skills_lint:
rules:
check-relative-paths: error
check-absolute-paths: error
directories:
- path: "~/.agents/skills"
ignore_file: "~/.agents/skills/ignore.json"
individual_skills:
- path: "my_custom_standalone_skill"
rules:
missing_install_script: warning
ignore_file: "my_ignores.json"
Then you can simply run:
dart run skills_lint
Rule Precedence #
When resolving which severity and parameters to apply for a rule, skills_lint evaluates settings in the following order of precedence (highest to lowest):
- CLI Flags / API Overrides:
- Rule severity overrides: Explicit flags passed to the CLI (e.g.,
--check-trailing-whitespaceor--no-check-trailing-whitespace). - Rule parameter overrides: Namespaced command-line parameter flags (e.g.,
--path-does-not-exist-exclude=".*-workspace"). Passing an empty string (e.g.--path-does-not-exist-exclude="") explicitly clears the custom parameter.
- Rule severity overrides: Explicit flags passed to the CLI (e.g.,
- Path-Specific Config: Rules defined under
directories:orindividual_skills:inskills_lint.yamlfor a matching path.- If a target config specifies a map (e.g.
path-does-not-exist: { severity: error, exclude: "..." }), the parameters map completely overrides any global parameters for that rule. - If a target config specifies a simple string severity (e.g.
path-does-not-exist: error), the severity is overridden, but the global parameters map is inherited/preserved.
- If a target config specifies a map (e.g.
- Global Config: Rules and parameters defined under the top-level
rules:inskills_lint.yaml. - Defaults: The hardcoded defaults for each rule.
This ensures that you can always override configuration file settings for a specific run by using CLI flags.
3. Custom Rules #
Custom rule authoring lives in the
dart-skills-lint-validation
skill — that skill walks through extending SkillRule and passing the
rule into the linter.
Built-in Rules #
For the full list of built-in validation rules — default severities, exact
diagnostic shapes, auto-fix behavior, and configuration options — see
RULES.md.
Recipes #
Drop-in snippets for the two most common ways to wire skills_lint
into a project's quality gates. Each recipe is exercised by
test/recipe_drift_test.dart, so if a
flag here goes stale, CI fails.
Recipe: GitHub Actions #
Save the following as .github/workflows/lint-skills.yml. It runs on
every push and PR, installs skills_lint globally on the runner,
and validates every skill under .claude/skills/. Adjust the path to
match where your skills live.
# .github/workflows/lint-skills.yml
name: Lint Agent Skills
on:
push:
branches: [main]
pull_request:
permissions: read-all
jobs:
lint-skills:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dart-lang/setup-dart@v1
- run: dart install skills_lint
- run: skills_lint --skills-directory ./.claude/skills
To validate a single skill directory instead, swap the last step:
- run: skills_lint --skill ./.claude/skills/my-skill
Recipe: Dart-native pre-commit hook #
A pre-commit hook that calls into the linter directly — no Husky, no
Python pre-commit framework, just Dart and the existing
dart install tooling.
Install the linter globally once per machine:
dart install skills_lint
Then install the hook into the repository (run from the repo root):
cat > .git/hooks/pre-commit <<'HOOK'
#!/bin/sh
set -e
# Lint every skill under .claude/skills before each commit.
# Add --skill arguments for other locations as needed.
exec skills_lint --skills-directory ./.claude/skills --quiet
HOOK
chmod +x .git/hooks/pre-commit
The hook exits non-zero on lint failure, blocking the commit. To
auto-apply fixable lints inside the hook, append --fix to the linter
invocation.
Recipe: have an agent set it up for you #
If you're using Claude Code, Gemini, or another agent that can read
repository-local skills, paste the following prompt to have the agent
install and validate skills_lint for you. The agent will
follow the
dart-skills-lint-setup
skill for first-time wiring, then the
dart-skills-lint-validation
skill to run the linter and resolve any failures.
Set up skills_lint in this project. Use the skill at
skills/dart-skills-lint-setup/SKILL.mdto add it as a dev_dependency, create the configuration file, and wire it into CI. Then use the skill atskills/dart-skills-lint-validation/SKILL.mdto run the linter and resolve any failures.
Contributing #
Contributions are welcome! Please ensure that any PRs pass the linter and test suite.