---
name: git-commit
description:
  Preparar y ejecutar git commit con mensajes Conventional Commits a partir del diff (tipo, scope, staging).
  Usar cuando pidan hacer commit, generar el mensaje o invocaciones tipo /commit.
license: MIT
allowed-tools: Bash
---

# Git Commit con Conventional Commits

## Purpose

Crear commits de git estandarizados y semánticos según Conventional Commits. Analizar el diff real para inferir tipo, scope y mensaje, y ejecutar el commit con staging coherente cuando haga falta.

Usar cuando el usuario pida hacer commit de cambios, crear un `git commit` o mencione `/commit`.

## Scope

**Incluye:** análisis de `git diff` / `git diff --staged`, sugerencia o generación de mensaje conventional (tipo, scope, descripción, body/footer si aplica), `git add` selectivo o por agrupación lógica, y `git commit` con el mensaje acordado (incluyendo flujo interactivo para sobrescribir tipo, scope o descripción).

**No incluye:** cambiar la configuración de git del usuario; operaciones destructivas (`--force`, reset duro, etc.) sin petición explícita; `git push` ni estrategias de ramas remotas; rebases interactivos o resolución de conflictos salvo que el usuario lo pida aparte; uso de `--no-verify` salvo petición explícita del usuario.

## Inputs

- Petición explícita de commit (o invocación tipo `/git-commit`).
- Estado del repo: preferiblemente conocer `git status` y el diff (staged y/o working tree).
- Opcional: preferencias del usuario sobre tipo, scope, título o agrupación de archivos en varios commits.
- Opcional: `docs/MEMORY.md` en la raíz del repo de trabajo, con `preferred language:` (véase Rules).

## Outputs

- Archivos en staging alineados con el cambio lógico que se va a commitear (cuando el agente gestione el staging).
- Un mensaje de commit que cumple Conventional Commits (tipo, scope opcional, descripción; body/footer si procede).
- Ejecución exitosa de `git commit` con ese mensaje, o explicación clara si debe hacerse en pasos manuales (p. ej. hooks, conflictos).

## Rules

- El mensaje debe seguir el formato Conventional Commit:

```
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]
```

- **Idioma del texto del commit (descripción, body y footers):** determinarlo en este orden: (1) inferencia del idioma del mensaje o petición del usuario en el turno actual; (2) si existe `docs/MEMORY.md` en el repo, leer la línea `preferred language:` (p. ej. `preferred language: es`) y usar ese código ISO 639-1; (3) si no existe el archivo o no hay esa línea, **preguntar al usuario** en qué idioma prefiere el texto en lenguaje natural (incluidos los mensajes de commit) y, con la respuesta, **crear** `docs/MEMORY.md` (o añadir la línea si el archivo existe) con `preferred language: <código ISO>` (p. ej. `es`, `en`). Redactar la parte en lenguaje natural del mensaje en ese idioma; **tipo y `scope`** siguen siendo las palabras clave convencionales en inglés (`feat`, `fix`, etc.) salvo que el equipo acuerde otra convención explícita.
- Inferir **tipo**, **scope** y **descripción** desde el diff; descripción en tiempo presente, modo imperativo, idealmente menos de 72 caracteres en la primera línea.
- **Un cambio lógico por commit**; si hay varios temas mezclados, proponer commits separados y staging acorde.
- **Nunca commitear secretos** (`.env`, credenciales, claves privadas).
- **Nunca** actualizar la configuración de git.
- **Nunca** ejecutar comandos destructivos (`--force`, hard reset, etc.) sin petición explícita.
- **Nunca** usar `--no-verify` salvo que el usuario lo pida.
- **Nunca** hacer force push a `main` / `master`.
- Si el commit falla por hooks, corregir el problema y crear un **nuevo** commit (no `amend`), salvo que el usuario indique lo contrario.
- Referencias a issues cuando aplique: `Closes #123`, `Refs #456`.

## Steps

### 1. Analizar el diff

```bash
# Si hay archivos en staging, usar el diff staged
git diff --staged

# Si no hay nada en staging, usar el diff del árbol de trabajo
git diff

# También verificar el estado
git status --porcelain
```

### 2. Añadir archivos al staging (si es necesario)

Si no hay nada en staging o conviene agrupar los cambios de otra forma:

```bash
# Añadir archivos específicos
git add path/to/file1 path/to/file2

# Añadir por patrón
git add *.test.*
git add src/components/*

# Staging interactivo
git add -p
```

### 3. Generar el mensaje del commit

Resolver primero el **idioma** del texto según las reglas (`docs/MEMORY.md` con `preferred language:` / petición / preguntar y persistir). A partir del diff, fijar:

- **Tipo:** qué clase de cambio es.
- **Scope:** área o módulo afectado (si es identificable).
- **Descripción:** una línea clara de qué cambió (imperativo, presente).

Ofrecer commit “interactivo”: el usuario puede sobrescribir tipo, scope o descripción antes de ejecutar.

### 4. Ejecutar el commit

```bash
# Una sola línea
git commit -m "<type>[scope]: <description>"

# Multi-línea con body/footer
git commit -m "$(cat <<'EOF'
<type>[scope]: <description>

<optional body>

<optional footer>
EOF
)"
```

## Examples

**Input:** usuario pide commit después de corregir un bug en el carrito; diff solo en `src/cart/checkout.ts`.

**Output:** `git add src/cart/checkout.ts` y `git commit -m "fix(cart): validate empty coupon before apply"`

**Input:** varios cambios: docs + feature mezclados.

**Output:** proponer dos commits: primero `docs: ...` con solo archivos de documentación, luego `feat(scope): ...` con el código de la feature.

## Anti-patterns

- Un solo commit gigante con refactors, features y fixes sin relación.
- Mensajes vagos (`update`, `fix stuff`, `changes`) sin tipo/scope alineados al diff.
- Incluir archivos sensibles porque “ya estaban en el directorio”.
- Saltar hooks con `--no-verify` por comodidad.
- Usar `git commit --amend` tras un fallo de hook cuando la regla del skill es crear un commit nuevo (salvo indicación contraria del usuario).

## Notes

### Tipos de commit (referencia)


| Tipo       | Propósito                         |
| ---------- | --------------------------------- |
| `feat`     | Nueva funcionalidad               |
| `fix`      | Corrección de bug                 |
| `docs`     | Solo documentación                |
| `style`    | Formato/estilo (sin lógica)       |
| `refactor` | Refactorización (sin feature/fix) |
| `perf`     | Mejora de rendimiento             |
| `test`     | Añadir/actualizar tests           |
| `build`    | Sistema de build/dependencias     |
| `ci`       | Cambios en CI/configuración       |
| `chore`    | Mantenimiento/miscelánea          |
| `revert`   | Revertir commit                   |


### Cambios breaking

```
# Signo de exclamación después de type/scope
feat!: remove deprecated endpoint

# Footer BREAKING CHANGE
feat: allow config to extend other configs

BREAKING CHANGE: `extends` key behavior changed
```

### Buenas prácticas adicionales

- Tiempo presente: “add”, no “added”.
- Modo imperativo: “fix bug”, no “fixes bug”.

