Añadidos arhcivos basicos de repos
This commit is contained in:
@@ -0,0 +1,377 @@
|
||||
# Comandos Claude disponibles
|
||||
|
||||
Índice de comandos personalizados. Todos los comandos siguen trunk-based development y el patrón pure core / impure shell.
|
||||
|
||||
## Estructura de Comandos
|
||||
|
||||
Los comandos están organizados en subdirectorios temáticos:
|
||||
|
||||
- **`git/`** - Comandos de gestión de ramas y merge
|
||||
- **`issues/`** - Comandos de gestión de issues del proyecto issues
|
||||
- **`project/`** - Comandos de proyecto (crear comandos, etc.)
|
||||
- **`workspace/`** - Comandos de workspace y worktrees
|
||||
|
||||
## Sistema de Inclusión
|
||||
|
||||
Los comandos pueden reutilizar fragmentos comunes usando el directorio `.claude/includes/`:
|
||||
|
||||
**Fragmentos disponibles:**
|
||||
- `git-verify-clean` - Verificar working tree limpio
|
||||
- `git-update-master` - Actualizar master desde remoto
|
||||
- `git-merge-to-master` - Merge a master con --no-ff
|
||||
- `ask-user-confirm` - Pedir confirmación al usuario
|
||||
- `issue-numbering` - Sistema de numeración de issues
|
||||
- `run-tests` - Ejecutar tests del proyecto
|
||||
|
||||
**Uso en comandos:**
|
||||
```markdown
|
||||
{{include: git-verify-clean}}
|
||||
```
|
||||
|
||||
Esto expande automáticamente el contenido de `.claude/includes/git-verify-clean.md` cuando Claude lee el comando.
|
||||
|
||||
## Comandos de Git
|
||||
|
||||
### `/git:branch <tipo> <slug>`
|
||||
Crea una rama de trabajo. Nunca trabajar directamente en master.
|
||||
|
||||
**Tipos:**
|
||||
- `issue <NNNN> <slug>` - Para implementar un issue existente
|
||||
- `quick <slug>` - Para cambios pequeños sin issue asociado
|
||||
|
||||
**Ejemplo:**
|
||||
```bash
|
||||
/git:branch issue 0013 hot-reload
|
||||
/git:branch quick fix-typo-readme
|
||||
```
|
||||
|
||||
### `/git:push`
|
||||
Integra cambios a master y publica. Soporta ramas `issue/*` y `quick/*`.
|
||||
|
||||
**Flujo:**
|
||||
1. Verifica rama y estado
|
||||
2. Crea commits atómicos por bloque lógico
|
||||
3. Ejecuta tests
|
||||
4. Merge --no-ff a master
|
||||
5. Push y limpieza
|
||||
|
||||
**Ejemplo:**
|
||||
```bash
|
||||
/git:push
|
||||
```
|
||||
|
||||
## Comandos de Issues
|
||||
|
||||
### `/issues:create-issue`
|
||||
Crea un issue nuevo en `dev/issues/` con confirmación del usuario.
|
||||
|
||||
**Características:**
|
||||
- Desglose automático en sub-issues si es necesario
|
||||
- Feature flags para issues multi-parte
|
||||
- Actualiza índice automáticamente
|
||||
- Pide confirmación antes de commit
|
||||
|
||||
**Ejemplo:**
|
||||
```bash
|
||||
/issues:create-issue
|
||||
```
|
||||
|
||||
### `/issues:auto-create`
|
||||
Crea un issue nuevo e integra automáticamente a master SIN pedir confirmación.
|
||||
|
||||
**Diferencia con `/issues:create-issue`:** No pausa para confirmación, ejecuta todo automáticamente.
|
||||
|
||||
**Ejemplo:**
|
||||
```bash
|
||||
/issues:auto-create
|
||||
```
|
||||
|
||||
### `/issues:fix-issue <NNNN>`
|
||||
Implementa un issue completo de punta a punta con confirmación.
|
||||
|
||||
**Flujo:**
|
||||
1. Crea rama issue/NNNN-slug
|
||||
2. Implementa todas las tareas
|
||||
3. Ejecuta tests
|
||||
4. Cierra el issue (mueve a completed/)
|
||||
5. Pide confirmación
|
||||
6. Integra a master
|
||||
|
||||
**Ejemplo:**
|
||||
```bash
|
||||
/issues:fix-issue 0013
|
||||
/issues:fix-issue 0013-hot-reload
|
||||
```
|
||||
|
||||
### `/issues:auto-fix <NNNN>`
|
||||
Implementa un issue completo automáticamente SIN pedir confirmación.
|
||||
|
||||
**Ejemplo:**
|
||||
```bash
|
||||
/issues:auto-fix 0013
|
||||
```
|
||||
|
||||
### `/issues:parallel`
|
||||
Analiza issues pendientes y genera plan de ejecución paralela en `PARALLEL_EXECUTION_ORDER.md`.
|
||||
|
||||
**Flujo:**
|
||||
1. Lee todas las issues en `dev/issues/`
|
||||
2. Detecta conflictos por archivos compartidos
|
||||
3. Detecta dependencias explícitas
|
||||
4. Agrupa issues independientes
|
||||
5. Genera plan con grupos paralelizables
|
||||
|
||||
**Ejemplo:**
|
||||
```bash
|
||||
/issues:parallel
|
||||
/issues:parallel --dry-run # Vista previa sin crear archivo
|
||||
```
|
||||
|
||||
### `/issues:execute-parallel`
|
||||
Ejecuta automáticamente issues del plan de ejecución paralela.
|
||||
|
||||
**Flujo:**
|
||||
1. Lee `PARALLEL_EXECUTION_ORDER.md`
|
||||
2. Crea worktrees para cada issue
|
||||
3. Ejecuta `/issues:auto-fix` en paralelo
|
||||
4. Merge y cleanup automático
|
||||
|
||||
**Ejemplo:**
|
||||
```bash
|
||||
/issues:execute-parallel 1 # Ejecutar Grupo 1
|
||||
/issues:execute-parallel --all-groups # Ejecutar TODOS los grupos
|
||||
/issues:execute-parallel 2 --dry-run # Vista previa del Grupo 2
|
||||
```
|
||||
|
||||
### `/issues:sort`
|
||||
Ordena issues en `dev/issues/README.md` según criterios específicos.
|
||||
|
||||
**Ejemplo:**
|
||||
```bash
|
||||
/issues:sort
|
||||
```
|
||||
|
||||
## Comandos de Workspace
|
||||
|
||||
### `/workspace:create-repo`
|
||||
Crea un nuevo subrepo (child repository) en `workspaces/` con estructura core/shell/app.
|
||||
|
||||
**Flujo:**
|
||||
1. Solicita nombre, descripción, tipo y privacidad
|
||||
2. Muestra resumen y pide confirmación
|
||||
3. Crea directorio local con estructura Go estándar
|
||||
4. Crea repositorio en Gitea
|
||||
5. Push inicial y registro en SQLite
|
||||
|
||||
**Prerequisitos:** `GITEA_URL` y `GITEA_TOKEN` configurados, feature flag `workspace_commands` habilitado.
|
||||
|
||||
**Ejemplo:**
|
||||
```bash
|
||||
/workspace:create-repo
|
||||
```
|
||||
|
||||
### `/workspace:sync-repos`
|
||||
Sincroniza workspaces locales con repositorios en Gitea.
|
||||
|
||||
**Flujo:**
|
||||
1. Obtiene workspaces locales desde SQLite
|
||||
2. Consulta repos en Gitea (organización o usuario)
|
||||
3. Genera plan: repos a clonar, actualizar, y huérfanos
|
||||
4. Muestra plan y pide confirmación
|
||||
5. Clona repos faltantes y actualiza metadata
|
||||
|
||||
**Prerequisitos:** `GITEA_URL` y `GITEA_TOKEN` configurados, feature flag `workspace_commands` habilitado.
|
||||
|
||||
**Ejemplo:**
|
||||
```bash
|
||||
/workspace:sync-repos # Sincronización con confirmación
|
||||
/workspace:sync-repos --dry-run # Solo análisis, sin cambios
|
||||
```
|
||||
|
||||
### `/workspace:list-repos`
|
||||
Lista todos los workspaces registrados en la BD local con soporte de filtro y ordenamiento.
|
||||
|
||||
**Flujo:**
|
||||
1. Obtiene workspaces de SQLite
|
||||
2. Aplica filtro si se especifica `--filter`
|
||||
3. Ordena según `--sort` (name o date)
|
||||
4. Muestra tabla ASCII con URLs de Gitea
|
||||
|
||||
**Prerequisitos:** Feature flag `workspace_commands` habilitado.
|
||||
|
||||
**Ejemplo:**
|
||||
```bash
|
||||
/workspace:list-repos
|
||||
/workspace:list-repos --filter pipeline
|
||||
/workspace:list-repos --sort name
|
||||
```
|
||||
|
||||
### `/workspace:cleanup-worktrees`
|
||||
Limpia worktrees obsoletos de git.
|
||||
|
||||
**Flujo:**
|
||||
1. Lista todos los worktrees activos
|
||||
2. Identifica worktrees sin rama asociada
|
||||
3. Pide confirmación
|
||||
4. Elimina worktrees y ramas
|
||||
|
||||
**Ejemplo:**
|
||||
```bash
|
||||
/workspace:cleanup-worktrees
|
||||
/workspace:cleanup-worktrees --all # Limpiar todos sin confirmación
|
||||
```
|
||||
|
||||
## Otros Comandos
|
||||
|
||||
### `/btw`
|
||||
Comando de contexto rápido ("by the way"). Permite agregar información contextual durante una conversación.
|
||||
|
||||
**Ejemplo:**
|
||||
```bash
|
||||
/btw
|
||||
```
|
||||
|
||||
## Comandos de Proyecto
|
||||
|
||||
### `/project:create-command`
|
||||
Crea un nuevo comando en `.claude/commands/` siguiendo la estructura estándar.
|
||||
|
||||
**Flujo:**
|
||||
1. Solicita inputs del comando
|
||||
2. Genera estructura desde template
|
||||
3. Muestra contenido al usuario
|
||||
4. Pide confirmación
|
||||
5. Integra a master automáticamente
|
||||
|
||||
**Ejemplo:**
|
||||
```bash
|
||||
/project:create-command
|
||||
```
|
||||
|
||||
## Convenciones Generales
|
||||
|
||||
### Mensajes estándar
|
||||
|
||||
**Éxito:**
|
||||
```
|
||||
✓ <acción> completada
|
||||
<detalles>
|
||||
```
|
||||
|
||||
**Error:**
|
||||
```
|
||||
✗ Error: <descripción>
|
||||
Solución: <pasos para resolver>
|
||||
```
|
||||
|
||||
**Advertencia:**
|
||||
```
|
||||
⚠ Advertencia: <descripción>
|
||||
¿Continuar? (s/n)
|
||||
```
|
||||
|
||||
### Estructura de comandos
|
||||
|
||||
Todos los comandos siguen esta estructura:
|
||||
|
||||
```markdown
|
||||
---
|
||||
version: X.Y.Z
|
||||
updated: YYYY-MM-DD
|
||||
tags: [categoria1, categoria2]
|
||||
---
|
||||
|
||||
# Command: nombre
|
||||
|
||||
## Para el usuario
|
||||
<Documentación de uso>
|
||||
|
||||
## Para Claude
|
||||
<Implementación técnica>
|
||||
|
||||
## Precondiciones
|
||||
<Verificaciones antes de ejecutar>
|
||||
|
||||
## Troubleshooting
|
||||
<Problemas comunes y soluciones>
|
||||
```
|
||||
|
||||
### Reglas de commits
|
||||
|
||||
- `feat:` nueva funcionalidad
|
||||
- `fix:` corrección de error
|
||||
- `refactor:` cambio estructural sin cambio funcional
|
||||
- `docs:` documentación
|
||||
- `chore:` mantenimiento
|
||||
- `test:` tests nuevos o modificados
|
||||
- `merge:` commit de merge (generado por --no-ff)
|
||||
|
||||
### Trunk-based development
|
||||
|
||||
- **Una rama por tarea**: corta (horas, no días)
|
||||
- **Merge rápido**: integrar a master frecuentemente
|
||||
- **No rebase interactivo**: preservar historia limpia
|
||||
- **Feature flags**: para features grandes, no para WIP
|
||||
- **Tests obligatorios**: siempre antes de merge
|
||||
|
||||
### Pure Core / Impure Shell
|
||||
|
||||
- **`core/`**: funciones puras, sin side effects
|
||||
- **`shell/`**: I/O, filesystem, network, APIs
|
||||
- **`app/`**: orquestación de core + shell
|
||||
|
||||
## Troubleshooting Global
|
||||
|
||||
### Error: "Rama ya existe"
|
||||
**Solución:**
|
||||
```bash
|
||||
git branch -D <rama> # Borrar rama local
|
||||
git checkout master # Volver a master
|
||||
/git:branch ... # Crear de nuevo
|
||||
```
|
||||
|
||||
### Error: "Working tree not clean"
|
||||
**Solución:**
|
||||
```bash
|
||||
git status # Ver cambios pendientes
|
||||
git add . # Stagear cambios
|
||||
git commit -m "..." # Commitear antes de cambiar rama
|
||||
```
|
||||
|
||||
### Error: "Tests failing"
|
||||
**Solución:**
|
||||
```bash
|
||||
go test -v -tags goolm ./... # Ver detalles de tests
|
||||
# Corregir errores
|
||||
# Re-ejecutar tests
|
||||
```
|
||||
|
||||
### Error: "Merge conflicts"
|
||||
**Solución:**
|
||||
```bash
|
||||
git status # Ver archivos en conflicto
|
||||
# Editar archivos y resolver conflictos manualmente
|
||||
git add <archivos-resueltos>
|
||||
git commit # Sin -m para mantener mensaje de merge
|
||||
```
|
||||
|
||||
### Error: "Cannot push to master directly"
|
||||
**Solución:**
|
||||
```bash
|
||||
git checkout -b quick/fix-direct-push
|
||||
# Ahora los cambios están en rama
|
||||
/git:push
|
||||
```
|
||||
|
||||
## Extensión de comandos
|
||||
|
||||
Para crear nuevos comandos, usar `/project:create-command` que genera la estructura estándar automáticamente.
|
||||
|
||||
Para modificar comandos existentes, seguir la estructura documentada en esta guía.
|
||||
|
||||
## Referencias
|
||||
|
||||
- Documentación de trunk-based: `CLAUDE.md`
|
||||
- Gestión de issues: `dev/README.md`
|
||||
- Roadmap del proyecto: `dev/ROADMAP.md`
|
||||
- Feature flags: `dev/feature_flags.json`
|
||||
@@ -0,0 +1,199 @@
|
||||
---
|
||||
version: 1.0.0
|
||||
updated: 2026-03-12
|
||||
tags: [conversation, read-only, discussion, opinion]
|
||||
---
|
||||
|
||||
# Command: btw
|
||||
|
||||
Permite conversar, preguntar y opinar sobre el repositorio en modo **read-only**. Este comando desactiva completamente la capacidad de escribir código o modificar archivos, permitiendo únicamente análisis, discusión y consultas.
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
Usa `/btw` cuando necesites:
|
||||
|
||||
- Charlar casualmente sobre el código sin riesgo de cambios accidentales
|
||||
- Pedir opiniones sobre arquitectura o diseño sin implementar
|
||||
- Hacer preguntas exploratorias sobre el codebase
|
||||
- Discutir ideas antes de comprometerte a implementarlas
|
||||
- Revisar código sin modificarlo
|
||||
- Analizar problemas sin aplicar fixes automáticamente
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
/btw [pregunta o tema de conversación]
|
||||
```
|
||||
|
||||
Si no proporcionas un tema, entra en modo conversación libre.
|
||||
|
||||
### Ejemplos
|
||||
|
||||
**Ejemplo 1:**
|
||||
```bash
|
||||
/btw qué opinas de la arquitectura core/shell/app?
|
||||
```
|
||||
|
||||
Abre una conversación sobre la arquitectura del proyecto sin realizar cambios.
|
||||
|
||||
**Ejemplo 2:**
|
||||
```bash
|
||||
/btw
|
||||
```
|
||||
|
||||
Entra en modo conversación libre para charlar sobre cualquier aspecto del repositorio.
|
||||
|
||||
**Ejemplo 3:**
|
||||
```bash
|
||||
/btw crees que deberíamos usar interfaces para el workspace manager?
|
||||
```
|
||||
|
||||
Discute opciones de diseño sin implementar nada todavía.
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
|
||||
- [ ] El usuario quiere conversar SIN modificar código
|
||||
- [ ] No hay expectativa de cambios inmediatos en el repositorio
|
||||
- [ ] Es una consulta exploratoria o discusión de ideas
|
||||
|
||||
### Inputs
|
||||
|
||||
Se necesitan los siguientes datos. Si no se proporcionan, preguntar al usuario:
|
||||
|
||||
- `topic` (opcional): tema o pregunta específica sobre el repositorio
|
||||
- Si no se proporciona: modo conversación libre
|
||||
|
||||
### Flujo obligatorio
|
||||
|
||||
#### 1. Activar modo read-only estricto
|
||||
|
||||
**IMPORTANTE:** Durante toda la ejecución de este comando:
|
||||
|
||||
- **NUNCA** uses las herramientas: `Write`, `Edit`, `NotebookEdit`, `Bash` (excepto para lectura)
|
||||
- **SOLO** puedes usar: `Read`, `Glob`, `Grep`, `Task` (con agentes read-only)
|
||||
- **NO** crees, modifíes ni elimines ningún archivo
|
||||
- **NO** ejecutes comandos que alteren el sistema de archivos
|
||||
- **NO** hagas commits, pushes ni cambios en git
|
||||
|
||||
Si el usuario pide hacer cambios durante la conversación, recuérdale amablemente:
|
||||
|
||||
```
|
||||
Estamos en modo /btw (read-only). Si quieres implementar cambios,
|
||||
sal de este comando y úsame normalmente.
|
||||
```
|
||||
|
||||
#### 2. Identificar el tema de conversación
|
||||
|
||||
Si el usuario proporcionó un `topic`:
|
||||
- Analiza qué información necesitas del repositorio
|
||||
- Lee los archivos relevantes usando `Read`, `Glob`, `Grep`
|
||||
- Responde basándote en el código actual
|
||||
|
||||
Si NO proporcionó `topic`:
|
||||
- Pregunta: "¿Sobre qué aspecto del repositorio quieres charlar?"
|
||||
- Espera su respuesta
|
||||
- Procede según el tema indicado
|
||||
|
||||
#### 3. Mantener conversación read-only
|
||||
|
||||
Durante la conversación:
|
||||
|
||||
- **Lee** archivos si es necesario para fundamentar respuestas
|
||||
- **Analiza** código existente
|
||||
- **Opina** sobre diseño, arquitectura, mejoras
|
||||
- **Sugiere** alternativas sin implementarlas
|
||||
- **Explica** conceptos y patrones del proyecto
|
||||
- **Discute** trade-offs y decisiones de diseño
|
||||
|
||||
**NUNCA:**
|
||||
- Modifiques código
|
||||
- Crees archivos de ejemplo
|
||||
- Ejecutes comandos que cambien el estado
|
||||
- Hagas refactors automáticos
|
||||
|
||||
#### 4. Salida del modo read-only
|
||||
|
||||
La conversación termina cuando:
|
||||
|
||||
- El usuario escribe otro comando (ej: `/factory:fix-issue`)
|
||||
- El usuario dice explícitamente "listo", "gracias", "suficiente"
|
||||
- El usuario pide implementar algo (recordarle que salga del modo `/btw`)
|
||||
|
||||
Al finalizar, confirmar:
|
||||
|
||||
```
|
||||
Conversación en modo read-only completada.
|
||||
Si quieres implementar algo de lo discutido, úsame normalmente (sin /btw).
|
||||
```
|
||||
|
||||
### Verificación final
|
||||
|
||||
No hay verificación de cambios porque este comando NO modifica nada.
|
||||
|
||||
Informar al usuario:
|
||||
|
||||
```
|
||||
✓ Modo conversación read-only activo
|
||||
|
||||
Puedes preguntarme lo que quieras sobre el repositorio.
|
||||
No realizaré ningún cambio en el código.
|
||||
|
||||
Para salir: usa otro comando o pide "listo"
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **No modificación**: Absolutamente ningún cambio en archivos, commits ni git
|
||||
- **Solo lectura**: Únicamente herramientas de lectura y análisis
|
||||
- **Conversación natural**: Responde como en una charla casual de code review
|
||||
- **Fundamenta en código**: Si opinas, referencia líneas específicas del código actual
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "Accidentalmente modifiqué un archivo"
|
||||
|
||||
**Causa:** Claude olvidó que está en modo `/btw`
|
||||
|
||||
**Solución:**
|
||||
1. Deshaz el cambio inmediatamente
|
||||
2. Recuerda las reglas del comando `/btw`
|
||||
3. Si el usuario quería ese cambio, sugiérele salir del modo `/btw`
|
||||
|
||||
### Usuario pide implementar durante /btw
|
||||
|
||||
**Causa:** El usuario olvidó que está en modo read-only
|
||||
|
||||
**Solución:**
|
||||
Responde amablemente:
|
||||
|
||||
```
|
||||
Estamos en modo /btw (solo lectura). Para implementar esto:
|
||||
1. Di "listo" para salir del modo /btw
|
||||
2. Luego pídeme que implemente el cambio normalmente
|
||||
```
|
||||
|
||||
### Necesitas ejecutar tests para responder
|
||||
|
||||
**Causa:** El usuario pregunta algo que requiere ejecutar código
|
||||
|
||||
**Solución:**
|
||||
Explica que en modo `/btw` no se ejecuta código:
|
||||
|
||||
```
|
||||
Para responder eso necesitaría ejecutar código, pero estamos en modo read-only.
|
||||
¿Quieres que salga del modo /btw y ejecute los tests?
|
||||
```
|
||||
|
||||
## Reglas críticas
|
||||
|
||||
- **NUNCA MODIFICAR ARCHIVOS** - Este es el propósito central del comando
|
||||
- **Solo herramientas read-only** - Read, Glob, Grep, Task (exploratorio)
|
||||
- **Recordatorio constante** - Si el usuario pide cambios, recordar que estamos en modo `/btw`
|
||||
- **Conversación fundamentada** - Basar opiniones en código real, no suposiciones
|
||||
- **Salida clara** - Confirmar cuando se sale del modo read-only
|
||||
@@ -0,0 +1,225 @@
|
||||
---
|
||||
version: 2.0.0
|
||||
updated: 2026-03-11
|
||||
tags: [git, workflow, trunk-based]
|
||||
---
|
||||
|
||||
# Command: git-branch
|
||||
|
||||
Crea una rama de trabajo. **Nunca trabajar directamente en master.**
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
Usar siempre antes de empezar cualquier trabajo. Dataforge sigue trunk-based development estricto: todo el trabajo se hace en ramas temporales que se integran rápidamente a master.
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
/git:branch issue <NNNN> <slug>
|
||||
/git:branch quick <slug>
|
||||
```
|
||||
|
||||
### Ejemplos
|
||||
|
||||
**Ejemplo 1: Rama para issue existente**
|
||||
```bash
|
||||
/git:branch issue 0013 hot-reload
|
||||
```
|
||||
|
||||
Crea rama `issue/0013-hot-reload` para implementar el issue 0013.
|
||||
|
||||
**Ejemplo 2: Rama para cambio rápido**
|
||||
```bash
|
||||
/git:branch quick fix-typo-readme
|
||||
```
|
||||
|
||||
Crea rama `quick/fix-typo-readme` para fix pequeño sin issue asociado.
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
|
||||
- [ ] Repositorio es un repo git válido
|
||||
- [ ] Branch master existe
|
||||
- [ ] No hay cambios sin commitear (working tree limpio)
|
||||
|
||||
### Inputs
|
||||
|
||||
Preguntar al usuario si el cambio está asociado a un issue o no.
|
||||
|
||||
#### Si es un issue:
|
||||
- `issue_number`: número de 4 dígitos (e.g. `0020`)
|
||||
- `slug`: nombre corto separado por guiones (e.g. `hot-reload`)
|
||||
|
||||
#### Si es un cambio rápido (sin issue):
|
||||
- `slug`: nombre corto descriptivo separado por guiones (e.g. `fix-typo-readme`)
|
||||
|
||||
### Flujo obligatorio
|
||||
|
||||
#### 1. Verificar estado actual del repositorio
|
||||
|
||||
{{include: git-verify-clean}}
|
||||
|
||||
```bash
|
||||
git branch --show-current
|
||||
git status --short
|
||||
```
|
||||
|
||||
**Si no estamos en master:**
|
||||
```bash
|
||||
git checkout master
|
||||
```
|
||||
|
||||
**Si hay cambios sin commitear:**
|
||||
✗ Error: Working tree no está limpio
|
||||
|
||||
⚠ Avisar al usuario y **STOP** hasta resolver:
|
||||
```
|
||||
Hay cambios sin commitear. Opciones:
|
||||
|
||||
1. Commitear cambios primero:
|
||||
git add .
|
||||
git commit -m "mensaje"
|
||||
|
||||
2. Hacer stash:
|
||||
git stash
|
||||
|
||||
3. Descartar cambios (⚠ peligroso):
|
||||
git reset --hard
|
||||
```
|
||||
|
||||
#### 2. Actualizar master desde remoto
|
||||
|
||||
{{include: git-update-master}}
|
||||
|
||||
```bash
|
||||
git pull --rebase
|
||||
```
|
||||
|
||||
#### 3. Crear la rama según tipo
|
||||
|
||||
**Para issues:**
|
||||
```bash
|
||||
git checkout -b issue/<issue_number>-<slug>
|
||||
```
|
||||
|
||||
Ejemplo: `git checkout -b issue/0013-hot-reload`
|
||||
|
||||
**Para cambios rápidos:**
|
||||
```bash
|
||||
git checkout -b quick/<slug>
|
||||
```
|
||||
|
||||
Ejemplo: `git checkout -b quick/fix-typo-readme`
|
||||
|
||||
#### 4. Verificar creación de rama
|
||||
|
||||
```bash
|
||||
git branch --show-current
|
||||
```
|
||||
|
||||
Debe mostrar el nombre de la nueva rama.
|
||||
|
||||
### Verificación final
|
||||
|
||||
Informar al usuario:
|
||||
|
||||
```
|
||||
✓ Rama `<nombre-rama>` creada desde master actualizado
|
||||
|
||||
Puedes empezar a trabajar.
|
||||
|
||||
Cuando termines:
|
||||
/git:push
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **Formato de rama issue**: `issue/<NNNN>-<slug>` (siempre 4 dígitos)
|
||||
- **Formato de rama quick**: `quick/<slug>` (sin número)
|
||||
- **Ramas cortas**: idealmente horas, no días
|
||||
- **Una rama por issue**: no mezclar issues en la misma rama
|
||||
- **Nunca pushear la rama al remoto**: el push se hace desde master después del merge
|
||||
- **No rebase interactivo**: si los commits son limpios desde el inicio, no reescribir historia
|
||||
- **No commits WIP**: cada commit en la rama debe ser atómico y con mensaje real
|
||||
|
||||
## Features multi-issue
|
||||
|
||||
Para features que no caben en una sola rama, usar sub-issues con sufijo letra:
|
||||
|
||||
```
|
||||
issue/0015a-telegram-types
|
||||
issue/0015b-telegram-client
|
||||
issue/0015c-telegram-listener
|
||||
issue/0015d-telegram-enable
|
||||
```
|
||||
|
||||
Cada sub-rama sigue el mismo flujo: crear → implementar → merge --no-ff → delete.
|
||||
El código parcial se protege con **feature flags** en `dev/feature_flags.json` (no con commits WIP).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "fatal: not a git repository"
|
||||
|
||||
**Causa:** El directorio actual no es un repositorio git.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
git init
|
||||
# O navegar al directorio correcto
|
||||
cd /ruta/al/repo
|
||||
```
|
||||
|
||||
### Error: "Your branch is behind 'origin/master'"
|
||||
|
||||
**Causa:** Master local está desactualizado respecto al remoto.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
git pull --rebase
|
||||
```
|
||||
|
||||
### Error: "fatal: A branch named 'issue/0013-hot-reload' already exists"
|
||||
|
||||
**Causa:** La rama ya existe localmente.
|
||||
|
||||
**Solución:**
|
||||
1. Verificar si tiene cambios importantes:
|
||||
```bash
|
||||
git log issue/0013-hot-reload
|
||||
```
|
||||
|
||||
2. Si no tiene cambios importantes, borrar:
|
||||
```bash
|
||||
git branch -D issue/0013-hot-reload
|
||||
```
|
||||
|
||||
3. Si tiene cambios importantes, usar otro nombre o recuperar esos cambios primero.
|
||||
|
||||
### Advertencia: "You have unstaged changes"
|
||||
|
||||
**Causa:** Hay archivos modificados sin stagear.
|
||||
|
||||
**Solución:**
|
||||
1. Ver cambios:
|
||||
```bash
|
||||
git status
|
||||
```
|
||||
|
||||
2. Decidir qué hacer:
|
||||
- Commitear: `git add . && git commit -m "mensaje"`
|
||||
- Descartar: `git restore <archivo>`
|
||||
- Stash: `git stash`
|
||||
|
||||
## Reglas críticas
|
||||
|
||||
- **NUNCA trabajar directamente en master** sin rama temporal
|
||||
- **SIEMPRE** verificar que el working tree esté limpio antes de crear rama
|
||||
- **SIEMPRE** actualizar master desde remoto antes de crear rama
|
||||
- **NO** pushear las ramas temporales al remoto (se integran via merge a master)
|
||||
- **NO** usar underscores en nombres de rama, solo guiones
|
||||
- **NO** crear ramas de larga duración (máximo 1-2 días, idealmente horas)
|
||||
@@ -0,0 +1,380 @@
|
||||
---
|
||||
version: 2.0.0
|
||||
updated: 2026-03-11
|
||||
tags: [git, workflow, trunk-based, integration]
|
||||
---
|
||||
|
||||
# Command: git-push
|
||||
|
||||
Integra cambios a master y publica. Soporta ramas `issue/*` y `quick/*`.
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
Usar cuando hayas terminado de trabajar en una rama temporal (issue/* o quick/*) y quieras integrar los cambios a master y publicar al remoto.
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
/git:push
|
||||
```
|
||||
|
||||
No requiere argumentos. Detecta automáticamente la rama actual y maneja el flujo completo.
|
||||
|
||||
### Ejemplos
|
||||
|
||||
**Ejemplo 1: Desde rama issue**
|
||||
```bash
|
||||
# Estando en issue/0013-hot-reload
|
||||
/git:push
|
||||
```
|
||||
|
||||
Crea commits atómicos, ejecuta tests, merge a master, push y limpia rama local.
|
||||
|
||||
**Ejemplo 2: Desde master con cambios**
|
||||
```bash
|
||||
# Estando en master con cambios pendientes
|
||||
/git:push
|
||||
```
|
||||
|
||||
Detecta cambios, crea automáticamente rama `quick/<slug>`, y ejecuta flujo completo.
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
|
||||
- [ ] Repositorio es un repo git válido
|
||||
- [ ] Hay cambios para commitear O estamos en una rama temporal
|
||||
- [ ] Tests del proyecto disponibles (si aplica)
|
||||
|
||||
### Inputs
|
||||
|
||||
No requiere inputs del usuario. El comando detecta automáticamente:
|
||||
- Rama actual (master, issue/*, quick/*)
|
||||
- Cambios pendientes (staged, unstaged)
|
||||
- Archivos modificados
|
||||
|
||||
### Flujo obligatorio
|
||||
|
||||
#### 1. Verificar rama actual y estado
|
||||
|
||||
```bash
|
||||
git branch --show-current
|
||||
git status --short
|
||||
```
|
||||
|
||||
##### Caso A: Estamos en rama `issue/*` o `quick/*`
|
||||
|
||||
✓ Continuar directamente al paso 2.
|
||||
|
||||
##### Caso B: Estamos en `master` con cambios pendientes
|
||||
|
||||
**Crear rama quick automáticamente antes de continuar:**
|
||||
|
||||
1. Detectar contexto automáticamente:
|
||||
|
||||
```bash
|
||||
git diff --name-only
|
||||
git diff --name-only --cached
|
||||
```
|
||||
|
||||
2. Analizar archivos para generar slug descriptivo:
|
||||
- Cambios en `README.md` → `update-readme`
|
||||
- Cambios en `.claude/` → `update-claude-config`
|
||||
- Cambios en `feature_flags.json` → `update-flags`
|
||||
- Cambios en `dev/issues/` → `update-issues`
|
||||
- Cambios en archivos de código → usar nombre del archivo principal
|
||||
- Cambios múltiples sin patrón claro → `misc-updates`
|
||||
|
||||
3. Crear rama quick automáticamente:
|
||||
|
||||
```bash
|
||||
git checkout -b quick/<slug-generado>
|
||||
```
|
||||
|
||||
4. Mostrar mensaje informativo:
|
||||
```
|
||||
✓ Creada rama automática: quick/<slug-generado>
|
||||
|
||||
Si estos cambios son parte de un issue, cancela (Ctrl+C) y usa:
|
||||
/factory:fix-issue <NNNN>
|
||||
```
|
||||
|
||||
5. Continuar al paso 2.
|
||||
|
||||
**IMPORTANTE:**
|
||||
- Por defecto siempre crear rama `quick/`
|
||||
- Solo usar `issue/` cuando se invoque desde `/factory:fix-issue` o el usuario indique explícitamente
|
||||
- No inventar números de issue
|
||||
- El objetivo es reducir fricción: si no sabes qué es, es un cambio quick
|
||||
|
||||
##### Caso C: Estamos en `master` sin cambios
|
||||
|
||||
✗ Error: No hay nada que publicar
|
||||
|
||||
**STOP**
|
||||
|
||||
#### 2. Revisar cambios y crear commits por bloque
|
||||
|
||||
```bash
|
||||
git status --short
|
||||
git diff --stat
|
||||
git diff
|
||||
```
|
||||
|
||||
Analizar los cambios y agruparlos en **bloques lógicos**. Cada bloque debe tener la misma naturaleza/propósito.
|
||||
|
||||
**Tipos de bloques comunes:**
|
||||
- Nuevas funcionalidades (feat)
|
||||
- Correcciones de bugs (fix)
|
||||
- Tests (test)
|
||||
- Documentación (docs)
|
||||
- Refactoring (refactor)
|
||||
- Configuración/mantenimiento (chore)
|
||||
|
||||
**Crear commits atómicos por bloque:**
|
||||
|
||||
```bash
|
||||
git add <archivos_del_bloque_1>
|
||||
git commit -m "<tipo>: <resumen breve>" -m "<descripción larga en español explicando qué cambia, por qué se hizo, impacto esperado y alcance del bloque>"
|
||||
|
||||
git add <archivos_del_bloque_2>
|
||||
git commit -m "<tipo>: <resumen breve>" -m "<descripción larga en español>"
|
||||
```
|
||||
|
||||
**Convención de tipos:**
|
||||
- `feat:` nueva funcionalidad
|
||||
- `fix:` corrección de error
|
||||
- `refactor:` cambio estructural sin cambio funcional
|
||||
- `docs:` documentación
|
||||
- `chore:` mantenimiento, config, deps
|
||||
- `test:` tests nuevos o modificados
|
||||
|
||||
**Reglas críticas de commits:**
|
||||
- **No WIP**: nunca commitear "wip", "tmp", "fix fix" ni código a medias
|
||||
- **No mezclar tipos**: no combinar `feat:` + `test:` en un mismo commit
|
||||
- **No squash**: los commits individuales se preservan en master via `--no-ff`
|
||||
- **No rebase interactivo**: si los commits ya son limpios, no reescribir historia
|
||||
- **Descripción larga obligatoria**: cada commit debe tener cuerpo explicativo en español
|
||||
|
||||
#### 3. Ejecutar tests
|
||||
|
||||
{{include: run-tests}}
|
||||
|
||||
**Obligatorio antes de mergear:**
|
||||
|
||||
```bash
|
||||
go test -tags goolm ./...
|
||||
```
|
||||
|
||||
**Casos:**
|
||||
- Tests **pasan** → ✓ Continuar al paso 4
|
||||
- Tests **fallan** → ✗ **STOP**: corregir antes de continuar. No mergear código roto.
|
||||
- No hay tests aplicables (solo docs/config) → ℹ Indicar al usuario y continuar al paso 4
|
||||
|
||||
#### 4. Evaluar feature flags
|
||||
|
||||
Feature flags se usan cuando el issue es **parte de una feature multi-issue** o el cambio tiene riesgo y necesita poder desactivarse.
|
||||
|
||||
**Feature flag ≠ WIP** — un flag protege código terminado y testeado, no código a medias.
|
||||
|
||||
**Si se modificó `dev/feature_flags.json` o cambios son parte de feature multi-fase:**
|
||||
|
||||
1. Verificar que `dev/feature_flags.json` existe y está actualizado
|
||||
2. Confirmar que el flag correspondiente tiene el estado correcto (`enabled: true/false`)
|
||||
3. Incluir el archivo en el commit correspondiente (no crear commit separado solo para flags)
|
||||
|
||||
**Si el issue es autocontenido** (se completa en esta rama):
|
||||
- No necesita flag
|
||||
- ✓ Saltar este paso
|
||||
|
||||
#### 5. Merge a master con --no-ff
|
||||
|
||||
{{include: git-merge-to-master}}
|
||||
|
||||
```bash
|
||||
git checkout master
|
||||
git pull --rebase
|
||||
git merge --no-ff <rama> -m "merge: <rama> — <título breve>"
|
||||
```
|
||||
|
||||
**Formato del mensaje de merge:**
|
||||
- Título: `merge: <rama> — <descripción corta>`
|
||||
- Cuerpo (opcional): resumen de lo que entra
|
||||
|
||||
**Ejemplos:**
|
||||
```
|
||||
merge: issue/0021-threads-default-config — habilitar threads en agentes
|
||||
merge: quick/fix-typo-readme — corregir typo en README
|
||||
```
|
||||
|
||||
**Si hay conflictos durante el merge:**
|
||||
1. Resolver los conflictos manualmente
|
||||
2. `git add` los archivos resueltos
|
||||
3. `git commit` (sin -m, para mantener el mensaje de merge)
|
||||
|
||||
#### 6. Push a remoto
|
||||
|
||||
```bash
|
||||
git push
|
||||
```
|
||||
|
||||
**Si falla el push:**
|
||||
- Error "rejected - non-fast-forward" → alguien pusheó a master antes
|
||||
- Solución: `git pull --rebase && git push`
|
||||
|
||||
#### 7. Limpiar rama local
|
||||
|
||||
```bash
|
||||
git branch -d <rama>
|
||||
```
|
||||
|
||||
**Si el branch delete falla:**
|
||||
- `-d` falla si la rama no está mergeada
|
||||
- Usar `-D` solo si estás seguro que el merge se completó correctamente
|
||||
|
||||
### Verificación final
|
||||
|
||||
```bash
|
||||
git log --oneline -3
|
||||
git branch --list
|
||||
```
|
||||
|
||||
Informar al usuario:
|
||||
|
||||
```
|
||||
✓ Rama `<rama>` integrada a master y publicada
|
||||
|
||||
Commits creados:
|
||||
- <commit 1>
|
||||
- <commit 2>
|
||||
- merge: <rama>
|
||||
|
||||
Rama local eliminada.
|
||||
Master actualizado y sincronizado con remoto.
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **Commits atómicos**: un commit = un cambio lógico completo
|
||||
- **Mensajes descriptivos**: título corto + cuerpo explicativo en español
|
||||
- **No mezclar tipos**: feat, fix, test, docs cada uno en su commit
|
||||
- **Tests obligatorios**: siempre ejecutar antes de merge
|
||||
- **Merge --no-ff**: preservar historia de la rama
|
||||
- **Push inmediato**: integrar y publicar en un solo flujo
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "nothing to commit, working tree clean"
|
||||
|
||||
**Causa:** No hay cambios pendientes para commitear.
|
||||
|
||||
**Solución:**
|
||||
Si estás en una rama temporal y todos los cambios ya están commiteados, continúa con el merge. Si estás en master sin cambios, no hay nada que hacer.
|
||||
|
||||
### Error: "Tests failing"
|
||||
|
||||
**Causa:** Los tests no pasan.
|
||||
|
||||
**Solución:**
|
||||
1. Ver detalles de los tests fallidos:
|
||||
```bash
|
||||
go test -v -tags goolm ./...
|
||||
```
|
||||
|
||||
2. Corregir el código que causa el fallo
|
||||
3. Re-ejecutar tests hasta que pasen
|
||||
4. Crear commit con el fix si es necesario
|
||||
5. Continuar con el merge
|
||||
|
||||
### Error: "merge conflict in <archivo>"
|
||||
|
||||
**Causa:** El archivo tiene cambios en master que conflictúan con tu rama.
|
||||
|
||||
**Solución:**
|
||||
1. Ver conflictos:
|
||||
```bash
|
||||
git status
|
||||
```
|
||||
|
||||
2. Abrir archivo y resolver marcadores de conflicto:
|
||||
```
|
||||
<<<<<<< HEAD
|
||||
código en master
|
||||
=======
|
||||
tu código
|
||||
>>>>>>> rama
|
||||
```
|
||||
|
||||
3. Editar y dejar solo la versión correcta
|
||||
|
||||
4. Stagear archivo resuelto:
|
||||
```bash
|
||||
git add <archivo>
|
||||
```
|
||||
|
||||
5. Completar merge:
|
||||
```bash
|
||||
git commit
|
||||
```
|
||||
|
||||
### Error: "branch -d <rama> failed"
|
||||
|
||||
**Causa:** Git detecta que la rama no está completamente mergeada.
|
||||
|
||||
**Solución:**
|
||||
1. Verificar si el merge se completó correctamente:
|
||||
```bash
|
||||
git log --oneline -5
|
||||
```
|
||||
|
||||
2. Si el merge commit está presente, forzar eliminación:
|
||||
```bash
|
||||
git branch -D <rama>
|
||||
```
|
||||
|
||||
3. Si el merge no se completó, volver atrás y resolver el problema.
|
||||
|
||||
### Error: "rejected - non-fast-forward"
|
||||
|
||||
**Causa:** Alguien más pusheó cambios a master mientras trabajabas.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
git pull --rebase
|
||||
git push
|
||||
```
|
||||
|
||||
Si hay conflictos durante el rebase, resolverlos y continuar:
|
||||
```bash
|
||||
# Resolver conflictos
|
||||
git add <archivos-resueltos>
|
||||
git rebase --continue
|
||||
git push
|
||||
```
|
||||
|
||||
### Advertencia: "Detached HEAD state"
|
||||
|
||||
**Causa:** No estás en ninguna rama.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
git checkout master
|
||||
# O crear rama si tienes cambios importantes
|
||||
git checkout -b quick/rescue-changes
|
||||
```
|
||||
|
||||
## Reglas críticas
|
||||
|
||||
- **NO hacer commits WIP** - cada commit debe ser atómico y completo
|
||||
- **NO mezclar tipos** en un commit (feat + test en commits separados)
|
||||
- **NO saltear tests** - si fallan, arreglar antes de merge
|
||||
- **NO hacer push --force** a master nunca
|
||||
- **NO hacer squash** - preservar commits individuales vía --no-ff
|
||||
- **SIEMPRE** escribir descripción larga en español en cada commit
|
||||
- **SIEMPRE** ejecutar tests antes de merge a master
|
||||
- **SIEMPRE** usar --no-ff para el merge
|
||||
- **SIEMPRE** limpiar rama local después del merge
|
||||
@@ -0,0 +1,407 @@
|
||||
# Command: git-recovery
|
||||
|
||||
Recupera el repositorio de estados inconsistentes causados por worktrees huérfanos, branches bloqueados o conflictos de git. Ejecuta automáticamente cuando se detectan errores git durante operaciones de issues.
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
- Cuando hay errores "exit status 128" al crear worktrees
|
||||
- Cuando git reporta "worktree already exists"
|
||||
- Cuando hay branches que no se pueden eliminar
|
||||
- Cuando `git worktree list` muestra worktrees huérfanos
|
||||
- Cuando el orquestador paralelo falla por problemas git
|
||||
- **Automáticamente:** El sistema lo invoca cuando detecta errores git
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
/git:recovery [--aggressive]
|
||||
```
|
||||
|
||||
### Parámetros
|
||||
|
||||
- `--aggressive` (opcional): Fuerza limpieza agresiva incluyendo branches remotas y reset de estado
|
||||
|
||||
### Ejemplos
|
||||
|
||||
**Ejemplo 1: Recuperación estándar (recomendado)**
|
||||
```bash
|
||||
/git:recovery
|
||||
```
|
||||
|
||||
Limpia worktrees huérfanos, verifica estado, sincroniza con remoto.
|
||||
|
||||
**Ejemplo 2: Recuperación agresiva**
|
||||
```bash
|
||||
/git:recovery --aggressive
|
||||
```
|
||||
|
||||
Incluye force-prune, eliminación de branches huérfanas, reset de índice.
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
|
||||
- [ ] Estamos en un repositorio git válido
|
||||
- [ ] Hay permisos para modificar .git/
|
||||
- [ ] No hay operaciones git críticas en progreso (rebase, merge)
|
||||
|
||||
### Inputs
|
||||
|
||||
- `--aggressive` (opcional): Modo agresivo de limpieza
|
||||
|
||||
### Flujo obligatorio
|
||||
|
||||
#### 1. Diagnóstico inicial
|
||||
|
||||
```bash
|
||||
echo "🔍 Diagnosticando estado del repositorio..."
|
||||
echo ""
|
||||
|
||||
# Verificar que estamos en repo git
|
||||
if [ ! -d ".git" ]; then
|
||||
echo "❌ Error: No estamos en un repositorio git"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Guardar estado actual
|
||||
git branch --show-current > /tmp/git-recovery-current-branch.txt
|
||||
git status --porcelain > /tmp/git-recovery-status.txt
|
||||
|
||||
echo "Rama actual: $(cat /tmp/git-recovery-current-branch.txt)"
|
||||
echo "Cambios pendientes: $(wc -l < /tmp/git-recovery-status.txt) archivos"
|
||||
echo ""
|
||||
```
|
||||
|
||||
#### 2. Análisis de problemas
|
||||
|
||||
```bash
|
||||
echo "📋 Analizando problemas..."
|
||||
echo ""
|
||||
|
||||
# Listar worktrees (puede fallar si hay huérfanos)
|
||||
echo "Worktrees actuales:"
|
||||
git worktree list 2>&1 || echo " (error listando worktrees - probablemente hay huérfanos)"
|
||||
echo ""
|
||||
|
||||
# Verificar branches locales
|
||||
echo "Branches locales:"
|
||||
git branch --list
|
||||
echo ""
|
||||
|
||||
# Verificar branches remotas
|
||||
echo "Estado remoto:"
|
||||
git remote -v
|
||||
git fetch --dry-run 2>&1 || echo " (problemas con fetch)"
|
||||
echo ""
|
||||
```
|
||||
|
||||
#### 3. Limpieza de worktrees huérfanos
|
||||
|
||||
```bash
|
||||
echo "🧹 Limpiando worktrees huérfanos..."
|
||||
echo ""
|
||||
|
||||
# Ejecutar prune (elimina referencias a worktrees que ya no existen)
|
||||
git worktree prune -v 2>&1
|
||||
|
||||
# Verificar si aún hay worktrees huérfanos en disco
|
||||
if [ -d "worktrees" ]; then
|
||||
echo ""
|
||||
echo "Verificando directorio worktrees/..."
|
||||
|
||||
# Listar directorios en worktrees/
|
||||
for worktree_dir in worktrees/issue-*; do
|
||||
if [ -d "$worktree_dir" ]; then
|
||||
worktree_name=$(basename "$worktree_dir")
|
||||
|
||||
# Verificar si git lo conoce
|
||||
if ! git worktree list | grep -q "$worktree_dir"; then
|
||||
echo " ⚠️ Worktree huérfano detectado: $worktree_name"
|
||||
|
||||
# Eliminar directorio huérfano
|
||||
rm -rf "$worktree_dir"
|
||||
echo " ✓ Eliminado: $worktree_dir"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✓ Limpieza de worktrees completada"
|
||||
echo ""
|
||||
```
|
||||
|
||||
#### 4. Verificación de branches bloqueados
|
||||
|
||||
```bash
|
||||
echo "🔓 Verificando branches bloqueados..."
|
||||
echo ""
|
||||
|
||||
# Listar branches que podrían estar bloqueados
|
||||
git branch --list 'issue/*' 'quick/*' | while read -r branch; do
|
||||
branch=$(echo "$branch" | sed 's/^\* //' | xargs)
|
||||
|
||||
# Verificar si la branch está asociada a un worktree
|
||||
if git worktree list | grep -q "$branch"; then
|
||||
echo " ℹ️ Branch activa en worktree: $branch"
|
||||
else
|
||||
# Branch no está en worktree, podría estar mergeada
|
||||
if git branch --merged master | grep -q "$branch"; then
|
||||
echo " ✓ Branch mergeada, puede eliminarse: $branch"
|
||||
git branch -d "$branch" 2>&1 || echo " (no se pudo eliminar automáticamente)"
|
||||
else
|
||||
echo " ⚠️ Branch NO mergeada: $branch"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
```
|
||||
|
||||
#### 5. Sincronización con remoto
|
||||
|
||||
```bash
|
||||
echo "🔄 Sincronizando con remoto..."
|
||||
echo ""
|
||||
|
||||
# Volver a master si no estamos ahí
|
||||
current_branch=$(git branch --show-current)
|
||||
if [ "$current_branch" != "master" ]; then
|
||||
echo "Cambiando a master desde $current_branch..."
|
||||
git checkout master 2>&1 || {
|
||||
echo "❌ No se pudo cambiar a master"
|
||||
echo " Quedando en rama: $current_branch"
|
||||
}
|
||||
fi
|
||||
|
||||
# Fetch y pull
|
||||
echo "Actualizando desde origin/master..."
|
||||
git fetch origin 2>&1
|
||||
git pull --rebase origin master 2>&1 || {
|
||||
echo "⚠️ Problemas al hacer pull, continuando..."
|
||||
}
|
||||
|
||||
echo ""
|
||||
echo "✓ Sincronización completada"
|
||||
echo ""
|
||||
```
|
||||
|
||||
#### 6. Modo agresivo (solo si --aggressive)
|
||||
|
||||
```bash
|
||||
if [ "$AGGRESSIVE" = "true" ]; then
|
||||
echo "⚡ MODO AGRESIVO ACTIVADO"
|
||||
echo ""
|
||||
|
||||
echo "Limpiando branches remotas obsoletas..."
|
||||
git remote prune origin -v 2>&1
|
||||
echo ""
|
||||
|
||||
echo "Verificando integridad del repositorio..."
|
||||
git fsck --full 2>&1 | head -20
|
||||
echo ""
|
||||
|
||||
echo "Limpiando objetos no referenciados..."
|
||||
git gc --prune=now 2>&1
|
||||
echo ""
|
||||
|
||||
echo "Verificando índice..."
|
||||
if [ -f ".git/index.lock" ]; then
|
||||
echo " ⚠️ Encontrado index.lock (proceso git interrumpido)"
|
||||
rm -f .git/index.lock
|
||||
echo " ✓ Eliminado .git/index.lock"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✓ Limpieza agresiva completada"
|
||||
echo ""
|
||||
fi
|
||||
```
|
||||
|
||||
#### 7. Verificación final
|
||||
|
||||
```bash
|
||||
echo "✅ Verificación final..."
|
||||
echo ""
|
||||
|
||||
# Estado limpio
|
||||
echo "Estado del repositorio:"
|
||||
git status
|
||||
echo ""
|
||||
|
||||
# Worktrees finales
|
||||
echo "Worktrees activos:"
|
||||
git worktree list
|
||||
echo ""
|
||||
|
||||
# Branches locales
|
||||
echo "Branches locales:"
|
||||
git branch --list
|
||||
echo ""
|
||||
```
|
||||
|
||||
#### 8. Resumen
|
||||
|
||||
```bash
|
||||
echo "════════════════════════════════════════════════════════"
|
||||
echo "RECUPERACIÓN COMPLETADA"
|
||||
echo "════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
|
||||
# Comparar estado antes/después
|
||||
CHANGES_BEFORE=$(wc -l < /tmp/git-recovery-status.txt)
|
||||
CHANGES_AFTER=$(git status --porcelain | wc -l)
|
||||
|
||||
echo "Resumen:"
|
||||
echo " Rama actual: $(git branch --show-current)"
|
||||
echo " Cambios pendientes: $CHANGES_AFTER (antes: $CHANGES_BEFORE)"
|
||||
echo " Worktrees activos: $(git worktree list | grep -v bare | wc -l)"
|
||||
echo " Sincronizado con origin: $(git rev-parse HEAD) = $(git rev-parse origin/master 2>/dev/null || echo 'N/A')"
|
||||
echo ""
|
||||
|
||||
if [ "$AGGRESSIVE" = "true" ]; then
|
||||
echo "Modo agresivo aplicado: ✓"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "Próximos pasos:"
|
||||
echo " - Verifica que master esté actualizado: git log --oneline -5"
|
||||
echo " - Reintenta la operación que falló"
|
||||
echo " - Si persisten errores, reporta el problema"
|
||||
echo ""
|
||||
|
||||
# Limpiar archivos temporales
|
||||
rm -f /tmp/git-recovery-*.txt
|
||||
```
|
||||
|
||||
### Detección automática de errores git
|
||||
|
||||
El orquestador Go debe detectar estos patrones de error:
|
||||
|
||||
**Patrones de error que activan recovery:**
|
||||
- `exit status 128` (error genérico de git)
|
||||
- `worktree .* already exists`
|
||||
- `reference is not a tree`
|
||||
- `cannot lock ref`
|
||||
- `index.lock`
|
||||
- `fatal: not a git repository`
|
||||
|
||||
**Flujo de auto-recovery:**
|
||||
1. Orquestador detecta error git
|
||||
2. Pausa ejecución del grupo actual
|
||||
3. Ejecuta `claude -p /git:recovery` automáticamente
|
||||
4. Si recovery tiene éxito (exit code 0), reintenta la operación
|
||||
5. Si recovery falla, aborta con error descriptivo
|
||||
|
||||
### Verificación final
|
||||
|
||||
```bash
|
||||
# Verificar que el repo quedó en estado válido
|
||||
git status --porcelain
|
||||
git worktree list
|
||||
|
||||
# Exit code 0 si todo OK, 1 si hay problemas
|
||||
if [ $? -eq 0 ]; then
|
||||
exit 0
|
||||
else
|
||||
echo "❌ El repositorio sigue con problemas"
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **No destructivo por defecto:** Solo limpia worktrees huérfanos y branches mergeadas
|
||||
- **Modo agresivo bajo demanda:** Solo con flag explícito
|
||||
- **Siempre sincroniza con remoto:** Garantiza consistencia
|
||||
- **Preserva cambios locales:** No hace reset hard sin --aggressive
|
||||
- **Logs detallados:** Reporta cada acción para debugging
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "cannot remove worktree"
|
||||
|
||||
**Causa:** Proceso usando archivos del worktree
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# Verificar procesos
|
||||
lsof +D worktrees/ 2>/dev/null
|
||||
|
||||
# Forzar eliminación con --aggressive
|
||||
/git:recovery --aggressive
|
||||
```
|
||||
|
||||
### Error: "index.lock exists"
|
||||
|
||||
**Causa:** Operación git previa interrumpida
|
||||
|
||||
**Solución:**
|
||||
Automáticamente manejado en modo estándar. Si persiste:
|
||||
```bash
|
||||
rm -f .git/index.lock
|
||||
/git:recovery
|
||||
```
|
||||
|
||||
### Warning: "branch no mergeada"
|
||||
|
||||
**Causa:** Branch contiene commits no integrados a master
|
||||
|
||||
**Solución:**
|
||||
Verificar manualmente si es seguro eliminarla:
|
||||
```bash
|
||||
git log master..branch-name
|
||||
git branch -D branch-name # Solo si estás seguro
|
||||
```
|
||||
|
||||
## Reglas críticas
|
||||
|
||||
- **NUNCA hacer git reset --hard sin --aggressive** - puede perder cambios
|
||||
- **SIEMPRE hacer backup del estado antes de recovery agresivo**
|
||||
- **NUNCA eliminar branches no mergeadas automáticamente**
|
||||
- **SIEMPRE sincronizar con remoto después de limpieza**
|
||||
- **SIEMPRE verificar que quedó en estado válido**
|
||||
- **LOGS completos** - reportar cada acción para auditoría
|
||||
|
||||
## Integración con orquestador
|
||||
|
||||
El orquestador Go debe:
|
||||
|
||||
1. **Capturar stderr** de comandos git
|
||||
2. **Detectar patrones** de error conocidos
|
||||
3. **Invocar recovery** automáticamente:
|
||||
```go
|
||||
if isGitError(err) {
|
||||
log.Warn("Error git detectado, ejecutando recovery...")
|
||||
if err := executeRecovery(); err != nil {
|
||||
return fmt.Errorf("recovery falló: %w", err)
|
||||
}
|
||||
// Reintentar operación original
|
||||
return retryOperation()
|
||||
}
|
||||
```
|
||||
4. **Limitar reintentos** a 1 vez por operación
|
||||
5. **Abortar si recovery falla**
|
||||
|
||||
## Ejemplos de uso automático
|
||||
|
||||
**Escenario 1: Error al crear worktree**
|
||||
```
|
||||
[ERROR] crear worktree: exit status 128
|
||||
[INFO] Detectado error git, ejecutando recovery...
|
||||
[INFO] ✓ Recovery completado
|
||||
[INFO] Reintentando crear worktree...
|
||||
[SUCCESS] ✓ Worktree creado exitosamente
|
||||
```
|
||||
|
||||
**Escenario 2: Recovery falla**
|
||||
```
|
||||
[ERROR] crear worktree: exit status 128
|
||||
[INFO] Detectado error git, ejecutando recovery...
|
||||
[ERROR] Recovery falló: problemas persistentes
|
||||
[ABORT] Abortando ejecución del grupo
|
||||
```
|
||||
@@ -0,0 +1,275 @@
|
||||
---
|
||||
version: 2.0.0
|
||||
updated: 2026-03-11
|
||||
tags: [issues, documentation, workflow, automation]
|
||||
---
|
||||
|
||||
# Command: auto-create-issue
|
||||
|
||||
Crea un issue nuevo en `dev/issues/` y lo integra automáticamente a master **sin pedir confirmación**.
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
Usar cuando estés completamente seguro del contenido del issue y quieras saltear la confirmación manual. El comando ejecuta todo el flujo automáticamente sin pausar.
|
||||
|
||||
**⚠️ Advertencia:** Este comando no pide confirmación. Si no estás seguro, usa `/issues:create-issue` en su lugar.
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
/issues:auto-create
|
||||
```
|
||||
|
||||
El comando preguntará interactivamente por los datos necesarios, pero NO pausará para confirmar.
|
||||
|
||||
### Ejemplos
|
||||
|
||||
**Ejemplo 1: Issue simple automatizado**
|
||||
```bash
|
||||
/issues:auto-create
|
||||
# Título: Actualizar dependencias
|
||||
# Descripción: Upgrade de módulos Go
|
||||
```
|
||||
|
||||
Crea, commitea, mergea y pushea automáticamente sin confirmación.
|
||||
|
||||
**Ejemplo 2: Issue multi-parte automatizado**
|
||||
```bash
|
||||
/issues:auto-create
|
||||
# Título: Sistema de notificaciones
|
||||
# Descripción: Email, SMS, y push notifications
|
||||
```
|
||||
|
||||
Crea sub-issues y feature flag, integra todo automáticamente.
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
|
||||
- [ ] Directorio `dev/issues/` existe
|
||||
- [ ] Archivo `dev/issues/README.md` existe
|
||||
- [ ] Template `.claude/templates/issue.md` existe
|
||||
- [ ] Working tree limpio (para poder crear rama)
|
||||
|
||||
### Inputs
|
||||
|
||||
Se necesitan los datos del issue. Si no se proporcionan, preguntar:
|
||||
|
||||
- `titulo`: título corto y descriptivo
|
||||
- `descripcion`: objetivo/descripción de lo que se quiere lograr
|
||||
- `dependencias` (opcional): issues de los que depende
|
||||
|
||||
### Flujo obligatorio
|
||||
|
||||
#### 1-7. Crear el issue (igual que `/issues:create-issue`)
|
||||
|
||||
{{include: issue-numbering}}
|
||||
|
||||
**Seguir los pasos 1-7 de `/issues:create-issue`:**
|
||||
1. Determinar número del issue
|
||||
2. Generar slug
|
||||
3. Evaluar tamaño (simple vs multi-issue)
|
||||
4. Crear issue desde template
|
||||
5. Agregar sección de desglose si es multi-issue
|
||||
6. Registrar feature flag si aplica
|
||||
7. Actualizar índice en `dev/issues/README.md`
|
||||
|
||||
**⚠️ DIFERENCIA CLAVE:** NO mostrar contenido ni pedir confirmación. Continuar directamente al paso 8.
|
||||
|
||||
#### 8. Integración automática a master
|
||||
|
||||
**SIN pedir confirmación**, ejecutar el flujo completo de git:
|
||||
|
||||
##### 8.1. Crear rama quick
|
||||
|
||||
{{include: git-update-master}}
|
||||
|
||||
```bash
|
||||
git checkout master
|
||||
git pull --rebase
|
||||
git checkout -b quick/issues:create-issue-<NNNN>
|
||||
```
|
||||
|
||||
##### 8.2. Crear commits atómicos
|
||||
|
||||
**Si es issue simple:**
|
||||
|
||||
```bash
|
||||
git add dev/issues/<NNNN>-<slug>.md dev/issues/README.md
|
||||
git commit -m "docs: crear issue <NNNN>-<slug>" -m "Crea issue <NNNN>: <titulo>
|
||||
|
||||
Objetivo: <resumen del objetivo>
|
||||
|
||||
Tipo: issue simple
|
||||
Archivos: dev/issues/<NNNN>-<slug>.md, dev/issues/README.md
|
||||
|
||||
Este issue define <descripción breve del alcance>."
|
||||
```
|
||||
|
||||
**Si es multi-issue:**
|
||||
|
||||
Commit 1 (archivos de issues - SOLO sub-issues, NO archivo principal):
|
||||
```bash
|
||||
git add dev/issues/<NNNN>*.md dev/issues/README.md
|
||||
git commit -m "docs: crear sub-issues para <NNNN>-<slug>" -m "Crea sub-issues <NNNN>a-<NNNN>d: <titulo>
|
||||
|
||||
Objetivo: <resumen>
|
||||
|
||||
Sub-issues creados (sin archivo principal):
|
||||
- <NNNN>a-<sub-slug>: <alcance>
|
||||
- <NNNN>b-<sub-slug>: <alcance>
|
||||
- <NNNN>c-<sub-slug>: <alcance>
|
||||
|
||||
Cada sub-issue es autocontenido con toda la información necesaria.
|
||||
Feature flag: <nombre-del-flag> (activado en último sub-issue)."
|
||||
```
|
||||
|
||||
Commit 2 (feature flag):
|
||||
```bash
|
||||
git add dev/feature_flags.json
|
||||
git commit -m "feat: agregar feature flag <nombre-del-flag>" -m "Agrega feature flag para issue multi-issue <NNNN>-<slug>
|
||||
|
||||
Flag: <nombre-del-flag>
|
||||
Estado inicial: disabled
|
||||
Issue: <NNNN>
|
||||
Descripción: <descripción>
|
||||
|
||||
Se activará cuando todos los sub-issues estén integrados y validados."
|
||||
```
|
||||
|
||||
##### 8.3. Ejecutar tests (si aplican)
|
||||
|
||||
{{include: run-tests}}
|
||||
|
||||
```bash
|
||||
go test -tags goolm ./...
|
||||
```
|
||||
|
||||
- Si fallan → **STOP** y reportar error al usuario
|
||||
- Si pasan o no aplican → continuar
|
||||
|
||||
##### 8.4. Merge a master
|
||||
|
||||
{{include: git-merge-to-master}}
|
||||
|
||||
```bash
|
||||
git checkout master
|
||||
git pull --rebase
|
||||
git merge --no-ff quick/issues:create-issue-<NNNN> -m "merge: quick/issues:create-issue-<NNNN> — crear issue <NNNN>-<slug>" -m "Integra issue <NNNN>: <titulo>
|
||||
|
||||
Tipo: [issue simple / issue multi-issue con N sub-issues]
|
||||
Archivos: dev/issues/<NNNN>*.md, dev/issues/README.md[, dev/feature_flags.json]
|
||||
|
||||
Listo para implementación con /issues:fix-issue <NNNN>[a/b/...]"
|
||||
```
|
||||
|
||||
##### 8.5. Push a remoto
|
||||
|
||||
```bash
|
||||
git push
|
||||
```
|
||||
|
||||
##### 8.6. Limpiar rama local
|
||||
|
||||
```bash
|
||||
git branch -d quick/issues:create-issue-<NNNN>
|
||||
```
|
||||
|
||||
### Verificación final
|
||||
|
||||
Informar al usuario:
|
||||
|
||||
**Issue simple:**
|
||||
```
|
||||
✓ Issue <NNNN>-<slug> creado e integrado a master automáticamente
|
||||
|
||||
Tipo: issue simple
|
||||
Rama: quick/issues:create-issue-<NNNN> (mergeada y limpiada)
|
||||
|
||||
Archivos creados:
|
||||
- dev/issues/<NNNN>-<slug>.md
|
||||
- dev/issues/README.md (actualizado)
|
||||
|
||||
Para implementar:
|
||||
/issues:fix-issue <NNNN>
|
||||
```
|
||||
|
||||
**Issue multi-issue:**
|
||||
```
|
||||
✓ Sub-issues <NNNN>a-<NNNN>d creados e integrados a master automáticamente
|
||||
|
||||
Tipo: issue multi-issue con N sub-issues (sin archivo principal)
|
||||
Rama: quick/issues:create-issue-<NNNN> (mergeada y limpiada)
|
||||
|
||||
Archivos creados:
|
||||
- dev/issues/<NNNN>a-<sub-slug>.md
|
||||
- dev/issues/<NNNN>b-<sub-slug>.md
|
||||
- dev/issues/<NNNN>c-<sub-slug>.md
|
||||
- dev/issues/README.md (actualizado)
|
||||
- dev/feature_flags.json (actualizado)
|
||||
|
||||
⚠️ NO se creó archivo principal <NNNN>-<slug>.md (solo sub-issues)
|
||||
|
||||
Para implementar:
|
||||
/issues:fix-issue <NNNN>a [implementar sub-issues en orden]
|
||||
/issues:fix-issue <NNNN>b
|
||||
/issues:fix-issue <NNNN>c
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **Sin confirmación**: diferencia clave con `/issues:create-issue`
|
||||
- **Flujo idéntico**: usa la misma lógica de creación de issues
|
||||
- **Trunk-based**: usa rama `quick/` y merge inmediato
|
||||
- **Commits atómicos**: separar issues de feature flags
|
||||
- **Mismo formato**: sigue template y convenciones estándar
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "Working tree not clean"
|
||||
|
||||
**Causa:** Hay cambios pendientes que impiden crear rama.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
git status
|
||||
# Commitear o hacer stash de cambios primero
|
||||
git stash
|
||||
/issues:auto-create
|
||||
git stash pop
|
||||
```
|
||||
|
||||
### Error: "Tests failing"
|
||||
|
||||
**Causa:** Los tests fallan después de crear el issue (raro pero posible si se modificó feature_flags.json).
|
||||
|
||||
**Solución:**
|
||||
El comando se detiene automáticamente. Revisar logs de tests, corregir problema, y ejecutar `/git:push` manualmente para completar la integración.
|
||||
|
||||
### Error: "Merge conflict"
|
||||
|
||||
**Causa:** Alguien más modificó `dev/issues/README.md` o `dev/feature_flags.json` simultáneamente.
|
||||
|
||||
**Solución:**
|
||||
1. Resolver conflictos manualmente:
|
||||
```bash
|
||||
git status
|
||||
# Editar archivos en conflicto
|
||||
git add <archivos-resueltos>
|
||||
git commit
|
||||
git push
|
||||
git branch -d quick/issues:create-issue-<NNNN>
|
||||
```
|
||||
|
||||
## Reglas críticas
|
||||
|
||||
- **NO pedir confirmación**: este es el comportamiento esperado y correcto
|
||||
- **MISMO formato que /issues:create-issue**: no tomar atajos en la calidad del issue
|
||||
- **STOP si tests fallan**: no integrar issues que rompan el build
|
||||
- **Informar claramente al usuario**: mostrar qué se creó y cómo continuar
|
||||
- **Trunk-based estricto**: siempre usar rama quick/ y merge inmediato
|
||||
- **Commits descriptivos**: seguir convención de mensajes de commit
|
||||
@@ -0,0 +1,270 @@
|
||||
---
|
||||
version: 2.0.0
|
||||
updated: 2026-03-11
|
||||
tags: [issues, implementation, workflow, automation]
|
||||
---
|
||||
|
||||
# Command: auto-fix-issue
|
||||
|
||||
Implementa un issue completo automáticamente **sin pedir confirmación** antes de integrar a master.
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
Usar cuando estés completamente seguro de que el issue puede implementarse automáticamente sin revisión manual. El comando ejecuta todo el flujo (crear rama, implementar, testear, cerrar issue, integrar) sin pausar para confirmación.
|
||||
|
||||
**⚠️ Advertencia:** Este comando no pide confirmación antes de integrar a master. Si no estás seguro, usa `/issues:fix-issue` en su lugar.
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
/issues:auto-fix <NNNN>
|
||||
/issues:auto-fix <NNNN>-<slug>
|
||||
```
|
||||
|
||||
### Ejemplos
|
||||
|
||||
**Ejemplo 1: Issue simple automatizado**
|
||||
```bash
|
||||
/issues:auto-fix 0013
|
||||
```
|
||||
|
||||
Implementa issue 0013 completo y lo integra a master sin pausar.
|
||||
|
||||
**Ejemplo 2: Por slug completo**
|
||||
```bash
|
||||
/issues:auto-fix 0013-hot-reload
|
||||
```
|
||||
|
||||
Implementa exactamente `dev/issues/0013-hot-reload.md` automáticamente.
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
|
||||
- [ ] Directorio `dev/issues/` existe
|
||||
- [ ] Directorio `dev/issues/completed/` existe
|
||||
- [ ] Archivo `dev/issues/README.md` existe
|
||||
- [ ] Tests configurados (go test disponible)
|
||||
- [ ] Working tree limpio
|
||||
|
||||
### Inputs
|
||||
|
||||
Se necesita el issue objetivo. Si no se proporciona, preguntar:
|
||||
|
||||
- `issue`: número o nombre (ej: `0010` o `0010-access-control`)
|
||||
|
||||
### Flujo obligatorio
|
||||
|
||||
#### 1-9. Implementar el issue (igual que `/issues:fix-issue`)
|
||||
|
||||
**Seguir los pasos 1-9 de `/issues:fix-issue`:**
|
||||
|
||||
1. Resolver el issue objetivo (verificar que existe)
|
||||
2. Leer completo el issue y extraer información
|
||||
3. Crear rama de trabajo `issue/<NNNN>-<slug>`
|
||||
4. Planificar con TodoWrite
|
||||
5. Implementar el issue completo (todas las tareas)
|
||||
6. Ejecutar tests obligatorios
|
||||
7. Evaluar feature flags (si aplica)
|
||||
8. Cerrar el issue (mover a completed/)
|
||||
9. ~~Mostrar resumen y confirmar~~ → **SKIP**
|
||||
|
||||
**⚠️ DIFERENCIA CLAVE:** NO mostrar resumen ni pedir confirmación. Continuar directamente al paso 10.
|
||||
|
||||
#### 10. Integración automática a master
|
||||
|
||||
**SIN pedir confirmación**, ejecutar el flujo completo de integración:
|
||||
|
||||
{{include: git-update-master}}
|
||||
{{include: run-tests}}
|
||||
{{include: git-merge-to-master}}
|
||||
|
||||
##### 10.1. Verificar estado final de la rama
|
||||
|
||||
```bash
|
||||
git status --short
|
||||
git log --oneline master..HEAD
|
||||
```
|
||||
|
||||
Asegurar que:
|
||||
- No hay cambios pendientes (todo commiteado)
|
||||
- Hay al menos 1 commit (la implementación)
|
||||
- Tests pasaron en paso 6
|
||||
|
||||
##### 10.2. Checkout a master y actualizar
|
||||
|
||||
```bash
|
||||
git checkout master
|
||||
git pull --rebase
|
||||
```
|
||||
|
||||
##### 10.3. Re-ejecutar tests (verificación final)
|
||||
|
||||
```bash
|
||||
go test -tags goolm ./...
|
||||
```
|
||||
|
||||
**Si fallan:**
|
||||
- ✗ **STOP** y reportar error al usuario
|
||||
- No integrar código roto
|
||||
- Usuario debe revisar y corregir manualmente
|
||||
|
||||
**Si pasan o no aplican:**
|
||||
- ✓ Continuar
|
||||
|
||||
##### 10.4. Merge a master con --no-ff
|
||||
|
||||
```bash
|
||||
git merge --no-ff issue/<NNNN>-<slug> -m "merge: issue/<NNNN>-<slug> — <título del issue>" -m "Implementa issue <NNNN>: <título>
|
||||
|
||||
Todas las tareas completadas:
|
||||
<lista breve de lo implementado>
|
||||
|
||||
Tests: pasando
|
||||
Issue: movido a dev/issues/completed/
|
||||
|
||||
Integración automática via /issues:auto-fix"
|
||||
```
|
||||
|
||||
##### 10.5. Push a remoto
|
||||
|
||||
```bash
|
||||
git push
|
||||
```
|
||||
|
||||
**Si falla:**
|
||||
- Error "rejected - non-fast-forward" → alguien pusheó antes
|
||||
- Solución: `git pull --rebase && git push`
|
||||
- Si hay conflictos, reportar al usuario para resolución manual
|
||||
|
||||
##### 10.6. Limpiar rama local
|
||||
|
||||
```bash
|
||||
git branch -d issue/<NNNN>-<slug>
|
||||
```
|
||||
|
||||
### Verificación final
|
||||
|
||||
Informar al usuario con resumen completo:
|
||||
|
||||
```
|
||||
✓ Issue <NNNN>-<slug> completado e integrado a master automáticamente
|
||||
|
||||
Rama: issue/<NNNN>-<slug> (mergeada y limpiada)
|
||||
Commits integrados: <N>
|
||||
Tests: pasando
|
||||
Issue: movido a dev/issues/completed/
|
||||
|
||||
Archivos modificados:
|
||||
<lista de archivos principales>
|
||||
|
||||
Master actualizado y sincronizado con remoto.
|
||||
|
||||
NOTA: Integración automática sin confirmación previa.
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **Sin confirmación**: diferencia clave con `/issues:fix-issue`
|
||||
- **Flujo idéntico**: usa la misma lógica de implementación
|
||||
- **Tests obligatorios**: STOP si fallan, no integrar código roto
|
||||
- **Commits durante implementación**: no al final
|
||||
- **Mismas reglas de calidad**: no tomar atajos por ser automático
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "Issue not found"
|
||||
|
||||
**Causa:** El archivo del issue no existe en `dev/issues/`
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
ls dev/issues/
|
||||
# Verificar número o slug correcto
|
||||
# O crear el issue primero con /issues:create-issue
|
||||
```
|
||||
|
||||
### Error: "Tests failing during merge"
|
||||
|
||||
**Causa:** Tests fallaron en la verificación final antes de merge
|
||||
|
||||
**Solución:**
|
||||
El comando se detiene automáticamente. La rama `issue/<NNNN>-<slug>` sigue existiendo con todos los cambios.
|
||||
|
||||
Para continuar:
|
||||
1. Cambiar a la rama:
|
||||
```bash
|
||||
git checkout issue/<NNNN>-<slug>
|
||||
```
|
||||
|
||||
2. Ver qué tests fallan:
|
||||
```bash
|
||||
go test -v -tags goolm ./...
|
||||
```
|
||||
|
||||
3. Corregir el problema y commitear fix
|
||||
|
||||
4. Ejecutar `/git:push` manualmente para completar integración
|
||||
|
||||
### Error: "Merge conflict during rebase/merge"
|
||||
|
||||
**Causa:** Alguien más modificó archivos que también modificaste
|
||||
|
||||
**Solución:**
|
||||
El comando se detiene. Resolver manualmente:
|
||||
|
||||
1. Ver conflictos:
|
||||
```bash
|
||||
git status
|
||||
```
|
||||
|
||||
2. Resolver conflictos en cada archivo
|
||||
|
||||
3. Completar merge:
|
||||
```bash
|
||||
git add <archivos-resueltos>
|
||||
git commit
|
||||
git push
|
||||
git branch -d issue/<NNNN>-<slug>
|
||||
```
|
||||
|
||||
### Error: "Working tree not clean at start"
|
||||
|
||||
**Causa:** Hay cambios sin commitear al iniciar el comando
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
git status
|
||||
# Commitear o hacer stash de cambios
|
||||
git stash
|
||||
/issues:auto-fix <NNNN>
|
||||
git stash pop
|
||||
```
|
||||
|
||||
### Advertencia: "Implementation incomplete"
|
||||
|
||||
**Causa:** El comando implementó parcialmente pero no todas las tareas del issue
|
||||
|
||||
**Solución:**
|
||||
Esto NO debería ocurrir. Si ocurre:
|
||||
1. Revisar el issue para ver qué faltó
|
||||
2. Completar manualmente las tareas faltantes
|
||||
3. Usar `/git:push` para integrar
|
||||
4. Reportar el problema para mejorar el comando
|
||||
|
||||
## Reglas críticas
|
||||
|
||||
- **NO pedir confirmación**: este es el comportamiento esperado
|
||||
- **MISMA calidad que /issues:fix-issue**: no tomar atajos
|
||||
- **STOP si tests fallan**: no integrar código roto nunca
|
||||
- **Implementar TODAS las tareas**: no parcial
|
||||
- **Respetar arquitectura**: pure core / impure shell
|
||||
- **Commits atómicos**: durante implementación, no al final
|
||||
- **SIEMPRE usar -tags goolm**: en build y test
|
||||
- **Informar claramente**: mostrar qué se hizo y resultado
|
||||
- **NO inventar soluciones**: seguir tareas del issue estrictamente
|
||||
- **Manejo de errores**: si algo falla, detener y reportar al usuario
|
||||
@@ -0,0 +1,236 @@
|
||||
---
|
||||
version: 1.0.0
|
||||
updated: 2026-03-13
|
||||
tags: [issues, workspace, batch, orchestration]
|
||||
---
|
||||
|
||||
# Command: create-batch
|
||||
|
||||
Crea múltiples issues en workspaces hijos a partir de un archivo YAML, pidiendo confirmación antes de proceder.
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
Usar cuando necesites crear la misma issue (o issues relacionadas) en múltiples workspaces simultáneamente. Ideal para migraciones, estandarizaciones o lanzamientos coordinados.
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
/issues:create-batch <path-to-yaml>
|
||||
```
|
||||
|
||||
### Formato YAML esperado
|
||||
|
||||
```yaml
|
||||
# migration-issues.yaml
|
||||
issues:
|
||||
- workspace: auth-service
|
||||
number: "0010"
|
||||
slug: migrate-to-v2-schema
|
||||
title: Migrate to v2 database schema
|
||||
description: Update database schema to v2 with new user fields
|
||||
tags: [database, migration]
|
||||
status: pending
|
||||
|
||||
- workspace: payment-service
|
||||
number: "0008"
|
||||
slug: migrate-to-v2-schema
|
||||
title: Migrate to v2 database schema
|
||||
description: Update database schema to v2 with new payment fields
|
||||
tags: [database, migration]
|
||||
status: pending
|
||||
|
||||
- workspace: notification-service
|
||||
number: "0005"
|
||||
slug: migrate-to-v2-schema
|
||||
title: Migrate to v2 database schema
|
||||
description: Update database schema to v2 with new notification fields
|
||||
tags: [database, migration]
|
||||
status: pending
|
||||
```
|
||||
|
||||
**Campos obligatorios por entry:** `workspace`, `number`, `slug`, `title`
|
||||
**Campos opcionales:** `description`, `tags`, `status` (default: `pending`)
|
||||
|
||||
**Restricciones de formato:**
|
||||
- `number`: exactamente 4 dígitos opcionalmente seguidos de una letra minúscula (ej: `0001`, `0012a`)
|
||||
- `slug`: lowercase alfanumérico con guiones, sin guiones al inicio o final (ej: `implement-auth`)
|
||||
- `status`: `pending`, `in_progress`, o `completed`
|
||||
|
||||
### Ejemplos
|
||||
|
||||
**Ejemplo 1: Creación batch de migración**
|
||||
```bash
|
||||
/issues:create-batch migration-issues.yaml
|
||||
```
|
||||
|
||||
Crea la misma issue de migración en tres workspaces diferentes.
|
||||
|
||||
**Ejemplo 2: Onboarding de nuevos servicios**
|
||||
```bash
|
||||
/issues:create-batch new-services-setup.yaml
|
||||
```
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
|
||||
- [ ] El argumento del comando es un path a un archivo YAML
|
||||
- [ ] El archivo YAML existe y es legible
|
||||
- [ ] `dev/feature_flags.json` tiene `centralized_issue_orchestration` habilitado (opcional, advertir si no)
|
||||
|
||||
### Inputs
|
||||
|
||||
- `yamlPath`: path al archivo YAML (argumento obligatorio del comando)
|
||||
|
||||
Si no se proporciona el path, solicitarlo al usuario.
|
||||
|
||||
### Flujo obligatorio
|
||||
|
||||
#### 1. Leer y validar el archivo YAML
|
||||
|
||||
Leer el archivo YAML indicado y parsearlo. Verificar:
|
||||
- El archivo existe
|
||||
- El YAML es sintácticamente válido
|
||||
- La estructura tiene clave `issues` con al menos una entrada
|
||||
- Cada entrada tiene campos obligatorios (`workspace`, `number`, `slug`, `title`)
|
||||
|
||||
Si hay errores de validación, mostrarlos todos antes de detenerse.
|
||||
|
||||
#### 2. Mostrar plan de creación
|
||||
|
||||
Mostrar al usuario lo que se va a crear:
|
||||
|
||||
```
|
||||
Plan de creación:
|
||||
workspace-1: 0010-migrate-to-v2-schema
|
||||
workspace-2: 0008-migrate-to-v2-schema
|
||||
workspace-3: 0005-migrate-to-v2-schema
|
||||
|
||||
Total: 3 issues en 3 workspaces
|
||||
```
|
||||
|
||||
#### 3. Verificar workspaces disponibles
|
||||
|
||||
Para cada workspace en el YAML, verificar que existe en `config.ReposBasePath`.
|
||||
Si algún workspace no existe, advertir al usuario pero no detener el proceso (se reportará como fallo en el reporte final).
|
||||
|
||||
#### 4. Pedir confirmación
|
||||
|
||||
```
|
||||
¿Proceder con la creación? (s/n):
|
||||
```
|
||||
|
||||
- Si responde afirmativo → continuar
|
||||
- Si responde negativo → **STOP**: "Operación cancelada. No se crearon issues."
|
||||
|
||||
#### 5. Ejecutar creación via app.CreateIssuesBatchCommand
|
||||
|
||||
Invocar la lógica app layer para crear cada issue:
|
||||
- Validar spec con `core.ValidateIssueSpec()`
|
||||
- Verificar workspace existe con `shell.WorkspaceExists()`
|
||||
- Verificar issue no existe con `shell.IssueExists()`
|
||||
- Crear issue con `shell.CreateIssueFile()`
|
||||
|
||||
El proceso continúa aunque fallen issues individuales (partial failure).
|
||||
|
||||
#### 6. Mostrar reporte detallado
|
||||
|
||||
```
|
||||
Creando issues...
|
||||
✓ auth-service/0010-migrate-to-v2-schema.md
|
||||
✓ payment-service/0008-migrate-to-v2-schema.md
|
||||
✗ notification-service: workspace no existe
|
||||
|
||||
Resultado:
|
||||
2/3 issues creadas exitosamente
|
||||
1 fallo(s):
|
||||
- notification-service/0005-migrate-to-v2-schema: workspace no existe
|
||||
```
|
||||
|
||||
#### 7. Si hubo fallos, indicar cómo resolver
|
||||
|
||||
Para cada fallo:
|
||||
- Si es "workspace no existe": `dataforge workspace create <nombre>`
|
||||
- Si es "issue ya existe": verificar con `ls workspaces/<nombre>/dev/issues/`
|
||||
- Si es error de validación: corregir el YAML y reintentar
|
||||
|
||||
### Verificación final
|
||||
|
||||
Informar al usuario:
|
||||
|
||||
```
|
||||
✓ Batch completado: X/Y issues creadas
|
||||
|
||||
Archivos creados:
|
||||
workspaces/<workspace>/dev/issues/<number>-<slug>.md
|
||||
...
|
||||
|
||||
Para ejecutarlas en paralelo: /issues:execute-parallel <plan.yaml>
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **Partial failure**: nunca abortar el batch por fallos individuales — reportar al final
|
||||
- **Confirmación obligatoria**: siempre pedir confirmación antes de crear
|
||||
- **Sin auto-commit**: no hacer commit automático, dejar que el usuario gestione git
|
||||
- **Idempotente**: si el issue ya existe, reportar como fallo, no sobrescribir
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "YAML parse error"
|
||||
|
||||
**Causa:** El archivo YAML tiene errores de sintaxis.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# Verificar sintaxis con un linter
|
||||
cat batch.yaml
|
||||
# Revisar indentación y caracteres especiales
|
||||
```
|
||||
|
||||
Errores comunes:
|
||||
- Números sin comillas: `number: 0001` → `number: "0001"`
|
||||
- Tags sin lista: `tags: backend,auth` → `tags: [backend, auth]`
|
||||
|
||||
### Error: "workspace X does not exist"
|
||||
|
||||
**Causa:** El workspace no está creado en el sistema.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# Crear el workspace primero
|
||||
/workspace:create-repo <nombre>
|
||||
# O importarlo si ya existe en Gitea
|
||||
/workspace:import-repo <nombre>
|
||||
```
|
||||
|
||||
### Error: "issue already exists"
|
||||
|
||||
**Causa:** Ya existe un issue con ese número en el workspace.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# Ver issues existentes en el workspace
|
||||
ls workspaces/<nombre>/dev/issues/
|
||||
# Usar un número diferente o verificar si ya está implementado
|
||||
```
|
||||
|
||||
### Error: "batch file contains no issues"
|
||||
|
||||
**Causa:** El archivo YAML está vacío o tiene `issues: []`.
|
||||
|
||||
**Solución:**
|
||||
Agregar al menos una entrada al archivo YAML con todos los campos obligatorios.
|
||||
|
||||
## Reglas críticas
|
||||
|
||||
- **Confirmación obligatoria**: nunca crear sin confirmación del usuario
|
||||
- **Partial failure permitido**: continuar aunque fallen issues individuales
|
||||
- **Sin sobrescritura**: nunca sobrescribir issues existentes
|
||||
- **Validación completa**: validar YAML y specs antes de mostrar el plan
|
||||
- **Reporte detallado**: siempre mostrar qué se creó y qué falló
|
||||
- **Sin auto-commit**: dejar git al usuario
|
||||
@@ -0,0 +1,289 @@
|
||||
---
|
||||
version: 2.0.0
|
||||
updated: 2026-03-11
|
||||
tags: [issues, documentation, workflow]
|
||||
---
|
||||
|
||||
# Command: create-issue
|
||||
|
||||
Crea un issue nuevo en `dev/issues/` con confirmación del usuario. Si el issue es grande, lo desglosa automáticamente en sub-issues con feature flags.
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
Usar cuando necesites documentar una nueva tarea, feature o fix antes de implementarlo. El comando crea la estructura completa del issue y pide confirmación antes de integrarlo.
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
/issues:create-issue
|
||||
```
|
||||
|
||||
El comando preguntará interactivamente por los datos necesarios.
|
||||
|
||||
### Ejemplos
|
||||
|
||||
**Ejemplo 1: Issue simple**
|
||||
```bash
|
||||
/issues:create-issue
|
||||
# Título: Hot reload de configuración
|
||||
# Descripción: Permitir recargar config sin reiniciar
|
||||
```
|
||||
|
||||
Crea `dev/issues/NNNN-hot-reload.md` y pide confirmación.
|
||||
|
||||
**Ejemplo 2: Issue multi-parte**
|
||||
```bash
|
||||
/issues:create-issue
|
||||
# Título: Integración completa con Telegram
|
||||
# Descripción: Cliente, listener, y handlers para Telegram
|
||||
```
|
||||
|
||||
Detecta que es grande y crea sub-issues (NNNN a, b, c...) con feature flag.
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
|
||||
- [ ] Directorio `dev/issues/` existe
|
||||
- [ ] Archivo `dev/issues/README.md` existe
|
||||
- [ ] Template `.claude/templates/issue.md` existe
|
||||
|
||||
### Inputs
|
||||
|
||||
Se necesitan los datos del issue. Si no se proporcionan, preguntar:
|
||||
|
||||
- `titulo`: título corto y descriptivo (ej: "Hot reload de configuración")
|
||||
- `descripcion`: objetivo/descripción de lo que se quiere lograr
|
||||
- `dependencias` (opcional): issues de los que depende (ej: "Requiere issue 0010")
|
||||
|
||||
### Flujo obligatorio
|
||||
|
||||
#### 1. Determinar el número del issue
|
||||
|
||||
{{include: issue-numbering}}
|
||||
|
||||
```bash
|
||||
ls dev/issues/ dev/issues/completed/ | grep -oP '^\d{4}' | sort -rn | head -1
|
||||
```
|
||||
|
||||
El próximo issue será: número_más_alto + 1 (formato 4 dígitos)
|
||||
|
||||
#### 2. Generar slug
|
||||
|
||||
A partir del título:
|
||||
- Lowercase
|
||||
- Palabras separadas por guiones
|
||||
- Conciso (2-4 palabras)
|
||||
- Ejemplo: "Hot reload de configuración" → `hot-reload`
|
||||
|
||||
#### 3. Evaluar tamaño del issue
|
||||
|
||||
Analizar el alcance y determinar si cabe en **una sola rama corta (horas)**.
|
||||
|
||||
**Criterios para desglosar en sub-issues:**
|
||||
- Toca más de 2 capas del patrón (core/ + shell/ + app/)
|
||||
- Requiere más de ~3 fases de implementación
|
||||
- El usuario lo indica explícitamente
|
||||
- La descripción implica múltiples componentes independientes
|
||||
|
||||
**Si es issue simple:**
|
||||
- Crear un solo archivo `dev/issues/<NNNN>-<slug>.md`
|
||||
- Continuar al paso 4
|
||||
|
||||
**Si es issue grande:**
|
||||
- NO crear archivo principal (no se necesita `dev/issues/<NNNN>-<slug>.md`)
|
||||
- Crear SOLO sub-issues `dev/issues/<NNNN><letra>-<sub-slug>.md`
|
||||
- Cada sub-issue debe ser autocontenido con toda la información necesaria
|
||||
- Agregar feature flag para coordinar sub-issues
|
||||
- Continuar al paso 4
|
||||
|
||||
#### 4. Crear el issue desde el template
|
||||
|
||||
Copiar `.claude/templates/issue.md` y rellenar **todas** las secciones:
|
||||
|
||||
- **Metadata**: ID, estado (pendiente), prioridad, tipo
|
||||
- **Objetivo**: 1-3 frases claras
|
||||
- **Contexto**: qué existe, qué falta, dependencias
|
||||
- **Arquitectura**: archivos afectados (marcar `NEW` los nuevos)
|
||||
- **Patrón pure/impure**: qué va en `core/` vs `shell/` vs `app/`
|
||||
- **Tareas**: fases con tareas numeradas (1.1, 1.2, etc.)
|
||||
- **Ejemplo de uso**: flujo concreto con código
|
||||
- **Decisiones de diseño**: justificaciones clave
|
||||
- **Prerequisitos**: qué debe existir antes
|
||||
- **Riesgos**: problemas potenciales y mitigación
|
||||
- **Criterios de aceptación**: checklist de completitud
|
||||
|
||||
#### 5. Para issues multi-issue — contenido en sub-issues
|
||||
|
||||
Ya que NO se crea archivo principal, cada sub-issue debe ser autocontenido:
|
||||
|
||||
**En cada sub-issue incluir:**
|
||||
- Objetivo específico del sub-issue
|
||||
- Contexto: parte de qué feature mayor (ej: "Parte 1 de 4 del sistema de distribución .claude")
|
||||
- Relación con otros sub-issues (dependencias, orden sugerido)
|
||||
- Tareas específicas de este sub-issue
|
||||
- Referencia al feature flag compartido
|
||||
|
||||
**En el PRIMER sub-issue (NNNNa) agregar tabla de coordinación:**
|
||||
|
||||
```markdown
|
||||
## Coordinación multi-issue
|
||||
|
||||
Este issue es parte de una implementación dividida en sub-issues:
|
||||
|
||||
| Sub-issue | Alcance | Estado |
|
||||
|-----------|---------|--------|
|
||||
| <NNNN>a-<slug> (este) | <qué cubre> | pendiente |
|
||||
| <NNNN>b-<slug> | <qué cubre> | pendiente |
|
||||
| <NNNN>c-<slug> | <qué cubre> | pendiente |
|
||||
|
||||
### Feature flag compartido
|
||||
|
||||
Nombre: `<nombre-del-flag>`
|
||||
Se activa en el último sub-issue (<NNNN>d) cuando todo está integrado.
|
||||
```
|
||||
|
||||
#### 6. Registrar feature flag (solo multi-issue)
|
||||
|
||||
Actualizar `dev/feature_flags.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"<nombre-del-flag>": {
|
||||
"enabled": false,
|
||||
"issue": "<NNNN>",
|
||||
"description": "<descripción breve>",
|
||||
"added": "<YYYY-MM-DD>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 7. Actualizar el índice
|
||||
|
||||
En `dev/issues/README.md`, agregar filas al final de la tabla.
|
||||
|
||||
**Issue simple:**
|
||||
```markdown
|
||||
| <N> | <Titulo> | [<NNNN>-<slug>.md](<NNNN>-<slug>.md) | pendiente |
|
||||
```
|
||||
|
||||
**Issue multi-issue (solo sub-issues, NO archivo principal):**
|
||||
```markdown
|
||||
| <N>a | <Titulo> (parte a) | [<NNNN>a-<slug>.md](<NNNN>a-<slug>.md) | pendiente |
|
||||
| <N>b | <Titulo> (parte b) | [<NNNN>b-<slug>.md](<NNNN>b-<slug>.md) | pendiente |
|
||||
| <N>c | <Titulo> (parte c) | [<NNNN>c-<slug>.md](<NNNN>c-<slug>.md) | pendiente |
|
||||
```
|
||||
|
||||
⚠️ **IMPORTANTE:** NO agregar fila para `<NNNN>-<slug>.md` ya que este archivo no se crea.
|
||||
|
||||
#### 8. Mostrar el issue creado y confirmar
|
||||
|
||||
{{include: ask-user-confirm}}
|
||||
|
||||
**Mostrar al usuario el contenido completo:**
|
||||
|
||||
**Issue simple:**
|
||||
```bash
|
||||
cat dev/issues/<NNNN>-<slug>.md
|
||||
```
|
||||
|
||||
**Issue multi-issue:**
|
||||
Mostrar resumen de sub-issues creados y el contenido del primer sub-issue:
|
||||
```bash
|
||||
echo "Sub-issues creados:"
|
||||
ls -1 dev/issues/<NNNN>*.md
|
||||
echo -e "\n=== Contenido del primer sub-issue (<NNNN>a) ==="
|
||||
cat dev/issues/<NNNN>a-<slug>.md
|
||||
```
|
||||
|
||||
**Pausar y preguntar:**
|
||||
|
||||
**Issue simple:**
|
||||
```
|
||||
Issue creado: <NNNN>-<slug>
|
||||
|
||||
¿Te parece bien el issue?
|
||||
- Si es correcto: se hará commit y push automáticamente
|
||||
- Si necesitas ajustes: puedes editarlo manualmente antes
|
||||
```
|
||||
|
||||
**Issue multi-issue:**
|
||||
```
|
||||
Issues creados: <NNNN>a, <NNNN>b, <NNNN>c (sin archivo principal)
|
||||
|
||||
¿Te parecen bien los sub-issues?
|
||||
- Si es correcto: se hará commit y push automáticamente
|
||||
- Si necesitas ajustes: puedes editarlos manualmente antes
|
||||
```
|
||||
|
||||
**Esperar respuesta del usuario:**
|
||||
- Si responde afirmativo → continuar al paso 9
|
||||
- Si responde negativo → **STOP**: "Edita los archivos y ejecuta `/git:push` cuando estés listo"
|
||||
|
||||
#### 9. Ejecutar /git:push automáticamente
|
||||
|
||||
Una vez confirmado, ejecutar `/git:push` para:
|
||||
1. Crear rama `quick/issues:create-issue-<NNNN>` automáticamente
|
||||
2. Commitear archivos (`dev/issues/<NNNN>*.md`, `dev/issues/README.md`, `dev/feature_flags.json` si aplica)
|
||||
3. Mergear a master con --no-ff
|
||||
4. Push a remoto
|
||||
5. Limpiar rama local
|
||||
|
||||
### Verificación final
|
||||
|
||||
Informar al usuario:
|
||||
|
||||
```
|
||||
✓ Issue <NNNN>-<slug> creado e integrado a master
|
||||
|
||||
Tipo: [issue simple / issue multi-issue con N sub-issues]
|
||||
Rama: quick/issues:create-issue-<NNNN> (mergeada y limpiada)
|
||||
|
||||
Para implementar:
|
||||
/issues:fix-issue <NNNN> [si es simple]
|
||||
/issues:fix-issue <NNNN>a [si es multi-issue, implementar sub-issues en orden]
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **Numeración continua**: nunca saltar números ni reusar
|
||||
- **Estado inicial**: siempre `pendiente`
|
||||
- **Issues cortos**: máximo horas de implementación por rama
|
||||
- **Sub-issues autocontenidos**: cada uno debe compilar y pasar tests independientemente
|
||||
- **Feature flags != WIP**: protegen código terminado, no código a medias
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "Template file not found"
|
||||
|
||||
**Causa:** No existe `.claude/templates/issue.md`
|
||||
|
||||
**Solución:**
|
||||
Crear el template desde el proyecto base o consultar documentación.
|
||||
|
||||
### Error: "Cannot determine next issue number"
|
||||
|
||||
**Causa:** No hay issues previos en `dev/issues/` o `dev/issues/completed/`
|
||||
|
||||
**Solución:**
|
||||
Comenzar con `0001` como primer issue.
|
||||
|
||||
### Advertencia: "Issue número ya existe"
|
||||
|
||||
**Causa:** Ya existe un archivo con ese número.
|
||||
|
||||
**Solución:**
|
||||
Verificar manualmente y usar el siguiente número disponible.
|
||||
|
||||
## Reglas críticas
|
||||
|
||||
- **Seguir template estrictamente**: no omitir secciones
|
||||
- **Patrón pure core / impure shell**: toda feature debe explicar qué va en `core/` vs `shell/`
|
||||
- **Tareas atómicas**: cada tarea debe ser implementable independientemente
|
||||
- **Numeración sin gaps**: siempre consecutiva
|
||||
- **Confirmación obligatoria**: siempre esperar aprobación del usuario antes de integrar
|
||||
- **Issues grandes**: desglosar en sub-issues con feature flags, nunca ramas de larga duración
|
||||
@@ -0,0 +1,359 @@
|
||||
---
|
||||
version: 1.0.0
|
||||
updated: 2026-03-11
|
||||
tags: [issues, parallel, execution, automation, worktree, golang]
|
||||
---
|
||||
|
||||
# Command: execute-parallel-issues
|
||||
|
||||
Ejecuta automáticamente las issues de un grupo paralelo del plan generado por `/issues:parallel`. Crea worktrees, ejecuta `/issues:fix-issue` en cada uno, mergea los cambios y limpia los worktrees al finalizar.
|
||||
|
||||
**Flujo completo:**
|
||||
1. Validar que existe `PARALLEL_EXECUTION_ORDER.md`
|
||||
2. Compilar programa Go si es necesario
|
||||
3. Ejecutar el orquestador Go para el grupo especificado
|
||||
4. El programa Go maneja:
|
||||
- Creación de worktrees y ramas
|
||||
- Ejecución paralela de `claude -p /issues:fix-issue`
|
||||
- Push de cada rama al completar
|
||||
- Limpieza de worktrees y ramas
|
||||
- Logging estructurado en `logs/`
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
- Después de ejecutar `/issues:parallel` y revisar el plan
|
||||
- Cuando quieres ejecutar issues automáticamente
|
||||
- Para aprovechar la ejecución paralela de issues independientes
|
||||
- Cuando prefieres automatización completa vs ejecutar manualmente cada issue
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
# Ejecutar TODOS los grupos secuencialmente (por defecto)
|
||||
/issues:execute-parallel [--sequential]
|
||||
|
||||
# Ejecutar un grupo específico
|
||||
/issues:execute-parallel --group <numero> [--sequential]
|
||||
```
|
||||
|
||||
### Parámetros
|
||||
|
||||
- `--group <numero>` (opcional): Ejecutar solo un grupo específico (1, 2, 3, etc.). Si no se especifica, ejecuta TODOS los grupos.
|
||||
- `--sequential` (opcional): Ejecutar issues una por una en vez de en paralelo
|
||||
|
||||
### Ejemplos
|
||||
|
||||
**Ejemplo 1: Ejecutar TODOS los grupos (comportamiento por defecto)**
|
||||
|
||||
```bash
|
||||
/issues:execute-parallel
|
||||
```
|
||||
|
||||
**Ejemplo 2: Ejecutar solo el Grupo 1**
|
||||
|
||||
```bash
|
||||
/issues:execute-parallel --group 1
|
||||
```
|
||||
|
||||
**Ejemplo 3: Ejecutar TODOS los grupos secuencialmente (sin paralelismo)**
|
||||
|
||||
```bash
|
||||
/issues:execute-parallel --sequential
|
||||
```
|
||||
|
||||
Comportamiento por defecto:
|
||||
- Ejecuta todos los grupos secuencialmente: Grupo 1 → Grupo 2 → Grupo 3 → etc.
|
||||
- Dentro de cada grupo, las issues se ejecutan en paralelo
|
||||
- Genera resumen consolidado de TODOS los grupos al final
|
||||
- Log detallado en `logs/consolidated-summary.txt`
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
|
||||
- [ ] Si no existe `PARALLEL_EXECUTION_ORDER.md`, generarlo automáticamente con `/issues:parallel`
|
||||
- [ ] El usuario está en la rama correcta (usualmente `main`)
|
||||
- [ ] No hay cambios sin commitear que puedan causar conflictos
|
||||
|
||||
### Inputs
|
||||
|
||||
**Por defecto, ejecuta TODOS los grupos automáticamente.** No es necesario preguntar al usuario.
|
||||
|
||||
Parámetros opcionales:
|
||||
- `--group <numero>` (opcional): Ejecutar solo un grupo específico
|
||||
- `--sequential` (opcional): Ejecutar secuencialmente en vez de en paralelo
|
||||
|
||||
**IMPORTANTE:** Si no se especifica `--group`, ejecuta todos los grupos automáticamente.
|
||||
|
||||
### Flujo obligatorio
|
||||
|
||||
#### 1. Validar precondiciones
|
||||
|
||||
```bash
|
||||
# Verificar que existe el plan, si no existe, generarlo automáticamente
|
||||
if [ ! -f "PARALLEL_EXECUTION_ORDER.md" ]; then
|
||||
echo "📋 PARALLEL_EXECUTION_ORDER.md no existe, generando plan automáticamente..."
|
||||
echo ""
|
||||
|
||||
# Ejecutar /issues:parallel para generar el plan
|
||||
claude -p /issues:parallel
|
||||
|
||||
# Verificar que se generó correctamente
|
||||
if [ ! -f "PARALLEL_EXECUTION_ORDER.md" ]; then
|
||||
echo "❌ Error: No se pudo generar PARALLEL_EXECUTION_ORDER.md"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✓ Plan de ejecución generado exitosamente"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Verificar que no hay cambios sin commitear (solo advertir, no bloquear)
|
||||
UNCOMMITTED=$(git status --porcelain | wc -l)
|
||||
if [ "$UNCOMMITTED" -gt 0 ]; then
|
||||
echo "⚠️ Advertencia: Hay cambios sin commitear"
|
||||
git status --short
|
||||
echo ""
|
||||
echo "Continuando de todas formas..."
|
||||
echo ""
|
||||
fi
|
||||
```
|
||||
|
||||
#### 2. Parsear argumentos
|
||||
|
||||
```bash
|
||||
# Por defecto ejecutar todos los grupos
|
||||
GRUPO=""
|
||||
ALL_GROUPS=true
|
||||
SEQUENTIAL=false
|
||||
|
||||
# Parsear argumentos
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--group)
|
||||
if [ -z "$2" ] || [[ ! "$2" =~ ^[0-9]+$ ]]; then
|
||||
echo "Error: --group requiere un número"
|
||||
exit 1
|
||||
fi
|
||||
GRUPO=$2
|
||||
ALL_GROUPS=false
|
||||
shift 2
|
||||
;;
|
||||
--sequential)
|
||||
SEQUENTIAL=true
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Error: Flag desconocido '$1'"
|
||||
echo "Uso: /issues:execute-parallel [--group <numero>] [--sequential]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
```
|
||||
|
||||
#### 3. Ejecutar programa Go
|
||||
|
||||
```bash
|
||||
echo ""
|
||||
|
||||
# Mensaje de inicio
|
||||
if [ "$ALL_GROUPS" = true ]; then
|
||||
echo "🚀 Iniciando ejecución de TODOS los grupos secuencialmente"
|
||||
else
|
||||
echo "🚀 Iniciando ejecución paralela del Grupo $GRUPO"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Construir argumentos para el programa Go
|
||||
if [ "$ALL_GROUPS" = true ]; then
|
||||
ARGS="--all-groups"
|
||||
else
|
||||
ARGS="--group $GRUPO"
|
||||
fi
|
||||
|
||||
if [ "$SEQUENTIAL" = true ]; then
|
||||
ARGS="$ARGS --sequential"
|
||||
fi
|
||||
|
||||
# Ejecutar el orquestador
|
||||
./cmd/parallel-executor/parallel-executor $ARGS
|
||||
|
||||
EXIT_CODE=$?
|
||||
|
||||
# Verificar resultado
|
||||
if [ $EXIT_CODE -eq 0 ]; then
|
||||
echo ""
|
||||
echo "✓ Ejecución completada exitosamente"
|
||||
echo ""
|
||||
|
||||
if [ "$ALL_GROUPS" = true ]; then
|
||||
echo "Logs guardados en:"
|
||||
echo " - logs/parallel-execution-*.log (logs individuales)"
|
||||
echo " - logs/consolidated-summary.txt (resumen consolidado)"
|
||||
else
|
||||
echo "Logs guardados en: logs/parallel-execution-*.log"
|
||||
fi
|
||||
|
||||
# Eliminar el archivo PARALLEL_EXECUTION_ORDER.md después de ejecución exitosa
|
||||
if [ -f "PARALLEL_EXECUTION_ORDER.md" ]; then
|
||||
rm -f PARALLEL_EXECUTION_ORDER.md
|
||||
echo ""
|
||||
echo "✓ Plan de ejecución eliminado (PARALLEL_EXECUTION_ORDER.md)"
|
||||
fi
|
||||
else
|
||||
echo ""
|
||||
echo "❌ Ejecución falló con código $EXIT_CODE"
|
||||
echo ""
|
||||
echo "Revisa los logs para más detalles:"
|
||||
echo " ls -lt logs/parallel-execution-*.log | head -1"
|
||||
exit $EXIT_CODE
|
||||
fi
|
||||
```
|
||||
|
||||
#### 4. Mostrar resumen
|
||||
|
||||
```bash
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "Resumen de ejecución:"
|
||||
echo ""
|
||||
|
||||
# El programa Go debe generar un archivo de resumen
|
||||
if [ -f "logs/last-execution-summary.txt" ]; then
|
||||
cat logs/last-execution-summary.txt
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Estado de worktrees:"
|
||||
git worktree list | grep -v "(bare)" || echo " (ninguno - todos limpiados)"
|
||||
|
||||
echo ""
|
||||
echo "Próximos pasos:"
|
||||
echo " 1. Verificar que todas las issues fueron mergeadas"
|
||||
if [ "$ALL_GROUPS" = false ]; then
|
||||
echo " 2. Si el Grupo $GRUPO fue exitoso, ejecutar siguiente grupo"
|
||||
fi
|
||||
echo " 3. Si hubo errores, revisar logs y reintentar"
|
||||
```
|
||||
|
||||
### Arquitectura del programa Go
|
||||
|
||||
El comando invoca un programa Go en `cmd/parallel-executor/` con la siguiente estructura:
|
||||
|
||||
```
|
||||
cmd/parallel-executor/
|
||||
├── main.go → Entry point, parseo de CLI
|
||||
├── parser.go → Parse PARALLEL_EXECUTION_ORDER.md
|
||||
├── worktree.go → Git worktree operations (shell layer)
|
||||
├── executor.go → Execute claude commands (shell layer)
|
||||
├── logger.go → Structured logging
|
||||
├── orchestrator.go → Orchestration logic con goroutines
|
||||
└── types.go → Estructuras de datos (core types)
|
||||
```
|
||||
|
||||
**Responsabilidades del programa Go:**
|
||||
|
||||
1. **Parser** (`parser.go`):
|
||||
- Leer `PARALLEL_EXECUTION_ORDER.md`
|
||||
- Extraer issues del grupo especificado
|
||||
- Parsear archivos afectados, dependencias, etc.
|
||||
|
||||
2. **Worktree Manager** (`worktree.go`):
|
||||
- Crear worktrees: `git worktree add worktrees/issue-NNNN -b issue/NNNN-slug`
|
||||
- Eliminar worktrees después de merge
|
||||
- Verificar estado de worktrees
|
||||
|
||||
3. **Executor** (`executor.go`):
|
||||
- Ejecutar `claude -p /issues:fix-issue NNNN` en cada worktree
|
||||
- Capturar output en tiempo real
|
||||
- Detectar éxito/fallo del comando
|
||||
- Ejecutar `/git:push` al completar exitosamente
|
||||
|
||||
4. **Logger** (`logger.go`):
|
||||
- Logging estructurado con timestamps
|
||||
- Archivo por ejecución: `logs/parallel-execution-YYYYMMDD-HHMMSS.log`
|
||||
- Output a consola + archivo simultáneamente
|
||||
- Niveles: INFO, WARN, ERROR, SUCCESS
|
||||
|
||||
5. **Orchestrator** (`orchestrator.go`):
|
||||
- Coordinar goroutines para ejecución paralela
|
||||
- Manejar canales de comunicación entre workers
|
||||
- Recolectar resultados y errores
|
||||
- Implementar timeout por issue (configurable)
|
||||
- Rollback en caso de fallo crítico
|
||||
|
||||
**Flujo del programa Go:**
|
||||
|
||||
```
|
||||
1. Parse CLI args (grupo, flags)
|
||||
2. Parse PARALLEL_EXECUTION_ORDER.md
|
||||
3. Extraer issues del grupo especificado
|
||||
4. Para cada issue en el grupo:
|
||||
4.1. Crear worktree + rama
|
||||
4.2. En el worktree:
|
||||
→ cd worktrees/issue-NNNN
|
||||
→ claude -p /issues:fix-issue NNNN
|
||||
→ Esperar a que termine
|
||||
→ Si exitoso: ejecutar /git:push
|
||||
→ Si fallo: reportar error y continuar
|
||||
4.3. Limpiar worktree y rama
|
||||
5. Generar resumen de ejecución
|
||||
6. Return exit code (0 si todo OK, 1 si hubo errores)
|
||||
```
|
||||
|
||||
### Verificación final
|
||||
|
||||
El programa Go se encarga de limpiar los worktrees automáticamente. El resumen final mostrará el estado de todas las ejecuciones.
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **Logs persistentes:** Cada ejecución genera un archivo en `logs/parallel-execution-YYYYMMDD-HHMMSS.log`
|
||||
- **Resumen ejecutivo:** Archivo `logs/last-execution-summary.txt` con métricas clave
|
||||
- **Timeouts:** 30 minutos por issue por defecto (configurable en código Go)
|
||||
- **Paralelismo:** Por defecto ejecuta issues en paralelo con `runtime.NumCPU()` goroutines
|
||||
- **Limpieza automática:** Siempre limpia worktrees al terminar (éxito o fallo)
|
||||
- **Eliminación del plan:** El archivo `PARALLEL_EXECUTION_ORDER.md` se elimina automáticamente al completar exitosamente
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "No existe PARALLEL_EXECUTION_ORDER.md"
|
||||
|
||||
**Causa:** No se ha generado el plan de ejecución paralela
|
||||
|
||||
**Solución:**
|
||||
El comando genera automáticamente el plan si no existe. Si este error persiste:
|
||||
```bash
|
||||
/issues:parallel
|
||||
```
|
||||
|
||||
### Advertencia: "Quedaron N worktrees sin limpiar"
|
||||
|
||||
**Causa:** Alguna issue falló y el worktree no pudo ser limpiado
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# Revisar el error en los logs
|
||||
cat logs/parallel-execution-*.log | grep ERROR
|
||||
|
||||
# Limpiar manualmente
|
||||
/workspace:cleanup-worktrees --all
|
||||
```
|
||||
|
||||
## Reglas críticas
|
||||
|
||||
- **SIEMPRE generar plan automáticamente** si no existe `PARALLEL_EXECUTION_ORDER.md`
|
||||
- **SIEMPRE ejecutar todos los grupos por defecto** - no preguntar al usuario
|
||||
- **SOLO advertir si hay cambios sin commitear** - nunca bloquear la ejecución
|
||||
- **SIEMPRE capturar logs** en archivo persistente
|
||||
- **SIEMPRE limpiar worktrees** incluso si hubo errores (usar defer en Go)
|
||||
- **NUNCA bloquear indefinidamente** - implementar timeouts razonables
|
||||
- **SIEMPRE reportar progreso** en tiempo real
|
||||
- **SIEMPRE eliminar el plan** después de ejecución exitosa
|
||||
- **VERIFICAR estado de git** antes de la ejecución (solo advertencia, no bloqueante)
|
||||
@@ -0,0 +1,387 @@
|
||||
---
|
||||
version: 2.0.0
|
||||
updated: 2026-03-11
|
||||
tags: [issues, implementation, workflow, trunk-based]
|
||||
---
|
||||
|
||||
# Command: fix-issue
|
||||
|
||||
Ejecuta de punta a punta el flujo de implementación/cierre de un issue siguiendo **estrictamente** la regla `fix_issue.md`.
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
Usar cuando quieras implementar un issue completo desde inicio hasta fin con confirmación antes de integrar. El comando maneja todo el ciclo: crear rama, implementar, testear, cerrar issue, pedir confirmación, e integrar a master.
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
/issues:fix-issue <NNNN>
|
||||
/issues:fix-issue <NNNN>-<slug>
|
||||
```
|
||||
|
||||
### Ejemplos
|
||||
|
||||
**Ejemplo 1: Por número**
|
||||
```bash
|
||||
/issues:fix-issue 0013
|
||||
```
|
||||
|
||||
Busca `dev/issues/0013-*.md`, implementa todas las tareas, cierra el issue, pide confirmación, e integra.
|
||||
|
||||
**Ejemplo 2: Por slug completo**
|
||||
```bash
|
||||
/issues:fix-issue 0013-hot-reload
|
||||
```
|
||||
|
||||
Usa exactamente `dev/issues/0013-hot-reload.md`.
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
|
||||
- [ ] Directorio `dev/issues/` existe
|
||||
- [ ] Directorio `dev/issues/completed/` existe
|
||||
- [ ] Archivo `dev/issues/README.md` existe
|
||||
- [ ] Tests configurados (go test disponible)
|
||||
- [ ] Working tree limpio
|
||||
|
||||
### Inputs
|
||||
|
||||
Se necesita el issue objetivo. Si no se proporciona, preguntar:
|
||||
|
||||
- `issue`: número o nombre (ej: `0010` o `0010-access-control`)
|
||||
|
||||
### Flujo obligatorio
|
||||
|
||||
#### 1. Resolver el issue objetivo
|
||||
|
||||
**Si viene solo número** (`0010`):
|
||||
```bash
|
||||
ls dev/issues/0010-*.md
|
||||
```
|
||||
|
||||
**Si viene slug completo** (`0010-access-control`):
|
||||
```bash
|
||||
ls dev/issues/0010-access-control.md
|
||||
```
|
||||
|
||||
**Validaciones:**
|
||||
- Si no existe en `dev/issues/` → ✗ **STOP**: "Issue no encontrado"
|
||||
- Si ya está en `dev/issues/completed/` → ✗ **STOP**: "Issue ya completado"
|
||||
|
||||
#### 2. Leer completo el issue y extraer información
|
||||
|
||||
```bash
|
||||
cat dev/issues/<NNNN>-<slug>.md
|
||||
```
|
||||
|
||||
Extraer:
|
||||
- **Objetivo**: qué se quiere lograr
|
||||
- **Tareas/fases**: lista completa de pasos
|
||||
- **Arquitectura**: archivos a crear/modificar
|
||||
- **Patrón pure/impure**: límites entre core/, shell/, app/
|
||||
- **Tests requeridos**: criterios de aceptación
|
||||
|
||||
#### 3. Crear rama de trabajo (inline)
|
||||
|
||||
{{include: git-verify-clean}}
|
||||
|
||||
Verificar rama actual:
|
||||
|
||||
```bash
|
||||
git branch --show-current
|
||||
```
|
||||
|
||||
**Si ya estamos en `issue/<NNNN>-<slug>`** que coincide:
|
||||
- ✓ Continuar directamente a paso 4
|
||||
|
||||
**Si estamos en master o cualquier otra rama:**
|
||||
|
||||
{{include: git-update-master}}
|
||||
|
||||
```bash
|
||||
git checkout master
|
||||
git pull --rebase
|
||||
git checkout -b issue/<NNNN>-<slug>
|
||||
```
|
||||
|
||||
**⚠️ IMPORTANTE:** Nunca trabajar directamente en `master`.
|
||||
|
||||
#### 4. Planificar con TodoWrite
|
||||
|
||||
Crear plan basado en las tareas del issue:
|
||||
|
||||
```markdown
|
||||
- [ ] Fase 1: <descripción>
|
||||
- [ ] Tarea 1.1
|
||||
- [ ] Tarea 1.2
|
||||
- [ ] Fase 2: <descripción>
|
||||
- [ ] Tarea 2.1
|
||||
- [ ] Tarea 2.2
|
||||
- [ ] Fase N: Tests y validación
|
||||
- [ ] Cerrar issue
|
||||
```
|
||||
|
||||
**Principios:**
|
||||
- Respetar el orden de fases del issue
|
||||
- Incluir siempre fase de tests
|
||||
- Marcar progreso al completar cada bloque
|
||||
|
||||
#### 5. Implementar el issue completo
|
||||
|
||||
**Ejecutar tareas en orden:**
|
||||
|
||||
Para cada tarea:
|
||||
1. Implementar cambios requeridos
|
||||
2. Seguir patrón **pure core / impure shell**:
|
||||
- `core/` → funciones puras, sin side effects
|
||||
- `shell/` → I/O, filesystem, network, APIs
|
||||
- `app/` → orquestación de core + shell
|
||||
3. Compilar frecuentemente:
|
||||
```bash
|
||||
go build -tags goolm ./...
|
||||
```
|
||||
4. Marcar progreso en TodoWrite
|
||||
5. Crear commits atómicos por bloque lógico (no al final, durante la implementación)
|
||||
|
||||
**Commits durante implementación:**
|
||||
```bash
|
||||
git add <archivos_del_bloque>
|
||||
git commit -m "<tipo>: <resumen>" -m "<descripción larga en español>"
|
||||
```
|
||||
|
||||
Tipos: `feat:`, `fix:`, `refactor:`, `test:`, `docs:`, `chore:`
|
||||
|
||||
#### 6. Tests obligatorios
|
||||
|
||||
{{include: run-tests}}
|
||||
|
||||
```bash
|
||||
go test -tags goolm ./...
|
||||
```
|
||||
|
||||
**Casos:**
|
||||
- Tests **pasan** → ✓ Continuar a paso 7
|
||||
- Tests **fallan** → ✗ **STOP**: corregir antes de continuar
|
||||
```bash
|
||||
go test -v -tags goolm ./... # Ver detalles
|
||||
# Corregir errores
|
||||
# Crear commit con fix
|
||||
# Re-ejecutar tests
|
||||
```
|
||||
- No hay tests aplicables → ℹ Indicar al usuario, continuar
|
||||
|
||||
**⚠️ CRÍTICO:** No cerrar el issue sin tests pasando.
|
||||
|
||||
#### 7. Feature flags (si aplica)
|
||||
|
||||
Evaluar si es feature multi-issue o despliegue gradual:
|
||||
|
||||
**Si aplica feature flag:**
|
||||
1. Actualizar `dev/feature_flags.json`:
|
||||
```json
|
||||
{
|
||||
"<nombre-del-flag>": {
|
||||
"enabled": false, // o true si es el último sub-issue
|
||||
"issue": "<NNNN>",
|
||||
"description": "<descripción>",
|
||||
"updated": "2026-03-11"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. Incluir en commit correspondiente (no commit separado solo para flags)
|
||||
|
||||
**Si NO aplica:**
|
||||
- Feature autocontenida que no necesita coordinación
|
||||
- ✓ Saltar este paso
|
||||
|
||||
**⚠️ Recordatorio:** Feature flag ≠ WIP. Los flags protegen código terminado y testeado, no código a medias.
|
||||
|
||||
#### 8. Cerrar el issue
|
||||
|
||||
Mover issue a completed:
|
||||
|
||||
```bash
|
||||
mv dev/issues/<NNNN>-<slug>.md dev/issues/completed/
|
||||
```
|
||||
|
||||
Actualizar índice en `dev/issues/README.md`:
|
||||
|
||||
Cambiar la línea del issue:
|
||||
- Link: de `[<NNNN>-<slug>.md](<NNNN>-<slug>.md)` a `[completed/<NNNN>-<slug>.md](completed/<NNNN>-<slug>.md)`
|
||||
- Estado: de `pendiente` o `en progreso` a `completado`
|
||||
|
||||
Crear commit:
|
||||
```bash
|
||||
git add dev/issues/completed/<NNNN>-<slug>.md dev/issues/README.md
|
||||
git commit -m "docs: cerrar issue <NNNN>-<slug>" -m "Issue <NNNN> completado y movido a completed/
|
||||
|
||||
Todas las tareas implementadas y tests pasando.
|
||||
Ready to merge to master."
|
||||
```
|
||||
|
||||
#### 9. Mostrar resumen de cambios y confirmar
|
||||
|
||||
{{include: ask-user-confirm}}
|
||||
|
||||
**Mostrar al usuario un resumen completo:**
|
||||
|
||||
```bash
|
||||
git status --short
|
||||
git diff --stat master
|
||||
git log --oneline master..HEAD
|
||||
```
|
||||
|
||||
**Mostrar tareas completadas del TodoWrite.**
|
||||
|
||||
**Pausar y preguntar:**
|
||||
|
||||
```
|
||||
✓ Issue <NNNN>-<slug> completado
|
||||
|
||||
Resumen de cambios:
|
||||
- <N> archivos modificados/creados
|
||||
- <N> commits realizados
|
||||
- Tests: [pasando / no aplica]
|
||||
- Issue movido a completed/
|
||||
|
||||
Commits:
|
||||
- <commit 1>
|
||||
- <commit 2>
|
||||
- ...
|
||||
|
||||
¿Está todo bien para integrar a master?
|
||||
- Si es correcto: se hará merge y push automáticamente
|
||||
- Si necesitas ajustes: puedes hacer cambios adicionales antes
|
||||
```
|
||||
|
||||
**Esperar respuesta del usuario:**
|
||||
- Si responde **SI** / afirmativo → continuar a paso 10
|
||||
- Si responde **NO** / necesita cambios → **STOP**: "Haz los ajustes necesarios y cuando estés listo ejecuta `/git:push`"
|
||||
|
||||
#### 10. Ejecutar /git:push automáticamente
|
||||
|
||||
Una vez confirmado por el usuario, ejecutar `/git:push` para:
|
||||
|
||||
1. Verificar que estamos en la rama correcta
|
||||
2. Re-ejecutar tests (verificación final)
|
||||
3. Checkout a master y actualizar
|
||||
4. Merge --no-ff:
|
||||
```bash
|
||||
git merge --no-ff issue/<NNNN>-<slug> -m "merge: issue/<NNNN>-<slug> — <título del issue>"
|
||||
```
|
||||
5. Push a remoto
|
||||
6. Limpiar rama local
|
||||
|
||||
El comando `/git:push` maneja todo el flujo de integración automáticamente.
|
||||
|
||||
### Verificación final
|
||||
|
||||
Informar al usuario:
|
||||
|
||||
```
|
||||
✓ Issue <NNNN>-<slug> completado e integrado a master
|
||||
|
||||
Rama: issue/<NNNN>-<slug> (mergeada y limpiada)
|
||||
Commits integrados: <N>
|
||||
Tests: pasando
|
||||
Issue: movido a dev/issues/completed/
|
||||
|
||||
Master actualizado y sincronizado con remoto.
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **Issue completo**: implementar todas las tareas, no parcial
|
||||
- **Commits atómicos**: durante implementación, no al final
|
||||
- **Tests obligatorios**: no cerrar sin tests pasando
|
||||
- **Pure core / impure shell**: respetar arquitectura estrictamente
|
||||
- **Feature flags solo si aplica**: no usar para ocultar trabajo incompleto
|
||||
- **Confirmación obligatoria**: siempre pedir antes de integrar
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "Issue not found"
|
||||
|
||||
**Causa:** El archivo del issue no existe en `dev/issues/`
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
ls dev/issues/
|
||||
# Verificar número o slug correcto
|
||||
# O crear el issue primero con /issues:create-issue
|
||||
```
|
||||
|
||||
### Error: "Issue already completed"
|
||||
|
||||
**Causa:** El issue ya está en `dev/issues/completed/`
|
||||
|
||||
**Solución:**
|
||||
El issue ya fue implementado. Si necesitas modificarlo:
|
||||
1. Crear nuevo issue que referencia el anterior
|
||||
2. O mover de vuelta a `dev/issues/` si realmente no estaba completo
|
||||
|
||||
### Error: "Tests failing during implementation"
|
||||
|
||||
**Causa:** Los cambios rompieron tests existentes
|
||||
|
||||
**Solución:**
|
||||
1. Ver detalles:
|
||||
```bash
|
||||
go test -v -tags goolm ./...
|
||||
```
|
||||
|
||||
2. Identificar qué test falló y por qué
|
||||
3. Corregir el código o actualizar el test si es legítimo
|
||||
4. Crear commit con el fix
|
||||
5. Continuar implementación
|
||||
|
||||
### Error: "Cannot create branch, working tree not clean"
|
||||
|
||||
**Causa:** Hay cambios sin commitear
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
git status
|
||||
# Opción 1: Commitear cambios primero
|
||||
git add . && git commit -m "mensaje"
|
||||
# Opción 2: Hacer stash
|
||||
git stash
|
||||
# Luego ejecutar /issues:fix-issue nuevamente
|
||||
```
|
||||
|
||||
### Error: "go build failed"
|
||||
|
||||
**Causa:** Errores de compilación en el código
|
||||
|
||||
**Solución:**
|
||||
1. Leer el error de compilación cuidadosamente
|
||||
2. Corregir el error en el código
|
||||
3. Intentar compilar de nuevo
|
||||
4. No continuar hasta que compile correctamente
|
||||
|
||||
### Advertencia: "Feature flag needed but not found"
|
||||
|
||||
**Causa:** El issue es parte de feature multi-issue pero no tiene flag
|
||||
|
||||
**Solución:**
|
||||
1. Revisar si realmente necesita feature flag
|
||||
2. Si sí: agregar a `dev/feature_flags.json`
|
||||
3. Si no: continuar sin flag
|
||||
|
||||
## Reglas críticas
|
||||
|
||||
- **Seguir fix_issue.md estrictamente**: no saltear pasos
|
||||
- **NO saltear tareas del issue**: implementar todas
|
||||
- **NO hacer commits WIP**: cada commit debe ser atómico y completo
|
||||
- **SIEMPRE usar -tags goolm**: en build y test
|
||||
- **SIEMPRE ejecutar tests**: antes de cerrar issue
|
||||
- **Confirmación obligatoria**: esperar aprobación del usuario antes de integrar
|
||||
- **Flujo automático post-confirmación**: ejecutar `/git:push` para integrar
|
||||
- **Respetar arquitectura**: core/ puro, shell/ impuro, app/ orquestación
|
||||
- **NO inventar soluciones**: seguir las tareas del issue al pie de la letra
|
||||
@@ -0,0 +1,481 @@
|
||||
---
|
||||
version: 1.0.0
|
||||
updated: 2026-03-11
|
||||
tags: [issues, parallel, development, worktree]
|
||||
---
|
||||
|
||||
# Command: parallel-issues
|
||||
|
||||
Analiza las issues pendientes en `dev/issues/` y genera un plan de ejecución paralela (`PARALLEL_EXECUTION_ORDER.md`) agrupando issues independientes que no tienen conflictos entre sí.
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
- Cuando quieres identificar qué issues puedes desarrollar en paralelo sin conflictos
|
||||
- Para acelerar el desarrollo trabajando en múltiples issues simultáneamente
|
||||
- Antes de iniciar una sesión de desarrollo intensivo con múltiples desarrolladores
|
||||
- Para planificar el uso de git worktrees con issues independientes
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
/issues:parallel [--dry-run]
|
||||
```
|
||||
|
||||
### Ejemplos
|
||||
|
||||
**Ejemplo 1:**
|
||||
```bash
|
||||
/issues:parallel
|
||||
```
|
||||
|
||||
Analiza todas las issues pendientes y genera el archivo `PARALLEL_EXECUTION_ORDER.md` con grupos de issues paralelizables.
|
||||
|
||||
**Ejemplo 2:**
|
||||
```bash
|
||||
/issues:parallel --dry-run
|
||||
```
|
||||
|
||||
Muestra el análisis de paralelización en consola sin crear el archivo (útil para vista previa).
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
|
||||
- [ ] Existe el directorio `dev/issues/`
|
||||
- [ ] Hay al menos una issue pendiente en formato `NNNN-*.md`
|
||||
- [ ] El proyecto sigue la estructura funcional (core/shell/app)
|
||||
|
||||
### Inputs
|
||||
|
||||
Se necesitan los siguientes datos. Si no se proporcionan, preguntar al usuario:
|
||||
|
||||
- `--dry-run` (opcional): Si está presente, solo muestra el análisis sin crear archivo
|
||||
|
||||
### Flujo obligatorio
|
||||
|
||||
#### 1. Detectar contexto del proyecto
|
||||
|
||||
Determinar si estamos en el proyecto padre (Dataforge) o en un proyecto hijo (workspaces/).
|
||||
|
||||
```bash
|
||||
# Verificar si estamos en un proyecto hijo
|
||||
if [[ "$PWD" == *"/workspaces/"* ]]; then
|
||||
PROJECT_TYPE="child"
|
||||
PROJECT_NAME=$(basename "$PWD")
|
||||
else
|
||||
PROJECT_TYPE="parent"
|
||||
PROJECT_NAME="Dataforge"
|
||||
fi
|
||||
|
||||
echo "Analizando issues en proyecto: $PROJECT_NAME ($PROJECT_TYPE)"
|
||||
```
|
||||
|
||||
Verificar que existe `dev/issues/`:
|
||||
|
||||
```bash
|
||||
if [ ! -d "dev/issues" ]; then
|
||||
echo "Error: No existe el directorio dev/issues/"
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
#### 2. Listar issues pendientes
|
||||
|
||||
Obtener todas las issues que no están marcadas como completadas:
|
||||
|
||||
```bash
|
||||
# Listar archivos de issues
|
||||
ls -1 dev/issues/*.md | grep -E '[0-9]{4}-.*\.md$' | sort
|
||||
```
|
||||
|
||||
Para cada issue, extraer:
|
||||
- **Número de issue** (NNNN)
|
||||
- **Título** (del nombre del archivo)
|
||||
- **Estado** (revisar si está en el índice como completada)
|
||||
- **Archivos mencionados** (parsear el contenido del issue)
|
||||
- **Dependencias explícitas** (buscar referencias a `#NNNN`)
|
||||
|
||||
**Parseo de archivos mencionados:**
|
||||
|
||||
Buscar patrones como:
|
||||
- `core/archivo.go`
|
||||
- `shell/archivo.go`
|
||||
- `app/archivo.go`
|
||||
- Cualquier path con extensión de código
|
||||
|
||||
**Parseo de dependencias:**
|
||||
|
||||
Buscar patrones como:
|
||||
- "depende de #0001"
|
||||
- "requiere #0002"
|
||||
- "bloqueado por #0003"
|
||||
|
||||
#### 3. Analizar conflictos y dependencias
|
||||
|
||||
Para cada par de issues (A, B), determinar si son **paralelizables**:
|
||||
|
||||
**Criterios de conflicto (NO paralelizables):**
|
||||
1. **Archivos compartidos:** Si ambas issues modifican el mismo archivo
|
||||
2. **Dependencias explícitas:** Si A menciona "#B" o viceversa
|
||||
3. **Dependencias transitivas:** Si A depende de C y B depende de C
|
||||
|
||||
**Criterios de paralelización (SÍ paralelizables):**
|
||||
1. **Archivos disjuntos:** Modifican archivos completamente diferentes
|
||||
2. **Capas diferentes:** Una toca `core/` y otra `shell/` sin archivos comunes
|
||||
3. **Sin referencias cruzadas:** Ninguna menciona a la otra
|
||||
|
||||
**Estructura de datos sugerida:**
|
||||
|
||||
```
|
||||
Issue #0001:
|
||||
- Archivos: [core/types.go, core/workspace.go]
|
||||
- Depende de: []
|
||||
- Capa principal: core
|
||||
|
||||
Issue #0002:
|
||||
- Archivos: [shell/gitea.go, shell/http.go]
|
||||
- Depende de: [#0001]
|
||||
- Capa principal: shell
|
||||
|
||||
Conflictos detectados:
|
||||
- #0002 → #0001 (dependencia explícita)
|
||||
```
|
||||
|
||||
#### 4. Agrupar issues por independencia
|
||||
|
||||
Usar algoritmo de agrupación por grafos:
|
||||
|
||||
1. **Construir grafo de dependencias:**
|
||||
- Nodos = issues
|
||||
- Aristas = conflictos/dependencias
|
||||
|
||||
2. **Detectar componentes independientes:**
|
||||
- Issues sin aristas entre sí → mismo grupo paralelo
|
||||
- Issues con aristas → grupos secuenciales
|
||||
|
||||
3. **Priorizar grupos:**
|
||||
- Grupo 1: Issues sin dependencias (pueden ejecutarse YA)
|
||||
- Grupo 2: Issues que dependen solo de Grupo 1
|
||||
- Grupo N: Issues que dependen de grupos anteriores
|
||||
|
||||
**Algoritmo simple:**
|
||||
|
||||
```
|
||||
Grupo_actual = 1
|
||||
Issues_restantes = todas las issues pendientes
|
||||
Issues_completadas = []
|
||||
|
||||
while Issues_restantes no está vacío:
|
||||
Grupo[Grupo_actual] = []
|
||||
|
||||
for issue in Issues_restantes:
|
||||
tiene_conflictos = false
|
||||
|
||||
# Verificar conflictos con issues ya en el grupo actual
|
||||
for otra in Grupo[Grupo_actual]:
|
||||
if conflicto(issue, otra):
|
||||
tiene_conflictos = true
|
||||
break
|
||||
|
||||
# Verificar dependencias no resueltas
|
||||
for dep in issue.dependencias:
|
||||
if dep not in Issues_completadas:
|
||||
tiene_conflictos = true
|
||||
break
|
||||
|
||||
if not tiene_conflictos:
|
||||
Grupo[Grupo_actual].append(issue)
|
||||
|
||||
# Si no pudimos agregar ninguna issue al grupo, hay dependencias circulares
|
||||
if Grupo[Grupo_actual] está vacío:
|
||||
ERROR: "Dependencias circulares detectadas"
|
||||
break
|
||||
|
||||
# Marcar issues del grupo como completadas para próxima iteración
|
||||
Issues_completadas += Grupo[Grupo_actual]
|
||||
Issues_restantes -= Grupo[Grupo_actual]
|
||||
Grupo_actual++
|
||||
```
|
||||
|
||||
#### 5. Estimar tiempos de desarrollo
|
||||
|
||||
Para cada issue, calcular complejidad basada en:
|
||||
|
||||
**Factores:**
|
||||
1. **Cantidad de archivos:**
|
||||
- 1-2 archivos = Simple (1-2 horas)
|
||||
- 3-5 archivos = Moderada (2-4 horas)
|
||||
- 6+ archivos = Compleja (4-8 horas)
|
||||
|
||||
2. **Capa afectada:**
|
||||
- Solo `core/` = Moderada (requiere tests extensivos)
|
||||
- Solo `shell/` = Alta (I/O, manejo de errores)
|
||||
- `app/` = Baja (orquestación)
|
||||
- Múltiples capas = Alta (integración compleja)
|
||||
|
||||
3. **Palabras clave en descripción:**
|
||||
- "refactor", "reestructurar" = +50% tiempo
|
||||
- "nuevo", "implementar" = tiempo base
|
||||
- "fix", "corregir" = -30% tiempo
|
||||
- "documentar" = tiempo muy bajo
|
||||
|
||||
**Estimación por grupo:**
|
||||
- Tiempo de grupo = MAX(tiempos individuales) ← porque se ejecutan en paralelo
|
||||
- Tiempo total = SUM(tiempos de grupos) ← porque los grupos son secuenciales
|
||||
|
||||
#### 6. Generar archivo PARALLEL_EXECUTION_ORDER.md
|
||||
|
||||
Crear el archivo con la siguiente estructura:
|
||||
|
||||
```markdown
|
||||
# Plan de Ejecución Paralela
|
||||
|
||||
**Proyecto:** {{PROJECT_NAME}}
|
||||
**Fecha de análisis:** {{FECHA}}
|
||||
**Issues analizadas:** {{TOTAL_ISSUES}}
|
||||
**Grupos paralelos:** {{TOTAL_GRUPOS}}
|
||||
|
||||
---
|
||||
|
||||
## Grupo 1: Issues Independientes (ejecutar en paralelo)
|
||||
|
||||
### Issue #0003 - Implementar shell/gitea.go
|
||||
- **Archivos afectados:**
|
||||
- `shell/gitea.go`
|
||||
- `shell/gitea_test.go`
|
||||
- **Capa:** shell
|
||||
- **Complejidad:** Moderada
|
||||
- **Tiempo estimado:** 3 horas
|
||||
- **Dependencias:** Ninguna
|
||||
- **Worktree sugerido:** `worktrees/issue-0003`
|
||||
- **Branch sugerida:** `quick/issues:fix-issue-0003`
|
||||
|
||||
### Issue #0006 - Añadir logging estructurado
|
||||
- **Archivos afectados:**
|
||||
- `shell/logger.go`
|
||||
- `app/main.go`
|
||||
- **Capa:** shell, app
|
||||
- **Complejidad:** Simple
|
||||
- **Tiempo estimado:** 2 horas
|
||||
- **Dependencias:** Ninguna
|
||||
- **Worktree sugerido:** `worktrees/issue-0006`
|
||||
- **Branch sugerida:** `quick/issues:fix-issue-0006`
|
||||
|
||||
### Issue #0008 - Documentación de módulos
|
||||
- **Archivos afectados:**
|
||||
- `README.md`
|
||||
- `docs/architecture.md`
|
||||
- **Capa:** docs
|
||||
- **Complejidad:** Simple
|
||||
- **Tiempo estimado:** 1.5 horas
|
||||
- **Dependencias:** Ninguna
|
||||
- **Worktree sugerido:** `worktrees/issue-0008`
|
||||
- **Branch sugerida:** `quick/issues:fix-issue-0008`
|
||||
|
||||
**Tiempo estimado del grupo:** 3 horas (máximo en paralelo)
|
||||
|
||||
---
|
||||
|
||||
## Grupo 2: Issues Dependientes (ejecutar después de Grupo 1)
|
||||
|
||||
### Issue #0004 - Implementar app/orchestrator.go
|
||||
- **Archivos afectados:**
|
||||
- `app/orchestrator.go`
|
||||
- `app/orchestrator_test.go`
|
||||
- **Capa:** app
|
||||
- **Complejidad:** Alta
|
||||
- **Tiempo estimado:** 5 horas
|
||||
- **Dependencias:**
|
||||
- `#0003` (requiere shell/gitea.go)
|
||||
- **Worktree sugerido:** `worktrees/issue-0004`
|
||||
- **Branch sugerida:** `quick/issues:fix-issue-0004`
|
||||
|
||||
**Tiempo estimado del grupo:** 5 horas
|
||||
|
||||
---
|
||||
|
||||
## Grupo 3: Issues Finales
|
||||
|
||||
### Issue #0005 - Integración completa
|
||||
- **Archivos afectados:**
|
||||
- `app/main.go`
|
||||
- `cmd/dataforge/main.go`
|
||||
- **Capa:** app
|
||||
- **Complejidad:** Moderada
|
||||
- **Tiempo estimado:** 3 horas
|
||||
- **Dependencias:**
|
||||
- `#0004` (requiere orchestrator)
|
||||
- **Worktree sugerido:** `worktrees/issue-0005`
|
||||
- **Branch sugerida:** `quick/issues:fix-issue-0005`
|
||||
|
||||
**Tiempo estimado del grupo:** 3 horas
|
||||
|
||||
---
|
||||
|
||||
## Conflictos Detectados
|
||||
|
||||
### Conflictos por archivos compartidos:
|
||||
- `#0002` y `#0003`: ambos modifican `core/types.go`
|
||||
- **Solución:** Ejecutar secuencialmente (están en grupos diferentes)
|
||||
|
||||
### Dependencias explícitas:
|
||||
- `#0004` depende de `#0003`
|
||||
- `#0005` depende de `#0004`
|
||||
|
||||
### Advertencias:
|
||||
- Ninguna circular detectada ✓
|
||||
|
||||
---
|
||||
|
||||
## Resumen
|
||||
|
||||
| Métrica | Valor |
|
||||
|---------|-------|
|
||||
| Issues totales | 8 |
|
||||
| Issues en Grupo 1 (paralelas) | 3 |
|
||||
| Issues secuenciales | 5 |
|
||||
| Grupos paralelos | 3 |
|
||||
| Tiempo total secuencial | 28 horas |
|
||||
| Tiempo total paralelo | 11 horas |
|
||||
| **Ahorro de tiempo** | **61%** |
|
||||
|
||||
---
|
||||
|
||||
## Recomendaciones
|
||||
|
||||
1. **Ejecutar Grupo 1 en paralelo:** Usar git worktrees para trabajar en las 3 issues simultáneamente
|
||||
2. **Esperar a Grupo 2:** No iniciar #0004 hasta que #0003 esté mergeada
|
||||
3. **Validar integraciones:** Después de cada grupo, ejecutar tests completos
|
||||
4. **Monitoring:** Si encuentras nuevas dependencias durante desarrollo, actualiza el plan
|
||||
|
||||
---
|
||||
|
||||
## Comandos para Setup de Worktrees
|
||||
|
||||
```bash
|
||||
# Grupo 1 - Crear worktrees para issues paralelas
|
||||
git worktree add worktrees/issue-0003 -b quick/issues:fix-issue-0003
|
||||
git worktree add worktrees/issue-0006 -b quick/issues:fix-issue-0006
|
||||
git worktree add worktrees/issue-0008 -b quick/issues:fix-issue-0008
|
||||
|
||||
# Ejecutar /issues:fix-issue en cada worktree (manual)
|
||||
# cd worktrees/issue-0003 && /issues:fix-issue 0003
|
||||
# cd worktrees/issue-0006 && /issues:fix-issue 0006
|
||||
# cd worktrees/issue-0008 && /issues:fix-issue 0008
|
||||
|
||||
# Después de mergear Grupo 1, crear worktree para Grupo 2
|
||||
git worktree add worktrees/issue-0004 -b quick/issues:fix-issue-0004
|
||||
|
||||
# Limpiar worktrees después de merge
|
||||
git worktree remove worktrees/issue-0003
|
||||
git worktree remove worktrees/issue-0006
|
||||
git worktree remove worktrees/issue-0008
|
||||
```
|
||||
```
|
||||
|
||||
**Notas importantes:**
|
||||
|
||||
- Usar formato markdown claro y estructurado
|
||||
- Incluir tabla de resumen con métricas
|
||||
- Calcular ahorro de tiempo (tiempo secuencial vs paralelo)
|
||||
- Sugerir comandos de worktree para facilitar setup
|
||||
- Documentar advertencias y conflictos detectados
|
||||
|
||||
#### 7. Mostrar resultado
|
||||
|
||||
Si se ejecutó con `--dry-run`:
|
||||
- Mostrar todo el contenido en consola
|
||||
- NO crear archivo
|
||||
- Terminar aquí
|
||||
|
||||
Si se ejecutó sin flags:
|
||||
- Crear archivo `PARALLEL_EXECUTION_ORDER.md`
|
||||
- Mostrar resumen en consola
|
||||
|
||||
```bash
|
||||
cat PARALLEL_EXECUTION_ORDER.md
|
||||
```
|
||||
|
||||
### Verificación final
|
||||
|
||||
```bash
|
||||
# Verificar que el archivo fue creado
|
||||
ls -lh PARALLEL_EXECUTION_ORDER.md
|
||||
|
||||
# Contar grupos generados
|
||||
grep -c "^## Grupo" PARALLEL_EXECUTION_ORDER.md
|
||||
```
|
||||
|
||||
Informar al usuario:
|
||||
|
||||
```
|
||||
✓ Plan de ejecución paralela generado
|
||||
|
||||
Archivo: PARALLEL_EXECUTION_ORDER.md
|
||||
|
||||
Resumen:
|
||||
- Issues analizadas: {{N}}
|
||||
- Grupos paralelos: {{M}}
|
||||
- Ahorro estimado: {{X}}%
|
||||
|
||||
Próximos pasos:
|
||||
1. Revisar el plan generado
|
||||
2. Crear worktrees para Grupo 1
|
||||
3. Ejecutar /issues:fix-issue en cada worktree
|
||||
4. Mergear y continuar con siguientes grupos
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **Nombres de grupo:** "Grupo N" donde N empieza en 1
|
||||
- **Worktrees sugeridos:** Siempre bajo `worktrees/issue-NNNN`
|
||||
- **Branches sugeridas:** Formato `quick/issues:fix-issue-NNNN`
|
||||
- **Estimación de tiempo:** En horas, redondeado a .5 (ej: 2.5h, 3h, 4.5h)
|
||||
- **Conflictos:** Documentar TODOS los conflictos detectados aunque estén resueltos en el plan
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "No se encontraron issues pendientes"
|
||||
|
||||
**Causa:** No hay archivos `.md` en `dev/issues/` o todos están marcados como completados
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
# Verificar issues existentes
|
||||
ls -1 dev/issues/*.md
|
||||
|
||||
# Verificar índice de issues completadas
|
||||
cat dev/issues/README.md
|
||||
```
|
||||
|
||||
### Error: "Dependencias circulares detectadas"
|
||||
|
||||
**Causa:** Las issues tienen dependencias que forman un ciclo (A→B→C→A)
|
||||
|
||||
**Solución:**
|
||||
1. Revisar manualmente las dependencias en los archivos de issues
|
||||
2. Identificar el ciclo
|
||||
3. Romper una de las dependencias refactorizando el alcance de una issue
|
||||
4. Re-ejecutar el comando
|
||||
|
||||
### Warning: "Múltiples issues modifican el mismo archivo"
|
||||
|
||||
**Causa:** Varias issues tocan el mismo archivo pero no tienen dependencias explícitas
|
||||
|
||||
**Solución:**
|
||||
1. El algoritmo las colocará en grupos secuenciales automáticamente
|
||||
2. Considerar refactorizar las issues para que sean más granulares
|
||||
3. O agregar dependencias explícitas si hay un orden lógico
|
||||
|
||||
## Reglas críticas
|
||||
|
||||
- **NUNCA ejecutar issues en paralelo si comparten archivos** - causará conflictos de merge
|
||||
- **SIEMPRE respetar dependencias explícitas** - aunque no compartan archivos
|
||||
- **NUNCA asumir independencia sin analizar el contenido** - leer cada issue completamente
|
||||
- **SIEMPRE calcular el tiempo del grupo como MAX(tiempos)** - no como suma (son paralelas)
|
||||
- **NUNCA crear el archivo si hay errores en el análisis** - informar al usuario y terminar
|
||||
- **SIEMPRE documentar conflictos detectados** - transparencia total en el análisis
|
||||
@@ -0,0 +1,212 @@
|
||||
---
|
||||
version: 1.0.0
|
||||
updated: 2026-03-15
|
||||
tags: [issues, quick, automation, tui]
|
||||
---
|
||||
|
||||
# Command: quick-issue
|
||||
|
||||
Crea un issue nuevo automáticamente desde la TUI con detección automática de workspace y número de issue.
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
Este comando es invocado automáticamente por la TUI cuando el usuario presiona la opción "Create Issue". **No se debe invocar manualmente** desde la línea de comandos.
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
/issues:quick-issue --text "descripción del issue"
|
||||
```
|
||||
|
||||
El comando auto-detecta el próximo número de issue disponible y crea el archivo automáticamente.
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
|
||||
- [ ] Directorio `dev/issues/` existe
|
||||
- [ ] Parámetro `--text` fue proporcionado
|
||||
- [ ] Working tree limpio
|
||||
|
||||
### Inputs
|
||||
|
||||
**Obligatorios:**
|
||||
- `--text`: Texto descriptivo del issue (se usará como título y descripción)
|
||||
|
||||
**Auto-detectados:**
|
||||
- Número de issue: Siguiente disponible en `dev/issues/`
|
||||
- Workspace: Proyecto padre (Dataforge)
|
||||
|
||||
### Flujo obligatorio
|
||||
|
||||
#### 1. Determinar número del issue
|
||||
|
||||
```bash
|
||||
# Listar issues existentes
|
||||
ls -1 dev/issues/*.md | grep -E '^dev/issues/[0-9]{4}[a-z]?-' | sort -V
|
||||
|
||||
# Extraer último número
|
||||
# Si el último es 0023-foo.md, siguiente es 0024
|
||||
# Si el último es 0023c-bar.md, siguiente es 0024
|
||||
```
|
||||
|
||||
Regla: **SIEMPRE incrementar el número base**, ignorar letras.
|
||||
|
||||
#### 2. Generar título y slug
|
||||
|
||||
- **Título**: Usar `--text` directamente
|
||||
- **Slug**: Convertir título a kebab-case
|
||||
|
||||
Ejemplo:
|
||||
```
|
||||
--text "Agregar soporte para temas oscuros"
|
||||
→ Título: "Agregar soporte para temas oscuros"
|
||||
→ Slug: "agregar-soporte-para-temas-oscuros"
|
||||
```
|
||||
|
||||
#### 3. Crear archivo de issue
|
||||
|
||||
Usar template `.claude/templates/issue.md` y completar:
|
||||
|
||||
```markdown
|
||||
# NNNN — [Título]
|
||||
|
||||
## Metadata
|
||||
|
||||
| Campo | Valor |
|
||||
|-------|-------|
|
||||
| **ID** | NNNN |
|
||||
| **Estado** | 🟡 pendiente |
|
||||
| **Prioridad** | media |
|
||||
| **Tipo** | feature |
|
||||
|
||||
## Dependencias
|
||||
|
||||
| ID | Título | Estado | Requerido |
|
||||
|----|--------|--------|-----------|
|
||||
| - | - | - | - |
|
||||
|
||||
**Bloqueada por:** Ninguna
|
||||
|
||||
**Desbloquea:** (a determinar)
|
||||
|
||||
---
|
||||
|
||||
## Objetivo
|
||||
|
||||
[Texto del parámetro --text]
|
||||
|
||||
## Contexto
|
||||
|
||||
(A completar durante implementación)
|
||||
|
||||
## Tareas
|
||||
|
||||
- [ ] (A detallar durante implementación con /issues:fix-issue)
|
||||
|
||||
---
|
||||
|
||||
## Criterios de aceptación
|
||||
|
||||
- [ ] Tests pasando
|
||||
- [ ] Documentación actualizada
|
||||
- [ ] Issue movida a completed/
|
||||
|
||||
---
|
||||
|
||||
## Notas de implementación
|
||||
|
||||
[Notas que surjan durante la implementación]
|
||||
```
|
||||
|
||||
#### 4. Actualizar índice
|
||||
|
||||
Agregar línea en `dev/issues/README.md`:
|
||||
|
||||
```markdown
|
||||
- [ ] [NNNN](NNNN-slug.md) — [Título] (pendiente)
|
||||
```
|
||||
|
||||
#### 5. Crear commits y mergear
|
||||
|
||||
**Sin pedir confirmación**, ejecutar:
|
||||
|
||||
```bash
|
||||
# Crear rama
|
||||
git checkout -b quick/issues:quick-issue-NNNN
|
||||
|
||||
# Commitear
|
||||
git add dev/issues/NNNN-slug.md dev/issues/README.md
|
||||
git commit -m "docs: crear issue NNNN-slug" -m "Issue NNNN: [Título]
|
||||
|
||||
Creado desde TUI con quick-issue.
|
||||
|
||||
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
|
||||
# Mergear
|
||||
git checkout master
|
||||
git pull --rebase
|
||||
git merge --no-ff quick/issues:quick-issue-NNNN -m "merge: quick/issues:quick-issue-NNNN — [título]"
|
||||
|
||||
# Push
|
||||
git push
|
||||
|
||||
# Limpiar
|
||||
git branch -d quick/issues:quick-issue-NNNN
|
||||
```
|
||||
|
||||
#### 6. Reportar resultado
|
||||
|
||||
Informar al usuario con formato claro:
|
||||
|
||||
```
|
||||
✓ Issue NNNN-slug creado e integrado
|
||||
|
||||
Título: [Título]
|
||||
Archivo: dev/issues/NNNN-slug.md
|
||||
|
||||
Para implementar:
|
||||
/issues:fix-issue NNNN
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **Auto-detección**: workspace y número de issue
|
||||
- **Sin confirmación**: flujo completamente automático
|
||||
- **Trunk-based**: rama quick/ y merge inmediato
|
||||
- **Template simple**: detalles se completan durante /fix-issue
|
||||
- **Commits atómicos**: issue + índice en un solo commit
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "Missing --text parameter"
|
||||
|
||||
**Causa:** El comando fue invocado sin el parámetro `--text`.
|
||||
|
||||
**Solución:** Este comando debe ser invocado automáticamente por la TUI. No invocar manualmente.
|
||||
|
||||
### Error: "Working tree not clean"
|
||||
|
||||
**Causa:** Hay cambios pendientes.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
git status
|
||||
git stash
|
||||
# Reintentar desde TUI
|
||||
git stash pop
|
||||
```
|
||||
|
||||
## Reglas críticas
|
||||
|
||||
- **SIEMPRE auto-detectar número de issue** - no pedirlo
|
||||
- **USAR --text como título completo** - no truncar
|
||||
- **NO pedir confirmación** - flujo automático
|
||||
- **Template minimalista** - los detalles se agregan en /fix-issue
|
||||
- **REPORTAR resultado claramente** - mostrar número y path del issue
|
||||
@@ -0,0 +1,103 @@
|
||||
---
|
||||
version: 1.0.0
|
||||
updated: 2026-03-15
|
||||
tags: [issues, planning, dependencies, order]
|
||||
---
|
||||
|
||||
# Command: sort-issues (issues)
|
||||
|
||||
Analiza las issues en `dev/issues/` del repositorio Dataforge (parent), construye el grafo de dependencias y muestra el orden de ejecución recomendado. Detecta dependencias circulares y las reporta claramente.
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
- Cuando quieres saber en qué orden ejecutar las issues del proyecto padre
|
||||
- Antes de empezar a trabajar para entender el flujo crítico
|
||||
- Cuando hay dudas sobre bloqueos entre issues
|
||||
- Invocado desde TUI con la tecla `s` en el selector de issues
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
/issues:sort-issues
|
||||
```
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
- [ ] Directorio `dev/issues/` existe
|
||||
- [ ] Hay archivos `.md` en `dev/issues/` (al menos uno)
|
||||
|
||||
### Flujo obligatorio
|
||||
|
||||
#### 1. Listar todas las issues pendientes
|
||||
|
||||
```bash
|
||||
ls dev/issues/*.md | grep -E '^dev/issues/[0-9]{4}[a-z]?-.*\.md$' | sort
|
||||
```
|
||||
|
||||
Excluir `README.md` y otros archivos que no sean issues numeradas.
|
||||
|
||||
#### 2. Para cada issue, extraer dependencias
|
||||
|
||||
Leer cada archivo y buscar:
|
||||
|
||||
1. **Tabla "## Dependencias"**: filas con IDs en primera columna
|
||||
2. **Línea "Bloqueada por"**: `**Bloqueada por:** \`#NNNN, #NNNN\``
|
||||
|
||||
Construir lista: `{id: "0003", deps: ["0001", "0002"]}`
|
||||
|
||||
#### 3. Construir grafo y detectar ciclos
|
||||
|
||||
Verificar si hay dependencias circulares (A → B → A).
|
||||
|
||||
**Si hay ciclos:**
|
||||
|
||||
```
|
||||
❌ Dependencias circulares detectadas:
|
||||
|
||||
0010 → 0011 → 0012 → 0010
|
||||
|
||||
Solución: Revisar dependencias en:
|
||||
- dev/issues/0010-*.md
|
||||
- dev/issues/0011-*.md
|
||||
- dev/issues/0012-*.md
|
||||
```
|
||||
|
||||
**Si no hay ciclos:** continuar al paso 4.
|
||||
|
||||
#### 4. Calcular orden topológico
|
||||
|
||||
Aplicar Kahn's algorithm o DFS post-order. Criterios de desempate:
|
||||
1. Número de issue menor primero
|
||||
2. Issues sin dependencias primero (nivel 0)
|
||||
|
||||
#### 5. Mostrar resultado
|
||||
|
||||
```
|
||||
Orden de ejecución recomendado para Dataforge:
|
||||
|
||||
1. [0001] Título issue 1
|
||||
2. [0002] Título issue 2
|
||||
3. [0003] Título issue 3 (depende de: 0001, 0002)
|
||||
4. [0004] Título issue 4 (depende de: 0002, 0003)
|
||||
5. [0005] Título issue 5 (depende de: 0004)
|
||||
|
||||
⚠️ Issues con dependencias circulares: Ninguna
|
||||
✓ Todas las issues pueden ejecutarse en este orden
|
||||
|
||||
Issues paralelizables (misma capa):
|
||||
- Capa 1 (sin deps): 0001
|
||||
- Capa 2: 0002
|
||||
- Capa 3: 0003, 0004
|
||||
- Capa 4: 0005
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **Solo leer**: nunca modificar los archivos de issues
|
||||
- **Análisis exhaustivo**: leer TODAS las issues antes de generar el orden
|
||||
- **Detectar ambos formatos**: tabla Dependencias + línea Bloqueada por
|
||||
- **Reportar claramente** los ciclos con los IDs involucrados
|
||||
@@ -0,0 +1,233 @@
|
||||
---
|
||||
version: 1.0.0
|
||||
updated: 2026-03-11
|
||||
tags: [issues, planning, order]
|
||||
---
|
||||
|
||||
# Command: sort-issues
|
||||
|
||||
Analiza las issues en `dev/issues/` y genera un archivo `dev/EXECUTION_ORDER.md` con el orden óptimo de ejecución basado en dependencias y relaciones entre issues.
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
- Cuando quieres planificar el orden de trabajo de las issues disponibles
|
||||
- Después de crear nuevas issues y necesitas priorizar
|
||||
- Antes de empezar una fase de desarrollo para entender el flujo crítico
|
||||
- Cuando hay cambios en dependencias entre issues
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
/issues:sort
|
||||
```
|
||||
|
||||
### Ejemplos
|
||||
|
||||
**Ejemplo 1:**
|
||||
```bash
|
||||
/issues:sort
|
||||
```
|
||||
|
||||
Analiza todas las issues en `dev/issues/` y crea `dev/EXECUTION_ORDER.md` con el orden recomendado.
|
||||
|
||||
**Ejemplo 2:**
|
||||
```bash
|
||||
/issues:sort
|
||||
```
|
||||
|
||||
Actualiza el orden de ejecución después de completar algunas issues.
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
|
||||
- [ ] Directorio `dev/issues/` existe
|
||||
- [ ] Hay archivos `.md` en `dev/issues/` (al menos uno)
|
||||
- [ ] Tienes permisos de escritura en `dev/`
|
||||
|
||||
### Inputs
|
||||
|
||||
No requiere inputs del usuario. Analiza automáticamente todas las issues en `dev/issues/`.
|
||||
|
||||
### Flujo obligatorio
|
||||
|
||||
#### 1. Listar todas las issues disponibles
|
||||
|
||||
Obtener lista de todas las issues en `dev/issues/`:
|
||||
|
||||
```bash
|
||||
ls -1 dev/issues/*.md | grep -E '[0-9]{4}-.*\.md$' | sort
|
||||
```
|
||||
|
||||
Excluir `README.md` y otros archivos que no sean issues numeradas.
|
||||
|
||||
#### 2. Analizar cada issue para extraer dependencias
|
||||
|
||||
Para cada archivo de issue encontrado:
|
||||
|
||||
1. Leer el contenido completo del archivo
|
||||
2. Buscar secciones que indiquen dependencias:
|
||||
- "Depends on", "Requires", "Prerequisites"
|
||||
- Referencias a otras issues (#NNNN)
|
||||
- Menciones en "Critical Path" o "Execution Order"
|
||||
3. Identificar el tipo de issue (foundational, feature, infrastructure)
|
||||
4. Analizar complejidad y alcance
|
||||
|
||||
**Patrones a buscar:**
|
||||
- `#0001`, `issue #0001`, `0001-nombre`
|
||||
- "must be completed before"
|
||||
- "blocks", "required for"
|
||||
- "depends on"
|
||||
|
||||
#### 3. Construir grafo de dependencias
|
||||
|
||||
Crear una representación mental del grafo:
|
||||
|
||||
- Nodos: cada issue
|
||||
- Aristas: relaciones de dependencia (A → B significa "A debe completarse antes que B")
|
||||
- Identificar:
|
||||
- Issues raíz (sin dependencias)
|
||||
- Issues bloqueadas (muchas dependencias)
|
||||
- Camino crítico
|
||||
- Issues paralelas (pueden ejecutarse simultáneamente)
|
||||
|
||||
#### 4. Calcular orden óptimo
|
||||
|
||||
Aplicar ordenamiento topológico considerando:
|
||||
|
||||
1. **Prioridad primaria:** Dependencias explícitas (hard dependencies)
|
||||
2. **Prioridad secundaria:** Dependencias implícitas (una issue menciona conceptos de otra)
|
||||
3. **Prioridad terciaria:** Orden lógico (fundamentos antes que features)
|
||||
4. **Desempate:** Número de issue (menor primero)
|
||||
|
||||
Estrategia:
|
||||
- Agrupar issues por "capas" (todas las de una capa pueden ejecutarse en paralelo)
|
||||
- Identificar camino crítico explícitamente
|
||||
- Sugerir paralelización cuando sea posible
|
||||
|
||||
#### 5. Generar archivo EXECUTION_ORDER.md
|
||||
|
||||
Crear archivo con formato muy sencillo:
|
||||
|
||||
```markdown
|
||||
# Execution Order for Issues
|
||||
|
||||
Last updated: YYYY-MM-DD
|
||||
|
||||
## Recommended Order
|
||||
|
||||
1. #0001 - <nombre> — <razón breve>
|
||||
2. #0002 - <nombre> — <razón breve>
|
||||
3. #0003 - <nombre> — <razón breve>
|
||||
...
|
||||
|
||||
## Critical Path
|
||||
|
||||
Issues que bloquean otras:
|
||||
- #0001 → #0002, #0003
|
||||
- #0005 → #0008
|
||||
|
||||
## Parallelizable Groups
|
||||
|
||||
### Group 1 (after #0001)
|
||||
- #0002
|
||||
- #0003
|
||||
|
||||
### Group 2 (after #0005)
|
||||
- #0006
|
||||
- #0007
|
||||
|
||||
## Notes
|
||||
|
||||
- <Nota importante sobre el orden>
|
||||
- <Consideraciones especiales>
|
||||
```
|
||||
|
||||
Escribir el archivo:
|
||||
|
||||
```bash
|
||||
cat > dev/EXECUTION_ORDER.md << 'EOF'
|
||||
<contenido-generado>
|
||||
EOF
|
||||
```
|
||||
|
||||
#### 6. Mostrar resumen al usuario
|
||||
|
||||
```
|
||||
✓ Archivo dev/EXECUTION_ORDER.md creado
|
||||
|
||||
Issues analizadas: N
|
||||
Camino crítico identificado: #XXXX → #YYYY → #ZZZZ
|
||||
Grupos paralelizables: M
|
||||
|
||||
Próxima issue recomendada: #NNNN - <nombre>
|
||||
```
|
||||
|
||||
### Verificación final
|
||||
|
||||
```bash
|
||||
cat dev/EXECUTION_ORDER.md
|
||||
```
|
||||
|
||||
Informar al usuario:
|
||||
|
||||
```
|
||||
✓ Orden de ejecución de issues generado en dev/EXECUTION_ORDER.md
|
||||
|
||||
Próximos pasos:
|
||||
1. Revisar el orden propuesto
|
||||
2. Comenzar con la primera issue del orden
|
||||
3. Actualizar con /issues:sort cuando completes issues o agregues nuevas
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **Formato simple**: Solo líneas numeradas con issues y razón breve
|
||||
- **Razones concisas**: Máximo 1 línea explicando por qué ese orden
|
||||
- **Actualización frecuente**: Re-ejecutar después de completar issues
|
||||
- **Nombres consistentes**: Usar formato `#NNNN - nombre-descriptivo`
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "No issues found"
|
||||
|
||||
**Causa:** No hay archivos `.md` con formato de issue en `dev/issues/`
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
ls -la dev/issues/
|
||||
# Verificar que existan archivos NNNN-nombre.md
|
||||
```
|
||||
|
||||
### Error: "Circular dependency detected"
|
||||
|
||||
**Causa:** Issue A depende de B, y B depende de A (ciclo)
|
||||
|
||||
**Solución:**
|
||||
1. Revisar manualmente las issues involucradas
|
||||
2. Romper la dependencia circular
|
||||
3. Actualizar la documentación de al menos una issue
|
||||
4. Re-ejecutar /issues:sort
|
||||
|
||||
### Error: "Permission denied writing to dev/"
|
||||
|
||||
**Causa:** No tienes permisos de escritura en el directorio `dev/`
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
chmod u+w dev/
|
||||
# O verificar permisos del directorio
|
||||
ls -ld dev/
|
||||
```
|
||||
|
||||
## Reglas críticas
|
||||
|
||||
- **No modificar issues**: Solo leer, nunca modificar los archivos de issues
|
||||
- **Análisis exhaustivo**: Leer TODAS las issues antes de generar el orden
|
||||
- **Formato consistente**: Mantener estructura simple y legible
|
||||
- **Actualización atómica**: Sobrescribir el archivo completo, no editar parcialmente
|
||||
- **Documentar razonamiento**: Cada issue en el orden debe tener su justificación breve
|
||||
@@ -0,0 +1,119 @@
|
||||
# Command: issues:status
|
||||
|
||||
Muestra un dashboard global de todas las issues en todos los workspaces, con métricas,
|
||||
filtros y sugerencias de próximas issues a ejecutar.
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
Usar para obtener una vista consolidada del estado de todas las issues en todos los workspaces.
|
||||
Útil para planificar qué ejecutar a continuación y ver el progreso general.
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
/issues:status # Dashboard global completo
|
||||
/issues:status <workspace> # Detalle de un workspace específico
|
||||
/issues:status --status pending # Filtrar por estado
|
||||
/issues:status --tag backend # Filtrar por tag
|
||||
/issues:status --export json # Exportar a JSON
|
||||
/issues:status --export csv # Exportar a CSV
|
||||
```
|
||||
|
||||
### Ejemplos
|
||||
|
||||
**Dashboard global:**
|
||||
```bash
|
||||
/issues:status
|
||||
```
|
||||
|
||||
**Ver solo issues pendientes:**
|
||||
```bash
|
||||
/issues:status --status pending
|
||||
```
|
||||
|
||||
**Ver detalle de un workspace:**
|
||||
```bash
|
||||
/issues:status my-api
|
||||
```
|
||||
|
||||
**Exportar métricas:**
|
||||
```bash
|
||||
/issues:status --export json
|
||||
```
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Inputs
|
||||
|
||||
Parsear argumentos del usuario:
|
||||
|
||||
- Primer argumento posicional (sin `--`) → `filterWorkspace`
|
||||
- `--status <value>` → `filterStatus` (pending | in_progress | completed)
|
||||
- `--tag <value>` → `filterTag`
|
||||
- `--export <format>` → `exportFormat` (json | csv)
|
||||
|
||||
### Flujo
|
||||
|
||||
1. **Parsear argumentos** del comando según la sintaxis arriba
|
||||
2. **Llamar `app.IssuesDashboardCommand(config, filterWorkspace, filterStatus, filterTag, exportFormat)`**
|
||||
3. Si se solicitó dashboard global (sin filtros), después de mostrar el dashboard preguntar:
|
||||
- "¿Ver detalle de algún workspace? (nombre o 'n')"
|
||||
- Si el usuario ingresa un nombre válido, llamar `app.RenderWorkspaceDetail()`
|
||||
|
||||
### Parseo de argumentos
|
||||
|
||||
```
|
||||
/issues:status → filterWorkspace="", filterStatus="", filterTag="", exportFormat=""
|
||||
/issues:status my-api → filterWorkspace="my-api"
|
||||
/issues:status --status pending → filterStatus="pending"
|
||||
/issues:status --tag backend → filterTag="backend"
|
||||
/issues:status my-api --status pending → filterWorkspace="my-api", filterStatus="pending"
|
||||
/issues:status --export json → exportFormat="json"
|
||||
```
|
||||
|
||||
### Lógica de llamada Go
|
||||
|
||||
```go
|
||||
// Cargar config
|
||||
config, err := app.LoadConfig()
|
||||
if err != nil {
|
||||
// Reportar error
|
||||
}
|
||||
|
||||
// Ejecutar dashboard
|
||||
err = app.IssuesDashboardCommand(config, filterWorkspace, filterStatus, filterTag, exportFormat)
|
||||
```
|
||||
|
||||
### Comandos sugeridos al final
|
||||
|
||||
Siempre mostrar al final:
|
||||
```
|
||||
Commands:
|
||||
/issues:status <workspace> # Detalle de workspace específico
|
||||
/issues:status --status pending # Solo pendientes
|
||||
/app:launch <workspace> <issue> # Lanzar una issue sugerida
|
||||
```
|
||||
|
||||
### Modo interactivo (dashboard global)
|
||||
|
||||
Cuando se muestra el dashboard global sin filtros:
|
||||
1. Mostrar el dashboard completo con sugerencias
|
||||
2. Preguntar: "¿Ver detalle de un workspace? (nombre o 'n' para salir)"
|
||||
3. Si el usuario responde con un nombre de workspace:
|
||||
- Obtener issues del workspace con `shell.ListIssuesInWorkspace(workspacePath)`
|
||||
- Renderizar con `app.RenderWorkspaceDetail(workspace, issues)`
|
||||
4. Si responde 'n' o vacío, terminar
|
||||
|
||||
### Manejo de errores
|
||||
|
||||
- Si `ReposBasePath` no existe: "No se encontraron workspaces. ¿Está configurado DATAFORGE_REPOS?"
|
||||
- Si no hay issues en ningún workspace: Mostrar dashboard vacío con sugerencia de crear issues
|
||||
- Si exportación falla: Reportar error específico
|
||||
|
||||
### Notas
|
||||
|
||||
- Las stats se calculan escaneando el filesystem y sincronizando con la BD
|
||||
- La BD actúa como cache — si está desactualizada, el scan la actualiza
|
||||
- Para workspaces con muchas issues, el scan puede tardar segundos
|
||||
@@ -0,0 +1,235 @@
|
||||
---
|
||||
version: 2.0.0
|
||||
updated: 2026-03-11
|
||||
tags: [commands, meta, automation, workflow]
|
||||
---
|
||||
|
||||
# Command: create-command
|
||||
|
||||
Crea un nuevo comando en `.claude/commands/` siguiendo la estructura estándar del proyecto. Usa el template en `.claude/templates/command.md` y incluye flujo completo de git.
|
||||
|
||||
**Flujo completo:**
|
||||
1. Solicita inputs del comando
|
||||
2. Crea el archivo `.md` del comando
|
||||
3. Muestra el contenido al usuario
|
||||
4. Pregunta si está bien
|
||||
5. Si el usuario confirma → ejecuta `/git:push` automáticamente
|
||||
|
||||
## Inputs
|
||||
|
||||
Se necesitan los datos del comando. Si no se proporcionan, preguntar.
|
||||
|
||||
- `nombre`: nombre del comando sin extensión (ej: `deploy`, `test-all`)
|
||||
- `descripcion`: breve descripción de qué hace el comando (1 frase)
|
||||
- `inputs`: lista de parámetros que recibe el comando (opcional)
|
||||
- `flujo`: pasos principales que ejecuta el comando
|
||||
|
||||
## Flujo obligatorio
|
||||
|
||||
### 1. Validar nombre del comando
|
||||
|
||||
- Solo minúsculas y guiones (no underscores ni espacios)
|
||||
- No usar nombres reservados del sistema (help, clear, exit)
|
||||
- Verificar que no exista ya en `.claude/commands/`
|
||||
|
||||
```bash
|
||||
ls -1 .claude/commands/ | grep -E "^${nombre}\.md$"
|
||||
```
|
||||
|
||||
Si existe, **STOP** e informar al usuario.
|
||||
|
||||
### 2. Determinar tipo de comando
|
||||
|
||||
Analizar la descripción y flujo para clasificar:
|
||||
|
||||
- **Comando de git** (git-*): manipula ramas, commits, merges
|
||||
- **Comando de issue** (create-issue, fix-issue, etc.): crea/modifica issues
|
||||
- **Comando de proyecto** (build, deploy, test): ejecuta operaciones del proyecto
|
||||
- **Comando genérico**: cualquier otro tipo
|
||||
|
||||
### 3. Cargar template base
|
||||
|
||||
Leer el template desde `.claude/templates/command.md`:
|
||||
|
||||
```bash
|
||||
cat .claude/templates/command.md
|
||||
```
|
||||
|
||||
### 4. Generar estructura del comando
|
||||
|
||||
Reemplazar los placeholders del template con los valores proporcionados:
|
||||
|
||||
```markdown
|
||||
# Command: <nombre>
|
||||
|
||||
<Descripción breve en 1-2 líneas. Indicar qué hace el comando.>
|
||||
|
||||
**Flujo completo:** [si aplica]
|
||||
<Lista numerada de pasos de alto nivel>
|
||||
|
||||
## Inputs
|
||||
|
||||
<Describir parámetros que recibe el comando>
|
||||
|
||||
- `param1`: descripción del parámetro
|
||||
- `param2` (opcional): descripción del parámetro opcional
|
||||
|
||||
## Flujo obligatorio
|
||||
|
||||
### 1. <Paso principal 1>
|
||||
|
||||
<Descripción detallada del paso>
|
||||
|
||||
```bash
|
||||
# Comandos ejemplo si aplica
|
||||
comando1
|
||||
comando2
|
||||
```
|
||||
|
||||
<Notas adicionales, casos especiales, validaciones>
|
||||
|
||||
### 2. <Paso principal 2>
|
||||
|
||||
...
|
||||
|
||||
### N. Confirmar al usuario [si es comando interactivo]
|
||||
|
||||
Mostrar resumen de lo realizado:
|
||||
|
||||
```
|
||||
<Mensaje de confirmación>
|
||||
```
|
||||
|
||||
## Convenciones [si aplica]
|
||||
|
||||
- Regla 1
|
||||
- Regla 2
|
||||
|
||||
## Reglas críticas [si aplica]
|
||||
|
||||
- Regla crítica 1
|
||||
- Regla crítica 2
|
||||
```
|
||||
|
||||
### 4. Rellenar secciones específicas por tipo
|
||||
|
||||
#### Para comandos de git:
|
||||
- Incluir verificaciones de branch y estado
|
||||
- Documentar convenciones de nombres de rama
|
||||
- Explicar flujo de merge y push
|
||||
|
||||
#### Para comandos de issue:
|
||||
- Referencia a `dev/issues/` y estructura
|
||||
- Manejo de numeración consecutiva
|
||||
- Actualización de `dev/issues/README.md`
|
||||
|
||||
#### Para comandos de proyecto:
|
||||
- Documentar dependencias (Go, herramientas, etc.)
|
||||
- Flags y opciones de ejecución
|
||||
- Manejo de errores
|
||||
|
||||
### 5. Agregar ejemplos concretos
|
||||
|
||||
Incluir al menos 1 ejemplo de uso típico:
|
||||
|
||||
```markdown
|
||||
## Ejemplo
|
||||
|
||||
**Input:**
|
||||
```bash
|
||||
/project:create-command build-all
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
Comando build-all creado en .claude/commands/build-all.md
|
||||
Listo para usar: /build-all
|
||||
```
|
||||
```
|
||||
|
||||
### 6. Validar completitud
|
||||
|
||||
Verificar que el comando tiene:
|
||||
|
||||
- [ ] Título con formato `# Command: <nombre>`
|
||||
- [ ] Descripción breve al inicio
|
||||
- [ ] Sección de inputs (aunque esté vacía si no tiene)
|
||||
- [ ] Flujo obligatorio con pasos numerados
|
||||
- [ ] Ejemplos de bash si aplica
|
||||
- [ ] Sección de convenciones si tiene reglas especiales
|
||||
- [ ] Reglas críticas si hay validaciones obligatorias
|
||||
|
||||
### 7. Crear el archivo
|
||||
|
||||
```bash
|
||||
cat > .claude/commands/<nombre>.md << 'EOF'
|
||||
<contenido-generado>
|
||||
EOF
|
||||
```
|
||||
|
||||
### 8. Mostrar el comando creado y confirmar
|
||||
|
||||
**Mostrar al usuario el contenido completo del comando:**
|
||||
|
||||
```bash
|
||||
cat .claude/commands/<nombre>.md
|
||||
```
|
||||
|
||||
**Pausar y preguntar:**
|
||||
|
||||
```
|
||||
Comando creado: <nombre>
|
||||
|
||||
¿Te parece bien el comando?
|
||||
- Si es correcto: se hará commit y push automáticamente
|
||||
- Si necesitas ajustes: puedes editarlo manualmente antes
|
||||
```
|
||||
|
||||
**Esperar respuesta del usuario:**
|
||||
|
||||
- Si responde **SI** / afirmativo → continuar al paso 9
|
||||
- Si responde **NO** / necesita cambios → **STOP** y decir: "Edita el archivo y cuando estés listo ejecuta `/git:push`"
|
||||
|
||||
### 9. Ejecutar git-push automáticamente
|
||||
|
||||
Una vez confirmado por el usuario, ejecutar el comando `/git:push` para:
|
||||
|
||||
1. Crear rama `quick/project:create-command-<nombre>` automáticamente
|
||||
2. Commitear el archivo `.claude/commands/<nombre>.md`
|
||||
3. Mergear a master con `--no-ff`
|
||||
4. Push a remoto
|
||||
5. Limpiar rama local
|
||||
|
||||
El comando `/git:push` maneja todo el flujo de git automáticamente.
|
||||
|
||||
### 10. Verificar disponibilidad
|
||||
|
||||
Informar al usuario:
|
||||
|
||||
```
|
||||
✓ Comando /<nombre> creado e integrado a master
|
||||
|
||||
Para usar:
|
||||
/<nombre> [argumentos]
|
||||
|
||||
Para ver ayuda:
|
||||
/<nombre> --help
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **Nombres descriptivos**: usar verbos de acción (create, fix, deploy, test)
|
||||
- **Guiones para separar**: `git-branch`, `fix-issue`, no `git_branch`
|
||||
- **Sin prefijo slash**: el archivo se llama `comando.md`, no `/comando.md`
|
||||
- **Extensión obligatoria**: siempre `.md`
|
||||
- **Estructura consistente**: seguir el template para mantener uniformidad
|
||||
|
||||
## Reglas críticas
|
||||
|
||||
- **Validar nombre antes de crear**: evitar sobrescribir comandos existentes
|
||||
- **Documentar exhaustivamente**: cada paso debe ser claro y reproducible
|
||||
- **Incluir ejemplos**: facilitar comprensión del uso
|
||||
- **Confirmación obligatoria**: siempre mostrar el comando completo al usuario y esperar su aprobación antes de hacer commit/push
|
||||
- **Flujo automático**: una vez aprobado por el usuario, ejecutar `/git:push` para integrar los cambios automáticamente
|
||||
- **No crear comandos redundantes**: verificar si funcionalidad ya existe en otro comando
|
||||
- **Respetar convenciones del proyecto**: seguir patrones de trunk-based development, pure core / impure shell, etc.
|
||||
@@ -0,0 +1,245 @@
|
||||
---
|
||||
version: 1.0.0
|
||||
updated: 2026-03-11
|
||||
tags: [worktree, git, cleanup, automation]
|
||||
---
|
||||
|
||||
# Command: cleanup-worktrees
|
||||
|
||||
Elimina worktrees y sus ramas locales asociadas después de haber sido mergeadas. Puede limpiar un worktree específico o todos los worktrees en `worktrees/`.
|
||||
|
||||
**Flujo completo:**
|
||||
1. Validar argumentos (issue number o --all)
|
||||
2. Listar worktrees a eliminar
|
||||
3. Para cada worktree:
|
||||
- Verificar que la rama fue mergeada
|
||||
- Eliminar worktree
|
||||
- Eliminar rama local
|
||||
4. Reportar limpieza completada
|
||||
|
||||
## Inputs
|
||||
|
||||
Se necesita UNO de estos parámetros:
|
||||
|
||||
- `issue_number`: Número de issue (NNNN) para limpiar solo ese worktree
|
||||
- `--all`: Limpiar todos los worktrees en `worktrees/`
|
||||
|
||||
## Flujo obligatorio
|
||||
|
||||
### 1. Validar argumentos
|
||||
|
||||
Verificar que se proporcionó exactamente un argumento:
|
||||
|
||||
```bash
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Error: Debes especificar un número de issue o --all"
|
||||
echo "Uso: /workspace:cleanup-worktrees <issue_number>"
|
||||
echo " /workspace:cleanup-worktrees --all"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $# -gt 1 ]; then
|
||||
echo "Error: Demasiados argumentos"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ARG=$1
|
||||
```
|
||||
|
||||
### 2. Determinar worktrees a limpiar
|
||||
|
||||
**Si es issue específica:**
|
||||
|
||||
```bash
|
||||
if [[ "$ARG" =~ ^[0-9]{4}$ ]]; then
|
||||
ISSUE_NUM=$ARG
|
||||
WORKTREE_PATH="worktrees/issue-$ISSUE_NUM"
|
||||
|
||||
# Verificar que existe el worktree
|
||||
if [ ! -d "$WORKTREE_PATH" ]; then
|
||||
echo "Error: No existe el worktree $WORKTREE_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
WORKTREES=("$WORKTREE_PATH")
|
||||
fi
|
||||
```
|
||||
|
||||
**Si es --all:**
|
||||
|
||||
```bash
|
||||
if [ "$ARG" = "--all" ]; then
|
||||
# Listar todos los worktrees en worktrees/
|
||||
if [ ! -d "worktrees" ]; then
|
||||
echo "No hay directorio worktrees/ para limpiar"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Obtener lista de directorios en worktrees/
|
||||
WORKTREES=($(find worktrees -maxdepth 1 -type d -name "issue-*" | sort))
|
||||
|
||||
if [ ${#WORKTREES[@]} -eq 0 ]; then
|
||||
echo "No hay worktrees para limpiar"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Se encontraron ${#WORKTREES[@]} worktrees para limpiar"
|
||||
fi
|
||||
```
|
||||
|
||||
**Si no es ninguno:**
|
||||
|
||||
```bash
|
||||
if [ -z "$WORKTREES" ]; then
|
||||
echo "Error: Argumento inválido '$ARG'"
|
||||
echo "Usa un número de issue (ej: 0003) o --all"
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
### 3. Confirmar con el usuario
|
||||
|
||||
Mostrar lo que se va a eliminar:
|
||||
|
||||
```bash
|
||||
echo "Se eliminarán los siguientes worktrees:"
|
||||
for wt in "${WORKTREES[@]}"; do
|
||||
ISSUE_NUM=$(basename "$wt" | sed 's/issue-//')
|
||||
BRANCH="quick/fix-issue-$ISSUE_NUM"
|
||||
echo " - $wt (rama: $BRANCH)"
|
||||
done
|
||||
|
||||
echo ""
|
||||
read -p "¿Continuar? (y/N): " CONFIRM
|
||||
|
||||
if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then
|
||||
echo "Operación cancelada"
|
||||
exit 0
|
||||
fi
|
||||
```
|
||||
|
||||
### 4. Limpiar cada worktree
|
||||
|
||||
Para cada worktree en la lista:
|
||||
|
||||
```bash
|
||||
for wt in "${WORKTREES[@]}"; do
|
||||
ISSUE_NUM=$(basename "$wt" | sed 's/issue-//')
|
||||
BRANCH="quick/fix-issue-$ISSUE_NUM"
|
||||
|
||||
echo ""
|
||||
echo "Limpiando issue $ISSUE_NUM..."
|
||||
|
||||
# Verificar que la rama fue mergeada (opcional, para seguridad)
|
||||
MERGED=$(git branch --merged main | grep -c "$BRANCH" || true)
|
||||
|
||||
if [ "$MERGED" -eq 0 ]; then
|
||||
echo "⚠️ Advertencia: La rama $BRANCH NO ha sido mergeada a main"
|
||||
read -p "¿Eliminar de todas formas? (y/N): " FORCE
|
||||
|
||||
if [[ ! "$FORCE" =~ ^[Yy]$ ]]; then
|
||||
echo "Saltando $wt"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
# Eliminar worktree
|
||||
echo " → Eliminando worktree $wt..."
|
||||
git worktree remove "$wt" --force 2>/dev/null || {
|
||||
echo " ⚠️ No se pudo eliminar worktree, puede que ya esté eliminado"
|
||||
}
|
||||
|
||||
# Eliminar rama local
|
||||
echo " → Eliminando rama $BRANCH..."
|
||||
git branch -D "$BRANCH" 2>/dev/null || {
|
||||
echo " ⚠️ No se pudo eliminar rama, puede que ya esté eliminada"
|
||||
}
|
||||
|
||||
echo " ✓ Issue $ISSUE_NUM limpiada"
|
||||
done
|
||||
```
|
||||
|
||||
### 5. Reportar resultado
|
||||
|
||||
```bash
|
||||
echo ""
|
||||
echo "✓ Limpieza completada"
|
||||
echo ""
|
||||
echo "Worktrees restantes:"
|
||||
git worktree list | grep -v "(bare)" || echo " (ninguno)"
|
||||
```
|
||||
|
||||
## Ejemplos
|
||||
|
||||
**Ejemplo 1: Limpiar una issue específica**
|
||||
|
||||
```bash
|
||||
/workspace:cleanup-worktrees 0003
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
Se eliminarán los siguientes worktrees:
|
||||
- worktrees/issue-0003 (rama: quick/fix-issue-0003)
|
||||
|
||||
¿Continuar? (y/N): y
|
||||
|
||||
Limpiando issue 0003...
|
||||
→ Eliminando worktree worktrees/issue-0003...
|
||||
→ Eliminando rama quick/fix-issue-0003...
|
||||
✓ Issue 0003 limpiada
|
||||
|
||||
✓ Limpieza completada
|
||||
|
||||
Worktrees restantes:
|
||||
(ninguno)
|
||||
```
|
||||
|
||||
**Ejemplo 2: Limpiar todos los worktrees**
|
||||
|
||||
```bash
|
||||
/workspace:cleanup-worktrees --all
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
Se encontraron 3 worktrees para limpiar
|
||||
Se eliminarán los siguientes worktrees:
|
||||
- worktrees/issue-0003 (rama: quick/fix-issue-0003)
|
||||
- worktrees/issue-0006 (rama: quick/fix-issue-0006)
|
||||
- worktrees/issue-0008 (rama: quick/fix-issue-0008)
|
||||
|
||||
¿Continuar? (y/N): y
|
||||
|
||||
Limpiando issue 0003...
|
||||
→ Eliminando worktree worktrees/issue-0003...
|
||||
→ Eliminando rama quick/fix-issue-0003...
|
||||
✓ Issue 0003 limpiada
|
||||
|
||||
Limpiando issue 0006...
|
||||
→ Eliminando worktree worktrees/issue-0006...
|
||||
→ Eliminando rama quick/fix-issue-0006...
|
||||
✓ Issue 0006 limpiada
|
||||
|
||||
Limpiando issue 0008...
|
||||
→ Eliminando worktree worktrees/issue-0008...
|
||||
→ Eliminando rama quick/fix-issue-0008...
|
||||
✓ Issue 0008 limpiada
|
||||
|
||||
✓ Limpieza completada
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **Nomenclatura de worktrees:** Siempre `worktrees/issue-NNNN`
|
||||
- **Nomenclatura de ramas:** Siempre `quick/fix-issue-NNNN`
|
||||
- **Confirmación interactiva:** Siempre pedir confirmación antes de eliminar
|
||||
- **Verificación de merge:** Advertir si la rama no fue mergeada
|
||||
|
||||
## Reglas críticas
|
||||
|
||||
- **SIEMPRE verificar que la rama fue mergeada** antes de eliminar (advertir si no)
|
||||
- **NUNCA eliminar sin confirmación del usuario** (a menos que se agregue flag `--force` en futuro)
|
||||
- **SIEMPRE usar --force en git worktree remove** para evitar errores por cambios sin commit
|
||||
- **NUNCA fallar silenciosamente** - reportar cada paso con claridad
|
||||
- **SIEMPRE mostrar worktrees restantes** al final para confirmar estado
|
||||
@@ -0,0 +1,224 @@
|
||||
---
|
||||
version: 1.0.0
|
||||
updated: 2026-03-12
|
||||
tags: [workspace, gitea, repo, creation]
|
||||
---
|
||||
|
||||
# Command: create-repo
|
||||
|
||||
Crea un nuevo subrepo (child repository) en `workspaces/`, inicializándolo con la estructura core/shell/app, creando el repo en Gitea, y registrándolo en la base de datos local.
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
Usar cuando necesites crear un nuevo workspace (subrepo) dentro de Dataforge. El comando:
|
||||
|
||||
1. Solicita el nombre y descripción del repositorio
|
||||
2. Muestra un resumen de lo que se creará
|
||||
3. Pide confirmación antes de proceder
|
||||
4. Crea el workspace completo (local + Gitea + BD)
|
||||
|
||||
### Prerequisitos
|
||||
|
||||
- Issues 0006, 0007, 0008 completados (workspaces base)
|
||||
- Issue 0011a completado (comandos organizados)
|
||||
- Gitea configurado y accesible (`GITEA_URL` y `GITEA_TOKEN` en env)
|
||||
- Base de datos SQLite disponible
|
||||
|
||||
### Variables de entorno requeridas
|
||||
|
||||
```bash
|
||||
export GITEA_URL="https://gitea.example.com"
|
||||
export GITEA_TOKEN="tu-token-de-api"
|
||||
export DATAFORGE_REPOS="./workspaces" # opcional, default: ./workspaces
|
||||
```
|
||||
|
||||
### Ejemplo de uso
|
||||
|
||||
```bash
|
||||
/workspace:create-repo
|
||||
```
|
||||
|
||||
```
|
||||
Nombre del repositorio: my-etl-pipeline
|
||||
Descripción: ETL pipeline para datos de ventas
|
||||
Tipo (go/data/etl/api) [go]: etl
|
||||
¿Repositorio privado? (s/n) [n]: n
|
||||
|
||||
Resumen:
|
||||
Nombre: my-etl-pipeline
|
||||
Path local: ./workspaces/my-etl-pipeline
|
||||
Gitea: https://gitea.example.com/Bl4cksmith/my-etl-pipeline
|
||||
Módulo Go: gitea.../my-etl-pipeline
|
||||
Tipo: etl
|
||||
Privado: no
|
||||
|
||||
¿Crear repositorio? (s/n): s
|
||||
|
||||
✓ Directorio creado: ./workspaces/my-etl-pipeline
|
||||
✓ Templates generados (core/, shell/, app/, go.mod, main.go)
|
||||
✓ Git inicializado
|
||||
✓ Repositorio Gitea creado
|
||||
✓ Push inicial completado
|
||||
✓ Registrado en base de datos
|
||||
|
||||
Workspace creado: ./workspaces/my-etl-pipeline
|
||||
|
||||
Para trabajar en él:
|
||||
cd workspaces/my-etl-pipeline
|
||||
```
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
- [ ] Feature flag `workspace_commands` habilitado en `feature_flags.json`
|
||||
- [ ] Variables de entorno `GITEA_URL` y `GITEA_TOKEN` configuradas
|
||||
- [ ] Directorio `workspaces/` existe (o se puede crear)
|
||||
|
||||
### Flujo de implementación
|
||||
|
||||
#### Paso 1: Solicitar inputs interactivos
|
||||
|
||||
Preguntar al usuario:
|
||||
|
||||
1. **Nombre del repositorio** — debe ser URL-safe (lowercase, alfanumérico, guiones)
|
||||
- Validar con `core.ValidateRepoName()`
|
||||
- Ejemplos válidos: `my-api`, `etl-pipeline`, `data-processor`
|
||||
- Ejemplos inválidos: `My API`, `my_api`, `-test-`
|
||||
|
||||
2. **Descripción** — texto libre, puede estar vacío
|
||||
|
||||
3. **Tipo** — uno de: `go` (default), `data`, `etl`, `api`
|
||||
|
||||
4. **¿Privado?** — `s/n`, default `n`
|
||||
|
||||
#### Paso 2: Mostrar resumen y pedir confirmación
|
||||
|
||||
```
|
||||
Resumen:
|
||||
Nombre: <nombre>
|
||||
Path local: <DATAFORGE_REPOS>/<nombre>
|
||||
Gitea: <GITEA_URL>/Bl4cksmith/<nombre>
|
||||
Módulo Go: gitea-dgg044oo04woo4ggcsws4gk0.organic-machine.com/Bl4cksmith/dataforge/<nombre>
|
||||
Tipo: <tipo>
|
||||
Privado: <sí/no>
|
||||
|
||||
¿Crear repositorio? (s/n):
|
||||
```
|
||||
|
||||
Si el usuario responde `n`, cancelar sin hacer cambios.
|
||||
|
||||
#### Paso 3: Ejecutar creación vía `app.CreateWorkspaceCommand`
|
||||
|
||||
El flujo completo está implementado en `app/workspace_create.go`:
|
||||
|
||||
```go
|
||||
params := app.CreateWorkspaceParams{
|
||||
Name: nombre,
|
||||
Description: descripcion,
|
||||
Type: tipo,
|
||||
IsPrivate: privado,
|
||||
}
|
||||
result, err := app.CreateWorkspaceCommand(config, params)
|
||||
```
|
||||
|
||||
El comando hace automáticamente:
|
||||
1. Validar nombre
|
||||
2. Verificar que no existe en local ni en Gitea
|
||||
3. Crear estructura `core/shell/app/`
|
||||
4. Escribir templates (`go.mod`, `main.go`, `core/core.go`, `shell/shell.go`, `app/app.go`, `.gitignore`, `README.md`)
|
||||
5. `git init` + configurar usuario
|
||||
6. Crear repo en Gitea
|
||||
7. Configurar remote y push inicial
|
||||
8. Registrar en SQLite
|
||||
|
||||
**Rollback automático:** Si falla cualquier paso, limpia directorio local y elimina repo Gitea si se creó.
|
||||
|
||||
#### Paso 4: Mostrar resultado
|
||||
|
||||
```
|
||||
✓ Workspace creado exitosamente
|
||||
|
||||
Path local: <localPath>
|
||||
Gitea: <giteaURL>
|
||||
Módulo Go: <moduleName>
|
||||
|
||||
Para trabajar en él:
|
||||
cd <localPath>
|
||||
```
|
||||
|
||||
### Manejo de errores
|
||||
|
||||
| Error | Causa | Solución |
|
||||
|-------|-------|----------|
|
||||
| "nombre de repositorio inválido" | Nombre no cumple reglas Gitea | Usar solo lowercase, alfanumérico y guiones |
|
||||
| "ya existe un directorio" | Workspace ya creado localmente | Verificar `ls workspaces/` |
|
||||
| "ya existe el repositorio en Gitea" | Repo creado en Gitea anteriormente | Verificar en Gitea o usar nombre diferente |
|
||||
| "error al crear repositorio en Gitea" | Token inválido o sin permisos | Verificar `GITEA_TOKEN` |
|
||||
| "error al hacer push inicial" | Credenciales git no configuradas | Configurar git credentials |
|
||||
|
||||
### Feature flag
|
||||
|
||||
Este comando requiere que `workspace_commands` esté habilitado:
|
||||
|
||||
```json
|
||||
{
|
||||
"features": {
|
||||
"workspace_commands": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Si está deshabilitado, informar al usuario que debe habilitarlo en `feature_flags.json`.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "nombre de repositorio inválido"
|
||||
|
||||
El nombre debe cumplir las reglas de Gitea:
|
||||
- Solo letras, números y guiones
|
||||
- No puede empezar o terminar con guión
|
||||
- Entre 2 y 100 caracteres
|
||||
|
||||
```bash
|
||||
# Válidos:
|
||||
my-api
|
||||
etl-pipeline-v2
|
||||
data-processor
|
||||
|
||||
# Inválidos:
|
||||
My API # espacios, mayúsculas
|
||||
my_api # guión bajo
|
||||
-test- # empieza/termina con guión
|
||||
```
|
||||
|
||||
### Error: "GITEA_URL o GITEA_TOKEN no configurados"
|
||||
|
||||
```bash
|
||||
export GITEA_URL="https://gitea.example.com"
|
||||
export GITEA_TOKEN="tu-token"
|
||||
# Luego ejecutar de nuevo
|
||||
/workspace:create-repo
|
||||
```
|
||||
|
||||
### Error: "ya existe un directorio en ./workspaces/<nombre>"
|
||||
|
||||
El workspace ya existe localmente. Opciones:
|
||||
1. Usar nombre diferente
|
||||
2. Eliminar directorio si fue creación fallida: `rm -rf workspaces/<nombre>`
|
||||
|
||||
### Error: "rollback falló"
|
||||
|
||||
En caso de rollback parcial, verificar manualmente:
|
||||
```bash
|
||||
# Ver estado local
|
||||
ls workspaces/
|
||||
|
||||
# Ver repos en Gitea (vía API o interfaz web)
|
||||
curl -H "Authorization: token $GITEA_TOKEN" $GITEA_URL/api/v1/user/repos
|
||||
```
|
||||
@@ -0,0 +1,272 @@
|
||||
---
|
||||
version: 1.0.0
|
||||
updated: 2026-03-12
|
||||
tags: [workspace, gitea, import, repos]
|
||||
---
|
||||
|
||||
# Command: import-repo
|
||||
|
||||
Importa repositorios existentes al sistema Dataforge: desde GitHub/GitLab/otra instancia Gitea (URL remota), o adoptando un repo local en `workspaces/` que aún no está en Gitea.
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
Usar cuando necesites incorporar un repositorio existente al sistema Dataforge:
|
||||
|
||||
- Tienes un repo en GitHub/GitLab y quieres migrarlo a Gitea
|
||||
- Tienes un repo en otra instancia de Gitea y quieres clonarlo a la tuya
|
||||
- Tienes un directorio en `workspaces/` con git, pero sin estar en Gitea
|
||||
- Quieres adoptar un proyecto legacy en el ecosistema Dataforge
|
||||
|
||||
### Prerequisitos
|
||||
|
||||
- Variables de entorno configuradas: `GITEA_URL` y `GITEA_TOKEN`
|
||||
- Acceso de lectura al repositorio origen (si es remoto)
|
||||
- Feature flag `workspace_commands` habilitado
|
||||
|
||||
### Variables de entorno requeridas
|
||||
|
||||
```bash
|
||||
export GITEA_URL="https://gitea.example.com"
|
||||
export GITEA_TOKEN="tu-token-de-api"
|
||||
export DATAFORGE_REPOS="./workspaces" # opcional, default: ./workspaces
|
||||
```
|
||||
|
||||
### Modos de importación
|
||||
|
||||
#### Caso 1: Importar desde URL remota
|
||||
|
||||
```bash
|
||||
/workspace:import-repo
|
||||
# Fuente: https://github.com/Bl4cksmith/analytics-pipeline
|
||||
# Destino en Gitea: analytics-pipeline (por defecto)
|
||||
```
|
||||
|
||||
Flujo interno:
|
||||
1. Crear repo vacío en Gitea
|
||||
2. Clonar origen con `git clone --mirror` (preserva historial completo)
|
||||
3. Push a Gitea con `git push --mirror`
|
||||
4. Clonar en `workspaces/` para desarrollo local
|
||||
5. Registrar en BD SQLite
|
||||
6. Limpiar temporales
|
||||
|
||||
#### Caso 2: Adoptar repo local
|
||||
|
||||
```bash
|
||||
/workspace:import-repo
|
||||
# Fuente: legacy-tool (nombre del dir en workspaces/)
|
||||
# Destino en Gitea: legacy-tool (por defecto)
|
||||
```
|
||||
|
||||
Flujo interno:
|
||||
1. Verificar que `workspaces/legacy-tool/.git` existe
|
||||
2. Crear repo vacío en Gitea
|
||||
3. Añadir Gitea como remote `gitea`
|
||||
4. Push de todos los branches y tags a Gitea
|
||||
5. Registrar en BD SQLite
|
||||
|
||||
---
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Flujo interactivo
|
||||
|
||||
#### Paso 1: Solicitar fuente
|
||||
|
||||
```
|
||||
Fuente del repositorio:
|
||||
- URL remota (ej: https://github.com/user/repo)
|
||||
- Nombre local en workspaces/ (ej: legacy-tool)
|
||||
|
||||
¿Fuente?
|
||||
```
|
||||
|
||||
Leer la respuesta del usuario.
|
||||
|
||||
#### Paso 2: Detectar modo y analizar
|
||||
|
||||
Usar funciones del core Go:
|
||||
- `core.ValidateImportSource(source)` — validar que es segura
|
||||
- `core.DetectImportMode(source)` — detectar si es remota o local
|
||||
- `core.GenerateDestinationName(source)` — sugerir nombre de destino
|
||||
|
||||
Si es remota, informar al usuario:
|
||||
```
|
||||
✓ Modo: importar desde URL remota
|
||||
Fuente: https://github.com/user/analytics-pipeline
|
||||
Historia Git: se preservará completa (--mirror)
|
||||
```
|
||||
|
||||
Si es local, informar:
|
||||
```
|
||||
✓ Modo: adoptar repositorio local
|
||||
Directorio: workspaces/legacy-tool
|
||||
Verificando .git...
|
||||
```
|
||||
|
||||
Si es local, verificar que existe `workspaces/{source}/.git`. Si no existe, informar error:
|
||||
```
|
||||
✗ No se encontró .git en workspaces/legacy-tool
|
||||
¿Quizás quisiste usar la URL completa?
|
||||
```
|
||||
|
||||
#### Paso 3: Solicitar nombre de destino
|
||||
|
||||
```
|
||||
Nombre en Gitea (Enter para usar '{nombre-generado}'):
|
||||
```
|
||||
|
||||
Si el usuario presiona Enter, usar el nombre generado. Si escribe otro, validar con `core.ValidateRepoName`.
|
||||
|
||||
#### Paso 4: Verificar que no existe en Gitea
|
||||
|
||||
Llamar `GET /api/v1/repos/{owner}/{destName}`. Si ya existe:
|
||||
```
|
||||
✗ El repositorio {owner}/{destName} ya existe en Gitea.
|
||||
|
||||
Opciones:
|
||||
1. Usar otro nombre
|
||||
2. Cancelar
|
||||
```
|
||||
|
||||
#### Paso 5: Solicitar opciones adicionales
|
||||
|
||||
```
|
||||
¿Repositorio privado? (s/N):
|
||||
Descripción (opcional):
|
||||
```
|
||||
|
||||
#### Paso 6: Mostrar resumen y confirmar
|
||||
|
||||
```
|
||||
Resumen de importación:
|
||||
Fuente: {source}
|
||||
Destino Gitea: {gitea_url}/{owner}/{destName}
|
||||
Workspace local: workspaces/{destName}
|
||||
Tipo detectado: {tipo}
|
||||
Historia Git: se preservará completa
|
||||
Privado: {sí/no}
|
||||
|
||||
¿Importar repositorio? (s/N):
|
||||
```
|
||||
|
||||
Si el usuario responde "n" o Enter, cancelar:
|
||||
```
|
||||
Importación cancelada.
|
||||
```
|
||||
|
||||
#### Paso 7: Ejecutar importación
|
||||
|
||||
Llamar `app.ImportRepositoryCommand(config, params)` con los parámetros recogidos.
|
||||
|
||||
Mostrar progreso:
|
||||
```
|
||||
Ejecutando importación...
|
||||
✓ Creando repositorio en Gitea...
|
||||
✓ Clonando fuente...
|
||||
✓ Subiendo contenido a Gitea...
|
||||
✓ Clonando en workspaces/...
|
||||
✓ Registrando en base de datos...
|
||||
✓ Limpiando temporales...
|
||||
```
|
||||
|
||||
O para modo adopción local:
|
||||
```
|
||||
Ejecutando adopción...
|
||||
✓ Creando repositorio en Gitea...
|
||||
✓ Añadiendo remote 'gitea'...
|
||||
✓ Subiendo branches y tags...
|
||||
✓ Registrando en base de datos...
|
||||
```
|
||||
|
||||
#### Paso 8: Mostrar resultado
|
||||
|
||||
**Éxito:**
|
||||
```
|
||||
Repositorio importado exitosamente.
|
||||
|
||||
Workspace: workspaces/{destName}
|
||||
Gitea URL: {gitea_url}/{owner}/{destName}
|
||||
Tipo: {tipo}
|
||||
|
||||
Pasos siguientes:
|
||||
cd workspaces/{destName}
|
||||
# El repositorio está listo para usar
|
||||
|
||||
# Para sincronizar en otros nodos:
|
||||
/workspace:sync-repos
|
||||
```
|
||||
|
||||
**Error:**
|
||||
```
|
||||
✗ Error durante la importación: {mensaje de error}
|
||||
|
||||
Rollback completado: no quedaron cambios parciales.
|
||||
|
||||
Sugerencias:
|
||||
- Verifica que tienes acceso al repositorio origen
|
||||
- Verifica que GITEA_TOKEN tiene permisos de escritura
|
||||
- Verifica la conectividad de red
|
||||
```
|
||||
|
||||
### Manejo de errores comunes
|
||||
|
||||
#### Repo ya existe en Gitea
|
||||
- Detectar en Paso 4, antes de iniciar la operación
|
||||
- Ofrecer cambiar el nombre
|
||||
|
||||
#### Credenciales inválidas / sin acceso
|
||||
- Ocurre al intentar clonar repo privado sin credenciales
|
||||
- Mensaje: "Acceso denegado al repositorio origen. Verifica que tienes acceso de lectura."
|
||||
|
||||
#### Tamaño excesivo
|
||||
- Si la operación tarda más de 10 minutos, el comando tiene timeout
|
||||
- Mensaje: "Timeout: el repositorio puede ser muy grande. Intenta clonar manualmente."
|
||||
|
||||
#### Fallo de red
|
||||
- Puede ocurrir durante clone o push
|
||||
- Rollback automático: se elimina el repo creado en Gitea
|
||||
|
||||
#### .git no encontrado (modo local)
|
||||
- Verificar antes de crear repo en Gitea
|
||||
- Mensaje: "No se encontró .git en workspaces/{source}"
|
||||
|
||||
### Integración con el sistema
|
||||
|
||||
Después de una importación exitosa:
|
||||
- El repo está en Gitea (fuente de verdad)
|
||||
- El repo está en `workspaces/{name}` (desarrollo local)
|
||||
- El repo está en la BD SQLite (consultable con `/workspace:list-repos`)
|
||||
- Compatible con `/workspace:sync-repos` para sincronizar en otros nodos
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
**Error: "fuente inválida"**
|
||||
- La fuente contiene caracteres especiales (`;`, `|`, etc.)
|
||||
- Verificar que la URL es correcta
|
||||
|
||||
**Error: "nombre de destino inválido"**
|
||||
- El nombre contiene caracteres no permitidos
|
||||
- Solo letras, números, guiones y puntos. Entre 2-100 caracteres.
|
||||
|
||||
**Error: "rollback falló"**
|
||||
- Estado inconsistente: repo puede existir en Gitea pero no localmente
|
||||
- Verificar manualmente: `GET /api/v1/repos/{owner}/{name}`
|
||||
- Si existe en Gitea pero no localmente, ejecutar `/workspace:sync-repos`
|
||||
|
||||
## Convenciones
|
||||
|
||||
- Confirmación obligatoria antes de ejecutar
|
||||
- Rollback automático si falla cualquier paso
|
||||
- Historia Git siempre preservada (--mirror para remotos, --all + --tags para locales)
|
||||
- El remote `gitea` se añade sin sobrescribir `origin` existente
|
||||
- Feature flag `workspace_commands` debe estar habilitado
|
||||
|
||||
## Referencias
|
||||
|
||||
- Issue 0011e: Especificación completa
|
||||
- `app.ImportRepositoryCommand`: Implementación Go
|
||||
- `core.ValidateImportSource`, `core.DetectImportMode`: Validación pura
|
||||
- `shell.CloneRemoteToTemp`, `shell.AdoptLocalRepo`: Operaciones I/O
|
||||
- Gitea API: GET /api/v1/repos/{owner}/{repo}
|
||||
@@ -0,0 +1,170 @@
|
||||
---
|
||||
version: 1.0.0
|
||||
updated: 2026-03-12
|
||||
tags: [workspace, list, repos]
|
||||
---
|
||||
|
||||
# Command: list-repos
|
||||
|
||||
Lista todos los workspaces registrados en la base de datos local con soporte de filtro y ordenamiento.
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
Usar para inspeccionar rápidamente los workspaces disponibles:
|
||||
|
||||
- Ver qué repos existen localmente
|
||||
- Verificar estado de sincronización con Gitea
|
||||
- Encontrar un workspace por nombre o descripción
|
||||
- Ver URLs de Gitea para clonar en otra máquina
|
||||
|
||||
### Prerequisitos
|
||||
|
||||
- Issue 0007 completado (base de datos SQLite)
|
||||
- Feature flag `workspace_commands` habilitado
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
/workspace:list-repos
|
||||
/workspace:list-repos --filter <term>
|
||||
/workspace:list-repos --sort <field>
|
||||
```
|
||||
|
||||
### Ejemplos
|
||||
|
||||
```bash
|
||||
# Listar todos los workspaces
|
||||
/workspace:list-repos
|
||||
|
||||
# Filtrar por nombre o descripción
|
||||
/workspace:list-repos --filter pipeline
|
||||
|
||||
# Ordenar por nombre alfabético
|
||||
/workspace:list-repos --sort name
|
||||
|
||||
# Filtrar y ordenar combinados
|
||||
/workspace:list-repos --filter etl --sort name
|
||||
```
|
||||
|
||||
### Salida esperada
|
||||
|
||||
```
|
||||
Workspaces locales (4 repos):
|
||||
|
||||
┌────────────────────────┬─────────────────────────────┬────────────────┬─────────────┐
|
||||
│ Nombre │ Descripción │ Última act. │ Estado │
|
||||
├────────────────────────┼─────────────────────────────┼────────────────┼─────────────┤
|
||||
│ my-etl-pipeline │ ETL para datos ventas │ hace 2 días │ ✓ activo │
|
||||
│ data-pipeline-v2 │ Pipeline v2 mejorado │ hace 1 sem. │ ✓ activo │
|
||||
│ ml-training-service │ Servicio ML training │ hace 3 días │ ✓ activo │
|
||||
│ old-experiment │ Experimento temporal │ hace 2 meses │ ✓ activo │
|
||||
└────────────────────────┴─────────────────────────────┴────────────────┴─────────────┘
|
||||
|
||||
URLs Gitea:
|
||||
- my-etl-pipeline: https://gitea-xxx.organic-machine.com/Bl4cksmith/my-etl-pipeline
|
||||
- data-pipeline-v2: https://gitea-xxx.organic-machine.com/Bl4cksmith/data-pipeline-v2
|
||||
- ml-training-service: https://gitea-xxx.organic-machine.com/Bl4cksmith/ml-training-service
|
||||
- old-experiment: (no disponible en Gitea)
|
||||
|
||||
Para trabajar en un workspace:
|
||||
cd workspaces/<nombre>
|
||||
```
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
- [ ] Feature flag `workspace_commands` habilitado en `dev/feature_flags.json`
|
||||
- [ ] Base de datos inicializada (issue 0007 completado)
|
||||
|
||||
### Flujo de implementación
|
||||
|
||||
#### Paso 0: Verificar feature flag
|
||||
|
||||
Leer `dev/feature_flags.json`. Si `workspace_commands.enabled: false`, informar al usuario:
|
||||
|
||||
```
|
||||
El comando /list-repos requiere que el feature flag 'workspace_commands' esté habilitado.
|
||||
Editar dev/feature_flags.json y cambiar "enabled": true para workspace_commands.
|
||||
```
|
||||
|
||||
#### Paso 1: Detectar argumentos
|
||||
|
||||
Parsear los argumentos del usuario:
|
||||
- `--filter <term>` → filtrar por nombre/descripción (case-insensitive)
|
||||
- `--sort <field>` → ordenar por campo (`name` o `date`, default: `date`)
|
||||
|
||||
#### Paso 2: Ejecutar vía `app.ListWorkspacesCommand`
|
||||
|
||||
El flujo completo está en `app/workspace_list.go`:
|
||||
|
||||
```go
|
||||
// Listar todos:
|
||||
err := app.ListWorkspacesCommand(config, "", "date")
|
||||
|
||||
// Filtrar:
|
||||
err := app.ListWorkspacesCommand(config, "pipeline", "date")
|
||||
|
||||
// Filtrar y ordenar:
|
||||
err := app.ListWorkspacesCommand(config, "etl", "name")
|
||||
```
|
||||
|
||||
El comando hace automáticamente:
|
||||
1. Obtener workspaces de SQLite (`shell.ListWorkspacesDB`)
|
||||
2. Filtrar si hay `--filter` (`core.FilterWorkspaces` — función pura)
|
||||
3. Ordenar (`core.SortWorkspaces` — función pura)
|
||||
4. Formatear tabla ASCII (`core.FormatWorkspaceTable` — función pura)
|
||||
5. Mostrar resultado con URLs de Gitea al final
|
||||
|
||||
#### Paso 3: Si no hay workspaces
|
||||
|
||||
Si la BD está vacía o el filtro no coincide con nada:
|
||||
|
||||
```
|
||||
No hay workspaces registrados.
|
||||
```
|
||||
|
||||
O si había filtro:
|
||||
```
|
||||
Workspaces que coinciden con 'pipeline':
|
||||
|
||||
No hay workspaces registrados.
|
||||
```
|
||||
|
||||
Sugerir usar `/workspace:create-repo` para crear el primero o `/workspace:sync-repos` para importar desde Gitea.
|
||||
|
||||
### Decisiones de diseño
|
||||
|
||||
1. **Tabla ASCII con box-drawing**: Legible en cualquier terminal sin dependencias adicionales.
|
||||
2. **Filtro case-insensitive**: Busca en slug, nombre y descripción.
|
||||
3. **Ordenamiento por fecha por defecto**: Los más recientes primero (más útil en el día a día).
|
||||
4. **URLs Gitea al final**: Separadas de la tabla para no saturar visualmente.
|
||||
5. **Nombres truncados a 22 chars**: Evita tablas muy anchas.
|
||||
|
||||
### Manejo de errores
|
||||
|
||||
| Error | Causa | Solución |
|
||||
|-------|-------|----------|
|
||||
| "error al inicializar base de datos" | BD no creada | Ejecutar `dataforge init` |
|
||||
| "error al listar workspaces" | Corrupción de BD | Ejecutar `dataforge workspace rebuild-db` |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### No aparecen workspaces
|
||||
|
||||
La BD puede estar vacía. Opciones:
|
||||
1. Crear un workspace: `/workspace:create-repo`
|
||||
2. Importar desde Gitea: `/workspace:sync-repos`
|
||||
|
||||
### El filtro no encuentra nada
|
||||
|
||||
El filtro busca en slug, nombre y descripción (case-insensitive). Verificar:
|
||||
- El término está bien escrito
|
||||
- El workspace existe: ejecutar `/workspace:list-repos` sin filtro
|
||||
|
||||
### Tabla con formato incorrecto
|
||||
|
||||
Puede ocurrir si la terminal es muy estrecha. Usar una terminal de al menos 80 columnas de ancho.
|
||||
@@ -0,0 +1,234 @@
|
||||
---
|
||||
version: 1.0.0
|
||||
updated: 2026-03-12
|
||||
tags: [workspace, gitea, sync, repos]
|
||||
---
|
||||
|
||||
# Command: sync-repos
|
||||
|
||||
Sincroniza workspaces locales con repositorios en Gitea: detecta repos nuevos en Gitea que no existen localmente, clona repos faltantes, actualiza metadata en la BD local, y detecta inconsistencias (huérfanos).
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
Usar cuando necesites sincronizar tu estado local con Gitea:
|
||||
|
||||
- Después de clonar el parent repo en una máquina nueva
|
||||
- Cuando otro nodo creó un workspace en Gitea
|
||||
- Para verificar consistencia entre local y Gitea
|
||||
- Después de ejecutar `/workspace:create-repo` en otra máquina
|
||||
|
||||
### Prerequisitos
|
||||
|
||||
- Issue 0011b completado (comando /create-repo)
|
||||
- Variables de entorno configuradas: `GITEA_URL` y `GITEA_TOKEN`
|
||||
- Feature flag `workspace_commands` habilitado
|
||||
|
||||
### Variables de entorno requeridas
|
||||
|
||||
```bash
|
||||
export GITEA_URL="https://gitea.example.com"
|
||||
export GITEA_TOKEN="tu-token-de-api"
|
||||
export DATAFORGE_REPOS="./workspaces" # opcional, default: ./workspaces
|
||||
```
|
||||
|
||||
### Ejemplo de uso
|
||||
|
||||
```bash
|
||||
# Sincronización completa (con confirmación interactiva)
|
||||
/workspace:sync-repos
|
||||
|
||||
# Solo análisis (dry-run)
|
||||
/workspace:sync-repos --dry-run
|
||||
```
|
||||
|
||||
### Salida esperada
|
||||
|
||||
```
|
||||
Analizando workspaces locales...
|
||||
Consultando repositorios en Gitea...
|
||||
|
||||
Plan de sincronización:
|
||||
|
||||
Repos a clonar (2) — existen en Gitea pero no localmente:
|
||||
+ data-pipeline-v2 (https://gitea.example.com/Bl4cksmith/data-pipeline-v2.git)
|
||||
+ ml-training-service (https://gitea.example.com/Bl4cksmith/ml-training-service.git)
|
||||
|
||||
Repos a actualizar metadata (1):
|
||||
~ my-etl-pipeline
|
||||
|
||||
Repos locales no en Gitea — huérfanos (1):
|
||||
? old-experiment
|
||||
|
||||
Total: 2 a clonar, 1 a actualizar, 1 huérfanos detectados
|
||||
|
||||
¿Ejecutar sincronización? (s/n): s
|
||||
|
||||
Clonando data-pipeline-v2...
|
||||
✓ data-pipeline-v2 clonado
|
||||
Clonando ml-training-service...
|
||||
✓ ml-training-service clonado
|
||||
⚠ old-experiment no está en Gitea (mantener local)
|
||||
|
||||
Sincronización completada.
|
||||
Clonados: 2
|
||||
Actualizados: 1
|
||||
Huérfanos: 1
|
||||
|
||||
Workspaces activos: 4
|
||||
```
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
- [ ] Feature flag `workspace_commands` habilitado en `feature_flags.json`
|
||||
- [ ] Variables de entorno `GITEA_URL` y `GITEA_TOKEN` configuradas
|
||||
- [ ] Issue 0011b completado
|
||||
|
||||
### Flujo de implementación
|
||||
|
||||
#### Paso 0: Verificar feature flag
|
||||
|
||||
Leer `feature_flags.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"features": {
|
||||
"workspace_commands": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Si `enabled: false`, informar al usuario y detenerse.
|
||||
|
||||
#### Paso 1: Detectar modo de ejecución
|
||||
|
||||
Determinar si el usuario pasó `--dry-run`:
|
||||
|
||||
- Con `--dry-run`: ejecutar solo análisis, no hacer cambios
|
||||
- Sin `--dry-run`: mostrar plan y pedir confirmación antes de ejecutar
|
||||
|
||||
#### Paso 2: Ejecutar análisis vía `app.SyncWorkspacesCommand`
|
||||
|
||||
El flujo completo está implementado en `app/workspace_sync.go`:
|
||||
|
||||
```go
|
||||
// Modo dry-run (solo análisis):
|
||||
err := app.SyncWorkspacesCommand(config, true)
|
||||
|
||||
// Modo ejecución completa:
|
||||
err := app.SyncWorkspacesCommand(config, false)
|
||||
```
|
||||
|
||||
El comando hace automáticamente:
|
||||
1. Obtener workspaces locales desde SQLite
|
||||
2. Consultar repos en Gitea (organización o usuario)
|
||||
3. Comparar con `core.CompareWorkspaces()` (función pura)
|
||||
4. Mostrar plan con ToClone, ToUpdate, Orphans
|
||||
5. Si no dry-run: clonar repos faltantes y actualizar metadata
|
||||
|
||||
#### Paso 3: Confirmación interactiva (si no --dry-run)
|
||||
|
||||
Después de mostrar el plan:
|
||||
|
||||
```
|
||||
¿Ejecutar sincronización? (s/n):
|
||||
```
|
||||
|
||||
- Si `n`: cancelar sin cambios
|
||||
- Si `s`: ejecutar sincronización completa
|
||||
|
||||
#### Paso 4: Mostrar resultado final
|
||||
|
||||
Mostrar resumen con conteos de clonados, actualizados, huérfanos.
|
||||
|
||||
### Decisiones de diseño importantes
|
||||
|
||||
1. **Huérfanos NO se eliminan**: Si un repo local no está en Gitea, solo se reporta como huérfano. NO se elimina automáticamente (podría ser un repo en desarrollo que no está pusheado aún).
|
||||
|
||||
2. **Dry-run por defecto** en análisis: El plan siempre se muestra antes de ejecutar, y siempre requiere confirmación.
|
||||
|
||||
3. **Confirmación obligatoria**: El comando SIEMPRE muestra el plan y pide confirmación antes de clonar o actualizar.
|
||||
|
||||
4. **Clonación secuencial**: Los repos se clonan uno a uno (no en paralelo por simplicidad).
|
||||
|
||||
### Manejo de errores
|
||||
|
||||
| Error | Causa | Solución |
|
||||
|-------|-------|----------|
|
||||
| "GITEA_URL y GITEA_TOKEN son requeridos" | Variables de entorno no configuradas | `export GITEA_URL=... GITEA_TOKEN=...` |
|
||||
| "error al obtener repositorios de Gitea" | Token inválido o Gitea inaccesible | Verificar token y conectividad |
|
||||
| "Error clonando <repo>" | URL incorrecta o permisos insuficientes | Verificar credenciales git y permisos |
|
||||
| "error al abrir base de datos" | BD no inicializada | Ejecutar `dataforge` para inicializar BD |
|
||||
|
||||
### Feature flag
|
||||
|
||||
Este comando requiere que `workspace_commands` esté habilitado:
|
||||
|
||||
```json
|
||||
{
|
||||
"features": {
|
||||
"workspace_commands": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Si está deshabilitado, informar al usuario:
|
||||
|
||||
```
|
||||
El comando /sync-repos requiere que el feature flag 'workspace_commands' esté habilitado.
|
||||
Editar feature_flags.json y cambiar "enabled": true para workspace_commands.
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "GITEA_URL y GITEA_TOKEN son requeridos"
|
||||
|
||||
```bash
|
||||
export GITEA_URL="https://gitea.example.com"
|
||||
export GITEA_TOKEN="tu-token"
|
||||
# Luego ejecutar de nuevo
|
||||
/workspace:sync-repos
|
||||
```
|
||||
|
||||
### Error: "error al obtener repositorios de Gitea"
|
||||
|
||||
Verificar:
|
||||
1. Gitea accesible: `curl -H "Authorization: token $GITEA_TOKEN" $GITEA_URL/api/v1/user`
|
||||
2. Token tiene permisos de lectura de repositorios
|
||||
|
||||
### Error: "Error clonando <repo>"
|
||||
|
||||
Posibles causas:
|
||||
- Credenciales git no configuradas para HTTPS
|
||||
- Repo privado sin permisos de acceso
|
||||
- URL de clone incorrecta
|
||||
|
||||
Solución:
|
||||
```bash
|
||||
# Verificar credenciales git
|
||||
git config --global credential.helper store
|
||||
|
||||
# Verificar acceso manual
|
||||
git clone <clone_url>
|
||||
```
|
||||
|
||||
### Los huérfanos no desaparecen
|
||||
|
||||
Los huérfanos son repos locales que no están en Gitea. Opciones:
|
||||
1. Si el repo fue eliminado de Gitea: ejecutar `dataforge workspace clean <slug>`
|
||||
2. Si el repo debe estar en Gitea: pushear el repo a Gitea primero
|
||||
|
||||
### La BD local está desactualizada
|
||||
|
||||
Usar `RebuildDBCommand` para reconstruir desde cero:
|
||||
```bash
|
||||
dataforge rebuild-db
|
||||
```
|
||||
@@ -0,0 +1,75 @@
|
||||
# Include: ask-user-confirm
|
||||
|
||||
Patrón estándar para pedir confirmación al usuario antes de operaciones críticas.
|
||||
|
||||
## Formato
|
||||
|
||||
### Mostrar resumen de la operación
|
||||
|
||||
Presentar claramente qué se va a hacer:
|
||||
|
||||
```
|
||||
<Título de la operación>
|
||||
|
||||
Cambios a realizar:
|
||||
- <cambio 1>
|
||||
- <cambio 2>
|
||||
- <cambio 3>
|
||||
|
||||
<Información adicional relevante>
|
||||
```
|
||||
|
||||
### Preguntar al usuario
|
||||
|
||||
```
|
||||
¿Todo está correcto para continuar?
|
||||
- Si es correcto: se ejecutará la operación automáticamente
|
||||
- Si necesitas ajustes: puedes hacer cambios antes de continuar
|
||||
```
|
||||
|
||||
### Esperar respuesta
|
||||
|
||||
**Respuestas afirmativas** (continuar):
|
||||
- "sí" / "si" / "yes" / "y" / "s"
|
||||
- "ok" / "okay" / "correcto"
|
||||
- "adelante" / "continúa" / "continuar"
|
||||
- "confirmo"
|
||||
|
||||
**Respuestas negativas** (detener):
|
||||
- "no" / "n"
|
||||
- "espera" / "wait" / "stop"
|
||||
- "necesito cambios" / "ajustar"
|
||||
- Cualquier otra respuesta → asumir que necesita ajustes
|
||||
|
||||
### Acciones según respuesta
|
||||
|
||||
#### Si responde afirmativo
|
||||
✓ Continuar con la operación
|
||||
|
||||
#### Si responde negativo
|
||||
⚠ STOP y decir:
|
||||
|
||||
```
|
||||
Entendido. Puedes hacer los ajustes necesarios.
|
||||
|
||||
Para continuar cuando estés listo:
|
||||
<comando o acción para retomar>
|
||||
```
|
||||
|
||||
## Ejemplo de uso
|
||||
|
||||
```
|
||||
Issue 0013-hot-reload creado.
|
||||
|
||||
Contenido:
|
||||
- dev/issues/0013-hot-reload.md
|
||||
- dev/issues/README.md actualizado
|
||||
|
||||
¿Todo está correcto para hacer commit y push?
|
||||
- Si es correcto: se integrará a master automáticamente
|
||||
- Si necesitas ajustes: puedes editar los archivos antes
|
||||
|
||||
[Usuario responde "sí"]
|
||||
|
||||
✓ Continuando con integración a master...
|
||||
```
|
||||
@@ -0,0 +1,72 @@
|
||||
# Include: git-merge-to-master
|
||||
|
||||
Realiza merge de una rama de trabajo a master con --no-ff para preservar historia.
|
||||
|
||||
## Precondiciones
|
||||
|
||||
- Estar en la rama de trabajo (issue/* o quick/*)
|
||||
- Tests ejecutados y pasando
|
||||
- Commits limpios y atómicos
|
||||
|
||||
## Flujo
|
||||
|
||||
### 1. Cambiar a master
|
||||
|
||||
```bash
|
||||
git checkout master
|
||||
```
|
||||
|
||||
### 2. Actualizar master ({{include: git-update-master}})
|
||||
|
||||
```bash
|
||||
git pull --rebase
|
||||
```
|
||||
|
||||
### 3. Merge con --no-ff
|
||||
|
||||
```bash
|
||||
git merge --no-ff <rama> -m "merge: <rama> — <descripción corta>"
|
||||
```
|
||||
|
||||
**Formato del mensaje:**
|
||||
- Título: `merge: <rama> — <descripción>`
|
||||
- Cuerpo (opcional): resumen de lo que entra
|
||||
|
||||
**Ejemplos:**
|
||||
```
|
||||
merge: issue/0021-threads-config — habilitar threads en agentes
|
||||
merge: quick/fix-typo-readme — corregir typo en README
|
||||
```
|
||||
|
||||
### 4. Casos especiales
|
||||
|
||||
#### Sin conflictos
|
||||
✓ Merge completado, continuar
|
||||
|
||||
#### Con conflictos
|
||||
⚠ Resolver conflictos:
|
||||
|
||||
1. Ver archivos en conflicto:
|
||||
```bash
|
||||
git status
|
||||
```
|
||||
|
||||
2. Editar archivos y resolver conflictos manualmente
|
||||
|
||||
3. Stagear archivos resueltos:
|
||||
```bash
|
||||
git add <archivos-resueltos>
|
||||
```
|
||||
|
||||
4. Completar merge (sin -m para mantener mensaje):
|
||||
```bash
|
||||
git commit
|
||||
```
|
||||
|
||||
## Verificación post-merge
|
||||
|
||||
```bash
|
||||
git log --oneline -3
|
||||
```
|
||||
|
||||
Debe aparecer el merge commit al tope del log.
|
||||
@@ -0,0 +1,37 @@
|
||||
# Include: git-update-master
|
||||
|
||||
Actualiza master desde el remoto con rebase para mantener historia lineal.
|
||||
|
||||
## Verificar rama actual
|
||||
|
||||
```bash
|
||||
git branch --show-current
|
||||
```
|
||||
|
||||
Si no estamos en master:
|
||||
```bash
|
||||
git checkout master
|
||||
```
|
||||
|
||||
## Actualizar desde remoto
|
||||
|
||||
```bash
|
||||
git pull --rebase
|
||||
```
|
||||
|
||||
## Casos
|
||||
|
||||
### Already up to date
|
||||
✓ Master actualizado, continuar
|
||||
|
||||
### Fast-forward
|
||||
✓ Master actualizado con cambios del remoto, continuar
|
||||
|
||||
### Rebase conflicts
|
||||
✗ Error: Conflictos durante rebase
|
||||
|
||||
**Solución:**
|
||||
1. Resolver conflictos manualmente
|
||||
2. `git add <archivos-resueltos>`
|
||||
3. `git rebase --continue`
|
||||
4. Si es muy complejo: `git rebase --abort` y pedir ayuda al usuario
|
||||
@@ -0,0 +1,24 @@
|
||||
# Include: git-verify-clean
|
||||
|
||||
Verifica que el repositorio esté en estado limpio antes de operaciones de git.
|
||||
|
||||
## Verificaciones
|
||||
|
||||
```bash
|
||||
git status --short
|
||||
```
|
||||
|
||||
## Casos
|
||||
|
||||
### Working tree limpio (sin output)
|
||||
✓ Continuar con la operación
|
||||
|
||||
### Working tree con cambios
|
||||
⚠ Advertencia: Hay cambios sin commitear
|
||||
|
||||
**Opciones:**
|
||||
1. Stagear y commitear cambios primero
|
||||
2. Hacer stash de cambios temporalmente
|
||||
3. Cancelar operación
|
||||
|
||||
**STOP**: No continuar hasta que el working tree esté limpio.
|
||||
@@ -0,0 +1,29 @@
|
||||
# Include: issue-numbering
|
||||
|
||||
Determina el próximo número de issue disponible.
|
||||
|
||||
## Comando
|
||||
|
||||
```bash
|
||||
ls dev/issues/ dev/issues/completed/ | grep -oP '^\d{4}' | sort -rn | head -1
|
||||
```
|
||||
|
||||
## Lógica
|
||||
|
||||
1. Lista todos los archivos en `dev/issues/` y `dev/issues/completed/`
|
||||
2. Extrae números de 4 dígitos al inicio del nombre
|
||||
3. Ordena de mayor a menor
|
||||
4. Toma el primero (más alto)
|
||||
5. El siguiente issue será: `número_más_alto + 1`
|
||||
|
||||
## Formato
|
||||
|
||||
Siempre usar **4 dígitos con ceros a la izquierda**:
|
||||
- `0001`, `0002`, ..., `0023`, `0024`, etc.
|
||||
- Nunca: `1`, `23`, `123`
|
||||
|
||||
## Ejemplo
|
||||
|
||||
Si el issue más reciente es `0023-hot-reload.md`:
|
||||
- Número actual: `0023`
|
||||
- Próximo issue: `0024`
|
||||
@@ -0,0 +1,65 @@
|
||||
# Include: run-tests
|
||||
|
||||
Ejecuta tests del proyecto Go con las tags apropiadas.
|
||||
|
||||
## Comando
|
||||
|
||||
```bash
|
||||
go test -tags goolm ./...
|
||||
```
|
||||
|
||||
## Casos
|
||||
|
||||
### Tests pasan (exit code 0)
|
||||
```
|
||||
ok gitea-dgg044oo04woo4ggcsws4gk0.organic-machine.com/Bl4cksmith/dataforge/core 0.123s
|
||||
ok gitea-dgg044oo04woo4ggcsws4gk0.organic-machine.com/Bl4cksmith/dataforge/shell 0.089s
|
||||
```
|
||||
|
||||
✓ Tests pasando, continuar
|
||||
|
||||
### Tests fallan (exit code != 0)
|
||||
```
|
||||
FAIL gitea-dgg044oo04woo4ggcsws4gk0.organic-machine.com/Bl4cksmith/dataforge/core 0.456s
|
||||
```
|
||||
|
||||
✗ Error: Tests fallando
|
||||
|
||||
**STOP**: No continuar hasta que los tests pasen.
|
||||
|
||||
**Solución:**
|
||||
1. Ver detalles con `-v`:
|
||||
```bash
|
||||
go test -v -tags goolm ./...
|
||||
```
|
||||
|
||||
2. Corregir errores en el código
|
||||
3. Re-ejecutar tests
|
||||
4. Continuar cuando todos pasen
|
||||
|
||||
### No hay tests (no packages)
|
||||
```
|
||||
? gitea-dgg044oo04woo4ggcsws4gk0.organic-machine.com/Bl4cksmith/dataforge/core [no test files]
|
||||
```
|
||||
|
||||
ℹ No hay tests aplicables (común en cambios de docs/config solamente)
|
||||
|
||||
✓ Continuar sin ejecutar tests
|
||||
|
||||
## Modo verbose (para debugging)
|
||||
|
||||
Si se necesita más información:
|
||||
|
||||
```bash
|
||||
go test -v -tags goolm ./...
|
||||
```
|
||||
|
||||
Muestra cada test individual y su resultado.
|
||||
|
||||
## Coverage (opcional)
|
||||
|
||||
Para ver cobertura de tests:
|
||||
|
||||
```bash
|
||||
go test -tags goolm -cover ./...
|
||||
```
|
||||
@@ -0,0 +1,144 @@
|
||||
---
|
||||
version: 1.0.0
|
||||
updated: {{FECHA}}
|
||||
tags: [{{TAGS}}]
|
||||
---
|
||||
|
||||
# Command: {{NOMBRE}}
|
||||
|
||||
{{DESCRIPCION_BREVE}}
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
{{CUANDO_USAR}}
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
/{{NOMBRE}} {{ARGUMENTOS}}
|
||||
```
|
||||
|
||||
### Ejemplos
|
||||
|
||||
**Ejemplo 1:**
|
||||
```bash
|
||||
/{{NOMBRE}} {{EJEMPLO_1}}
|
||||
```
|
||||
|
||||
{{DESCRIPCION_EJEMPLO_1}}
|
||||
|
||||
**Ejemplo 2:**
|
||||
```bash
|
||||
/{{NOMBRE}} {{EJEMPLO_2}}
|
||||
```
|
||||
|
||||
{{DESCRIPCION_EJEMPLO_2}}
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
|
||||
- [ ] {{PRECONDICION_1}}
|
||||
- [ ] {{PRECONDICION_2}}
|
||||
- [ ] {{PRECONDICION_3}}
|
||||
|
||||
### Inputs
|
||||
|
||||
Se necesitan los siguientes datos. Si no se proporcionan, preguntar al usuario:
|
||||
|
||||
- `{{INPUT_1}}`: {{DESCRIPCION_INPUT_1}}
|
||||
- `{{INPUT_2}}` (opcional): {{DESCRIPCION_INPUT_2}}
|
||||
|
||||
### Flujo obligatorio
|
||||
|
||||
#### 1. {{PASO_1}}
|
||||
|
||||
{{DESCRIPCION_PASO_1}}
|
||||
|
||||
```bash
|
||||
{{COMANDOS_PASO_1}}
|
||||
```
|
||||
|
||||
{{NOTAS_PASO_1}}
|
||||
|
||||
#### 2. {{PASO_2}}
|
||||
|
||||
{{DESCRIPCION_PASO_2}}
|
||||
|
||||
```bash
|
||||
{{COMANDOS_PASO_2}}
|
||||
```
|
||||
|
||||
{{NOTAS_PASO_2}}
|
||||
|
||||
#### 3. {{PASO_3}}
|
||||
|
||||
{{include: ask-user-confirm}}
|
||||
|
||||
{{MENSAJE_CONFIRMACION}}
|
||||
|
||||
#### 4. {{PASO_4}}
|
||||
|
||||
{{DESCRIPCION_PASO_4}}
|
||||
|
||||
```bash
|
||||
{{COMANDOS_PASO_4}}
|
||||
```
|
||||
|
||||
### Verificación final
|
||||
|
||||
```bash
|
||||
{{COMANDOS_VERIFICACION}}
|
||||
```
|
||||
|
||||
Informar al usuario:
|
||||
|
||||
```
|
||||
✓ {{MENSAJE_EXITO}}
|
||||
|
||||
{{DETALLES_FINALES}}
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **{{CONVENCION_1}}**: {{DESCRIPCION_CONVENCION_1}}
|
||||
- **{{CONVENCION_2}}**: {{DESCRIPCION_CONVENCION_2}}
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "{{ERROR_1}}"
|
||||
|
||||
**Causa:** {{CAUSA_ERROR_1}}
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
{{SOLUCION_ERROR_1}}
|
||||
```
|
||||
|
||||
### Error: "{{ERROR_2}}"
|
||||
|
||||
**Causa:** {{CAUSA_ERROR_2}}
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
{{SOLUCION_ERROR_2}}
|
||||
```
|
||||
|
||||
### Error: "{{ERROR_3}}"
|
||||
|
||||
**Causa:** {{CAUSA_ERROR_3}}
|
||||
|
||||
**Solución:**
|
||||
1. {{PASO_SOLUCION_3_1}}
|
||||
2. {{PASO_SOLUCION_3_2}}
|
||||
3. {{PASO_SOLUCION_3_3}}
|
||||
|
||||
## Reglas críticas
|
||||
|
||||
- {{REGLA_CRITICA_1}}
|
||||
- {{REGLA_CRITICA_2}}
|
||||
- {{REGLA_CRITICA_3}}
|
||||
@@ -0,0 +1,128 @@
|
||||
# NNNN — [Título de la Issue]
|
||||
|
||||
## Metadata
|
||||
|
||||
| Campo | Valor |
|
||||
|-------|-------|
|
||||
| **ID** | NNNN |
|
||||
| **Estado** | 🟡 pendiente / 🔵 en progreso / ✅ completado / 🔴 bloqueado |
|
||||
| **Prioridad** | alta / media / baja |
|
||||
| **Tipo** | feature / bugfix / refactor / docs / infrastructure |
|
||||
|
||||
## Dependencias
|
||||
|
||||
<!-- Issues que DEBEN estar completadas antes de empezar esta -->
|
||||
|
||||
| ID | Título | Estado | Requerido |
|
||||
|----|--------|--------|-----------|
|
||||
| 0001 | Actualizar nombre del módulo | ✅ | Sí |
|
||||
| 0002 | Implementar core/ | ✅ | Sí |
|
||||
|
||||
**Bloqueada por:** `#0001, #0002`
|
||||
|
||||
**Desbloquea:** `#0006, #0007`
|
||||
|
||||
> **⚠️ VALIDACIÓN AUTOMÁTICA**: Esta issue no puede iniciarse hasta que todas las dependencias estén en estado `✅ completado`.
|
||||
|
||||
---
|
||||
|
||||
## Objetivo
|
||||
|
||||
[Descripción concisa de qué se quiere lograr en 1-3 oraciones]
|
||||
|
||||
## Contexto
|
||||
|
||||
- [Punto de contexto 1]
|
||||
- [Punto de contexto 2]
|
||||
- [Referencias a otras issues o decisiones previas]
|
||||
|
||||
## Arquitectura
|
||||
|
||||
```
|
||||
[Estructura de archivos afectados]
|
||||
dir/
|
||||
├── file1.go — Descripción
|
||||
├── file2.go — NEW: Nuevo archivo
|
||||
└── file3.go — MODIFY: Modificación
|
||||
```
|
||||
|
||||
### Patrón pure core / impure shell
|
||||
|
||||
- `core/` — [Qué funciones puras se agregan]
|
||||
- `shell/` — [Qué operaciones I/O se implementan]
|
||||
- `app/` — [Cómo se orquesta]
|
||||
|
||||
## Tareas
|
||||
|
||||
### Fase 1: [Nombre de fase]
|
||||
|
||||
- [ ] **1.1** [Descripción detallada de tarea]
|
||||
- [ ] **1.2** [Otra tarea]
|
||||
|
||||
### Fase 2: [Otra fase]
|
||||
|
||||
- [ ] **2.1** [Tarea]
|
||||
- [ ] **2.2** [Tarea]
|
||||
|
||||
### Fase N: Cleanup y docs
|
||||
|
||||
- [ ] Actualizar `README.md` con cambios relevantes
|
||||
- [ ] Actualizar `CLAUDE.md` si hay cambios arquitectónicos
|
||||
- [ ] Ejecutar `go mod tidy`
|
||||
- [ ] Ejecutar `go test ./...`
|
||||
- [ ] Actualizar issue en `dev/issues/README.md`
|
||||
|
||||
---
|
||||
|
||||
## Ejemplo de uso
|
||||
|
||||
```bash
|
||||
# Comandos de ejemplo
|
||||
comando ejemplo arg1 arg2
|
||||
|
||||
# Output esperado:
|
||||
# ✓ Success message
|
||||
```
|
||||
|
||||
```go
|
||||
// Código de ejemplo si aplica
|
||||
package example
|
||||
|
||||
func Example() {}
|
||||
```
|
||||
|
||||
## Decisiones de diseño
|
||||
|
||||
- **Decisión 1**: Razón y trade-offs
|
||||
- **Decisión 2**: Alternativas consideradas y por qué se eligió esta
|
||||
|
||||
## Prerequisitos
|
||||
|
||||
- Issue #NNNN completado
|
||||
- Herramienta X instalada
|
||||
- Configuración Y realizada
|
||||
|
||||
## Riesgos
|
||||
|
||||
- **Riesgo 1**: Descripción del riesgo. **Mitigación**: Cómo se mitigará
|
||||
- **Riesgo 2**: Otro riesgo. **Mitigación**: Plan de mitigación
|
||||
|
||||
## Criterios de aceptación
|
||||
|
||||
- [ ] Todos los tests pasan
|
||||
- [ ] Feature flag agregado en `feature_flags.json`
|
||||
- [ ] Documentación actualizada
|
||||
- [ ] Code review aprobado
|
||||
- [ ] Deployable a main
|
||||
|
||||
---
|
||||
|
||||
## Notas de implementación
|
||||
|
||||
[Notas que surjan durante la implementación, decisiones tomadas, problemas encontrados]
|
||||
|
||||
## Referencias
|
||||
|
||||
- [Link a documentación relevante]
|
||||
- [Link a PRs relacionados]
|
||||
- [Link a discusiones]
|
||||
Reference in New Issue
Block a user