@@ -19,7 +19,11 @@ composer require stolt/skill-validator
1919
2020## Usage
2121
22- The validator can validate either existing ` SKILL.md ` files or raw ` SKILL.md ` content.
22+ The ` SkillMd ` class from the [ stolt/skill-md] ( https://github.com/raphaelstolt/skill-md/ ) package is the primary
23+ abstraction for a validated skill: every valid result exposes a ` SkillMd ` instance, and the validator also accepts
24+ ` SkillMd ` instances directly as input.
25+
26+ The validator can validate existing ` SKILL.md ` files, raw ` SKILL.md ` content, or ` SkillMd ` instances.
2327
2428### Validating a ` SKILL.md ` file
2529
@@ -60,14 +64,31 @@ $validator = new Validator();
6064$result = $validator->validateContent('raw-skill-content');
6165```
6266
67+ ### Validating a ` SkillMd ` instance
68+
69+ ``` php
70+ use Stolt\Ai\Skill\Validator;
71+ use Stolt\Ai\SkillMd;
72+
73+ $skillMd = SkillMd::create(
74+ 'code-review',
75+ 'Review code changes and provide actionable feedback.',
76+ "# Code review\n\nReview the changed files and report issues.",
77+ ['tags' => ['php', 'review'], 'version' => '1.0.0']
78+ );
79+
80+ $validator = new Validator();
81+ $result = $validator->validateSkillMd($skillMd);
82+ ```
83+
6384> [ !TIP]
64- > The ` validate ` alias method accepts either a file path, directory path, or raw content and delegates to the
65- > appropriate method automatically.
85+ > The ` validate ` alias method accepts a file path, directory path, raw content, or a ` SkillMd ` instance and delegates
86+ > to the appropriate method automatically.
6687
6788### Accessing validation results and metadata
6889
69- Validation returns a ` Stolt\Ai\Skill\ValidationResult ` object. When the ` SKILL.md ` content contains the required ` name `
70- and ` description ` fields, the parsed metadata is exposed as a ` Stolt\Ai\Skill\Metadata ` object.
90+ Validation returns a ` Stolt\Ai\Skill\ValidationResult ` object. When the ` SKILL.md ` content is valid, a ` SkillMd `
91+ instance is available directly. The parsed metadata is also accessible as a ` Stolt\Ai\Skill\Metadata ` object.
7192
7293``` php
7394use Stolt\Ai\Skill\Validator;
@@ -78,28 +99,30 @@ $result = $validator->validateContent('raw-skill-content');
7899if ($result->isInvalid()) {
79100 foreach ($result->errors() as $error) {
80101 echo $error . PHP_EOL;
81- }
102+ }
82103 // Raw metadata can still be inspected when parsing succeeded but validation failed.
83104 $rawMetadata = $result->rawMetadata();
84105 exit(1);
85- }
106+ }
86107
87- $metadata = $result->metadata();
108+ // Primary SkillMd abstraction — available on every valid result.
109+ $skillMd = $result->skillMd(); // returns ?SkillMd (null when invalid)
88110
89- if ($metadata === null) {
90- throw new RuntimeException('Expected validated SKILL.md metadata.');
91- }
111+ // Or assert the SkillMd directly, which throws a LogicException when the result is invalid.
112+ $skillMd = $result->toSkillMd();
92113
93- // Required SKILL.md metadata fields.
94- $name = $metadata->name();
95- $description = $metadata->description();
114+ // Use the SkillMd instance.
115+ $name = $skillMd->name();
116+ $description = $skillMd->description();
117+ $body = $skillMd->body();
118+ $tags = $skillMd->tags();
119+ $version = $skillMd->version();
96120
97- // Optional SKILL.md metadata fields.
98- $version = $metadata->version();
99- $tags = $metadata->tags();
100- $allowedTools = $metadata->get('allowed-tools', []);
101- $model = $metadata->get('model');
102- $effort = $metadata->get('effort');
121+ // Metadata object for field access with defaults.
122+ $metadata = $result->metadata();
123+ $allowedTools = $metadata?->get('allowed-tools', []);
124+ $model = $metadata?->get('model');
125+ $effort = $metadata?->get('effort');
103126
104127// Markdown instructions after the YAML frontmatter.
105128$instructions = $result->body();
@@ -110,20 +133,28 @@ $arrayResult = $result->toArray();
110133echo sprintf('Skill "%s" is valid: %s', $name, $description) . PHP_EOL;
111134```
112135
113- For an actual integration, the project [ list-skills-command ] ( https://github.com/raphaelstolt/list-skills-command ) can also be consolidated.
136+ ### Round-tripping between content and ` SkillMd `
114137
115- > [ !TIP ]
116- > As of version ` 0.0.5 ` you can use the ` toSkillMd() ` method to collect a populated ` SkillMd ` instance of the [ stolt/skill-md ] ( https://github.com/raphaelstolt/skill-md/ ) package.
138+ Because ` validateSkillMd() ` accepts a ` SkillMd ` instance and ` toSkillMd() ` returns one, validation results and
139+ ` SkillMd ` objects round-trip cleanly:
117140
118141``` php
119142use Stolt\Ai\Skill\Validator;
120143
121144$validator = new Validator();
122- $result = $validator->validateContent('raw-skill-content');
123145
146+ // Parse and validate raw content.
147+ $result = $validator->validateContent($rawContent);
148+
149+ // Obtain the primary SkillMd abstraction.
124150$skillMd = $result->toSkillMd();
151+
152+ // Re-validate the SkillMd — e.g. after modifying it.
153+ $revalidated = $validator->validateSkillMd($skillMd);
125154```
126155
156+ For an actual integration, the project [ list-skills-command] ( https://github.com/raphaelstolt/list-skills-command ) can also be consolidated.
157+
127158## Validation rules
128159
129160The validator checks that a ` SKILL.md ` document:
0 commit comments