kvnwolf

create-skill

Write, structure, and improve agent skills following best practices. Consult this skill whenever creating a new skill, improving an existing skill's description or body, structuring a SKILL.md file, or deciding how to organize skill content — even for quick fixes like rewriting a description that undertriggers.

kvnwolf 4 Updated 3mo ago

Resources

1
GitHub

Install

npx skillscat add kvnwolf/devtools/create-skill

Install via the SkillsCat registry.

SKILL.md

Creating Agent Skills

A skill is a markdown file that injects specialized instructions into the agent's context. Well-written skills dramatically improve the agent's output for specific tasks; poorly written ones waste tokens or never trigger at all.

Anatomy

skill-name/
├── SKILL.md                 ← required (the only file the agent loads on trigger)
├── scripts/                 ← optional (executable code for deterministic tasks)
├── references/              ← optional (docs loaded into context as needed)
└── assets/                  ← optional (templates, icons, fonts used in output)

Every skill has a SKILL.md with YAML frontmatter between --- markers. The frontmatter contains metadata; the body contains instructions.

---
name: my-skill
description: What it does and when to trigger it.
---

name and description are the two essential fields. For the complete list of frontmatter fields (allowed-tools, context, model, hooks, etc.), see references/frontmatter.md.

Three-Level Loading

Skills load progressively to minimize token cost:

Level When Loaded Budget Content
Metadata Always at startup ~100 tokens per skill name + description only
Body When skill triggers < 5k tokens ideal SKILL.md markdown content
Resources On demand Unlimited Files in references/, scripts/, assets/

The agent sees all skill descriptions at startup and decides which to load based on the current task. The body only enters context when the skill triggers. Resources load only when the body explicitly tells the agent to read them.

Writing the Description

The description is the single most important part of a skill — it determines whether the agent ever loads the rest. A vague description can drop activation rates to ~20%; a well-crafted one reaches 50-90%.

Rules

  • Write in third person (the description is injected into the agent's system prompt; first/second person causes discovery problems).
  • Stay under 1024 characters.
  • Lead with what the skill does, then list when to consult it.
  • Be task-oriented, not user-oriented — say "whenever installing components" rather than "whenever the user asks to install components." This ensures the skill triggers regardless of whether a human or another skill initiated the task.
  • Be broad with triggers. The agent uses LLM reasoning for routing (not keyword matching), so natural language works well. Include edge cases and indirect phrasings that might not seem obvious.

Formula

[Capability in third person]. Consult this skill whenever [trigger 1], [trigger 2], [trigger 3], or [edge-case trigger].

Bad vs. Good

Bad: "Helps with components" — too vague, won't trigger reliably.

Bad: "This skill should be used when the user wants to install shadcn components" — formulaic, user-dependent.

Good: "Install and customize shadcn/ui components to match project conventions. Consult this skill whenever installing, adding, or customizing shadcn/ui components — whether from a direct request or any task that involves running the shadcn CLI or editing shadcn component files."

Writing the Body

The body is what the agent reads when the skill triggers. Every line costs tokens across potentially millions of invocations, so each one should earn its place.

Core Principles

Only add what the agent doesn't already know. Challenge each paragraph: "Does the agent really need this?" For instance, the agent knows what PDFs are — don't explain that. But the agent doesn't know your project's compound component pattern — explain that.

Use imperative form. Write "Run the migration script" rather than "You should run the migration script" or "The migration script should be run."

Explain WHY, not just WHAT. Instead of rigid directives, give reasoning so the agent can adapt to edge cases:

# Heavy-handed (yellow flag)
NEVER use `--overwrite` when installing components.

# Reasoning-based (preferred)
Skip the `--overwrite` flag — existing components contain project-specific
customizations (compound patterns, import fixes) that would be lost on overwrite.

If you find yourself writing MUST, NEVER, or ALWAYS in caps, that's a signal to reframe. Explain the reasoning instead — the agent is smart enough to follow intent when it understands the consequences.

Match freedom to fragility. Not all instructions need the same specificity:

Freedom When Example
High Multiple valid approaches, context-dependent "Choose an appropriate caching strategy"
Medium Preferred pattern exists but variation is acceptable Pseudocode with parameters
Low Operations are fragile, consistency is critical Exact scripts, precise configs

Keep It Under 500 Lines

If SKILL.md approaches 500 lines, move detailed content into references/ files and point the agent to them with clear guidance on when to read each one:

For the complete API reference, see `references/api.md`.
For migration patterns from v1, see `references/migration.md`.

Progressive Disclosure

Use references/ and scripts/ directories to keep the main SKILL.md lean while providing depth on demand.

When to Split

  • SKILL.md exceeds ~300 lines and contains distinct sections that aren't always needed
  • Content spans multiple domains or frameworks (create one reference per domain)
  • Advanced features are optional or infrequently used

Rules of Thumb

  • Keep references one level deep from SKILL.md (no references/sub/nested.md).
  • Add a table of contents to reference files longer than 100 lines.
  • For domain-specific content, organize by variant so the agent reads only what's relevant:
cloud-deploy/
├── SKILL.md          (workflow + domain selection)
└── references/
    ├── aws.md
    ├── gcp.md
    └── azure.md

Bundled Scripts

Place pre-made scripts in scripts/ for operations that are deterministic, repetitive, or error-prone. Scripts are more reliable than having the agent write them from scratch every time, save tokens, and ensure consistency.

skill-name/
├── SKILL.md
└── scripts/
    ├── validate.sh
    └── generate-config.py

Good candidates for scripts:

  • File transformations with precise rules (parsing, formatting, conversion)
  • Validation and verification steps
  • Setup/scaffolding sequences with many exact commands
  • Any operation where the agent tends to reinvent the same helper across invocations

In SKILL.md, tell the agent to execute the script (not read it as reference) and explain what it does so the agent understands the output:

Run the validation script to check the generated output:
`scripts/validate.sh <output-path>`
It returns exit code 0 on success or prints the failing checks to stderr.

Handle errors inside the script rather than leaving the agent to figure them out — scripts should solve problems, not punt them. Justify any non-obvious configuration values in comments to avoid "magic constants."

Patterns

These recurring patterns work well across different skill types. See references/examples.md for full before/after demonstrations.

Reference Skills (Domain Knowledge)

For skills that provide conventions, patterns, or style guides without prescribing a specific workflow. Structure with clear sections, tables for quick lookup, and code examples.

## Variable Types
### Client Variables (`VITE_` prefix)
Variables the browser can read. Must have `VITE_` prefix.
### Server Variables (no prefix)
Variables only available on the server.

## Quick Reference
| Task | Action |
|------|--------|
| Access env var | `import { env } from "@/lib/env"` |

Task Skills (Step-by-Step Workflows)

For skills that prescribe an exact sequence of operations. Use numbered steps with clear conditionals and provide exact commands or file contents.

## Steps
### 1. Create config file
### 2. Install dependencies
### 3. Run initial setup

Before/After Examples

Show transformations clearly. This pattern helps the agent understand the desired output better than verbose descriptions:

**Example 1:**
Input: Added user authentication with JWT tokens
Output: feat(auth): implement JWT-based authentication

Or for code:

// Before (default)
export { Button, buttonVariants }

// After (project pattern)
export function Button({ className, ...props }: ButtonProps) { ... }

Quick Reference Tables

End with a lookup table for common operations:

## Quick Reference
| Task | Pattern |
|------|---------|
| Add render prop | `useRender.ComponentProps<"tagname">` |
| Merge props | `mergeProps<"tagname">({ ...defaults }, props)` |

Known Issues and Workarounds

Document gotchas with clear error messages and solutions:

## Known Issue: Custom Data Attributes
**Error:**
`Object literal may only specify known properties...`
**Workaround:**
Use `["data-slot" as string]: "value"` to bypass strict typing.

Naming Conventions

  • Folder names: kebab-case, no spaces or capitals (processing-pdfs, not ProcessingPDFs)
  • Skill names: lowercase letters, numbers, hyphens only, max 64 characters
  • Avoid reserved words (anthropic, claude) and XML angle brackets in names
  • Prefer gerund form for clarity: installing-components, managing-databases
  • File must be exactly SKILL.mdSKILL.MD or skill.md won't be discovered

Common Pitfalls

Pitfall Why It's a Problem
Vague description ~20% activation rate vs. 50-90% with specific triggers
"When to use" only in body The description is the trigger mechanism; the body loads after triggering
First/second person in description Causes discovery problems when injected into system prompt
Deeply nested references The agent may partially read nested files; keep references one level deep
Time-sensitive information Becomes stale; use "old patterns" sections instead
Inconsistent terminology Pick one term and use it everywhere
Over-explaining basics Wastes tokens — the agent already has general knowledge
Hardcoded absolute paths Use relative paths or {baseDir} references
All-caps MUST/NEVER/ALWAYS Yellow flag — reframe with reasoning instead
Too many options without a default Provide one recommended path with an escape hatch

Pre-Ship Checklist

Before finalizing a skill, verify:

  • SKILL.md exists with exact casing
  • Folder is kebab-case, no spaces
  • name and description in YAML frontmatter
  • Description is third-person, under 1024 chars
  • Description covers what it does AND when to trigger
  • Body is under 500 lines
  • Body uses imperative form
  • No unexplained MUST/NEVER/ALWAYS in caps
  • Instructions explain WHY, not just WHAT
  • Includes concrete examples (before/after, input/output)
  • References are one level deep
  • Large reference files (>100 lines) have a table of contents
  • Bundled scripts handle errors internally (no "voodoo constants")
  • Consistent terminology throughout
  • No time-sensitive information that will go stale