Saltar al contenido principal

czg — Wizard interactivo de commits

🔄 Reemplazado por wietoo (2026-07). czg + commitlint ya no son el estándar Wiedii — el hook compartido lefthook/base.yaml de wiedii-configs usa el binario nativo wietoo para el asistente y la validación de commits, en todos los stacks (sin Node). Esta nota queda como referencia histórica de cómo funcionaba el flujo anterior; para el flujo vigente ver wietoo-cli.

⚠️ Verificar versiones antes de usar — las versiones de czg, cz-git, @commitlint/cli y @commitlint/config-conventional en esta nota pueden estar desactualizadas. Consultar bun info <paquete> version antes de instalar. Ver politicas-core.

Qué es​

czg (cz-git) es un wizard de línea de comandos que guía al desarrollador a través de la creación de un mensaje de commit siguiendo el estándar Conventional Commits. En lugar de escribir el mensaje manualmente, el dev responde una serie de preguntas y czg construye el mensaje correctamente formateado.

En Wiedii, bun commit era el alias que invocaba czg — reemplazado por wietoo commit.

Por qué lo usábamos en Wiedii​

  • Eliminaba el margen de error humano en el formato de commits — feat(auth): add OAuth2 login siempre quedaba bien escrito
  • Guiaba a devs nuevos que aún no tenían memorizado el formato Conventional Commits
  • Se integraba con commitlint — el hook commit-msg validaba que el mensaje generado cumpliera las reglas, cerrando el ciclo
  • Velocidad — czg era significativamente más rápido que alternativas como commitizen con cz-conventional-changelog

Instalación​

Las secciones siguientes son referencia histórica del flujo anterior. Para el flujo vigente ver wietoo-cli.

czg iba como devDependency en el package.json de cada repo. No se instalaba globalmente.

bun add -d czg cz-git @commitlint/cli @commitlint/config-conventional
{
"type": "module",
"scripts": {
"commit": "bun --bun czg"
},
"devDependencies": {
"@commitlint/cli": "21.0.2",
"@commitlint/config-conventional": "21.0.2",
"cz-git": "1.13.1",
"czg": "1.13.1"
},
"engines": {
"bun": "1.3.14",
"node": "Please use Bun instead of Node to install dependencies",
"npm": "Please use Bun instead of NPM to install dependencies",
"pnpm": "Please use Bun instead of PNPM to install dependencies",
"yarn": "Please use Bun instead of Yarn to install dependencies"
}
}

czg vs cz-git — cz-git es dependencia transitiva de czg, pero se declara explícitamente porque commitlint.config.js la importa directamente (import { defineConfig } from 'cz-git'). commitizen no se usa — en Wiedii solo se invoca bun commit → czg.

"type": "module" — todos los repos nuevos en Wiedii usan ESM. El archivo de configuración commitlint.config.js usa import/export default en lugar de require/module.exports.

bun --bun czg — bun --bun fuerza el runtime de Bun (más rápido que Node). czg es el binario del wizard (lo instala el paquete czg). El binario para scripts es czg, no git-czg (este último solo habilita el atajo git czg).

engines — patrón Wiedii: mensajes de error en los campos de versión de otros package managers hace explícito que solo se usa Bun.


Uso​

# Flujo anterior — referencia histórica
git add .
bun commit # ejecutaba: bun --bun czg → abría el wizard interactivo

El wizard hacía las siguientes preguntas en orden:

  1. Tipo — feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
  2. Scope (opcional) — el módulo o área afectada, ej. auth, api, ui
  3. Título — descripción corta en imperativo, sin mayúscula inicial, sin punto final
  4. Cuerpo (opcional) — descripción larga con contexto adicional
  5. Breaking change — si es un cambio que rompe compatibilidad
  6. Issues relacionados (opcional) — referencia a issues de GitLab ej. #42

El resultado es un mensaje como:

feat(auth): add OAuth2 login with GitLab provider

Implements OAuth2 flow using GitLab as identity provider.
Replaces the previous username/password form.

BREAKING CHANGE: removes /api/login endpoint

Closes #42

Configuración estándar en Wiedii​

// commitlint.config.js — ESM (requiere "type": "module" en package.json)
import { defineConfig } from 'cz-git'

export default defineConfig({
extends: ['@commitlint/config-conventional'],
rules: {
'subject-case': [2, 'always', 'lower-case'],
'subject-full-stop': [2, 'never', '.'],
'header-max-length': [2, 'always', 100],
},
prompt: {
messages: {
type: "Select the type of change that you're committing:",
scope: 'Denote the SCOPE of this change (optional):',
customScope: 'Denote the SCOPE of this change:',
subject: 'Write a SHORT, IMPERATIVE tense description of the change:\n',
body: 'Provide a LONGER description of the change (optional). Use "|" to break new line:\n',
breaking: 'List any BREAKING CHANGES (optional). Use "|" to break new line:\n',
footerPrefixesSelect: 'Select the ISSUES type of change (optional):',
customFooterPrefix: 'Input ISSUES prefix:',
footer: 'List any ISSUES by this change. E.g.: #31, #34:\n',
confirmCommit: 'Are you sure you want to proceed with the commit above?',
},
types: [
{ value: 'feat', name: 'feat: ✨ A new feature', emoji: '✨' },
{ value: 'fix', name: 'fix: 🐛 A bug fix', emoji: '🐛' },
{ value: 'docs', name: 'docs: 📝 Documentation only changes', emoji: '📝' },
{ value: 'style', name: 'style: 💄 Changes that do not affect the meaning of the code', emoji: '💄' },
{ value: 'refactor', name: 'refactor: ♻️ A code change that neither fixes a bug nor adds a feature', emoji: '♻️' },
{ value: 'perf', name: 'perf: ⚡️ A code change that improves performance', emoji: '⚡️' },
{ value: 'test', name: 'test: ✅ Adding missing tests or correcting existing tests', emoji: '✅' },
{ value: 'build', name: 'build: 📦️ Changes that affect the build system or external dependencies', emoji: '📦️' },
{ value: 'ci', name: 'ci: 🎡 Changes to CI configuration files and scripts', emoji: '🎡' },
{ value: 'chore', name: "chore: 🔨 Other changes that don't modify src or test files", emoji: '🔨' },
{ value: 'revert', name: 'revert: ⏪️ Reverts a previous commit', emoji: '⏪️' },
],
useEmoji: true,
emojiAlign: 'center',
scopes: [],
allowCustomScopes: true,
allowEmptyScopes: true,
customScopesAlign: 'bottom',
customScopesAlias: 'custom',
emptyScopesAlias: 'empty',
enableMultipleScopes: true,
scopeEnumSeparator: ',',
upperCaseSubject: false,
markBreakingChangeMode: false,
allowBreakingChanges: ['feat', 'fix'],
maxHeaderLength: 100,
maxSubjectLength: 100,
breaklineNumber: 100,
breaklineChar: '|',
skipQuestions: [],
issuePrefixes: [
{ value: 'closed', name: 'closed: ISSUES has been processed' },
{ value: 'Fixes', name: 'Fixes: 🐛 Fixes an open ISSUE' },
{ value: 'Ref', name: 'Ref: 🔗 Related ISSUES' },
],
emptyIssuePrefixAlias: 'skip',
customIssuePrefixAlias: 'custom',
allowCustomIssuePrefix: true,
allowEmptyIssuePrefix: true,
confirmColorize: true,
defaultBody: '',
defaultIssues: '',
defaultScope: '',
defaultSubject: '',
},
})

changelog.config.js​

Archivo separado de commitlint.config.js. Lo consume conventional-changelog / Nx Release para generar CHANGELOG.md. Define los scopes del proyecto y el límite de longitud del mensaje.

// changelog.config.js — ESM
// Sobreescribe 'scopes' con los paquetes reales del repo
export default {
scopes: [], // ← completar con los módulos del proyecto
maxMessageLength: 100,
}

scopes debe reflejar exactamente los mismos valores definidos en commitlint.config.js → rules['scope-enum'] cuando el proyecto tiene scopes fijos.


Integración con lefthook​

El hook commit-msg valida el mensaje generado por czg antes de completar el commit:

# lefthook.yaml
commit-msg:
parallel: false
jobs:
- run: mise trust
- run: mise install --yes
commands:
commitlint:
priority: 1
run: mise exec -- bun commitlint --config commitlint.config.js --edit "$1"

Si el mensaje no cumple las reglas de commitlint.config.js, el commit se rechaza con un mensaje de error claro.


Troubleshooting rápido​

bun commit abre el wizard pero el commit falla con error de commitlint:

# Verificar que commitlint.config.js existe en la raíz del repo
ls commitlint.config.js

# Probar commitlint manualmente
bun commitlint --from HEAD~1

El wizard no muestra los tipos personalizados:

# Verificar que commitlint.config.js exporta el bloque `prompt`
# y que czg y cz-git están en devDependencies, no en dependencies
cat package.json | grep -E "czg|cz-git"

bun commit no encuentra czg:

# Verificar que está instalado
bun install
ls node_modules/.bin/czg

Referencias​