Skip to content

test: share one skill-structure lint across the four plugin suites - #714

Merged
gtapps merged 2 commits into
mainfrom
chore/shared-skill-lint-module
Aug 14, 2026
Merged

test: share one skill-structure lint across the four plugin suites#714
gtapps merged 2 commits into
mainfrom
chore/shared-skill-lint-module

Conversation

@gtapps

@gtapps gtapps commented Aug 14, 2026

Copy link
Copy Markdown
Owner

Summary

The skill-structure lint existed in four copies and tests/test-utils.ts was byte-identical (md5 1ffd9c8f9149eb75ff6f86b886f5e4f2) in dev, fitness, and forge. Because the copies drifted independently, parser improvements never propagated: only feed's version folded YAML block scalars, so a description: >- in any dev/fitness/forge skill would have been read as the literal >- and failed lint as "description too short". This extracts the shared checks into one repo-root module and adopts feed's parser as the shared one.

Monorepo dev tooling only — never shipped to operators, which is why it may live at the repo root and cross plugin boundaries (same territory as tests/cross-plugin/). No CHANGELOG entries: root-scope and test-only changes aren't something an operator experiences.

Changes

  • New tests/lib/skill-lint.tsparseFrontmatter (dev's {raw, fields, body} shape + feed's block-scalar folding), makeReporter (moved verbatim from the deleted copies), and lintSkills(pluginRoot, skills). lintSkills is pure: it returns failure messages and never prints or exits, so both the console-reporter suites (dev/fitness/forge, which run each lint as its own bun process) and feed's bun test consume it without touching forge's shared-runner constraint.
  • Four per-plugin lints shrunk to expectations + their own checks — dev keeps its ${CLAUDE_PLUGIN_ROOT}/scripts/ dangling-reference check, fitness its CLAUDE-APPEND trim guard, forge its PHP-floor assertion; feed's first loop now calls lintSkills and its local parser is gone.
  • Three test-utils.ts copies deleted, with all five importers repointed.
  • CI: tests/lib/** added to the path filters of test-dev, test-fitness, test-forge, test-feed, and test-cross-plugin; previously an edit to shared test code matched no filter and ran in zero suites. The cross-plugin job also runs tests/lib/.

Side effect worth noting: feed's per-skill checks previously asserted only name/description; routing through lintSkills also applies the gate-count and internal-link checks to its skills. That's an expansion of what CI enforces for that plugin, consistent with the other three.

Test plan

All run and green on the rebased branch:

  • bash tests/run-all.sh in claude-code-dev-hermit (13 passed), claude-code-fitness-hermit (129 passed), laravel-forge-hermit (13 passed, incl. PHP suite) — exit 0 each
  • bun test in feed-hermit — 54 passed
  • bun test tests/lib/ tests/cross-plugin/ — 110 passed
  • bunx tsc --noEmit from repo root (strict) — exit 0
  • Mutation check: changing dev's dev-pr expectation from 5 gates to 4 fails with dev-pr: expected 4 Gate headers, found 5; reverted and green

gtapps added 2 commits August 14, 2026 10:08
The lint existed four times and test-utils.ts was byte-identical in three
plugins, so parser fixes never propagated: only feed's copy folded YAML block
scalars, meaning a `description: >-` in any dev/fitness/forge skill would have
failed lint as "too short". tests/lib/skill-lint.ts now owns the shared checks
with feed's parser, and lintSkills returns failures rather than exiting, so the
console-runner suites and feed's bun:test both consume it without touching
forge's shared-runner constraint. Per-plugin files keep only their expectations
and genuinely plugin-specific checks.

The four plugin workflows plus the cross-plugin one now trigger on tests/lib/**,
which previously matched no path filter at all.
The shared lint's frontmatter parser stopped folding a block scalar at the
first blank line, silently truncating a multi-paragraph description to its
first paragraph — latent for today's skills, but this parser now backs four
plugin suites. tsconfig also excluded tests/, so the module's own test file
was never type-checked.
@gtapps
gtapps merged commit 0a20e8f into main Aug 14, 2026
15 checks passed
@gtapps
gtapps deleted the chore/shared-skill-lint-module branch August 14, 2026 09:25
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