mirror of
https://github.com/mattpocock/skills.git
synced 2026-07-29 11:02:41 +07:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab8e3cd904 | ||
|
|
66898f60e8 | ||
|
|
0ac3f3fbf1 | ||
|
|
697d4ce974 | ||
|
|
8f4952b6a3 | ||
|
|
42a5b70fca |
@@ -0,0 +1,28 @@
|
|||||||
|
# Ship the skill set as a native Claude Code plugin; defer a native Codex plugin
|
||||||
|
|
||||||
|
These skills have always been installable via [skills.sh](https://skills.sh/mattpocock/skills) (`npx skills add mattpocock/skills`), which copies editable skill files into a user's project across Claude Code, Codex, and other Agent-Skills-standard harnesses. A recurring request is a **plug-and-play** distribution: subscribe to the set as a read-only, always-current bundle you don't edit, rather than a fork you own. That is exactly what native plugin systems provide.
|
||||||
|
|
||||||
|
We ship a native **Claude Code plugin** and, for now, **defer** a native **Codex plugin**. The split is forced by how each ecosystem's plugin manifest selects skills, against this repo's bucketed layout.
|
||||||
|
|
||||||
|
## The constraint: bucketed skills vs. single-path selection
|
||||||
|
|
||||||
|
Skills live in bucket folders under `skills/` — `engineering/` and `productivity/` are **promoted** (shipped); `misc/`, `personal/`, `in-progress/`, and `deprecated/` are **not**. A plugin must expose only the promoted set, which spans two of those bucket folders.
|
||||||
|
|
||||||
|
- **Claude Code** — `.claude-plugin/plugin.json` accepts `skills` as an **array of explicit skill-directory paths**. We list the promoted skills one by one, exclude everything else with zero ambiguity, and add `.claude-plugin/marketplace.json` so the repo is its own single-plugin marketplace. Verified end to end: `claude plugin validate . --strict` passes, and `marketplace add` → `install` resolves all promoted skills.
|
||||||
|
|
||||||
|
- **Codex** — `.codex-plugin/plugin.json` accepts `skills` only as a **single path string** (arrays are rejected with `missing or invalid plugin.json`), and Codex discovers `SKILL.md` files recursively under it. There is no way to name two bucket folders, or to curate a subset, from one path. Two escape hatches were tested and rejected:
|
||||||
|
- Pointing at `./skills/` would also ship `deprecated/`, `in-progress/`, `personal/`, and `misc/` — retired, draft, and personal skills we deliberately don't promote.
|
||||||
|
- A curated flat directory of **symlinks** into the buckets does not survive install: Codex copies the plugin tree into its cache and **drops symlinks**, so the skills arrive empty.
|
||||||
|
|
||||||
|
The only robust ways to give Codex a single promoted-only path are (a) **restructure** so `skills/` contains only promoted skills (moving the non-promoted buckets out — a large blast radius across `CLAUDE.md`, `scripts/link-skills.sh`, the bucket READMEs, and the local dev workflow that relies on `in-progress/` and `personal/`), or (b) **commit duplicate copies** of promoted skills into a flat directory (a sync burden and a second source of truth). Both are structural decisions, not something to bundle into shipping the Claude plugin. This is very likely the original, half-remembered reason a plugin wasn't shipped earlier: the manifest formats didn't cleanly express a curated subset of a bucketed repo.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
- Ship the **Claude Code plugin** now (`.claude-plugin/plugin.json` + `.claude-plugin/marketplace.json`), curated to the promoted set, as the headline v1.2 deliverable.
|
||||||
|
- Keep **skills.sh** as the universal installer — it already serves Codex and other harnesses today, so no Codex user is left without an install path.
|
||||||
|
- **Defer** the native Codex plugin until we decide between restructuring `skills/` to promoted-only vs. committing a generated flat copy. Revisit when Codex either supports a `skills` array / include-list or preserves symlinks on install.
|
||||||
|
|
||||||
|
## Invariants this creates
|
||||||
|
|
||||||
|
- Every promoted skill has an entry in `.claude-plugin/plugin.json`'s `skills` array (this already stood as a `CLAUDE.md` rule; it now also gates the plugin's contents).
|
||||||
|
- `.claude-plugin/plugin.json`'s `version` tracks `package.json`'s version — bump both together on release. Claude uses the plugin `version` to decide when installed users see an update.
|
||||||
@@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
Every `SKILL.md` in this repo is a skill. The one axis that splits them is **invocation** — who can reach it:
|
Every `SKILL.md` in this repo is a skill. The one axis that splits them is **invocation** — who can reach it:
|
||||||
|
|
||||||
- **User-invoked** — reachable **only by the human typing its name**. Set `disable-model-invocation: true` in the frontmatter. The `description` is **human-facing**: a one-line summary read by a person browsing slash-commands. Strip trigger lists ("Use when the user says…").
|
- **User-invoked** — reachable **only by the human typing its name**. Set `disable-model-invocation: true` in the frontmatter (Claude Code) and `policy.allow_implicit_invocation: false` in `agents/openai.yaml` (Codex). The `description` is **human-facing**: a one-line summary read by a person browsing slash-commands. Strip trigger lists ("Use when the user says…").
|
||||||
- **Model-invoked** — reachable by **model or user**. The default: omit `disable-model-invocation`. The `description` is **model-facing** and keeps rich trigger phrasing ("Use when the user wants…, mentions…, asks for…") so auto-invocation fires. The test for whether a skill should stay model-invoked: _could the model usefully reach for this autonomously?_ (Reuse is the reason to extract a skill, not the test.)
|
- **Model-invoked** — reachable by **model or user**. The default: omit `disable-model-invocation` and the `policy` block from `agents/openai.yaml`. The `description` is **model-facing** and keeps rich trigger phrasing ("Use when the user wants…, mentions…, asks for…") so auto-invocation fires. The test for whether a skill should stay model-invoked: _could the model usefully reach for this autonomously?_ (Reuse is the reason to extract a skill, not the test.)
|
||||||
|
|
||||||
Because a user-invoked skill has no description, nothing but the human can reach it — no other skill can fire it. So a user-invoked skill may invoke model-invoked skills, but it can never reach another user-invoked skill.
|
Each harness excludes a user-invoked skill from the model's reach in its own way, so nothing but the human can fire it — no other skill can. A user-invoked skill may invoke model-invoked skills, but it can never reach another user-invoked skill.
|
||||||
|
|
||||||
|
Every skill also carries an `agents/openai.yaml` beside its `SKILL.md`. It holds Codex UI metadata — `interface.display_name` and `interface.short_description` for the skill picker — and, for user-invoked skills, the `policy.allow_implicit_invocation: false` that pairs with `disable-model-invocation`. Keep the two in sync: a skill is user-invoked in both harnesses or neither.
|
||||||
|
|
||||||
Bucket `README.md`s and the top-level `README.md` group entries into **User-invoked** and **Model-invoked**.
|
Bucket `README.md`s and the top-level `README.md` group entries into **User-invoked** and **Model-invoked**.
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
"mattpocock-skills": patch
|
|
||||||
---
|
|
||||||
|
|
||||||
Make `/ask-matt` clued-up about `/wayfinder` — the heaviest, most cognitively demanding flow.
|
|
||||||
|
|
||||||
The router now sharpens the two routing mistakes people most often make with wayfinder:
|
|
||||||
|
|
||||||
- **Over-reaching for it.** It's slower and denser than a single grill, so it's flagged as the heaviest flow and reserved for the idea that genuinely won't fit one session — a well-scoped feature belongs on `/grill-with-docs`, not here.
|
|
||||||
- **Losing the way at the handoff.** When the map clears, wayfinder hands off, it doesn't build: merge onto the main flow at `/to-spec` (which collapses the map's linked decisions into a buildable plan) rather than looping the map straight into `/implement`. Straight-to-`/implement` is only for efforts that turned out genuinely small.
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
"mattpocock-skills": patch
|
|
||||||
---
|
|
||||||
|
|
||||||
Make `/setup-matt-pocock-skills` friendlier and align the local-markdown tracker with the current spec.
|
|
||||||
|
|
||||||
- **Triage labels** are now asked about only when the `triage` skill is installed, and then as a single recommended-yes question ("keep the default triage labels?") instead of an override interrogation. When `triage` isn't installed, the section — and `docs/agents/triage-labels.md` — are skipped.
|
|
||||||
- **External PRs as a request surface** is no longer a setup question. The GitHub/GitLab templates still carry the flag, defaulted off; a user can flip it in `docs/agents/issue-tracker.md` later.
|
|
||||||
- **Domain docs** default to single-context without asking; multi-context is only offered when the repo shows monorepo signals.
|
|
||||||
- **Local-markdown tickets** are now one file per ticket under `.scratch/<feature>/issues/<NN>-<slug>.md` — never a single combined `tickets.md`. `/to-tickets` and the local issue-tracker template now agree, and the spec file is `spec.md` (not `PRD.md`) to match `/to-spec`.
|
|
||||||
|
|
||||||
Docs pages for `setup-matt-pocock-skills` and `to-tickets` re-synced.
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
"mattpocock-skills": patch
|
|
||||||
---
|
|
||||||
|
|
||||||
Reword **`grilling`** for general use. Its description and body no longer scope the interview to a software plan: "this plan" → "this", "enact the plan" → "act on it", and "exploring the codebase" → "exploring the environment". The technique is unchanged; it now reads as a stress-test of any plan, decision, or idea.
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
"mattpocock-skills": minor
|
|
||||||
---
|
|
||||||
|
|
||||||
Reword how the **`prototype`** skill handles its artifacts around a single idea: **the prototype is a primary source**. Rather than being deleted once it's answered its question, the prototype is captured as runnable evidence on a throwaway branch (`prototype/<name>`) out of main, with a context pointer to it left on the implementation issue — so the main branch keeps only the validated decision while the exploration stays findable. The answer (verdict + question) is still captured durably in an issue/ADR/commit.
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
---
|
|
||||||
"mattpocock-skills": patch
|
|
||||||
---
|
|
||||||
|
|
||||||
Name the `/wayfinder` unit a **decision ticket**.
|
|
||||||
|
|
||||||
People kept reading a wayfinder ticket as an ordinary *implementation* ticket — a slice of a build to execute — when wayfinder uses them as **decision tickets**: questions whose resolution is a decision. The skill description and its opening line now introduce "decision ticket" (and say what makes it one), and the `ask-matt` / engineering README wayfinder blurbs and the docs page match — while "ticket" stays the everyday word once the term is established. `CONTEXT.md` records **Decision ticket** as a domain term so the "avoid: ticket" guidance no longer contradicts wayfinder's deliberate use of the word.
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
---
|
|
||||||
"mattpocock-skills": minor
|
|
||||||
---
|
|
||||||
|
|
||||||
Wayfinder now burns research tickets down with subagents instead of leaving them parked for a separately-launched session.
|
|
||||||
|
|
||||||
Research stays a real ticket type — it's a genuine shared blocker that downstream decisions hang on, and that dependency is exactly what the frontier's blocking edges exist to render. What changes is how it's resolved: because research is AFK, charting doesn't stop and read it. After creating the tickets, the charting session fires a `/research` subagent for each research ticket to burn it down in parallel, capturing the findings on a throwaway `research/<name>` branch with a context pointer. Research tickets are the one exception to *one ticket per session*.
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
"mattpocock-skills": minor
|
|
||||||
---
|
|
||||||
|
|
||||||
Add a YAGNI scoping filter to the **`improve-codebase-architecture`** skill's Explore step. Instead of scanning the whole repo evenly, it now scopes to where change is actually landing: if you name a direction it takes it, otherwise it reads the last ~20 commit messages to bias exploration toward actively-developed paths. A deepening opportunity in code nobody touches is a refactor you'll never cash in — the leverage only pays off where you keep editing — so the report stops tidying dormant corners of the repo.
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "mattpocock",
|
||||||
|
"owner": {
|
||||||
|
"name": "Matt Pocock",
|
||||||
|
"url": "https://www.aihero.dev"
|
||||||
|
},
|
||||||
|
"description": "Matt Pocock's skills for real engineering, as an installable Claude Code plugin.",
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "mattpocock-skills",
|
||||||
|
"source": "./",
|
||||||
|
"description": "Matt Pocock's agent skills for real engineering — grilling, spec/ticket flows, TDD, code review, domain modelling and more.",
|
||||||
|
"category": "engineering",
|
||||||
|
"keywords": [
|
||||||
|
"engineering",
|
||||||
|
"skills",
|
||||||
|
"tdd",
|
||||||
|
"code-review",
|
||||||
|
"grilling"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,5 +1,23 @@
|
|||||||
{
|
{
|
||||||
"name": "mattpocock-skills",
|
"name": "mattpocock-skills",
|
||||||
|
"version": "1.2.0",
|
||||||
|
"description": "Matt Pocock's agent skills for real engineering — grilling, spec/ticket flows, TDD, code review, domain modelling and more. Plug-and-play, not vibe coding.",
|
||||||
|
"author": {
|
||||||
|
"name": "Matt Pocock",
|
||||||
|
"url": "https://www.aihero.dev"
|
||||||
|
},
|
||||||
|
"homepage": "https://www.aihero.dev/s/skills-newsletter",
|
||||||
|
"repository": "https://github.com/mattpocock/skills",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"engineering",
|
||||||
|
"skills",
|
||||||
|
"tdd",
|
||||||
|
"code-review",
|
||||||
|
"grilling",
|
||||||
|
"domain-modeling",
|
||||||
|
"productivity"
|
||||||
|
],
|
||||||
"skills": [
|
"skills": [
|
||||||
"./skills/engineering/ask-matt",
|
"./skills/engineering/ask-matt",
|
||||||
"./skills/engineering/diagnosing-bugs",
|
"./skills/engineering/diagnosing-bugs",
|
||||||
|
|||||||
@@ -1,5 +1,57 @@
|
|||||||
# mattpocock-skills
|
# mattpocock-skills
|
||||||
|
|
||||||
|
## 1.2.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- [#551](https://github.com/mattpocock/skills/pull/551) [`697d4ce`](https://github.com/mattpocock/skills/commit/697d4ce9742da558fd1ba6697c8e9775e2e302dd) Thanks [@mattpocock](https://github.com/mattpocock)! - Add Codex metadata alongside each skill's Claude Code frontmatter so the set works in both harnesses without generated copies.
|
||||||
|
|
||||||
|
- Add an `agents/openai.yaml` beside every `SKILL.md` with Codex UI metadata (`interface.display_name`, `interface.short_description`).
|
||||||
|
- Mark every user-invoked skill with `policy.allow_implicit_invocation: false`, the Codex analog of `disable-model-invocation: true`, so Codex excludes it from implicit invocation while explicit `$skill` invocation still works.
|
||||||
|
- Document the dual-harness invocation model in `.agents/invocation.md`, `CLAUDE.md`, and the promoted-bucket READMEs.
|
||||||
|
- Add `AGENTS.md` as a symlink to `CLAUDE.md` so Codex reads the same repo instructions.
|
||||||
|
|
||||||
|
- [#488](https://github.com/mattpocock/skills/pull/488) [`cdec9f6`](https://github.com/mattpocock/skills/commit/cdec9f6eb24dbfe606e3ad9b3eb457ba09210b85) Thanks [@mattpocock](https://github.com/mattpocock)! - Reword how the **`prototype`** skill handles its artifacts around a single idea: **the prototype is a primary source**. Rather than being deleted once it's answered its question, the prototype is captured as runnable evidence on a throwaway branch (`prototype/<name>`) out of main, with a context pointer to it left on the implementation issue — so the main branch keeps only the validated decision while the exploration stays findable. The answer (verdict + question) is still captured durably in an issue/ADR/commit.
|
||||||
|
|
||||||
|
- [#536](https://github.com/mattpocock/skills/pull/536) [`42a5b70`](https://github.com/mattpocock/skills/commit/42a5b70fcacc7baff1977b13f3919fb2f63af14e) Thanks [@mattpocock](https://github.com/mattpocock)! - Ship the skill set as a native **Claude Code plugin**. The repo is now its own single-plugin marketplace, so you can subscribe to the promoted skills as a managed, read-only bundle instead of copying editable files:
|
||||||
|
|
||||||
|
```
|
||||||
|
/plugin marketplace add mattpocock/skills
|
||||||
|
/plugin install mattpocock-skills@mattpocock
|
||||||
|
```
|
||||||
|
|
||||||
|
`.claude-plugin/plugin.json` gains full marketplace metadata (version, description, author, license, keywords) and a sibling `.claude-plugin/marketplace.json` lists the plugin. `skills.sh` remains the universal installer (and the path for Codex and other harnesses today); a native Codex plugin is deferred — see `.agents/adr/0002-ship-as-a-claude-code-plugin.md` for why.
|
||||||
|
|
||||||
|
- [#538](https://github.com/mattpocock/skills/pull/538) [`2602257`](https://github.com/mattpocock/skills/commit/260225724133c4a204489599f04642aa089259a0) Thanks [@mattpocock](https://github.com/mattpocock)! - Wayfinder now burns research tickets down with subagents instead of leaving them parked for a separately-launched session.
|
||||||
|
|
||||||
|
Research stays a real ticket type — it's a genuine shared blocker that downstream decisions hang on, and that dependency is exactly what the frontier's blocking edges exist to render. What changes is how it's resolved: because research is AFK, charting doesn't stop and read it. After creating the tickets, the charting session fires a `/research` subagent for each research ticket to burn it down in parallel, capturing the findings on a throwaway `research/<name>` branch with a context pointer. Research tickets are the one exception to _one ticket per session_.
|
||||||
|
|
||||||
|
- [#533](https://github.com/mattpocock/skills/pull/533) [`45afd80`](https://github.com/mattpocock/skills/commit/45afd8074a8b7de5fe073845d080fa9dd6c429fa) Thanks [@mattpocock](https://github.com/mattpocock)! - Add a YAGNI scoping filter to the **`improve-codebase-architecture`** skill's Explore step. Instead of scanning the whole repo evenly, it now scopes to where change is actually landing: if you name a direction it takes it, otherwise it reads the last ~20 commit messages to bias exploration toward actively-developed paths. A deepening opportunity in code nobody touches is a refactor you'll never cash in — the leverage only pays off where you keep editing — so the report stops tidying dormant corners of the repo.
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- [#535](https://github.com/mattpocock/skills/pull/535) [`e74fee8`](https://github.com/mattpocock/skills/commit/e74fee89feb6025a6a74f6282feb7d33b1b6e578) Thanks [@mattpocock](https://github.com/mattpocock)! - Make `/ask-matt` clued-up about `/wayfinder` — the heaviest, most cognitively demanding flow.
|
||||||
|
|
||||||
|
The router now sharpens the two routing mistakes people most often make with wayfinder:
|
||||||
|
|
||||||
|
- **Over-reaching for it.** It's slower and denser than a single grill, so it's flagged as the heaviest flow and reserved for the idea that genuinely won't fit one session — a well-scoped feature belongs on `/grill-with-docs`, not here.
|
||||||
|
- **Losing the way at the handoff.** When the map clears, wayfinder hands off, it doesn't build: merge onto the main flow at `/to-spec` (which collapses the map's linked decisions into a buildable plan) rather than looping the map straight into `/implement`. Straight-to-`/implement` is only for efforts that turned out genuinely small.
|
||||||
|
|
||||||
|
- [#502](https://github.com/mattpocock/skills/pull/502) [`44eed54`](https://github.com/mattpocock/skills/commit/44eed545186ffd0263e8004867750b80cfddd215) Thanks [@mattpocock](https://github.com/mattpocock)! - Make `/setup-matt-pocock-skills` friendlier and align the local-markdown tracker with the current spec.
|
||||||
|
|
||||||
|
- **Triage labels** are now asked about only when the `triage` skill is installed, and then as a single recommended-yes question ("keep the default triage labels?") instead of an override interrogation. When `triage` isn't installed, the section — and `docs/agents/triage-labels.md` — are skipped.
|
||||||
|
- **External PRs as a request surface** is no longer a setup question. The GitHub/GitLab templates still carry the flag, defaulted off; a user can flip it in `docs/agents/issue-tracker.md` later.
|
||||||
|
- **Domain docs** default to single-context without asking; multi-context is only offered when the repo shows monorepo signals.
|
||||||
|
- **Local-markdown tickets** are now one file per ticket under `.scratch/<feature>/issues/<NN>-<slug>.md` — never a single combined `tickets.md`. `/to-tickets` and the local issue-tracker template now agree, and the spec file is `spec.md` (not `PRD.md`) to match `/to-spec`.
|
||||||
|
|
||||||
|
Docs pages for `setup-matt-pocock-skills` and `to-tickets` re-synced.
|
||||||
|
|
||||||
|
- [#532](https://github.com/mattpocock/skills/pull/532) [`170ad48`](https://github.com/mattpocock/skills/commit/170ad48655825783d0193e850e31a9aac957bb95) Thanks [@mattpocock](https://github.com/mattpocock)! - Reword **`grilling`** for general use. Its description and body no longer scope the interview to a software plan: "this plan" → "this", "enact the plan" → "act on it", and "exploring the codebase" → "exploring the environment". The technique is unchanged; it now reads as a stress-test of any plan, decision, or idea.
|
||||||
|
|
||||||
|
- [#534](https://github.com/mattpocock/skills/pull/534) [`7d694b7`](https://github.com/mattpocock/skills/commit/7d694b7ae981ca221a8f759b15273fe7b5dc393e) Thanks [@mattpocock](https://github.com/mattpocock)! - Name the `/wayfinder` unit a **decision ticket**.
|
||||||
|
|
||||||
|
People kept reading a wayfinder ticket as an ordinary _implementation_ ticket — a slice of a build to execute — when wayfinder uses them as **decision tickets**: questions whose resolution is a decision. The skill description and its opening line now introduce "decision ticket" (and say what makes it one), and the `ask-matt` / engineering README wayfinder blurbs and the docs page match — while "ticket" stays the everyday word once the term is established. `CONTEXT.md` records **Decision ticket** as a domain term so the "avoid: ticket" guidance no longer contradicts wayfinder's deliberate use of the word.
|
||||||
|
|
||||||
## 1.1.0
|
## 1.1.0
|
||||||
|
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ Skills are organized into bucket folders under `skills/`:
|
|||||||
- `in-progress/` — drafts not yet ready to ship
|
- `in-progress/` — drafts not yet ready to ship
|
||||||
- `deprecated/` — no longer used
|
- `deprecated/` — no longer used
|
||||||
|
|
||||||
Every skill in `engineering/` or `productivity/` (the **promoted** buckets) must have a reference in the top-level `README.md` and an entry in `.claude-plugin/plugin.json`. Skills in `misc/`, `personal/`, `in-progress/`, and `deprecated/` must not appear in either.
|
Every skill in `engineering/` or `productivity/` (the **promoted** buckets) must have a reference in the top-level `README.md` and an entry in `.claude-plugin/plugin.json`'s `skills` array (the Claude Code plugin ships exactly the promoted set). Skills in `misc/`, `personal/`, `in-progress/`, and `deprecated/` must not appear in either.
|
||||||
|
|
||||||
|
The repo is also its own single-plugin Claude Code marketplace: `.claude-plugin/marketplace.json` lists the one `mattpocock-skills` plugin. When bumping the release version, keep `.claude-plugin/plugin.json`'s `version` in sync with `package.json`'s — Claude uses the plugin `version` to decide when installed users see an update. Run `claude plugin validate . --strict` after touching either manifest. Why a Claude plugin but not (yet) a Codex one lives in [.agents/adr/0002-ship-as-a-claude-code-plugin.md](./.agents/adr/0002-ship-as-a-claude-code-plugin.md).
|
||||||
|
|
||||||
Each skill entry in the top-level `README.md` must link the skill name to its `SKILL.md`.
|
Each skill entry in the top-level `README.md` must link the skill name to its `SKILL.md`.
|
||||||
|
|
||||||
@@ -15,7 +17,7 @@ Each bucket folder has a `README.md` that lists every skill in the bucket with a
|
|||||||
|
|
||||||
Skills in `engineering/` and `productivity/` also have a human-facing docs page at `docs/<bucket>/<skill-name>.md` (the docs tree mirrors those two bucket folders under `skills/`). The published URL is `https://aihero.dev/skills-<skill-name>` regardless of bucket — the docs path is repo organisation only. When you add, rename, or change the behaviour of a skill in `engineering/` or `productivity/`, create or re-sync its docs page following [.agents/writing-docs.md](./.agents/writing-docs.md). Skills in the non-promoted buckets (`misc/`, `personal/`, `in-progress/`, `deprecated/`) get **no** docs page.
|
Skills in `engineering/` and `productivity/` also have a human-facing docs page at `docs/<bucket>/<skill-name>.md` (the docs tree mirrors those two bucket folders under `skills/`). The published URL is `https://aihero.dev/skills-<skill-name>` regardless of bucket — the docs path is repo organisation only. When you add, rename, or change the behaviour of a skill in `engineering/` or `productivity/`, create or re-sync its docs page following [.agents/writing-docs.md](./.agents/writing-docs.md). Skills in the non-promoted buckets (`misc/`, `personal/`, `in-progress/`, `deprecated/`) get **no** docs page.
|
||||||
|
|
||||||
Every `SKILL.md` is either user-invoked (`disable-model-invocation: true`, reachable only by the human) or model-invoked (model- or user-reachable). See [.agents/invocation.md](./.agents/invocation.md).
|
Every `SKILL.md` is either user-invoked (`disable-model-invocation: true` plus `policy.allow_implicit_invocation: false` in `agents/openai.yaml`, reachable only by the human) or model-invoked (model- or user-reachable). See [.agents/invocation.md](./.agents/invocation.md).
|
||||||
|
|
||||||
[`ask-matt`](./skills/engineering/ask-matt/SKILL.md) is the router that maps every user-reachable skill and how they relate. The same trigger that re-syncs a docs page applies to it: whenever you add, rename, remove, or change how a user-reachable skill fits the flows, re-read `ask-matt`'s `SKILL.md` and update it so the map stays accurate — a new skill it never mentions, or a stale one it still routes to, is a router that lies.
|
[`ask-matt`](./skills/engineering/ask-matt/SKILL.md) is the router that maps every user-reachable skill and how they relate. The same trigger that re-syncs a docs page applies to it: whenever you add, rename, remove, or change how a user-reachable skill fits the flows, re-read `ask-matt`'s `SKILL.md` and update it so the map stays accurate — a new skill it never mentions, or a stale one it still routes to, is a router that lies.
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,33 @@ npx skills@latest add mattpocock/skills
|
|||||||
|
|
||||||
4. Bam - you're ready to go.
|
4. Bam - you're ready to go.
|
||||||
|
|
||||||
|
## Install as a Claude Code plugin
|
||||||
|
|
||||||
|
Prefer a plug-and-play install you don't maintain by hand? These skills also ship as a native [Claude Code plugin](https://code.claude.com/docs/en/plugins). Instead of copying editable files into your repo, the plugin installs the whole skill set as a managed bundle that updates when I ship a new version — you subscribe rather than fork.
|
||||||
|
|
||||||
|
Inside Claude Code:
|
||||||
|
|
||||||
|
```
|
||||||
|
/plugin marketplace add mattpocock/skills
|
||||||
|
/plugin install mattpocock-skills@mattpocock
|
||||||
|
```
|
||||||
|
|
||||||
|
Or from your shell:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
claude plugin marketplace add mattpocock/skills
|
||||||
|
claude plugin install mattpocock-skills@mattpocock
|
||||||
|
```
|
||||||
|
|
||||||
|
Then run `/setup-matt-pocock-skills` once per repo, exactly as in the quickstart above.
|
||||||
|
|
||||||
|
Two ways to install, two philosophies:
|
||||||
|
|
||||||
|
- **[skills.sh](https://skills.sh/mattpocock/skills)** copies the skills into your project so you can hack on them and make them your own.
|
||||||
|
- **The plugin** keeps them as a read-only, always-current bundle you don't edit — best when you just want my set to work and follow along as it evolves.
|
||||||
|
|
||||||
|
> Using Codex or another agent? The [skills.sh installer](https://skills.sh/mattpocock/skills) already installs these skills into Codex and other Agent-Skills-standard harnesses today. A native Codex plugin is on the roadmap — see [`.agents/adr/0002-ship-as-a-claude-code-plugin.md`](./.agents/adr/0002-ship-as-a-claude-code-plugin.md).
|
||||||
|
|
||||||
## Why These Skills Exist
|
## Why These Skills Exist
|
||||||
|
|
||||||
I built these skills as a way to fix common failure modes I see with Claude Code, Codex, and other coding agents.
|
I built these skills as a way to fix common failure modes I see with Claude Code, Codex, and other coding agents.
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mattpocock-skills",
|
"name": "mattpocock-skills",
|
||||||
"version": "1.1.0",
|
"version": "1.2.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Matt Pocock's agent skills for real engineering",
|
"description": "Matt Pocock's agent skills for real engineering",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ set -euo pipefail
|
|||||||
# Links all skills in the repository into the local skill directories used by
|
# Links all skills in the repository into the local skill directories used by
|
||||||
# each agent harness:
|
# each agent harness:
|
||||||
# - ~/.claude/skills — Claude Code
|
# - ~/.claude/skills — Claude Code
|
||||||
# - ~/.agents/skills — pi and other Agent-Skills-standard harnesses
|
# - ~/.agents/skills — Codex and other Agent Skills-compatible harnesses
|
||||||
# Each entry is a symlink into this repo, so a `git pull` is all that's needed
|
# Each entry is a symlink into this repo, so a `git pull` is all that's needed
|
||||||
# to keep installed skills up to date.
|
# to keep installed skills up to date.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Design an Interface"
|
||||||
|
short_description: "Explore alternative module interfaces"
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "QA"
|
||||||
|
short_description: "Conversational QA that files issues"
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Request Refactor Plan"
|
||||||
|
short_description: "Plan a safe incremental refactor"
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Ubiquitous Language"
|
||||||
|
short_description: "Build a shared domain glossary"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -4,7 +4,7 @@ Skills I use daily for code work.
|
|||||||
|
|
||||||
## User-invoked
|
## User-invoked
|
||||||
|
|
||||||
Reachable only when you type them (`disable-model-invocation: true`).
|
Reachable only when you type them (Claude Code: `disable-model-invocation: true`; Codex: `policy.allow_implicit_invocation: false` in `agents/openai.yaml`).
|
||||||
|
|
||||||
- **[ask-matt](./ask-matt/SKILL.md)** — Ask which skill or flow fits your situation. A router over the user-invoked skills in this repo.
|
- **[ask-matt](./ask-matt/SKILL.md)** — Ask which skill or flow fits your situation. A router over the user-invoked skills in this repo.
|
||||||
- **[grill-with-docs](./grill-with-docs/SKILL.md)** — Grilling session that also builds your project's domain model, sharpening terminology and updating `CONTEXT.md` and ADRs inline.
|
- **[grill-with-docs](./grill-with-docs/SKILL.md)** — Grilling session that also builds your project's domain model, sharpening terminology and updating `CONTEXT.md` and ADRs inline.
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Ask Matt"
|
||||||
|
short_description: "Find the right skill or workflow"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Code Review"
|
||||||
|
short_description: "Review a diff on standards and spec"
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Codebase Design"
|
||||||
|
short_description: "Vocabulary for deep-module design"
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Diagnosing Bugs"
|
||||||
|
short_description: "Diagnose hard bugs and regressions"
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Domain Modeling"
|
||||||
|
short_description: "Build and sharpen a domain model"
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Grill with Docs"
|
||||||
|
short_description: "Grill a design and write its docs"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Implement"
|
||||||
|
short_description: "Build work from a spec or tickets"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Improve Codebase Architecture"
|
||||||
|
short_description: "Find and grill architecture improvements"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Prototype"
|
||||||
|
short_description: "Prototype to answer a design question"
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Research"
|
||||||
|
short_description: "Research from high-trust sources"
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Resolving Merge Conflicts"
|
||||||
|
short_description: "Resolve merge and rebase conflicts"
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Setup Matt Pocock Skills"
|
||||||
|
short_description: "Configure a repo for the skills"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "TDD"
|
||||||
|
short_description: "Test-driven red-green-refactor"
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "To Spec"
|
||||||
|
short_description: "Turn a conversation into a spec"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "To Tickets"
|
||||||
|
short_description: "Split a plan into tracer-bullet tickets"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Triage"
|
||||||
|
short_description: "Move issues through triage roles"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Wayfinder"
|
||||||
|
short_description: "Map a large effort as decision tickets"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Claude Handoff"
|
||||||
|
short_description: "Hand off to a background agent"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Loop Me"
|
||||||
|
short_description: "Spec the workflows you want to build"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Setup TS Deep Modules"
|
||||||
|
short_description: "Enforce deep TypeScript modules"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Wizard"
|
||||||
|
short_description: "Generate an interactive setup wizard"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Writing Beats"
|
||||||
|
short_description: "Assemble raw material into beats"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Writing Fragments"
|
||||||
|
short_description: "Mine raw writing fragments"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Writing Shape"
|
||||||
|
short_description: "Shape raw material into an article"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Git Guardrails for Claude Code"
|
||||||
|
short_description: "Block dangerous git commands"
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Migrate to Shoehorn"
|
||||||
|
short_description: "Replace test assertions with shoehorn"
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Scaffold Exercises"
|
||||||
|
short_description: "Scaffold lint-ready course exercises"
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Setup Pre-Commit"
|
||||||
|
short_description: "Add pre-commit quality checks"
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Edit Article"
|
||||||
|
short_description: "Restructure and tighten a draft"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Obsidian Vault"
|
||||||
|
short_description: "Manage linked notes in Obsidian"
|
||||||
@@ -4,7 +4,7 @@ General workflow tools, not code-specific.
|
|||||||
|
|
||||||
## User-invoked
|
## User-invoked
|
||||||
|
|
||||||
Reachable only when you type them (`disable-model-invocation: true`).
|
Reachable only when you type them (Claude Code: `disable-model-invocation: true`; Codex: `policy.allow_implicit_invocation: false` in `agents/openai.yaml`).
|
||||||
|
|
||||||
- **[grill-me](./grill-me/SKILL.md)** — Get relentlessly interviewed about a plan or design until every branch of the decision tree is resolved.
|
- **[grill-me](./grill-me/SKILL.md)** — Get relentlessly interviewed about a plan or design until every branch of the decision tree is resolved.
|
||||||
- **[handoff](./handoff/SKILL.md)** — Compact the current conversation into a handoff document so another agent can continue the work.
|
- **[handoff](./handoff/SKILL.md)** — Compact the current conversation into a handoff document so another agent can continue the work.
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Grill Me"
|
||||||
|
short_description: "Sharpen a plan through interview"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Grilling"
|
||||||
|
short_description: "Stress-test thinking one question at a time"
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Handoff"
|
||||||
|
short_description: "Compact a conversation into a handoff"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Teach"
|
||||||
|
short_description: "Learn a concept in a guided workspace"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Writing Great Skills"
|
||||||
|
short_description: "Principles for predictable skills"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
Reference in New Issue
Block a user