PHPackages                             stolt/skill-validator - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [File &amp; Storage](/categories/file-storage)
4. /
5. stolt/skill-validator

ActiveLibrary[File &amp; Storage](/categories/file-storage)

stolt/skill-validator
=====================

A library for parsing and validating SKILL.md files or raw SKILL.md content.

v0.1.0(2mo ago)25.2k↓84.8%[1 issues](https://github.com/raphaelstolt/skill-validator/issues)2MITPHPPHP &gt;=8.2CI passing

Since May 4Pushed 1mo agoCompare

[ Source](https://github.com/raphaelstolt/skill-validator)[ Packagist](https://packagist.org/packages/stolt/skill-validator)[ RSS](/packages/stolt-skill-validator/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (8)Versions (7)Used By (2)

skill-validator
===============

[](#skill-validator)

[![Test Status](https://github.com/raphaelstolt/skill-validator/workflows/test/badge.svg)](https://github.com/raphaelstolt/skill-validator/workflows/test/badge.svg)[![Lint Status](https://github.com/raphaelstolt/skill-validator/workflows/lint/badge.svg)](https://github.com/raphaelstolt/skill-validator/workflows/lint/badge.svg)[![Version](https://camo.githubusercontent.com/23147240bf8a2860ca19aad05d71aabd87e10e7052e30e944431a42123269f24/687474703a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f73746f6c742f736b696c6c2d76616c696461746f722e7376673f7374796c653d666c6174)](https://packagist.org/packages/stolt/skill-validator)[![Downloads](https://camo.githubusercontent.com/52402ce7aede83c3a3825f86e5990ae44eb6920496d16189f4ed0d1d521adbf5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f73746f6c742f736b696c6c2d76616c696461746f72)](https://camo.githubusercontent.com/52402ce7aede83c3a3825f86e5990ae44eb6920496d16189f4ed0d1d521adbf5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f73746f6c742f736b696c6c2d76616c696461746f72)[![PHP Version](https://camo.githubusercontent.com/bee070518258ca00da0973b812d6713d5b4a97a70b8a92b1043436deed97d5dd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e322b2d6666363962342e737667)](https://camo.githubusercontent.com/bee070518258ca00da0973b812d6713d5b4a97a70b8a92b1043436deed97d5dd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e322b2d6666363962342e737667)[![PDS Skeleton](https://camo.githubusercontent.com/3c7140ee36205075ed977142f25c29eb1fb7809e9b86a865461fc21776ad1665/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7064732d736b656c65746f6e2d626c75652e7376673f7374796c653d666c6174)](https://github.com/php-pds/skeleton)[![Lean dist package](https://camo.githubusercontent.com/9ef308bdbe7c45e8b0328885c82eb69788f8204f9483a16c8dff3b778346637a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c65616e2d646973742532307061636b6167652d3030666662362e7376673f7374796c653d666c6174)](https://github.com/raphaelstolt/lean-package-validator)

A PHP library to parse and validate `SKILL.md` files or raw `SKILL.md` content against the [SKILL.md format specification](https://www.skillsdirectory.com/docs/skill-md-format).

Installation and usage
----------------------

[](#installation-and-usage)

```
composer require stolt/skill-validator
```

Usage
-----

[](#usage)

The `SkillMd` class from the [stolt/skill-md](https://github.com/raphaelstolt/skill-md/) package is the primary abstraction for a validated skill. Every valid result exposes a `SkillMd` instance, and the validator also accepts `SkillMd` instances directly as input.

The validator can validate existing `SKILL.md` files, raw `SKILL.md` content, or the mentioned `SkillMd` instances.

### Validating a `SKILL.md` file

[](#validating-a-skillmd-file)

```
use Stolt\Ai\Skill\Validator;

$validator = new Validator();
$result = $validator->validateFile('/path/to/an-ai-skill/SKILL.md');
```

### Validating all `SKILL.md` files in a directory

[](#validating-all-skillmd-files-in-a-directory)

```
use Stolt\Ai\Skill\Validator;

$validator = new Validator();
$results = $validator->validateFromDirectory('/path/to/skills');

foreach ($results as $filePath => $result) {
    if ($result->isInvalid()) {
        echo sprintf('Invalid: %s', $filePath) . PHP_EOL;
        foreach ($result->errors() as $error) {
            echo '  - ' . $error . PHP_EOL;
        }
    }
}
```

The method returns an `array` keyed by absolute file path, covering all `SKILL.md` files found recursively under the given directory.

### Validating raw `SKILL.md` content

[](#validating-raw-skillmd-content)

```
use Stolt\Ai\Skill\Validator;

$validator = new Validator();
$result = $validator->validateContent('raw-skill-content');
```

### Validating a `SkillMd` instance

[](#validating-a-skillmd-instance)

```
use Stolt\Ai\Skill\Validator;
use Stolt\Ai\SkillMd;

$skillMd = SkillMd::create(
    'code-review',
    'Review code changes and provide actionable feedback.',
    "# Code review\n\nReview the changed files and report issues.",
    ['tags' => ['php', 'review'], 'version' => '1.0.0']
);

$validator = new Validator();
$result = $validator->validateSkillMd($skillMd);
```

Tip

The `validate` alias method accepts a file path, directory path, raw content, or a `SkillMd` instance and delegates to the appropriate method automatically.

### Accessing validation results and metadata

[](#accessing-validation-results-and-metadata)

Validation returns a `Stolt\Ai\Skill\ValidationResult` object. When the `SKILL.md` content is valid, a `SkillMd`instance is available directly. The parsed metadata is also accessible as a `Stolt\Ai\Skill\Metadata` object.

```
use Stolt\Ai\Skill\Validator;

$validator = new Validator();
$result = $validator->validateContent('raw-skill-content');

if ($result->isInvalid()) {
    foreach ($result->errors() as $error) {
        echo $error . PHP_EOL;
    }
    // Raw metadata can still be inspected when parsing succeeded but validation failed.
    $rawMetadata = $result->rawMetadata();
    exit(1);
}

// Primary SkillMd abstraction — available on every valid result.
$skillMd = $result->skillMd();  // returns ?SkillMd (null when invalid)

// Or assert the SkillMd directly, which throws a LogicException when the result is invalid.
$skillMd = $result->toSkillMd();

// Use the SkillMd instance.
$name        = $skillMd->name();
$description = $skillMd->description();
$body        = $skillMd->body();
$tags        = $skillMd->tags();
$version     = $skillMd->version();

// Metadata object for field access with defaults.
$metadata    = $result->metadata();
$allowedTools = $metadata?->get('allowed-tools', []);
$model       = $metadata?->get('model');
$effort      = $metadata?->get('effort');

// Markdown instructions after the YAML frontmatter.
$instructions = $result->body();

// Array representation for logging, JSON APIs, or integrations.
$arrayResult = $result->toArray();

echo sprintf('Skill "%s" is valid: %s', $name, $description) . PHP_EOL;
```

### Round-tripping between content and `SkillMd`

[](#round-tripping-between-content-and-skillmd)

Because `validateSkillMd()` accepts a `SkillMd` instance and `toSkillMd()` returns one, validation results and `SkillMd` objects round-trip cleanly:

```
use Stolt\Ai\Skill\Validator;

$validator = new Validator();

// Parse and validate raw content.
$result = $validator->validateContent($rawContent);

// Get the primary SkillMd abstraction.
$skillMd = $result->toSkillMd();

// Re-validate the SkillMd — e.g. after modifying it.
$revalidated = $validator->validateSkillMd($skillMd);
```

For an actual integration, the project [list-skills-command](https://github.com/raphaelstolt/list-skills-command) can also be consolidated.

Validation rules
----------------

[](#validation-rules)

The validator checks that a `SKILL.md` document:

- starts with YAML frontmatter delimited by `---` lines,
- contains the **required** `name` field,
- contains the **required** `description` field,
- uses a non-empty, lowercase, hyphenated skill name,
- contains Markdown instructions after the frontmatter,
- only uses supported frontmatter fields,
- uses lists for list-like fields such as `tags`, `paths`, and `allowed-tools`,
- uses a boolean value for `disable-model-invocation`.

Supported frontmatter fields include:

- `name`
- `description`
- `when_to_use`
- `allowed-tools`
- `disable-model-invocation`
- `argument-hint`
- `arguments`
- `paths`
- `model`
- `effort`
- `metadata`
- `compatibility`
- `license`
- `author`
- `version`
- `tags`

### Running tests

[](#running-tests)

```
composer test
```

### License

[](#license)

This library is licensed under the MIT license. Please see [LICENSE.md](LICENSE.md) for more details.

### Changelog

[](#changelog)

Please see [CHANGELOG.md](CHANGELOG.md) for more details.

### Inspiration

[](#inspiration)

This library idea is inspired by the work on [agent-skills-validator](https://github.com/ronaldtebrake/agent-skills-validator)by [ronaldtebrake](https://github.com/ronaldtebrake).

### Contributing

[](#contributing)

Please see [CONTRIBUTING.md](.github/CONTRIBUTING.md) for more details.

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance78

Regular maintenance activity

Popularity27

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~2 days

Total

6

Last Release

69d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/132faf5713fa951f4263fad02858a62e55c5d832ad775b33e49ba0cda2f2a028?d=identicon)[Raphael Stolt](/maintainers/Raphael%20Stolt)

---

Top Contributors

[![raphaelstolt](https://avatars.githubusercontent.com/u/48225?v=4)](https://github.com/raphaelstolt "raphaelstolt (26 commits)")

---

Tags

parsing-libraryphpskill-developmentskill-mdskill-md-libraryskill-md-validationvalidation-libraryphpaifilecontentvalidateparseparsingskillsvalidatingagent-skillsSKILL.mdskills directory

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/stolt-skill-validator/health.svg)

```
[![Health](https://phpackages.com/badges/stolt-skill-validator/health.svg)](https://phpackages.com/packages/stolt-skill-validator)
```

###  Alternatives

[blueimp/jquery-file-upload

File Upload widget for jQuery.

141.5M20](/packages/blueimp-jquery-file-upload)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
