Receta · Básico · 10 min
Crea tu primera skill de Claude Code paso a paso
Crea una skill de proyecto en .claude/skills con SKILL.md, un script de apoyo y una description que Claude reconoce. Ejemplo: notas de versión con git.
Probado con Claude Code 2.1.316 · revisado
El problema
Cada vez que preparas una versión le pegas a Claude las mismas instrucciones: «mira los commits desde la última etiqueta, agrúpalos en novedades y correcciones, no inventes nada». Si esas instrucciones viven en tu cabeza o en el chat, se pierden y cada persona del equipo obtiene un resultado distinto. Una skill guarda ese procedimiento en el repositorio para que lo uses con /nombre o para que Claude lo cargue solo cuando haga falta.
La solución
Vamos a crear la skill notas-version, que genera notas de versión en Markdown a partir de git log.
1. Crea la carpeta de la skill
Las skills de proyecto viven en .claude/skills/<nombre>/SKILL.md, en la raíz del repositorio. Las personales van en ~/.claude/skills/<nombre>/SKILL.md y sirven para todos tus proyectos.
mkdir -p .claude/skills/notas-version/scripts
2. Escribe el SKILL.md
Guárdalo en .claude/skills/notas-version/SKILL.md. El bloque entre --- es el frontmatter y tiene que empezar en la primera línea del archivo.
---
name: notas-version
description: Genera notas de versión en Markdown a partir de los commits de git desde la última etiqueta. Úsala cuando pidan notas de versión, changelog, release notes o «qué cambió desde la última versión».
argument-hint: "[desde-etiqueta]"
allowed-tools: Bash(bash *notas-version/scripts/commits.sh*) Bash(git log *) Bash(git describe *)
---
# Notas de versión
## Commits desde la última versión
!`bash "${CLAUDE_SKILL_DIR}/scripts/commits.sh" $ARGUMENTS`
## Instrucciones
1. Agrupa los commits de arriba por su prefijo: `feat` → **Novedades**, `fix` → **Correcciones**, `docs` → **Documentación**, el resto → **Otros cambios**.
2. Reescribe cada commit como una frase corta para usuarios (sin hash ni prefijo), en el idioma de los commits.
3. Omite las secciones vacías. No inventes cambios que no estén en la lista.
4. Devuelve solo el Markdown, empezando por `## Cambios desde <etiqueta>`. Sigue el formato de [plantilla.md](plantilla.md).
Qué hace cada campo:
| Campo | Para qué sirve |
|---|---|
name | El comando del menú /. Si no lo pones, se usa el nombre de la carpeta. |
description | Qué hace y cuándo usarla. Claude la lee para decidir si carga la skill. |
argument-hint | La pista que ves al autocompletar, por ejemplo [desde-etiqueta]. |
allowed-tools | Herramientas que no piden permiso mientras dura el turno que invoca la skill. |
La línea ` !comando se ejecuta **antes** de que Claude lea la skill y su salida sustituye a la línea. Así Claude recibe los commits reales en lugar de tener que buscarlos. ${CLAUDE_SKILL_DIR} es la carpeta de la skill y $ARGUMENTS es lo que escribas después de /notas-version`.
Otros campos opcionales que documenta la guía oficial: when_to_use (más frases de activación), arguments (argumentos con nombre), disable-model-invocation: true (solo tú puedes invocarla), user-invocable: false (solo Claude puede invocarla), disallowed-tools, model, effort, context: fork con agent (ejecutarla en un subagente), hooks, paths (activarla solo con ciertos archivos) y shell. Todos son opcionales; Claude Code ignora sin avisar los nombres que no reconoce.
3. Añade un script de apoyo
Los scripts se ejecutan, no se cargan en el contexto. Guarda esto en .claude/skills/notas-version/scripts/commits.sh:
#!/usr/bin/env bash
# Lista los commits desde la etiqueta dada (o la última). Sin etiquetas, lista todo el historial.
desde="${1:-$(git describe --tags --abbrev=0 2>/dev/null)}"
if [ -n "$desde" ]; then
echo "Etiqueta de partida: $desde"
git log --no-merges --pretty='- %s (%h)' "$desde"..HEAD
else
echo "Etiqueta de partida: (ninguna, historial completo)"
git log --no-merges --pretty='- %s (%h)'
fi
chmod +x .claude/skills/notas-version/scripts/commits.sh
4. Añade un archivo de referencia
Los archivos de apoyo mantienen corto el SKILL.md: Claude los lee solo cuando los necesita porque el SKILL.md los enlaza. Guarda esto en .claude/skills/notas-version/plantilla.md:
## Cambios desde v1.2.0
### Novedades
- Exporta tus favoritos a CSV.
### Correcciones
- El cierre de sesión ya no deja la sesión abierta.
Al final te queda esta estructura:
.claude/skills/notas-version/
├── SKILL.md
├── plantilla.md
└── scripts/
└── commits.sh
5. Invócala
Dentro de Claude Code escribe /notas-version o, para partir de otra etiqueta o commit, /notas-version v1.0.0. Fuera de una sesión también funciona en modo no interactivo:
claude -p "/notas-version"
No hace falta reiniciar: Claude Code vigila las carpetas de skills y aplica los cambios en la sesión abierta. Si creaste la carpeta .claude/skills/ con la sesión ya abierta, ejecuta /reload-skills.
6. Escribe una description que haga que Claude la use
Claude solo ve el name y la description de cada skill hasta que decide cargarla. Para que la elija:
- Empieza por lo que hace: «Genera notas de versión en Markdown a partir de los commits de git…».
- Di cuándo usarla, con las palabras que diría alguien: «notas de versión, changelog, release notes, qué cambió desde la última versión».
- Pon lo importante al principio:
descriptionywhen_to_usejuntos se recortan a 1536 caracteres en el listado. - Evita
<y>: se muestran como<y>. Usa corchetes, como en[desde-etiqueta].
Con esa description, la pregunta «¿qué cambió desde la última versión? dame el changelog» hizo que Claude invocara la skill por su cuenta, sin escribir /notas-version.
Compruébalo
Probado con Claude Code 2.1.316 en un repositorio de prueba con la etiqueta v0.1.0 y dos commits posteriores (feat: exporta favoritos a CSV y docs: explica la instalación en el README):
claude -p "/notas-version"
Salida real:
## Cambios desde v0.1.0
### Novedades
- Exporta tus favoritos a CSV.
### Documentación
- Instrucciones de instalación añadidas al README.
Con un argumento (claude -p "/notas-version ffe8a84") también aparecieron el fix y la sección Correcciones. La redacción exacta cambia un poco en cada ejecución; los commits incluidos, no.
Por qué funciona
Al arrancar, Claude Code carga solo el nombre y la descripción de cada skill. El cuerpo del SKILL.md entra en el contexto cuando lo invocas con /notas-version o cuando Claude decide que la descripción encaja con lo que pides, y desde ahí se queda en la conversación. Antes de entregárselo a Claude, ejecuta las líneas ` !… ` y pone su salida en su lugar. Por eso la skill no gasta contexto mientras no la usas.
Skill, CLAUDE.md y subagente, según la documentación oficial:
| Cuándo se carga | Para qué sirve | |
|---|---|---|
CLAUDE.md | Siempre, al iniciar la sesión | Datos y convenciones fijas del proyecto |
| Skill | La descripción siempre; el cuerpo solo al invocarla | Procedimientos, listas de pasos, material de referencia |
| Subagente | En su propio contexto aparte | Trabajo delegado con sus propias herramientas e instrucciones |
La regla práctica de la guía: crea una skill cuando te descubras pegando las mismas instrucciones en el chat, o cuando una sección de CLAUDE.md se haya convertido en un procedimiento en vez de un dato. Si quieres que la skill corra aislada, context: fork la ejecuta en un subagente, que no ve tu conversación. Documentación: Skills y Subagentes.
Errores típicos
- Llamaste a la skill
release-notesyclaude -p "/release-notes"no imprime nada →/release-noteses un comando integrado de Claude Code y en modo-pse ejecutó el integrado, no tu skill (la guía solo dice que tu skill lo sustituye en una sesión de terminal local) → usa un nombre que no coincida con ningún comando integrado, comonotas-version. claude -p "/notas-version"termina sin imprimir nada → la línea `!…necesitaba permiso y en modo no interactivo no hay a quién preguntárselo, así que la invocación se cancela → añade el comando aallowed-tools, por ejemploBash(bash notas-version/scripts/commits.sh). Conclaude --debug-file log.txtverásShell command permission check failed`.- En
claude -p, Claude intenta usar la skill sola, dice que «dio un error al cargarse» y hace el trabajo a mano → el modo no interactivo no tenía permiso para la herramienta Skill → añade--allowedTools "Skill(notas-version)"o la reglaSkill(notas-version)en la listaallowde tus permisos. - Los campos del frontmatter no tienen efecto → el
---no está en la primera línea, el YAML no es válido o hay un nombre mal escrito (disable-model-invocationlleva guiones) → corrígelo;claude plugin validate .claude/skillsencuentra los SKILL.md con frontmatter roto. - Claude nunca la usa sin que escribas
/nombre→ la description es vaga o tienedisable-model-invocation: true→ incluye las palabras que dirías al pedirlo.
Preguntas frecuentes
¿Cuál es la diferencia entre una skill y un comando de .claude/commands?
Los comandos personalizados se fusionaron con las skills: .claude/commands/deploy.md y .claude/skills/deploy/SKILL.md crean el mismo /deploy. La skill añade una carpeta para archivos de apoyo y la carga automática por parte de Claude; si los dos tienen el mismo nombre, gana la skill.
¿Tengo que reiniciar Claude Code después de editar una skill?
No. Claude Code vigila las carpetas de skills y aplica los cambios en la sesión abierta. Solo si creas por primera vez una carpeta de skills de nivel superior necesitas /reload-skills.
¿Cómo impido que Claude la ejecute por su cuenta?
Añade disable-model-invocation: true al frontmatter. Así solo se ejecuta cuando escribes /notas-version, algo recomendable en skills con efectos, como desplegar o publicar.
¿Puedo compartirla con mi equipo?
Sí. Sube la carpeta .claude/skills/ al repositorio y cualquiera que abra Claude Code en ese proyecto tendrá /notas-version.
¿Qué tamaño debería tener el SKILL.md?
La guía oficial recomienda menos de 500 líneas. Lo detallado va a archivos de apoyo enlazados desde el SKILL.md, que Claude lee solo cuando los necesita.