Align output with the agentskills.io specification#6
Merged
Conversation
Brings skillgen's output and validation in line with https://agentskills.io/specification. Four coordinated changes. Directory layout ---------------- Skills now write as <name>/SKILL.md inside the target directory instead of a flat <name>.md. This is what the spec requires — and, not coincidentally, what Claude Code's skill loader actually looks for. Skills generated by prior versions were ignored by real loaders, which explains reports that agents never found them. Skill.Filename → Skill.Path, holding the full relative path (<prefix><name>/SKILL.md). Skill.Dir() returns the directory name. WriteTo creates the subdirectory before writing the file. Spec-standard frontmatter ------------------------- Three new annotations fill the gaps we had under every target: - skill.license → `license:` field (SPDX name or bundled file ref). - skill.compatibility → `compatibility:` field (env requirements, max 500 chars). - skill.metadata.<key> → `metadata:` map, prefix pattern so authors can add arbitrary keys without a wrapper API. Keys emitted sorted for determinism. FrontmatterField gains a Map field for map-typed values; writeFrontmatterField dispatches between scalar and map emission. targetFrontmatter is replaced by buildFrontmatter, which composes spec-standard fields first and target-specific ones second. Spec-limit lint rules --------------------- Generator.Lint now rounds out the previous per-command checks with spec-enforcement against the rendered skills: - name empty / > 64 chars / bad format → error (hard spec rule; invalid names break loaders, which is why we promote to error rather than warning). - description empty / > 1024 chars → error. - compatibility > 500 chars → error. - body > 5000 tokens → warning (spec recommendation). - body > 500 lines → warning (spec recommendation). skillNamePattern matches ^[a-z0-9]+(?:-[a-z0-9]+)*$ — enforces lowercase alphanumerics and hyphens with no leading/trailing/ consecutive hyphens, exactly as the spec requires. SpecMax* constants are exported so consumers writing their own validation can mirror the same limits. Per-skill budget warnings ------------------------- `skills generate` now warns once per skill whose body exceeds the 5000-token spec recommendation, in addition to the existing aggregate warning. The aggregate threshold was misleading: a CLI with 20 small skills could stay under the aggregate cap while each leaf still burned too much context on its own. Tests ----- 14 new tests in spec_test.go covering directory layout, prefixed directories, split-mode layout, all three new frontmatter annotations (with sorted key emission and empty-value filtering), and every new lint rule (positive + negative cases). Docs ---- README gains an "Output layout" section, rewritten annotations table including license / compatibility / metadata / allowed-tools, and a Linting section call-out for spec enforcement. CHANGELOG under Unreleased gets Changed (breaking) and Added entries.
Windows CI failed because filepath.Join uses backslash there, so Skill.Path came out "mytool\SKILL.md" and the exact-string tests fell over. More importantly, Skill.Path is a manifest-style identifier that ships in YAML and git — it should be platform- neutral regardless of where skills generate runs. Switch to path.Join / path.Dir (always forward slash) for Skill.Path and Skill.Dir. WriteTo still uses filepath.Join(dir, s.Path) at write time, which correctly converts to OS-specific separators.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings skillgen's output and validation in line with https://agentskills.io/specification. Four coordinated changes. The output-layout change is breaking but targeted — no public consumers depend on the old
<name>.mdflat form yet.Directory layout (breaking)
Skills now write as
<name>/SKILL.mdinside the target directory instead of a flat<name>.md. This is what the spec requires and what Claude Code's skill loader actually looks for. Skills from prior versions were silently ignored by real loaders.Skill.Filename→Skill.Path(<prefix><name>/SKILL.md).Skill.Dir()returns the directory name.WriteTocreates the subdirectory before writing.Spec-standard frontmatter
Three new annotations under every target:
skill.license→license:skill.compatibility→compatibility:(max 500 chars)skill.metadata.<key>→metadata:map, prefix-pattern so authors add arbitrary keys without a wrapper API. Keys emitted in sorted order.FrontmatterFieldgains aMapfield; scalar vs. map emission dispatched inwriteFrontmatterField.targetFrontmatter→buildFrontmatter, composing spec-standard fields first and target extensions second.Spec-limit lint rules
Generator.Lint()now also checks the rendered skills against spec hard/soft limits:skillNamePatternenforces the spec regex^[a-z0-9]+(?:-[a-z0-9]+)*$.SpecMax*constants exported for external consumers.Per-skill budget warnings
skills generatenow emits a per-skill warning when any one skill body exceeds the 5000-token spec recommendation, alongside the existing aggregate warning. The aggregate alone was misleading: a CLI with many small skills could stay under the aggregate cap while individual leaves still burned too much context.Test plan
go build ./...go test ./...— 14 new tests inspec_test.gopass alongside existing suitego vet ./...golangci-lint run ./...— 0 issuesgo run ./example skills generate --dir /tmp/outproduces/tmp/out/mytool/SKILL.mdwith valid spec frontmattergo run ./example skills lintstill passes without errors on the test CLIMigration (for any consumers)
Skill.Filename→Skill.Path;Pathnow contains the directory too.<dir>/<name>.mdshould read<dir>/<name>/SKILL.md.