docs: add human-facing pages for the remaining 22 promoted skills
Adds a docs page for every promoted skill that lacked one, following .agents/writing-docs.md and using docs/engineering/to-prd.md as the worked exemplar. Covers all of engineering/ (bar to-prd, already done), productivity/, and misc/. Each page states its load-bearing constraint, its invocation mode and trigger boundary, surfaces the skill's leading word, and routes back to ask-matt so the set forms a connected router with no dead ends. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
5694f83609
commit
f5ed5657bd
22 changed files with 888 additions and 0 deletions
38
docs/misc/git-guardrails-claude-code.md
Normal file
38
docs/misc/git-guardrails-claude-code.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
Quickstart:
|
||||
|
||||
```bash
|
||||
npx skills add mattpocock/skills --skill=git-guardrails-claude-code
|
||||
```
|
||||
|
||||
```bash
|
||||
npx skills update git-guardrails-claude-code
|
||||
```
|
||||
|
||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/misc/git-guardrails-claude-code)
|
||||
|
||||
## What it does
|
||||
|
||||
`git-guardrails-claude-code` installs a Claude Code **PreToolUse hook** that blocks destructive git commands — `git push`, `reset --hard`, `clean -f`, `branch -D`, `checkout .` / `restore .` — before they run.
|
||||
|
||||
The load-bearing constraint: this is a **guardrail**, not a request. The block lives in the harness, not in the agent's instructions — the hook inspects every Bash command and, on a match, exits with code 2 so the command never executes. An agent can forget a "please don't push" note in its prompt; it cannot talk its way past a hook that fires before the tool call lands.
|
||||
|
||||
## When to reach for it
|
||||
|
||||
Type `/git-guardrails-claude-code`, or the agent reaches for it automatically when a task fits.
|
||||
|
||||
Reach for it when you want an agent to work freely in a repo but never perform the handful of git operations that lose work or rewrite shared history. It's a one-time install: run it once per project (or once globally) and the guardrail is standing thereafter. For enforcing quality *at commit time* — Prettier, type-checking, tests via Husky — that's a different mechanism, so use [setup-pre-commit](https://aihero.dev/skills-setup-pre-commit) instead.
|
||||
|
||||
## The guardrail
|
||||
|
||||
The hook is a small shell script matching each Bash command against a list of dangerous patterns. When one matches, the agent sees a `BLOCKED` message telling it that it does not have authority to run that command, and the command is dropped.
|
||||
|
||||
Two knobs at install time: **scope** — this project (`.claude/settings.json`) or all projects (`~/.claude/settings.json`) — and the **pattern list**, which you can extend or trim so the wall sits exactly where you want it. Everything not on the list still runs untouched.
|
||||
|
||||
## It's working if
|
||||
|
||||
- A blocked command (e.g. `git push`) never executes, and the agent reports it was denied rather than that it failed.
|
||||
- Ordinary git — `add`, `commit`, `status`, `checkout <branch>` — runs as normal.
|
||||
|
||||
## Where it fits
|
||||
|
||||
This is a **run-once setup** skill, and a standalone: install the guardrail and forget it. Its closest neighbour is [setup-pre-commit](https://aihero.dev/skills-setup-pre-commit), which also writes hooks into a repo but guards commit *quality* rather than destructive git *actions* — the two stack cleanly. When you're unsure which safety or setup skill fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||
43
docs/misc/migrate-to-shoehorn.md
Normal file
43
docs/misc/migrate-to-shoehorn.md
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
Quickstart:
|
||||
|
||||
```bash
|
||||
npx skills add mattpocock/skills --skill=migrate-to-shoehorn
|
||||
```
|
||||
|
||||
```bash
|
||||
npx skills update migrate-to-shoehorn
|
||||
```
|
||||
|
||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/misc/migrate-to-shoehorn)
|
||||
|
||||
## What it does
|
||||
|
||||
`migrate-to-shoehorn` sweeps a test suite for `as` type assertions and replaces them with `@total-typescript/shoehorn` helpers, so a test can pass just the properties it cares about while TypeScript stays happy.
|
||||
|
||||
The load-bearing constraint: this is **test code only**. Shoehorn exists to fake partial data behind a type-safe front; it must never touch production code, where a real value is always required.
|
||||
|
||||
## When to reach for it
|
||||
|
||||
Type `/migrate-to-shoehorn`, or the agent reaches for it automatically when a task fits — it triggers when you mention shoehorn, want to strip `as` out of tests, or need to hand a function partial test data.
|
||||
|
||||
Reach for it when a test is forced to fabricate a whole object — every header, every cookie, twenty more fields — just to satisfy one property the assertion actually reads, or when `as unknown as Type` is smuggling deliberately-wrong data past the compiler for an error case.
|
||||
|
||||
## The partial idea
|
||||
|
||||
The word to think with is **partial**. A test rarely needs a complete object; it needs the one or two fields under test. `as` forces you to either build the whole thing or lie to the compiler. Shoehorn lets you supply the *partial* and infers the rest:
|
||||
|
||||
- `fromPartial()` — pass the fields that matter, still type-checked against the real shape.
|
||||
- `fromAny()` — pass intentionally wrong data for error paths, keeping autocomplete.
|
||||
- `fromExact()` — force a full object when you want no gaps.
|
||||
|
||||
The migration is mechanical: `as Type` becomes `fromPartial()`, `as unknown as Type` becomes `fromAny()`, imports get added, and a type check confirms the swap held.
|
||||
|
||||
## It's working if
|
||||
|
||||
- Test files no longer carry `as Type` or `as unknown as Type` on faked data.
|
||||
- Each migrated call passes only the properties the test reads, wrapped in `fromPartial` or `fromAny`.
|
||||
- The type check still passes, and no shoehorn import leaks into production source.
|
||||
|
||||
## Where it fits
|
||||
|
||||
This is a reach-for-it-anytime standalone — a one-shot cleanup you run over a test file or suite whenever `as` has crept in. It sits naturally alongside [tdd](https://aihero.dev/skills-tdd), which is where those test files get written in the first place and where partial test data pays off most. When you're unsure which skill fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||
43
docs/misc/scaffold-exercises.md
Normal file
43
docs/misc/scaffold-exercises.md
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
Quickstart:
|
||||
|
||||
```bash
|
||||
npx skills add mattpocock/skills --skill=scaffold-exercises
|
||||
```
|
||||
|
||||
```bash
|
||||
npx skills update scaffold-exercises
|
||||
```
|
||||
|
||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/misc/scaffold-exercises)
|
||||
|
||||
## What it does
|
||||
|
||||
`scaffold-exercises` reads a course plan and builds the exercise directory tree it describes — numbered sections, numbered exercises, and their `problem/`, `solution/`, and `explainer/` variant folders, each seeded with a stub `readme.md`.
|
||||
|
||||
The load-bearing constraint: the scaffold is only done when it **passes `pnpm ai-hero-cli internal lint`**. The linter is the contract — folder shape, numeric prefixes, non-empty readmes, no stray `.gitkeep` or `speaker-notes.md`, no broken links. The skill scaffolds, runs the lint, and iterates until it's green rather than leaving you a tree that merely looks right.
|
||||
|
||||
## When to reach for it
|
||||
|
||||
Type `/scaffold-exercises`, or the agent reaches for it automatically when a task fits — turning a plan into stubbed exercise directories, or setting up a new course section.
|
||||
|
||||
Reach for it when you have a plan (section names, exercise names, which variants each needs) and want the skeleton on disk and lint-clean before you write any real content. It only lays down structure and empty-but-valid readmes; the teaching material comes later.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
The skill writes into an `exercises/` directory and validates with `pnpm ai-hero-cli internal lint`, so run it inside a course repo that has the AI Hero CLI available. Outside that tooling the lint step — the whole point — can't run.
|
||||
|
||||
## Lint-passing is the spec
|
||||
|
||||
The naming isn't cosmetic: sections are `XX-section-name/`, exercises are `XX.YY-exercise-name/` in dash-case, and every variant folder carries a non-empty `readme.md`. Those rules exist because the linter enforces them, and the linter is what downstream course tooling relies on. So the mental model is inverted from "make a folder tree" to "make a tree the linter accepts" — default new stubs to `explainer/`, keep readmes real (a single title line counts), and let the lint pass be the definition of done.
|
||||
|
||||
Renumbering later follows the same rule: use `git mv` so history survives, then re-run lint.
|
||||
|
||||
## It's working if
|
||||
|
||||
- `pnpm ai-hero-cli internal lint` passes with the new tree in place.
|
||||
- Every variant folder has a non-empty `readme.md`; no `.gitkeep` or `speaker-notes.md` slipped in.
|
||||
- Section and exercise folders carry correct `XX` / `XX.YY` prefixes in dash-case.
|
||||
|
||||
## Where it fits
|
||||
|
||||
`scaffold-exercises` is a reach-for-it-anytime standalone at the start of building a course section: it produces the empty, lint-clean scaffold you then fill in. It sits next to Matt's course-planning work — once a plan exists, this turns it into directories — but it owns no planning itself. When you're unsure which skill or flow fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||
37
docs/misc/setup-pre-commit.md
Normal file
37
docs/misc/setup-pre-commit.md
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
Quickstart:
|
||||
|
||||
```bash
|
||||
npx skills add mattpocock/skills --skill=setup-pre-commit
|
||||
```
|
||||
|
||||
```bash
|
||||
npx skills update setup-pre-commit
|
||||
```
|
||||
|
||||
[Source](https://github.com/mattpocock/skills/tree/main/skills/misc/setup-pre-commit)
|
||||
|
||||
## What it does
|
||||
|
||||
`setup-pre-commit` wires up a Husky pre-commit hook in the current repo: lint-staged runs Prettier over your staged files, then a type check and the test suite run before the commit is allowed through.
|
||||
|
||||
The load-bearing constraint: it **adapts to the repo instead of imposing a fixed config**. It detects your package manager from the lockfile, only wires up the `typecheck` and `test` steps that already exist as scripts (and tells you which it skipped), and writes a Prettier config only if you don't already have one. You get a working gate tuned to what the repo actually has, not a template you then have to unpick.
|
||||
|
||||
## When to reach for it
|
||||
|
||||
Type `/setup-pre-commit`, or the agent reaches for it automatically when a task fits.
|
||||
|
||||
Reach for it when a repo has no commit-time formatting or checks and you want them added once — "set up Husky", "add pre-commit hooks", "run Prettier on commit". It is about the commit boundary specifically; to stop dangerous git operations (`push`, `reset --hard`, `clean`) from running at all, use [git-guardrails-claude-code](https://aihero.dev/skills-git-guardrails-claude-code) instead.
|
||||
|
||||
## The gate
|
||||
|
||||
The hook is a **gate**: nothing lands in a commit until it passes. Ordering is deliberate — lint-staged goes first because it is fast and touches only staged files, then the slower whole-repo `typecheck` and `test` run. The final step is a real commit through the new hook, so the gate is smoke-tested the moment it's installed rather than the next time you happen to commit.
|
||||
|
||||
## It's working if
|
||||
|
||||
- A commit runs Prettier, the type check, and the tests before it completes — and a failing check aborts the commit.
|
||||
- `.husky/pre-commit`, `.lintstagedrc`, and a Prettier config exist, and `prepare` in package.json is `"husky"`.
|
||||
- The hook uses your repo's package manager, and only names steps whose scripts exist.
|
||||
|
||||
## Where it fits
|
||||
|
||||
A **run-once setup** — you install the gate once per repo and it runs on every commit thereafter, no re-invocation. Its natural neighbour is [git-guardrails-claude-code](https://aihero.dev/skills-git-guardrails-claude-code), because the two guard different edges: this one gates what enters a commit, that one blocks destructive git commands from executing. When you're unsure which skill fits, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
|
||||
Loading…
Add table
Add a link
Reference in a new issue