Skip to content

Add ESLint plugins for Agent Skills frontmatter validation#67

Merged
gtbuchanan merged 1 commit into
mainfrom
feature/eslint-skills
Apr 25, 2026
Merged

Add ESLint plugins for Agent Skills frontmatter validation#67
gtbuchanan merged 1 commit into
mainfrom
feature/eslint-skills

Conversation

@gtbuchanan
Copy link
Copy Markdown
Owner

@gtbuchanan gtbuchanan commented Apr 25, 2026

Summary

Adds two new packages that compose to validate SKILL.md files at lint time:

  • @gtbuchanan/eslint-plugin-md-frontmatter — generic. One rule, md-frontmatter/schema, validates Markdown YAML frontmatter against any JSON Schema via ajv. Each error is mapped back to the offending YAML node range for inline reporting.
  • @gtbuchanan/eslint-plugin-agent-skills — focused. Ships:
    • skillFrontmatterSchema — the Agent Skills JSON Schema as a real .json file with $id set to a future canonical URL.
    • agent-skills/name-matches-dir — the one spec constraint pure schemas can't express.
    • configs.recommended — a ready-to-spread flat-config block that wires both plugins plus core max-lines: 500 for **/skills/*/SKILL.md. One-line setup for consumers: [...configs.recommended].

eslint-config delegates to configs.recommended. ajv ^8.20.0 added to the workspace catalog. resolveJsonModule: true moved to the shared @gtbuchanan/tsconfig/node.json so consumers get JSON imports by default.

Plugin-level RuleTester unit tests (test/*.test.ts per package) cover rule behavior. End-to-end coverage in eslint-config/e2e/skill.test.ts exercises the fully-wired pipeline against synthetic SKILL.md fixtures.

CHANGELOG.md stubs added to both new packages matching the existing format. No changeset — these will land as initial 0.1.0 entries on first release.

Relates to #41 — sets up the lint-side validation that #41 calls out as a CI checklist item. Follow-up rules tracked in #68.

Test plan

  • pnpm install && pnpm check — 32/32 turbo tasks green
  • pnpm test:e2e — 24 e2e tests pass (18 existing + 6 new SKILL.md cases)
  • Rules fire on a synthetic bad SKILL.md (uppercase name, missing description, unknown extra field, mismatched parent dir):
    mkdir -p packages/cli/skills/test-bad
    printf -- '---\nname: WrongName\nunknown: foo\n---\n# Body\n' \
      > packages/cli/skills/test-bad/SKILL.md
    pnpm -C packages/cli exec eslint --no-cache skills/test-bad/SKILL.md
    rm -rf packages/cli/skills/test-bad
    Confirmed: 4 plugin warnings + 1 Prettier warning at 2:1 (missing description), 2:7 (name pattern + dir mismatch), 3:1 (unknown field), 5:1 (no trailing newline).
  • Existing packages/cli/skills/gtb-build-pipeline/SKILL.md lints clean
  • src/schema.json is shipped in the eslint-plugin-agent-skills tarball (verified via tar -tzf)

🤖 Generated with Claude Code

Adds two new packages that compose to validate SKILL.md files:

- @gtbuchanan/eslint-plugin-md-frontmatter — generic. One rule
  `md-frontmatter/schema` validates Markdown YAML frontmatter
  against any JSON Schema via ajv, mapping each error to the
  YAML node range for inline reporting.
- @gtbuchanan/eslint-plugin-agent-skills — focused. Exports
  `skillFrontmatterSchema` (the Agent Skills JSON Schema, with
  `$id` set to a future canonical URL) and ships
  `agent-skills/name-matches-dir` for the one spec constraint
  pure schemas can't express (name === parent directory name).

Wires both into eslint-config for `**/skills/*/SKILL.md`
alongside core `max-lines: 500` for file-length enforcement per
the spec.

Adds ajv ^8.20.0 to the workspace catalog.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@gtbuchanan gtbuchanan force-pushed the feature/eslint-skills branch from b408c45 to 9fc2a16 Compare April 25, 2026 16:16
@gtbuchanan gtbuchanan marked this pull request as ready for review April 25, 2026 16:17
@gtbuchanan gtbuchanan merged commit 2872195 into main Apr 25, 2026
7 of 8 checks passed
@gtbuchanan gtbuchanan deleted the feature/eslint-skills branch April 25, 2026 16:26
gtbuchanan added a commit that referenced this pull request Apr 28, 2026
Add the initial-release changelog stub that every other publishable
package has. Convention reinforced in #67. No functional impact.

Closes #69
gtbuchanan added a commit that referenced this pull request Apr 28, 2026
Strip the auto-generated `a135a59:` commit prefix from the Initial
release entries in eslint-config, tsconfig, and vitest-config. The
hash references the changesets pipeline-bootstrap commit (PR #1),
not an actual release — nothing has been published to npm yet, and
`changeset version` only appends new entries, so it would never
overwrite these stale prefixes.

Also drop the orphaned `Patch Changes` block from eslint-config that
referenced @gtbuchanan/oxlint-config@0.1.0; that package was replaced
by regular ESLint in #43.

Aligns these stubs with the bare `- Initial release` form used by the
newer packages added in #67.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant