This repository has moved to github.com/aicatalyst-team/skill-linter.
Linter for AI agent skill files following the Agent Skills specification.
47 rules across 5 categories: structural, frontmatter, content, security, and best practices. Supports text, JSON, SARIF, and GitHub Actions output formats. Optional LLM-powered deep analysis via Anthropic API or Google Cloud Vertex AI.
npx skilleval check ./my-skillOr install globally:
npm install -g skillevalgit clone https://github.com/natifridman/skilleval.git
cd skilleval
npm install
npm run build
npm linkThis makes the skilleval command available globally, so you can use it like the published package:
skilleval check ./my-skill
skilleval check https://github.com/org/repo
skilleval rulesTo rebuild after making changes:
npm run buildOr use watch mode for continuous rebuilds during development:
npm run devTo unlink when done:
npm unlink -g skillevalRequires Node.js >= 22.
# Lint a skill directory
skilleval check ./my-skill
# Lint multiple skills
skilleval check ./skill-a ./skill-b
# Lint skills from a GitHub repo
skilleval check https://github.com/org/repo
skilleval check github:org/repo
# Target a specific skill in a repo
skilleval check https://github.com/org/repo/tree/main/skills/my-skill
# Scaffold a new skill
skilleval new my-new-skill
# List all 47 rules
skilleval rulesLint and evaluate skill directories.
skilleval check ./my-skill
skilleval check ./my-skill --format json
skilleval check ./my-skill --format sarif > results.sarif
skilleval check ./my-skill --format github
skilleval check ./my-skill --strict
skilleval check ./my-skill --fix
skilleval check ./my-skill --deep
skilleval check ./my-skill --deep --deep-provider vertex
# Remote GitHub repos
skilleval check https://github.com/org/repo
skilleval check https://github.com/org/repo/tree/main/skills/my-skill
skilleval check github:org/repo| Flag | Description |
|---|---|
-f, --format <type> |
Output format: text, json, sarif, github (default: text) |
--fix |
Auto-fix fixable issues |
--deep |
Run LLM-powered semantic analysis |
--deep-provider <name> |
LLM provider: anthropic, vertex (auto-detected) |
--deep-model <name> |
LLM model to use for deep analysis |
--strict |
Treat warnings as errors |
--rule <id> |
Run only specific rules (repeatable) |
--category <name> |
Run only rules in a category (repeatable) |
-c, --config <path> |
Path to config file |
--no-config |
Ignore config files, use defaults |
-q, --quiet |
Suppress warnings and info, show only errors |
-v, --verbose |
Show all skills including those with no issues |
Exit codes: 0 = pass, 1 = errors found (or warnings with --strict), 2 = config error, 3 = CLI error.
List all available rules.
skilleval rules
skilleval rules --category security
skilleval rules --severity errorCreate a .skillevalrc.json config file in the current directory.
Scaffold a new skill directory with a SKILL.md template.
| Rule | Severity | Description |
|---|---|---|
structural/skill-md-exists |
error | SKILL.md must exist |
structural/directory-structure |
info | Warn on non-standard directories |
structural/no-extra-top-level-files |
info | Warn on unexpected root files |
structural/file-references-valid |
warning | Referenced file paths must exist |
| Rule | Severity | Fixable | Description |
|---|---|---|---|
frontmatter/frontmatter-present |
error | Must have YAML frontmatter | |
frontmatter/name-required |
error | name is required |
|
frontmatter/name-format |
error | yes | 1-64 chars, lowercase, hyphens |
frontmatter/name-matches-directory |
error | Must match parent directory | |
frontmatter/name-no-reserved-words |
error | Must not contain reserved words ('anthropic', 'claude') | |
frontmatter/description-required |
error | description is required |
|
frontmatter/description-length |
error | 1-1024 characters | |
frontmatter/description-quality |
warning | Must be substantive | |
frontmatter/no-extra-fields |
error | Only 6 allowed fields | |
frontmatter/compatibility-length |
error | Max 500 characters | |
frontmatter/metadata-types |
error | Must be string-to-string map | |
frontmatter/allowed-tools-format |
warning | Must be space-separated string |
| Rule | Severity | Description |
|---|---|---|
content/body-not-empty |
warning | Body must not be empty |
content/body-token-budget |
warning | Body under 5000 tokens |
content/body-line-limit |
warning | Body under 500 lines |
content/has-headings |
info | Should have headings |
content/no-html-in-body |
info | No raw HTML tags |
content/references-depth |
info | References one level deep |
content/no-backslash-paths |
info | Use forward slashes for cross-platform compatibility |
content/no-ascii-art |
info | No decorative ASCII art or box-drawing characters |
Based on Snyk ToxicSkills research and OWASP Agentic Skills Top 10.
| Rule | Severity | Description |
|---|---|---|
security/no-prompt-injection |
error | Detects prompt injection patterns (context-aware: patterns in quotes, backticks, or code blocks are downgraded to warnings) |
security/no-base64-payloads |
error | Detects obfuscated base64 content |
security/no-credential-access |
error | Detects sensitive file/env access |
security/no-curl-bash |
error | Detects pipe-to-shell execution |
security/no-remote-fetch |
warning | Detects untrusted remote content |
security/no-obfuscation |
error | Detects Unicode smuggling |
security/no-memory-poisoning |
error | Detects agent config writes |
security/no-secret-literals |
warning | Detects hardcoded secrets |
security/no-password-archives |
error | Detects password-protected archives |
| Rule | Severity | Description |
|---|---|---|
best-practices/description-has-trigger-words |
info | Use imperative phrasing |
best-practices/description-no-first-person |
warning | Use third-person voice in descriptions |
best-practices/progressive-disclosure |
info | Split large bodies into references/ |
best-practices/scripts-are-referenced |
info | Scripts should be referenced in body |
best-practices/has-examples |
info | Should contain code blocks |
best-practices/gotchas-section |
info | Non-trivial skills need gotchas |
best-practices/pinned-versions |
info | Pin package versions |
best-practices/scripts-have-help |
info | Scripts should support --help |
best-practices/no-generic-names |
info | Avoid generic names like 'helper' or 'utils' |
best-practices/no-persona-instructions |
warning | Provide instructions, not persona assignments |
best-practices/no-vague-instructions |
info | Avoid vague directives like 'follow best practices' |
best-practices/no-time-sensitive-content |
info | Avoid time-sensitive language that becomes stale |
best-practices/no-excessive-negation |
info | Tell agents what to do, not what not to do |
best-practices/non-descriptive-filenames |
info | Use descriptive filenames, not generic ones |
Create .skillevalrc.json (or use skilleval init):
{
"extends": "recommended",
"rules": {
"content/no-html-in-body": "off",
"best-practices/gotchas-section": "warning"
},
"ignore": ["node_modules", ".git"]
}Config is discovered via lilconfig: .skillevalrc.json, .skillevalrc.yaml, skilleval.config.js, or package.json["skilleval"].
| Preset | Description |
|---|---|
recommended |
All spec rules as errors, best practices as info (default) |
strict |
Recommended + best practices elevated to warnings |
security |
Security rules only, all as errors |
Suppress specific findings with HTML comments in your SKILL.md:
<!-- skilleval-disable-next-line -->
This line's diagnostics are suppressed.
<!-- skilleval-disable-next-line security/no-prompt-injection -->
Only the specified rule is suppressed on the next line.Pass a GitHub URL instead of a local path to scan skills hosted on GitHub:
skilleval check https://github.com/org/repo
skilleval check https://github.com/org/repo/tree/main/skills/my-skill
skilleval check github:org/repoAuthentication uses gh CLI (if installed and logged in) with a fallback to the GITHUB_TOKEN environment variable. Public repos work without authentication.
Optional LLM-powered semantic analysis that catches issues regex can't:
- Subtle prompt injection and social engineering
- Self-contradicting instructions
- Description-body misalignment
- System message impersonation
- Script safety issues
When --deep is enabled, the LLM also triages static security findings and dismisses confirmed false positives (e.g., injection patterns that appear in documentation or examples). Dismissed findings are removed from the output with an explanation.
Anthropic API:
export ANTHROPIC_API_KEY=sk-ant-...
skilleval check ./my-skill --deepGoogle Cloud Vertex AI:
export GOOGLE_CLOUD_PROJECT=my-project
export GOOGLE_CLOUD_LOCATION=us-east5
skilleval check ./my-skill --deep --deep-provider vertexRequires installing the provider SDK:
npm install @anthropic-ai/sdk # For Anthropic
npm install @anthropic-ai/vertex-sdk # For Vertex AI- uses: actions/setup-node@v4
- run: npx skilleval check ./skills --format sarif > results.sarif
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif- run: npx skilleval check ./skills --format githubimport { lint, registerAllRules } from "skilleval";
registerAllRules();
const result = await lint("./my-skill");
console.log(result.errorCount, result.diagnostics);See CONTRIBUTING.md for development setup, how to add rules, and PR guidelines.
AI agents: see AGENTS.md for codebase architecture and conventions.
MIT