@spardutti/claude-skills 2.24.0 → 2.25.1

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 (2) hide show
  1. package/README.md +67 -236
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -1,22 +1,31 @@
1
1
  # Claude Skills
2
2
 
3
- > **Make Claude Code write like a senior engineer who actually keeps up.**
3
+ Guardrails for Claude Code — best-practice skills, planning commands, and delivery gates.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@spardutti/claude-skills)](https://www.npmjs.com/package/@spardutti/claude-skills)
6
6
  [![npm downloads](https://img.shields.io/npm/dm/@spardutti/claude-skills)](https://www.npmjs.com/package/@spardutti/claude-skills)
7
7
  [![license](https://img.shields.io/npm/l/@spardutti/claude-skills)](./LICENSE)
8
8
 
9
- Opinionated, always-current best-practice playbooks that load while Claude codes — so it writes today's idioms for the tools you actually use, not the averaged, two-years-stale code its training defaults to. This repo is the source catalog; the CLI installs exactly what each project needs from an interactive menu, pulling in any subagents your chosen commands depend on.
9
+ Coding agents are good at writing code. They are much worse at holding to
10
+ engineering discipline — reading the codebase before changing it, keeping to
11
+ current idioms, proving a test would actually catch a break.
10
12
 
11
- ## Why This Exists
12
-
13
- Coding agents don't fail because they can't code — they fail because they write **dated** code. A model's knowledge is frozen and averaged: ask for React and it reaches for `useEffect` and manual `useMemo`; ask for TypeScript and it assumes 5.x; it defaults to patterns that were fine two years ago and are wrong today.
14
-
15
- The ecosystem's answer has been **process** — planning frameworks, spec-driven workflows, agent orchestration. Those steer *how* the agent works. None of them fix *what the code looks like*.
13
+ This installs both halves into your project: **current technical guidance**, and
14
+ **the enforcement that makes it stick**. Guidance your agent can skip is a
15
+ suggestion. Every skill here loads behind a hook that requires it to be applied,
16
+ and nothing reaches a PR without passing a gate that ran for real.
16
17
 
17
- **This is the other half.** Each skill is a tight, opinionated playbook that pins Claude to current, senior-level practice for one tool — React 19.2 + the React Compiler, TypeScript 7.0, TanStack Query v5, Drizzle, FastAPI, SQL. Claude loads only the skills a task touches, so many can stay installed cheaply. Bring whatever planning framework you like on top; this makes sure the code that comes out isn't 2023-vintage.
18
+ ## Contents
18
19
 
19
- **Freshness is the feature.** These track the changelogs as the tools move — the React Compiler going stable, TS 7.0's native compiler, Drizzle Relations v2 — so you don't have to.
20
+ - [Quick Start](#quick-start)
21
+ - [Why This Exists](#why-this-exists)
22
+ - [Skill Catalog](#skill-catalog)
23
+ - [Commands](#commands)
24
+ - [How It Works](#how-it-works)
25
+ - [Hooks & Internals](./HOOKS.md)
26
+ - [Repository Layout](#repository-layout)
27
+ - [Getting Help](#getting-help)
28
+ - [Contributing](#contributing)
20
29
 
21
30
  ## Quick Start
22
31
 
@@ -27,7 +36,7 @@ npx @spardutti/claude-skills
27
36
  ```
28
37
 
29
38
  ```text
30
- Claude Skills Installer v2.6.0
39
+ Claude Skills Installer v2.25.0
31
40
 
32
41
  ── Frontend ──────────────────────────────
33
42
  ◉ react ◯ tanstack-query
@@ -47,11 +56,33 @@ The CLI will:
47
56
  2. Let you pick skills to install → `.claude/skills/`
48
57
  3. Let you pick commands to install → `.claude/commands/`
49
58
  4. Auto-install any subagents the selected commands declare → `.claude/agents/`
50
- 5. Optionally set up the **hooks** — skill evaluation before edits, verification after (recommended — see [How It Works](#how-it-works))
59
+ 5. Optionally set up the **hooks** — skill evaluation before edits, verification after (recommended)
60
+
61
+ ## Why This Exists
62
+
63
+ **A model's knowledge is frozen and averaged.** Ask for React and it reaches for
64
+ `useEffect` and manual `useMemo`. Ask for TypeScript and it assumes 5.x. The code
65
+ compiles, passes review, and is two years out of date. Skills fix that: tight,
66
+ opinionated playbooks pinned to current practice for one tool each — React 19.2 and
67
+ the Compiler, TypeScript 7.0, TanStack Query v5, Drizzle, FastAPI, SQL. They track
68
+ the changelogs so you don't.
69
+
70
+ **But guidance nobody checks is a suggestion.** An agent under deadline pressure
71
+ skips the playbook, writes the test after the code, and reports a pass. So the same
72
+ install adds the part that does not negotiate:
73
+
74
+ - A gate that blocks the first edit until your skills have been applied to the file
75
+ being written — not just read.
76
+ - A `Stop` hook that runs your typecheck and tests on the changed files every turn,
77
+ and refuses to let the turn end red.
78
+ - A delivery gate that **changes your code on purpose and checks whether any test
79
+ notices.** When none do, the PR does not open.
80
+
81
+ That last one is the difference. Your agent says the tests pass. This finds out.
51
82
 
52
83
  ## Skill Catalog
53
84
 
54
- **14 skills**, grouped the same way the installer presents them.
85
+ **16 skills**, grouped the same way the installer presents them.
55
86
 
56
87
  > [!NOTE]
57
88
  > Skills marked **📦 Bundle** ship a concise always-loaded entry point plus reference files Claude reads only when a task needs them — comprehensive coverage at a low context cost.
@@ -91,7 +122,7 @@ Cross-cutting craft — applies to any stack, any language.
91
122
  | `git-merge-conflicts` | Resolve a merge/rebase conflict by intent, not by side — `zdiff3` to see the merge base, the inverted meaning of `ours`/`theirs` during a rebase, the semantic and tree conflicts git never marks, lockfiles and migrations you regenerate instead of merging |
92
123
  | `research` | Open the source, don't recall it — route to the tool that owns the answer, primary sources only, pin the version you're actually on, run the validator instead of guessing, and mark every claim VERIFIED / INFERRED / UNVERIFIED |
93
124
  | `typescript-best-practices` | TypeScript 7.x — type design, generics, type guards, `satisfies`, `using`, error handling, `tsconfig` |
94
- | `testing-best-practices` 📦 | Arrange-Act-Assert, factory-based test data, isolation, mocking boundaries, a pyramid-balanced suite; bundle covers mutation testing — Stryker and mutmut setup, diff-scoped runs, the traps, and working score thresholds |
125
+ | `testing-best-practices` 📦 | Arrange-Act-Assert, factory-based test data, isolation, mocking boundaries, a pyramid-balanced suite; bundle covers mutation testing — Stryker and mutmut setup, `ignoreStatic`, diff-scoped runs, the traps, and working score thresholds |
95
126
  | `security-practices` | OWASP Top 10 prevention, input validation, auth, SQL injection, XSS, CSRF, secure defaults |
96
127
 
97
128
  ## Commands
@@ -101,14 +132,13 @@ Portable slash commands installed to `.claude/commands/`. Some orchestrate paral
101
132
  | Command | What it does |
102
133
  |---------|--------------|
103
134
  | `/ship` | Unified delivery pipeline — commit → gate → PR → merge → release. The gate is the one enforcement moment: it checks the diff's file lengths, audits it against the skills installed in the project, and mutation-tests the changed lines to prove the tests would catch a break — **fixing what it finds** rather than handing you a list. It runs before the **PR**, not before every commit: its scope is the whole branch, so gating each commit re-mutated every file the branch had ever touched. `--force` skips it. No argument steps through interactively; `/ship pr` runs through PR creation; `/ship release` runs the full pipeline |
104
- | `/discover` | Find the right problem before deciding what to build — diverges first: generates competing framings through blind subagents under forced constraints, stress-tests the winner with a blind critic, and refuses to converge until every open question is answered or deferred. Run before `/preplan` |
105
- | `/preplan` | Resolve a fuzzy feature idea into concrete decisions — 6 fixed phases, one question at a time, ends with a decision log. Run before `/plan-feature` |
135
+ | `/discover` | Find the right problem before deciding what to build — diverges first: generates competing framings through blind subagents under forced constraints, stress-tests the winner with a blind critic, and refuses to converge until every open question is answered or deferred, then drafts scope, non-goals, edge cases and success criteria for you to correct. Run before `/plan-feature` |
106
136
  | `/plan-feature` | Integration-first feature planning — 3 parallel subagents scan for reusable code, patterns, and touch points before producing a short plan |
107
137
  | `/refactor` | Detect size / complexity / duplication / coupling issues via 4 parallel subagents, then refactor |
108
138
  | `/deep-review` | Multi-agent deep code review — 5 parallel subagents catch guard bypasses, lost async state, wrong-table queries, dead references, protocol violations |
109
139
  | `/test-review` | Write-then-verify test review — scopes to the diff, runs red-green + mutation gates, then an isolated read-only subagent proves each test would catch a regression instead of rubber-stamping it |
140
+ | `/handoff` | Write a handoff doc so a fresh session picks the work up — captures what auto-compaction loses: decisions made and rejected, dead ends already ruled out, why the tree is dirty, and the one next step |
110
141
  | `/lockdown` | Per-repo supply-chain hardening — detects the package managers, Dockerfiles, and CI in use, then guides you through and applies install-time, deploy, and pipeline hardening for npm/pnpm, pip/uv, Docker, and GitHub Actions |
111
- | `/handoff` | Write a handoff doc so a fresh session picks the work up — captures what auto-compaction loses: decisions made and rejected, dead ends already ruled out, why the tree is dirty, and the one next step. Links to specs, commits, and PRs instead of restating them |
112
142
 
113
143
  ## How It Works
114
144
 
@@ -118,239 +148,35 @@ The CLI installs three kinds of artifact into your project's `.claude/` director
118
148
  - **Commands** → `.claude/commands/` — slash commands you invoke directly.
119
149
  - **Subagents** → `.claude/agents/` — declared by commands via `requires-agents`, installed for you.
120
150
 
151
+ It then offers to install the hooks. Two guard the **front**: nothing is written
152
+ until your skills have been evaluated *and* applied to the file being written.
153
+ Two guard the **back**: a `Stop` hook runs your typecheck and tests on the changed
154
+ files every turn, and a `PreToolUse` gate refuses to open or merge a PR without a
155
+ receipt proving the delivery gate passed on exactly that code.
156
+
157
+ Full details — every hook, every marker, every config key, and what to do when one
158
+ blocks something it shouldn't — are in **[HOOKS.md](./HOOKS.md)**.
159
+
121
160
  ### Tracking & Updates
122
161
 
123
162
  Every install writes a manifest at `.claude/.claude-skills.json` recording what the CLI installed and the catalog version. On the next run it uses the manifest to:
124
163
 
125
164
  - **Pre-check what you already have** in the picker — re-running doubles as an update screen; toggle to add or remove.
126
- - **Detect stale items** — skills/commands renamed or removed from the catalog upstream (e.g. when several skills are merged into a bundle) are flagged, and the CLI offers to delete them.
165
+ - **Detect stale items** — skills/commands renamed or removed from the catalog upstream are flagged, and the CLI offers to delete them.
127
166
  - **Never touch what it didn't install** — the manifest is the CLI's own record; hand-written skills are invisible to it and always safe.
128
167
 
129
168
  ```bash
130
169
  npx @spardutti/claude-skills --sync
131
170
  ```
132
171
 
133
- `--local[=path]` reads the catalog from a working copy instead of GitHub, so an unreleased
134
- change can be installed and tried without publishing it first:
135
-
136
- ```bash
137
- node ~/projects/claude-skills/cli/bin/cli.mjs --local
138
- ```
139
-
140
172
  `--sync` refreshes every tracked item to the latest catalog and prunes stale ones in one shot — no menu. For a project that predates the manifest, the first normal run offers a one-time cleanup of `.claude/` content no longer in the catalog.
141
173
 
142
- ### Automatic Skill Evaluation
143
-
144
- After installing skills, the CLI offers to set up a hook that **guarantees** Claude evaluates your skills before writing code — instead of a soft reminder it can ignore.
145
-
146
- It installs four hooks and appends a rule to your `CLAUDE.md`. Three guard the
147
- **front** — nothing is written until your skills are considered:
148
-
149
- - `skill-gate.sh` — a `PreToolUse` gate on `Write|Edit|MultiEdit|Bash`
150
- - `skill-application-gate.sh` — a second `PreToolUse` gate requiring each loaded skill to be applied, not just read
151
-
152
- Both cover **Bash**, not only the file-writing tools. A session that edits through
153
- `python3 - <<'PY'` in Bash walked past the old matcher entirely — twelve source files, not
154
- one prompt — and some harnesses actively tell the model to prefer Bash for edits. Only
155
- commands that can write are gated (a redirect, `tee`, `sed -i`, `cp`/`mv`, or an
156
- interpreter given inline code or a heredoc); `git status` and a redirect to `/dev/null`
157
- pass untouched, and the command that clears the gate is never gated against itself.
158
-
159
- Neither gate fires on **prose** — `.md`, `.mdx`, `.txt`, `.rst`, `.adoc`, images. Skills
160
- are about code, and a repo full of `PLAN_*.md` otherwise hits the gate on every write.
161
- Config files (`.json`, `.yml`, `.toml`) stay gated, because skills do have rules about
162
- `tsconfig`, `package.json`, and Compose.
163
- - `skill-gate-automark.sh` — a `PostToolUse` hook on `Skill` that clears the gate
164
-
165
- The last two guard the **back** — nothing finishes or ships until the code passes:
166
-
167
- - `gauntlet.sh` — a `Stop` hook running the fast gates on your changed files (see [Automatic Verification](#automatic-verification-gauntlet))
168
- - `ship-gate-hook.sh` — a `PreToolUse` gate on `Bash` that refuses `git commit` and `git push` without a receipt from `ship-gate.sh`
169
-
170
- One more hook stays out of the way entirely:
171
-
172
- - `version-check.sh` — a `SessionStart` hook that mentions a newer catalog at most once a day. It never touches the network in the foreground: it reads a cache the previous session refreshed in the background, so it costs a file read. Silent when there is no cache, no network, or nothing new. `CLAUDE_SKILLS_NO_VERSION_CHECK=1` turns it off.
173
-
174
- <details>
175
- <summary>How the gate works</summary>
176
-
177
- The gate hard-blocks `Write`, `Edit`, and `MultiEdit` until a per-session marker exists at `/tmp/claude-skill-gate-<SESSION_ID>`. The marker is created automatically the first time Claude invokes any `Skill()` in the session — so the normal flow is: Claude lists skills as ACTIVATE/SKIP, calls `Skill()` for the ACTIVATE ones, and the gate clears for the rest of the session. If every skill is SKIP, Claude clears the gate with `touch /tmp/claude-skill-gate-<SESSION_ID>`.
178
-
179
- The marker is **per-session, not per-turn** — short follow-ups like "yes" don't re-lock it. The gate auto-passes when a project has no `.claude/skills/*/SKILL.md`, so it's safe to leave on globally.
180
-
181
- It registers in `.claude/settings.json`:
182
-
183
- ```json
184
- {
185
- "hooks": {
186
- "PreToolUse": [
187
- { "matcher": "Write|Edit|MultiEdit|Bash", "hooks": [
188
- { "type": "command", "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/skill-gate.sh" } ] },
189
- { "matcher": "Write|Edit|MultiEdit|Bash", "hooks": [
190
- { "type": "command", "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/skill-application-gate.sh" } ] }
191
- ],
192
- "PostToolUse": [
193
- { "matcher": "Skill", "hooks": [
194
- { "type": "command", "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/skill-gate-automark.sh" } ] }
195
- ]
196
- }
197
- }
198
- ```
199
-
200
- </details>
201
-
202
- ### Automatic Verification (Gauntlet)
203
-
204
- The same install adds `gauntlet.sh` — a `Stop` hook that runs the cheap, deterministic
205
- gates on your changed files every time Claude finishes a turn. Green is silent; red exits 2,
206
- which keeps the turn from ending, shows you the failure, and hands it to Claude to fix.
207
-
208
- Exit 2 matters: `{"decision":"continue"}` also keeps the turn going, but its reason reaches
209
- Claude alone. A failing gate was then invisible from the outside — indistinguishable from a
210
- gauntlet that does nothing.
211
-
212
- Keep the gates fast for a reason beyond patience: a `command` hook that reaches its timeout
213
- (600s by default) is cancelled and its **output discarded**, so the turn ends as if the hook
214
- never ran. A stalled gate is a silent pass, not a block.
215
-
216
- Only fast gates live here (target: under ~30s). Mutation testing and deep review stay
217
- manual — they belong to `/test-review` and `/deep-review`, not to every turn.
218
-
219
- At install time the CLI reports what it found, so a silent no-op is never a surprise:
220
-
221
- ```text
222
- Gauntlet detected tsc + vitest — it will run those on changed files.
223
- ```
224
-
225
- If no test runner is detected it says so, and offers to write a `.claude/gauntlet.conf`
226
- pointing at your test command. Detection covers vitest, jest, pytest, `tsc`, and `mypy`;
227
- everything else needs that one config line.
228
-
229
- <details>
230
- <summary>How the gauntlet hook works</summary>
231
-
232
- It runs a skip ladder first, cheapest check first, and quits at the first "no":
233
-
234
- 1. no changed files (planning turns, questions)
235
- 2. no changed **code** files (docs/config only)
236
- 3. this exact diff already passed — the hash of a green run is cached per session and repo
237
- 4. no gates detected for this repo
238
-
239
- Rule 3 is what makes repeated `/ship` runs free: the gates run once per distinct diff.
240
-
241
- To confirm it is alive when everything is green — green prints nothing, by design:
174
+ `--local[=path]` reads the catalog from a working copy instead of GitHub, so an unreleased change can be installed and tried without publishing it first:
242
175
 
243
176
  ```bash
244
- ls -t /tmp/claude-gauntlet-*.why | head -1 | xargs cat
245
- ```
246
-
247
- Every run records why it ended in `/tmp/claude-gauntlet-<session>.why`, so a green run
248
- and a skipped one are told apart without re-running the hook. `GAUNTLET_DEBUG=1` prints
249
- the same line to stderr:
250
-
251
- ```text
252
- gauntlet: green: gates passed
253
- gauntlet: skipped: no changed code files (docs/config only)
254
- gauntlet: green: gates passed, but the runner matched 0 test files — the changed code was never executed
255
- ```
256
-
257
- That last one is the false green worth knowing about. A test runner given files it has no
258
- tests for exits 0 and looks exactly like a pass — in a monorepo whose vitest workspace
259
- excludes a package, **no** change in that package can ever be covered. The hook names it
260
- instead of reporting green. Set `GAUNTLET_REQUIRE_TESTS=1` to make it block instead.
261
-
262
- The stack is auto-detected: vitest / jest / pytest for tests, and for typechecking the
263
- repo's own `typecheck` script if it has one, else bare `tsc --noEmit` or `mypy`. The script
264
- is preferred because a workspace root `tsconfig.json` is often solution-style, where
265
- `tsc --noEmit` does not mean what the repo's `tsc -b` means.
266
-
267
- **Monorepos work, including the ones with nothing at the root.** Detection collects every
268
- gate it finds rather than stopping at the first, and each gate carries the file pattern it
269
- applies to — so a JS + Python repo gets four gates, and a turn that touched only `.py` files
270
- runs the Python two and skips the JS two entirely. Typechecks always run before tests, and
271
- the first red stops the rest.
272
-
273
- When the root has no manifest, detection looks two levels down for `package.json` /
274
- `pyproject.toml` / `pytest.ini` — the `web/` + `api/`, `apps/*`, `packages/*` layouts — and
275
- scopes each gate to that folder's files, running the command from inside it. Nested gates
276
- are only added for the kind the root did not already provide, so a repo that works today
277
- keeps working.
278
-
279
- Setting `GAUNTLET_TEST` or `GAUNTLET_TYPECHECK` switches the repo to explicit mode:
280
- auto-detection is off and only what you set runs.
281
-
282
- **A missing tool is a skip, not a red.** A fresh clone with no `node_modules`, or a venv
283
- without pytest, would otherwise fail every gate and block every turn — so the hook reports
284
- `skipped: node_modules is missing — run your install first` and gets out of the way. Only
285
- a gate that actually ran and actually failed blocks. Override anything in
286
- a config file — two are read, in this order, and the project's wins key by key:
287
-
288
- ```text
289
- ~/.claude/gauntlet.conf your defaults for every project
290
- <project>/.claude/gauntlet.conf overrides for this one
291
- ```
292
-
293
- ```bash
294
- GAUNTLET_OFF=1 # disable entirely
295
- GAUNTLET_TYPECHECK='npm run check' # "" to skip the gate
296
- GAUNTLET_TEST='npm test -- $FILES' # $FILES = changed code files
297
- GAUNTLET_CODE_EXT='ts|tsx|py' # what counts as a change worth checking
298
- GAUNTLET_DEBUG=1 # print the outcome to stderr every run
299
- GAUNTLET_REQUIRE_TESTS=1 # block when the runner matched 0 test files
300
-
301
- # /ship's gate reads its own keys from the same file
302
- GAUNTLET_MAX_LINES=200 # per-file limit; 0 turns the check off
303
- GAUNTLET_SOURCE_EXT='ts|tsx|py' # what counts as SOURCE — not the same question
304
- GAUNTLET_MUTATE='bash mutate.sh' # replace per-project mutation detection
305
- GAUNTLET_IGNORE_FILES='*.gen.ts' # globs that are never gated — see below
306
- ```
307
-
308
- `GAUNTLET_IGNORE_FILES` holds files nobody wrote, so the line limit and mutation both
309
- skip them. It defaults to `*.gen.ts *.gen.tsx *.generated.* */migrations/*.py
310
- */alembic/versions/*.py */components/ui/*.tsx` — a TanStack `routeTree.gen.ts`, a Django
311
- or Alembic migration, and a vendored shadcn component are all over 200 lines, none of
312
- them can be split, and gating them only teaches `--force`. Every skipped file is named in
313
- the output. Patterns match against `/<path>`, so `*/components/ui/*.tsx` covers the repo
314
- root and `apps/web/src` alike. Set it to `""` to gate everything.
315
-
316
- `GAUNTLET_SOURCE_EXT` is separate from `GAUNTLET_CODE_EXT` on purpose. The Stop hook asks
317
- "did anything worth checking change", so a docs repo sets `CODE_EXT` to include `.md`. The
318
- line limit and mutation ask about source code, where that answer is wrong.
319
-
320
- Set your house rules once in `~/.claude/gauntlet.conf`; only reach for the project file
321
- where a repo does something unusual (or set `GAUNTLET_OFF=1` there to opt one out).
322
-
323
- It registers in `.claude/settings.json`:
324
-
325
- ```json
326
- {
327
- "hooks": {
328
- "Stop": [
329
- { "hooks": [
330
- { "type": "command", "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/gauntlet.sh" } ] }
331
- ]
332
- }
333
- }
334
- ```
335
-
336
- </details>
337
-
338
- <details>
339
- <summary>Manual install (without the CLI)</summary>
340
-
341
- ```bash
342
- # Skills
343
- cp -r skills/<skill-name> /path/to/project/.claude/skills/
344
-
345
- # Commands
346
- cp commands/<command-name>.md /path/to/project/.claude/commands/
347
-
348
- # Subagents — see the command's `requires-agents` frontmatter
349
- cp agents/<agent-name>.md /path/to/project/.claude/agents/
177
+ node ~/projects/claude-skills/cli/bin/cli.mjs --local
350
178
  ```
351
179
 
352
- </details>
353
-
354
180
  ## Repository Layout
355
181
 
356
182
  ```text
@@ -360,7 +186,7 @@ agents/ Subagent definitions — commands declare which they need via req
360
186
  scripts/ validate-skills.mjs — checks skill length caps and reference integrity
361
187
  gauntlet.sh — the Stop-hook verification gates, embedded by the CLI
362
188
  ship-gate.sh — /ship's file-length and mutation checks, behind an exit code
363
- ship-gate-hook.sh — refuses git commit/push without a ship-gate receipt
189
+ ship-gate-hook.sh — refuses gh pr create/merge without a ship-gate receipt
364
190
  version-check.sh — SessionStart nudge when a newer catalog is published
365
191
  gauntlet-selftest.sh — behavioural tests for the hooks (runs on pre-push)
366
192
  gauntlet-survey.sh — what the hook would do in every repo under a directory
@@ -371,6 +197,12 @@ cli/ The npm installer (npx @spardutti/claude-skills); version in cli/
371
197
  package.json Private dev-tooling package (claude-skills-dev) — not the published one
372
198
  ```
373
199
 
200
+ ## Getting Help
201
+
202
+ - **Something broken, or a skill teaching something stale?** [Open an issue](https://github.com/Spardutti/claude-skills/issues).
203
+ - **A hook not firing, or a gate blocking something it shouldn't?** [HOOKS.md](./HOOKS.md) covers the markers, the matchers, and the escape hatches — including the auto-mode permission rule the gates need.
204
+ - **Want a skill for a tool that isn't here?** Issues are the place; see [Contributing](#contributing) for what a good one looks like.
205
+
374
206
  ## Contributing
375
207
 
376
208
  Skills live in `skills/<name>/SKILL.md`. Authoring conventions are in [CLAUDE.md](./CLAUDE.md) — the short version:
@@ -389,9 +221,8 @@ Skills live in `skills/<name>/SKILL.md`. Authoring conventions are in [CLAUDE.md
389
221
  anything. Read the rows that say `nothing`.
390
222
 
391
223
  To get the validator on **every turn** instead of only on push, drop this into
392
- this repo's `.claude/gauntlet.conf` — `.claude/` is gitignored, so each contributor adds it
393
- locally. It has to be the project file, not `~/.claude/gauntlet.conf`: these settings are
394
- only right for a skills repo:
224
+ this repo's `.claude/gauntlet.conf`. It has to be the project file, not
225
+ `~/.claude/gauntlet.conf`: these settings are only right for a skills repo:
395
226
 
396
227
  ```bash
397
228
  GAUNTLET_CODE_EXT='md|mjs|js|json|sh' # markdown IS the product here
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@spardutti/claude-skills",
3
- "version": "2.24.0",
4
- "description": "CLI to install Claude Code skills from the claude-skills collection",
3
+ "version": "2.25.1",
4
+ "description": "Guardrails for Claude Code — best-practice skills, planning commands, and delivery gates.",
5
5
  "type": "module",
6
6
  "repository": {
7
7
  "type": "git",