skill-check 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +360 -0
  3. package/bin/skill-check.js +11 -0
  4. package/dist/cli/main.d.ts +5 -0
  5. package/dist/cli/main.js +724 -0
  6. package/dist/core/agent-scan.d.ts +19 -0
  7. package/dist/core/agent-scan.js +88 -0
  8. package/dist/core/allowlist.d.ts +1 -0
  9. package/dist/core/allowlist.js +8 -0
  10. package/dist/core/analyze.d.ts +6 -0
  11. package/dist/core/analyze.js +72 -0
  12. package/dist/core/artifact.d.ts +2 -0
  13. package/dist/core/artifact.js +33 -0
  14. package/dist/core/baseline.d.ts +8 -0
  15. package/dist/core/baseline.js +17 -0
  16. package/dist/core/config.d.ts +2 -0
  17. package/dist/core/config.js +215 -0
  18. package/dist/core/defaults.d.ts +6 -0
  19. package/dist/core/defaults.js +34 -0
  20. package/dist/core/discovery.d.ts +2 -0
  21. package/dist/core/discovery.js +46 -0
  22. package/dist/core/duplicates.d.ts +2 -0
  23. package/dist/core/duplicates.js +60 -0
  24. package/dist/core/errors.d.ts +4 -0
  25. package/dist/core/errors.js +8 -0
  26. package/dist/core/fix.d.ts +11 -0
  27. package/dist/core/fix.js +172 -0
  28. package/dist/core/formatters.d.ts +4 -0
  29. package/dist/core/formatters.js +182 -0
  30. package/dist/core/frontmatter.d.ts +7 -0
  31. package/dist/core/frontmatter.js +39 -0
  32. package/dist/core/github-formatter.d.ts +2 -0
  33. package/dist/core/github-formatter.js +10 -0
  34. package/dist/core/html-report.d.ts +3 -0
  35. package/dist/core/html-report.js +320 -0
  36. package/dist/core/interactive-fix.d.ts +9 -0
  37. package/dist/core/interactive-fix.js +22 -0
  38. package/dist/core/links.d.ts +17 -0
  39. package/dist/core/links.js +94 -0
  40. package/dist/core/open-browser.d.ts +6 -0
  41. package/dist/core/open-browser.js +20 -0
  42. package/dist/core/plugins.d.ts +2 -0
  43. package/dist/core/plugins.js +41 -0
  44. package/dist/core/quality-score.d.ts +14 -0
  45. package/dist/core/quality-score.js +55 -0
  46. package/dist/core/report.d.ts +2 -0
  47. package/dist/core/report.js +26 -0
  48. package/dist/core/rule-engine.d.ts +2 -0
  49. package/dist/core/rule-engine.js +52 -0
  50. package/dist/core/sarif.d.ts +2 -0
  51. package/dist/core/sarif.js +48 -0
  52. package/dist/index.d.ts +11 -0
  53. package/dist/index.js +8 -0
  54. package/dist/rules/core/body.d.ts +2 -0
  55. package/dist/rules/core/body.js +39 -0
  56. package/dist/rules/core/description.d.ts +2 -0
  57. package/dist/rules/core/description.js +66 -0
  58. package/dist/rules/core/file.d.ts +2 -0
  59. package/dist/rules/core/file.js +26 -0
  60. package/dist/rules/core/frontmatter.d.ts +2 -0
  61. package/dist/rules/core/frontmatter.js +124 -0
  62. package/dist/rules/core/index.d.ts +2 -0
  63. package/dist/rules/core/index.js +12 -0
  64. package/dist/rules/core/links.d.ts +2 -0
  65. package/dist/rules/core/links.js +54 -0
  66. package/dist/types.d.ts +92 -0
  67. package/dist/types.js +1 -0
  68. package/package.json +82 -0
  69. package/schemas/config.schema.json +53 -0
  70. package/skills/skill-check/SKILL.md +76 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 David Dias
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,360 @@
1
+ # skill-check
2
+
3
+ Linter for agent skill files — validates SKILL.md files against the spec with extensible custom rules.
4
+
5
+ ![skill-check demo](docs/assets/skill-check-demo.gif)
6
+
7
+ Regenerate with `pnpm run demo:readme` (source: `scripts/readme-demo.tape`).
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npx skill-check check .
13
+ ```
14
+
15
+ Global install via curl:
16
+
17
+ ```bash
18
+ curl -fsSL https://raw.githubusercontent.com/thedaviddias/skill-check/main/scripts/install.sh | bash
19
+ ```
20
+
21
+ Install via Homebrew:
22
+
23
+ ```bash
24
+ brew tap thedaviddias/skill-check https://github.com/thedaviddias/skill-check
25
+ brew install skill-check
26
+ ```
27
+
28
+ ## Commands
29
+
30
+ | Command | Description |
31
+ |---|---|
32
+ | `skill-check check [path]` | Run validation (and optional security scan) |
33
+ | `skill-check new <name>` | Scaffold a new skill directory with SKILL.md template |
34
+ | `skill-check watch [path]` | Watch for changes and re-run validation on save |
35
+ | `skill-check diff <a> <b>` | Compare diagnostics between two skill directories |
36
+ | `skill-check report [path]` | Generate a markdown health report |
37
+ | `skill-check rules [id]` | List all rules, or show detail for a specific rule |
38
+ | `skill-check security-scan [path]` | Run security scan via agent-scan (mcp-scan) |
39
+ | `skill-check init` | Create `skill-check.config.json` template |
40
+
41
+ ### check options
42
+
43
+ | Flag | Description |
44
+ |---|---|
45
+ | `--fix` | Apply safe automatic fixes for supported findings |
46
+ | `--fix --interactive` | Prompt before applying each fix (TTY only) |
47
+ | `--baseline <path>` | Compare against a previous JSON run and show new/fixed counts |
48
+ | `--format <fmt>` | Output format (see below) |
49
+ | `--no-open` | Skip auto-opening HTML reports |
50
+ | `--no-security-scan` | Skip the security scan |
51
+ | `--strict` | Treat warnings as errors |
52
+ | `--lenient` | Relax selected strict rules |
53
+ | `--fail-on-warning` | Exit non-zero when warnings exist |
54
+
55
+ ## Output Formats
56
+
57
+ | Format | Description |
58
+ |---|---|
59
+ | `text` | Colorized terminal output with ASCII tables, severity badges, and quality scores (default) |
60
+ | `json` | Machine-readable output including quality scores and optional baseline diff |
61
+ | `sarif` | SARIF format for security tooling and GitHub Code Scanning |
62
+ | `html` | Self-contained HTML report with scores, filtering, and dark mode |
63
+ | `github` | `::error` / `::warning` annotations for GitHub Actions |
64
+
65
+ **HTML reports** are written to `skill-check-report.html` (or `output.reportPath`). In an interactive terminal the report opens in your browser automatically; use `--no-open` to skip.
66
+
67
+ **View locally:** `npx skill-check check . --format html` or open the file directly: `open skill-check-report.html` (macOS).
68
+
69
+ The `text` formatter includes quality score bars per skill, colorized severity badges, and boxed summaries.
70
+ An ASCII CLI banner is shown in interactive text mode; set `SKILL_CHECK_NO_BANNER=1` to disable it.
71
+
72
+ ## Quality Scores
73
+
74
+ Every `check` run computes a quality score (0-100) per skill based on five weighted categories:
75
+
76
+ | Category | Weight | What it measures |
77
+ |---|---|---|
78
+ | Frontmatter | 30% | Required fields, naming, ordering |
79
+ | Description | 30% | Length, "Use when" phrasing |
80
+ | Body | 20% | Line/token limits |
81
+ | Links | 10% | Broken local and reference links |
82
+ | File | 10% | Trailing newlines, formatting |
83
+
84
+ Scores appear in `text`, `html`, and `json` output.
85
+
86
+ ## Duplicate Detection
87
+
88
+ When multiple skills share the same `name` or identical `description`, `check` emits `duplicates.name` / `duplicates.description` warnings so agents can reliably differentiate skills.
89
+
90
+ ## Baseline Comparison
91
+
92
+ Save a JSON run as a baseline and compare later:
93
+
94
+ ```bash
95
+ npx skill-check check . --format json --no-security-scan > baseline.json
96
+ # ... make changes ...
97
+ npx skill-check check . --baseline baseline.json --no-security-scan
98
+ ```
99
+
100
+ Output shows how many diagnostics are new, fixed, or unchanged.
101
+
102
+ ## Quick Start
103
+
104
+ ```bash
105
+ pnpm install
106
+ pnpm run check
107
+ pnpm run report
108
+ ```
109
+
110
+ Generate real CLI outputs from multi-skill fixtures:
111
+
112
+ ```bash
113
+ pnpm run smoke:cli
114
+ ```
115
+
116
+ Smoke output files are written to `reports/smoke/`.
117
+ Smoke includes a real security scan run by default.
118
+ Smoke also includes a real `--fix` run on a temp copy of the failing mixed fixture.
119
+ You can control smoke output colors with `SMOKE_COLOR=always|auto|never`.
120
+ You can set `SMOKE_SECURITY_SCAN=0` to skip security smoke and `SMOKE_SECURITY_SCAN_RUNNER=auto|local|uvx|pipx` to choose the runner (default: `pipx`).
121
+ Use `SMOKE_SECURITY_SCAN_SKILLS=/path/to/skills` to override the skills path scanned in smoke mode.
122
+
123
+ Create config with guided setup:
124
+
125
+ ```bash
126
+ npx skill-check init --interactive
127
+ ```
128
+
129
+ ## Security Scan
130
+
131
+ `skill-check` can validate repos or direct skills directories:
132
+
133
+ ```bash
134
+ npx skill-check check /path/to/repo
135
+ npx skill-check check ~/.claude/skills
136
+ ```
137
+
138
+ `check` runs the security scan by default.
139
+ If dependencies are missing, `skill-check` asks before installing in interactive terminals.
140
+ In non-interactive/CI environments, use `--allow-installs` to permit automatic installs.
141
+
142
+ Run security scan without UV by forcing `pipx`:
143
+
144
+ ```bash
145
+ npx skill-check security-scan . --security-scan-runner pipx --allow-installs
146
+ ```
147
+
148
+ Run validation + security scan in one pipeline step with explicit runner:
149
+
150
+ ```bash
151
+ npx skill-check check . --security-scan-runner pipx
152
+ ```
153
+
154
+ Skip security scan for local/offline linting:
155
+
156
+ ```bash
157
+ npx skill-check check . --no-security-scan
158
+ ```
159
+
160
+ Apply safe auto-fixes and then re-run validation:
161
+
162
+ ```bash
163
+ npx skill-check check . --fix --no-security-scan
164
+ ```
165
+
166
+ Interactively choose which fixes to apply:
167
+
168
+ ```bash
169
+ npx skill-check check . --fix --interactive --no-security-scan
170
+ ```
171
+
172
+ Scaffold a new skill:
173
+
174
+ ```bash
175
+ npx skill-check new my-skill
176
+ ```
177
+
178
+ Watch for changes during development:
179
+
180
+ ```bash
181
+ npx skill-check watch . --no-security-scan
182
+ ```
183
+
184
+ Compare two skill directories:
185
+
186
+ ```bash
187
+ npx skill-check diff skills/ other-skills/
188
+ ```
189
+
190
+ Use GitHub annotations in CI:
191
+
192
+ ```bash
193
+ npx skill-check check . --format github --no-security-scan
194
+ ```
195
+
196
+ Hard-block dependency installs:
197
+
198
+ ```bash
199
+ npx skill-check check . --no-installs
200
+ ```
201
+
202
+ ## Auto-fix Coverage
203
+
204
+ `--fix` currently handles deterministic formatting/metadata issues:
205
+
206
+ - `frontmatter.required`
207
+ - `frontmatter.name_required`
208
+ - `frontmatter.description_required`
209
+ - `frontmatter.name_matches_directory`
210
+ - `frontmatter.name_slug_format`
211
+ - `frontmatter.field_order`
212
+ - `description.use_when_phrase`
213
+ - `description.min_recommended_length`
214
+ - `file.trailing_newline_single`
215
+
216
+ Rules requiring human intent (content quality, max-length trimming, broken links, or oversized bodies) remain manual and are reported after fixes are applied.
217
+
218
+ Use `--fix --interactive` for per-diagnostic approval prompts (requires TTY).
219
+
220
+ ## GitHub Action
221
+
222
+ Use `skill-check` directly in workflows:
223
+
224
+ Marketplace status: not listed in GitHub Marketplace yet.
225
+ Supported usage today is direct repo tags (`uses: thedaviddias/skill-check@v1` or `@v1.x.y`).
226
+ See `docs/github-action-publishing.md` for the publication playbook.
227
+
228
+ ```yaml
229
+ name: skill-check
230
+
231
+ on:
232
+ pull_request:
233
+ push:
234
+ branches: [main]
235
+
236
+ jobs:
237
+ validate:
238
+ runs-on: ubuntu-latest
239
+ steps:
240
+ - uses: actions/checkout@v4
241
+ - uses: thedaviddias/skill-check@v1
242
+ with:
243
+ path: .
244
+ ```
245
+
246
+ Use `--format github` for inline annotations on PRs:
247
+
248
+ ```yaml
249
+ - run: npx skill-check check . --format github --no-security-scan
250
+ ```
251
+
252
+ Enable security scan explicitly (default is disabled in the action):
253
+
254
+ ```yaml
255
+ name: skill-check-security
256
+
257
+ on:
258
+ pull_request:
259
+
260
+ jobs:
261
+ validate:
262
+ runs-on: ubuntu-latest
263
+ steps:
264
+ - uses: actions/checkout@v4
265
+ - uses: thedaviddias/skill-check@v1
266
+ with:
267
+ path: .
268
+ security-scan: "true"
269
+ security-scan-install-policy: allow
270
+ security-scan-runner: pipx
271
+ ```
272
+
273
+ Emit SARIF and upload to GitHub Code Scanning:
274
+
275
+ ```yaml
276
+ name: skill-check-sarif
277
+
278
+ on:
279
+ pull_request:
280
+ push:
281
+ branches: [main]
282
+
283
+ permissions:
284
+ contents: read
285
+ security-events: write
286
+
287
+ jobs:
288
+ validate:
289
+ runs-on: ubuntu-latest
290
+ steps:
291
+ - uses: actions/checkout@v4
292
+ - id: skillcheck
293
+ uses: thedaviddias/skill-check@v1
294
+ with:
295
+ path: .
296
+ format: sarif
297
+ sarif-file: reports/skill-check.sarif.json
298
+ - uses: github/codeql-action/upload-sarif@v3
299
+ with:
300
+ sarif_file: ${{ steps.skillcheck.outputs.sarif-file }}
301
+ ```
302
+
303
+ The action outputs:
304
+
305
+ - `exit-code`: CLI exit code
306
+ - `sarif-file`: absolute path to SARIF file when `format=sarif`
307
+ - `command`: full command used for execution
308
+
309
+ `format=sarif` cannot be combined with `security-scan=true` in the action because security scan output is not SARIF.
310
+
311
+ ## Action Release Checklist
312
+
313
+ 1. Ensure `main` contains the desired `action.yml` and `github-action/index.js`.
314
+ 2. Create and push an immutable version tag (example: `v1.2.0`).
315
+ 3. Move the major tag to the latest stable release (`v1` -> `v1.2.0` commit).
316
+ 4. Verify a workflow using `uses: thedaviddias/skill-check@v1` resolves the updated action.
317
+
318
+ ## Rules Reference
319
+
320
+ Run `skill-check rules` to see all built-in rules with severity and fixable status.
321
+ Run `skill-check rules <id>` for detail on a specific rule.
322
+
323
+ | Rule | Default | Fixable |
324
+ |---|---|---|
325
+ | `frontmatter.required` | error | yes |
326
+ | `frontmatter.name_required` | error | yes |
327
+ | `frontmatter.description_required` | error | yes |
328
+ | `frontmatter.name_matches_directory` | error | yes |
329
+ | `frontmatter.name_slug_format` | error | yes |
330
+ | `frontmatter.field_order` | error | yes |
331
+ | `description.max_length` | error | no |
332
+ | `description.use_when_phrase` | warn | yes |
333
+ | `description.min_recommended_length` | warn | yes |
334
+ | `body.max_lines` | error | no |
335
+ | `body.max_tokens` | warn | no |
336
+ | `file.trailing_newline_single` | warn | yes |
337
+ | `links.local_markdown_resolves` | warn | no |
338
+ | `links.references_resolve` | warn | no |
339
+ | `duplicates.name` | warn | no |
340
+ | `duplicates.description` | warn | no |
341
+
342
+ All rules emit actionable `suggestion` text to guide fixes.
343
+
344
+ ## Releasing
345
+
346
+ Releases are automated with [semantic-release](https://github.com/semantic-release/semantic-release). Pushing to `main` (after CI passes) runs the release workflow: commits are analyzed for [Conventional Commits](https://www.conventionalcommits.org/) (`fix:`, `feat:`, `BREAKING CHANGE:`), the version is bumped, `CHANGELOG.md` is updated, the package is published to npm, and a GitHub release is created.
347
+
348
+ - **Commit messages** are validated locally by [commitlint](https://commitlint.js.org/) (enforced by the `commit-msg` hook). Use `fix:`, `feat:`, `docs:`, `chore:`, etc.
349
+ - **Secrets:** In GitHub, set the `NPM_TOKEN` repository secret (npm automation token with publish scope) so the workflow can publish to npm. `GITHUB_TOKEN` is provided automatically.
350
+
351
+ To simulate a release locally (without publishing): `pnpm run release:dry-run`. It will fail `verifyConditions` without `NPM_TOKEN` and `GITHUB_TOKEN`; in CI both are set.
352
+
353
+ ## Docs
354
+
355
+ - `docs/quickstart.md`
356
+ - `docs/github-action-publishing.md`
357
+ - `docs/config.md`
358
+ - `docs/rules.md`
359
+ - `docs/plugins.md`
360
+ - `docs/migration-from-agent-forge.md`
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from '../dist/cli/main.js';
3
+
4
+ runCli(process.argv.slice(2))
5
+ .then((code) => {
6
+ process.exit(code);
7
+ })
8
+ .catch((error) => {
9
+ console.error(error instanceof Error ? error.message : String(error));
10
+ process.exit(2);
11
+ });
@@ -0,0 +1,5 @@
1
+ export interface CliIO {
2
+ stdout: (text: string) => void;
3
+ stderr: (text: string) => void;
4
+ }
5
+ export declare function runCli(argv: string[], io?: CliIO): Promise<number>;