Install
openclaw skills install @dennisrongo/write-a-skillCreate a new Claude Code skill — scaffolds a properly-structured SKILL.md (with YAML frontmatter, trigger-rich description, workflow, examples, anti-patterns), drops it in the right location (this library's skills/, the project's .claude/skills/, or the global ~/.claude/skills/), and — when adding to the dennisrongo/claude-skills library — also updates the README table. Use this skill whenever the user says "create a skill", "write a skill", "new skill", "add a skill", "make a skill", "/write-a-skill", or pastes a SKILL.md URL and asks for something similar — even if they don't explicitly say "skill author".
openclaw skills install @dennisrongo/write-a-skillAuthor a new Claude Code skill that Claude will actually trigger when it should. The description field is the only thing Claude sees when deciding whether to load the skill, so most of the effort goes into making that field specific and trigger-rich — not into the body.
SKILL.md (e.g. a GitHub link to someone else's skill) and asks for "one like this" / "similar to this" / "based on this".CLAUDE.md.Do not auto-trigger when the user is just discussing skills, asking how skills work in general, or editing an existing skill's body. Wait for an explicit author-a-new-skill cue.
Before scaffolding anything, figure out where the new skill belongs. The CWD usually tells you:
| Signal | Target |
|---|---|
CWD is the dennisrongo/claude-skills repo (has bin/claude-skills.js + skills/_template/) | skills/<name>/SKILL.md in this library — and update README table |
| CWD is some other project, user says "project skill" / "for this repo" | ./.claude/skills/<name>/SKILL.md |
| User says "global" / "every project" / "all my sessions" | ~/.claude/skills/<name>/SKILL.md |
| Ambiguous | Ask once with AskUserQuestion — don't guess |
If you're in the library repo, prefer that destination — the user can install it elsewhere later with claude-skills install <name>.
Confirm the trigger — and that a skill is the right tool. Restate in one sentence what the skill is for and the phrases that should trigger it. Bail and ask if either is fuzzy. Don't write a skill for: a one-off solution; a project-specific convention (belongs in CLAUDE.md/AGENTS.md); or a mechanical constraint a linter, hook, or validation script could enforce (automate it — save prose for judgment calls).
Gather requirements with AskUserQuestion (one question at a time, max 3–4 total). Pull from this menu — skip ones already answered:
SKILL.md enough?Pick the name. kebab-case, 2–4 words, matches what the user says. Use the leading-verb form when the skill does something (write-a-skill, diagnose, handoff); use the noun form when it defines something (conventional-commits, model-inventory).
Check for collisions. ls the target skills directory. If a skill with the same name exists, stop and ask the user whether to overwrite, rename, or extend the existing one.
Scaffold from _template/ if it exists in the destination, otherwise from the template embedded below. Create the parent directory if missing.
Draft the SKILL.md using the section structure in Required structure. Write the description LAST — it depends on the body. Match the form to the failure you're fixing:
| Baseline failure | Right form | Wrong form |
|---|---|---|
| Knows the rule, skips it under pressure | Prohibition + rationalization table ("Excuse → Reality") + red-flags list | Soft guidance ("prefer…", "consider…") |
| Complies, but output has the wrong shape (bloated, buried verdict) | A recipe/contract stating what the output IS — its parts, in order | A list of "don't"s (agents negotiate with prohibitions under competing incentives) |
| Omits a required element from something it already produces | A REQUIRED slot in the template it fills in | A prose reminder near the template |
| Behavior should depend on a condition | A conditional keyed to an observable predicate ("if X.md exists, …") | An unconditional rule plus exemption clauses |
No nuance clauses ("don't X unless it matters" reopens the negotiation) — express a real exception as its own conditional on something observable.
Write the description carefully — see Writing the description. This is the single highest-leverage part of the file.
Self-review against the Review checklist before showing the user.
If targeting the library repo, update README.md — add a row to the skills table in alphabetical order with a one-paragraph "what it does" hook matching the existing voice. Verify the row by re-reading the file after the edit.
Report back: skill path, the description verbatim, and the install command the user can run on other machines (npx --yes github:dennisrongo/claude-skills install <name> for library skills).
---
name: <kebab-case-name>
description: <see "Writing the description">
---
# <Title Case Name>
<1–2 sentence elevator pitch — what this skill does and why it exists.>
## When to use this skill
- <Concrete trigger phrase or condition>
- <Concrete trigger phrase or condition>
- <Concrete trigger phrase or condition>
<Optional: "Do **not** auto-trigger when …" — explicit non-triggers if the skill has near-neighbors.>
## Workflow
1. <Imperative step>
2. <Imperative step>
3. <Imperative step>
## Examples
### Example 1: <scenario name>
**User:** "<exact phrasing>"
**Claude:** <what the ideal behavior looks like — 1–3 bullets, not a full transcript>
## Anti-patterns
- ❌ <Thing Claude would plausibly do that's wrong>
- ❌ <Thing Claude would plausibly do that's wrong>
- ✅ <The right thing, contrasted>
## Notes
<Caveats, edge cases, things that only matter occasionally. Optional.>
Skip sections that would be empty. Reorder only if there's a real reason. Keep the file under ~150 lines — split into references/ if a section grows past that.
The description is the only field Claude reads when deciding whether to consult the skill. Optimize it for that decision:
Executes plans — dispatches a sub-agent per task with a code review between tasks. (a model reading this does one review and never opens the skill)Executes a written implementation plan task-by-task with fresh sub-agents. (outcome + scope; the review protocol lives in the body)Use this skill whenever the user says "<phrase 1>", "<phrase 2>", "<phrase 3>", … — even if they don't explicitly say "<skill name>". Include symptoms as well as commands ("flaky", "hanging", "is this a breaking change") — the model searches by problem, not by skill name.Good:
Capture a session hand-off so work can resume cleanly in a new Claude session before context runs out. Writes a canonical dated Markdown file (objective, progress, decisions, files, open issues, and a ready-to-paste "Next Session Prompt") AND a lightweight project-memory pointer to it. Use this skill whenever the user says "/handoff", "hand off", "handoff", "save context", "preserve context", "running out of context", …
Bad:
Helps the user create handoffs.
(The bad one tells Claude nothing about when — it'll under-trigger and the skill effectively doesn't exist.)
The most common failure mode is under-triggering (Claude doesn't load the skill when it should). Err on the side of more trigger phrases — three is the floor, not the ceiling.
The skill will be executed by whatever model loads it — often a smaller one. A top-tier model fills gaps with judgment; a weak one fills them with confident garbage. Encode the judgment explicitly. Preempt these predictable failure modes:
blocker must name a concrete failure scenario in one sentence (user does X → wrong Y). No scenario → demote to suggestion. Zero blockers is a valid result."tests: not run."references/ before you exceed ~150 lines.When reviewing a draft, simulate the weakest reader: for each instruction ask "could this be followed wrong while technically complying?" If yes, tighten it with a check, a threshold, or an example.
Default to a single SKILL.md. Only escalate when:
scripts/*.{js,sh,py}) — the operation is deterministic and Claude would otherwise regenerate the same code each call (validators, formatters, scaffolders). Scripts save tokens and improve reliability.references/*.md) — long lookup tables, exhaustive option lists, or domain glossaries that Claude only needs occasionally. Link from SKILL.md rather than inlining.If you do add either, mention them by relative path from the SKILL.md body so Claude knows they exist.
Before showing the draft to the user:
name: matches the directory name exactlydescription: starts with what the skill does (outcome + scope, no workflow steps), then "Use this skill whenever the user says …"## When to use this skill lists the same triggers as bullets (so the body reinforces the description)references/User: "/write-a-skill — I want one that runs eslint --fix and stages the changes whenever I say 'lint this'"
Claude:
AskUserQuestion.lint-and-stage, scaffolds skills/lint-and-stage/SKILL.md from _template/.eslint --fix, run git add -u, summarize changed files).README.md skills table.User: "Create a skill like https://github.com/mattpocock/skills/blob/main/skills/productivity/write-a-skill/SKILL.md but for our repo"
Claude:
User: "Add a skill just for this repo that reminds me to run pnpm changeset before any feat/fix commit"
Claude:
./.claude/skills/changeset-reminder/SKILL.md..claude/skills/ if missing.git commit / "commit" triggers that checks for a changeset file and warns if missing.SKILL.md with motivational prose. Every line should change Claude's behavior; if removing it changes nothing, cut it.SKILL.md prose when a 10-line script would be deterministic and cheaper._template/SKILL.template.md is the canonical starting point when working inside dennisrongo/claude-skills. It lives outside skills/ (so clawhub sync can't publish it and the installer can't pick it up) — copy it in as skills/<name>/SKILL.md.## Notes line — don't copy verbatim if the voice doesn't match this repo's existing skills.~/.claude/skills/ are picked up by every Claude Code session globally; .claude/skills/ in a project is scoped to that repo. The library repo's skills/<name>/ is the source — not where Claude reads from at runtime.