From 31b28cf2608bfd27496a99e4632acb7f955c34a8 Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Thu, 9 Apr 2026 23:26:58 +0200 Subject: [PATCH] feat: agregar skill parallel-fix-issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nuevo skill que permite implementar múltiples issues en paralelo usando git worktrees aislados y agentes concurrentes. Analiza dependencias, verifica builds/tests e integra a master en orden. Incluye scripts auxiliares en scripts/. Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/skills/parallel-fix-issues/SKILL.md | 268 ++++++++++++++++++ .../scripts/integrate-worktrees.sh | 117 ++++++++ .../scripts/setup-worktrees.sh | 76 +++++ .../scripts/verify-worktree.sh | 88 ++++++ 4 files changed, 549 insertions(+) create mode 100644 .claude/skills/parallel-fix-issues/SKILL.md create mode 100755 .claude/skills/parallel-fix-issues/scripts/integrate-worktrees.sh create mode 100755 .claude/skills/parallel-fix-issues/scripts/setup-worktrees.sh create mode 100755 .claude/skills/parallel-fix-issues/scripts/verify-worktree.sh diff --git a/.claude/skills/parallel-fix-issues/SKILL.md b/.claude/skills/parallel-fix-issues/SKILL.md new file mode 100644 index 0000000..972aada --- /dev/null +++ b/.claude/skills/parallel-fix-issues/SKILL.md @@ -0,0 +1,268 @@ +--- +name: parallel-fix-issues +description: > + Implementar múltiples issues en paralelo. Analiza dependencias entre issues pendientes, + crea git worktrees aislados, lanza agentes concurrentes para cada issue, verifica + resultados (build + tests) e integra todo a master en orden. +allowed-tools: Bash Read Write Edit Grep Glob Agent +argument-hint: "[issue-numbers... | all]" +--- + +# Parallel Fix Issues + +Skill para implementar múltiples issues simultáneamente usando git worktrees y agentes paralelos. + +## Inputs + +- `$ARGUMENTS`: lista de issue numbers (ej: `0026 0027 0031`) o `all` para todos los pendientes. +- Si no hay argumentos, preguntar al usuario qué issues quiere procesar. + +## Proceso completo + +### Fase 1: Análisis de dependencias + +Lanzar un **Agent** (subagent_type: `Explore`) para analizar los issues y producir un plan de ejecución. + +El agente debe: + +1. Leer `dev/issues/README.md` y filtrar los issues pendientes +2. Si `$ARGUMENTS` no es `all`, filtrar solo los issues solicitados +3. Para cada issue pendiente, leer el archivo completo y extraer: + - **Objetivo** (resumen) + - **Prerequisitos** y dependencias explícitas (ej: "requiere issue 0026") + - **Archivos afectados** (para detectar conflictos potenciales entre issues) +4. Construir un **grafo de dependencias** y agrupar en **waves** (oleadas): + - Wave 1: issues sin dependencias entre sí y sin dependencias pendientes + - Wave 2: issues que dependen de wave 1 + - Wave N: etc. +5. Dentro de cada wave, identificar **conflictos potenciales** (dos issues que tocan los mismos archivos) +6. Devolver el resultado en este formato exacto: + +``` +WAVE 1 (paralelo): +- - — archivos: +- - — archivos: + +WAVE 2 (paralelo, después de wave 1): +- - — depende de: + +CONFLICTOS POTENCIALES: +- y tocan — riesgo de merge conflict + +ISSUES EXCLUIDOS: +- - — razón (dependencia externa no resuelta, etc.) +``` + +**Mostrar el resultado al usuario y pedir confirmación** antes de continuar. El usuario puede: +- Aprobar el plan tal cual +- Excluir issues específicos +- Reordenar waves + +### Fase 2: Setup de worktrees + +Una vez aprobado el plan, crear los worktrees. + +```bash +.claude/skills/parallel-fix-issues/scripts/setup-worktrees.sh ... +``` + +El script crea un worktree por issue en `worktrees//`, cada uno en su propia branch `issue/`. + +**Verificar** que todos los worktrees se crearon correctamente: + +```bash +git worktree list +``` + +### Fase 3: Ejecución paralela por waves + +Para cada wave, lanzar **Agents en paralelo** (un Agent por issue, todos en el mismo mensaje para ejecución concurrente). + +**CRÍTICO**: Lanzar todos los agentes de una wave en una sola respuesta con múltiples tool calls. NO lanzar de uno en uno. + +**PERMISOS**: Todas las llamadas Bash de los agentes deben usar `dangerouslyDisableSandbox: true` para evitar prompts de permisos que bloqueen la ejecución paralela. Indicar esto explícitamente en el prompt de cada agente. + +El prompt de cada agente debe incluir: + +1. **Ruta absoluta del worktree**: `/home/ubuntu/CodeProyects/agents_and_robots/worktrees/` +2. **Contenido completo del issue** (copiar el markdown entero) +3. **Instrucciones de ejecución** (ver template abajo) + +#### Template de prompt para cada agente + +``` +Eres un agente de desarrollo implementando el issue -. + +## Directorio de trabajo + +Worktree: /home/ubuntu/CodeProyects/agents_and_robots/worktrees/ + +Usa SIEMPRE esta ruta como prefijo en paths absolutos. +Variable de conveniencia para comandos: + W=/home/ubuntu/CodeProyects/agents_and_robots/worktrees/ + +## Permisos + +IMPORTANTE: En TODAS tus llamadas al tool Bash, usa el parámetro `dangerouslyDisableSandbox: true`. +Esto es necesario porque estás ejecutando en paralelo con otros agentes y no hay usuario interactivo +para aprobar permisos. Ejemplo: + + Bash({ command: "cd $W && go build -tags goolm ./...", dangerouslyDisableSandbox: true }) + +## Issue a implementar + + + +## Instrucciones + +Sigue este flujo estrictamente: + +1. **Leer el issue** — ya lo tienes arriba, entiende objetivo, tareas y arquitectura. + +2. **Implementar todas las tareas** en orden: + - Respetar pure core / impure shell (pkg/ puro, shell/ impuro) + - Hacer commits atómicos por bloque lógico + - Prefijos: feat:, fix:, test:, docs:, refactor:, chore: + - NO hacer commits WIP ni código a medias + - Compilar frecuentemente: + Bash({ command: "cd $W && go build -tags goolm ./...", dangerouslyDisableSandbox: true }) + +3. **Tests obligatorios**: + - Escribir tests para todo código nuevo + - Ejecutar: + Bash({ command: "cd $W && go test -tags goolm ./...", dangerouslyDisableSandbox: true }) + - NO continuar si los tests fallan + +4. **Cerrar el issue** — solo mover el archivo, NO tocar README: + - Bash({ command: "cd $W && git mv dev/issues/-.md dev/issues/completed/", dangerouslyDisableSandbox: true }) + - Commit: docs: cerrar issue + IMPORTANTE: usar `git mv` (no `mv` + `git add`) para que git registre el movimiento. + IMPORTANTE: NO modificar dev/issues/README.md — lo hace el orquestador después del merge + para evitar conflictos entre agentes paralelos. + +5. **NO hacer merge a master, NO hacer push.** La integración la maneja el orquestador. + +6. **Reportar resultado** al final: + - ÉXITO: qué se implementó, cuántos commits, tests pasando + - FALLO: qué falló, en qué paso, qué queda pendiente +``` + +**Esperar** a que todos los agentes de la wave terminen antes de pasar a la siguiente wave. + +### Fase 4: Verificación + +Después de cada wave, verificar TODOS los worktrees completados: + +```bash +.claude/skills/parallel-fix-issues/scripts/verify-worktree.sh worktrees/ +``` + +El script verifica: +- `go build -tags goolm ./...` — compila sin errores +- `go test -tags goolm ./...` — tests pasan +- Issue movido a `dev/issues/completed/` +- Al menos 1 commit en la branch + +**Si un worktree falla verificación**: +1. Reportar al usuario qué falló +2. Preguntar si quiere: (a) intentar arreglar, (b) excluir ese issue, (c) abortar todo +3. Si se excluye, marcar para no integrar + +### Fase 5: Integración a master + +Una vez todas las waves verificadas, integrar a master **en orden de waves** (wave 1 primero, luego wave 2, etc.). + +```bash +.claude/skills/parallel-fix-issues/scripts/integrate-worktrees.sh ... +``` + +El script hace para cada branch: +1. `git checkout master` +2. `git merge --no-ff issue/` con mensaje descriptivo +3. Si hay **merge conflict**: PARAR e informar al usuario + +**Después de cada merge**, re-verificar que master compila: + +```bash +go build -tags goolm ./... && go test -tags goolm ./... +``` + +Si falla después de un merge, PARAR e informar — no continuar con más merges. + +### Fase 6: Actualizar README de issues + +Después de integrar TODOS los issues exitosos, actualizar `dev/issues/README.md` **una sola vez** desde master. +Esto evita conflictos: los agentes paralelos solo mueven archivos, el orquestador actualiza el índice. + +Para cada issue integrado: +1. Cambiar el link de `[-.md](-.md)` a `[-.md](completed/-.md)` +2. Cambiar el estado de `pendiente` a `completado` + +Hacer un solo commit: + +```bash +git add dev/issues/README.md +git commit -m "docs: actualizar README de issues — marcar issues como completados" +``` + +### Fase 7: Limpieza + +Si todo fue exitoso: + +```bash +# Eliminar worktrees y branches +for slug in ; do + git worktree remove "worktrees/${slug}" 2>/dev/null + git branch -d "issue/${slug}" 2>/dev/null +done +``` + +### Fase 8: Reporte final + +Mostrar al usuario un resumen: + +``` +## Resultado de parallel-fix-issues + +### Issues completados +- ✓ 0026-split-runtime — 5 commits +- ✓ 0027-prune-config-schema — 3 commits +- ✓ 0031-expand-file-tools — 7 commits + +### Issues fallidos +- ✗ 0029-core-tests — falló en fase de tests (excluido) + +### Estado de master +- Build: OK +- Tests: OK (142 passed) +- Commits nuevos: 18 + +### Siguiente paso +Ejecutar: git push +``` + +## Notas importantes + +- **Siempre compilar con `-tags goolm`** +- **Siempre usar `dangerouslyDisableSandbox: true`** en todas las llamadas Bash de los agentes paralelos +- **Nunca hacer push automáticamente** — el usuario decide cuándo pushear +- **Si hay merge conflicts**, parar y pedir intervención manual +- **Un worktree = un issue = una branch** — nunca mezclar +- Los worktrees se crean desde `master` actualizado +- La carpeta `worktrees/` está en `.gitignore` +- Issues con dependencias externas no resueltas se excluyen automáticamente +- **README centralizado**: los agentes NO tocan `dev/issues/README.md` — solo el orquestador lo actualiza después del merge, en un solo commit. Esto evita merge conflicts entre agentes paralelos +- **`git mv` para cerrar issues**: usar `git mv` (no `mv` + `git add`) para mover issues a `completed/` + +## Casos de uso + +``` +# Implementar todos los issues pendientes +/parallel-fix-issues all + +# Implementar issues específicos +/parallel-fix-issues 0026 0027 0031 + +# Solo los issues de refactor +/parallel-fix-issues 0026 0027 0028 +``` diff --git a/.claude/skills/parallel-fix-issues/scripts/integrate-worktrees.sh b/.claude/skills/parallel-fix-issues/scripts/integrate-worktrees.sh new file mode 100755 index 0000000..16cd223 --- /dev/null +++ b/.claude/skills/parallel-fix-issues/scripts/integrate-worktrees.sh @@ -0,0 +1,117 @@ +#!/bin/bash +# integrate-worktrees.sh — Integra branches de worktrees a master con --no-ff +# +# Uso: ./integrate-worktrees.sh ... +# Ejemplo: ./integrate-worktrees.sh 0026-split-runtime 0027-prune-config-schema +# +# Para cada slug: +# 1. git merge --no-ff issue/ a master +# 2. Verificar que master compila después del merge +# 3. Si hay conflict o fallo de build, PARAR inmediatamente +# +# Los slugs deben pasarse en el orden correcto (waves ya resueltas). +# NO hace push — eso lo decide el usuario. + +set -euo pipefail + +REPO_ROOT="$(git rev-parse --show-toplevel)" + +if [ $# -eq 0 ]; then + echo "ERROR: se necesita al menos un slug" + echo "Uso: $0 ..." + exit 1 +fi + +# Asegurar que estamos en master +echo "=== Cambiando a master ===" +cd "$REPO_ROOT" +git checkout master + +MERGED=0 +FAILED_AT="" + +for slug in "$@"; do + branch="issue/${slug}" + + echo "" + echo "=== Integrando: ${branch} ===" + + # Verificar que la branch existe + if ! git show-ref --verify --quiet "refs/heads/${branch}"; then + echo "FAIL: branch ${branch} no existe" + FAILED_AT="$slug" + break + fi + + # Merge --no-ff + if ! git merge --no-ff "$branch" -m "merge: ${branch} — implementación paralela"; then + echo "" + echo "CONFLICT: merge de ${branch} tiene conflictos" + echo "Resolver manualmente y luego continuar con los slugs restantes" + echo "" + echo "Para resolver:" + echo " 1. git status (ver archivos en conflicto)" + echo " 2. Resolver conflictos en cada archivo" + echo " 3. git add " + echo " 4. git commit" + echo "" + echo "Slugs pendientes después de ${slug}:" + FOUND=0 + for remaining in "$@"; do + if [ "$FOUND" -eq 1 ]; then + echo " - ${remaining}" + fi + if [ "$remaining" = "$slug" ]; then + FOUND=1 + fi + done + exit 1 + fi + + echo "MERGED: ${branch}" + + # Verificar que master sigue compilando + echo "--- Verificando build post-merge ---" + if ! (cd "$REPO_ROOT" && go build -tags goolm ./... 2>&1); then + echo "" + echo "FAIL: master no compila después de mergear ${branch}" + echo "Revertir con: git reset --hard HEAD~1" + echo "Investigar el problema antes de continuar." + FAILED_AT="$slug" + break + fi + echo "OK: build post-merge exitoso" + + MERGED=$((MERGED + 1)) +done + +echo "" +echo "=== Resumen de integración ===" +echo "Mergeados: ${MERGED} de $#" + +if [ -n "$FAILED_AT" ]; then + echo "Falló en: ${FAILED_AT}" + echo "" + echo "Worktrees NO limpiados (resolver primero el fallo)" + exit 1 +fi + +# Limpieza de worktrees y branches +echo "" +echo "=== Limpieza ===" +for slug in "$@"; do + path="${REPO_ROOT}/worktrees/${slug}" + branch="issue/${slug}" + + if [ -d "$path" ]; then + git worktree remove "$path" 2>/dev/null && echo "REMOVED: worktree ${path}" || echo "WARN: no se pudo eliminar worktree ${path}" + fi + + git branch -d "$branch" 2>/dev/null && echo "DELETED: branch ${branch}" || echo "WARN: no se pudo eliminar branch ${branch}" +done + +echo "" +echo "=== Integración completa ===" +echo "Master tiene ${MERGED} merges nuevos." +echo "" +echo "Para publicar: git push" diff --git a/.claude/skills/parallel-fix-issues/scripts/setup-worktrees.sh b/.claude/skills/parallel-fix-issues/scripts/setup-worktrees.sh new file mode 100755 index 0000000..a8854ec --- /dev/null +++ b/.claude/skills/parallel-fix-issues/scripts/setup-worktrees.sh @@ -0,0 +1,76 @@ +#!/bin/bash +# setup-worktrees.sh — Crea git worktrees para ejecución paralela de issues +# +# Uso: ./setup-worktrees.sh ... +# Ejemplo: ./setup-worktrees.sh 0026-split-runtime 0027-prune-config-schema +# +# Cada slug genera: +# worktrees// (worktree completo) +# branch: issue/ + +set -euo pipefail + +REPO_ROOT="$(git rev-parse --show-toplevel)" +WORKTREE_DIR="${REPO_ROOT}/worktrees" + +if [ $# -eq 0 ]; then + echo "ERROR: se necesita al menos un slug de issue" + echo "Uso: $0 ..." + exit 1 +fi + +# Asegurar que master está actualizado +echo "=== Actualizando master ===" +CURRENT_BRANCH="$(git branch --show-current)" +git checkout master 2>/dev/null +git pull --rebase 2>/dev/null || echo "WARN: no se pudo pull (sin remote o sin conexión)" + +# Volver a la rama original si no era master +if [ "$CURRENT_BRANCH" != "master" ] && [ -n "$CURRENT_BRANCH" ]; then + git checkout "$CURRENT_BRANCH" 2>/dev/null +fi + +mkdir -p "$WORKTREE_DIR" + +CREATED=0 +SKIPPED=0 +FAILED=0 + +for slug in "$@"; do + branch="issue/${slug}" + path="${WORKTREE_DIR}/${slug}" + + if [ -d "$path" ]; then + echo "SKIP: worktree ya existe: ${path}" + SKIPPED=$((SKIPPED + 1)) + continue + fi + + # Verificar que la branch no existe ya + if git show-ref --verify --quiet "refs/heads/${branch}" 2>/dev/null; then + echo "WARN: branch ${branch} ya existe, creando worktree desde ella" + git worktree add "$path" "$branch" 2>/dev/null || { + echo "FAIL: no se pudo crear worktree para ${slug}" + FAILED=$((FAILED + 1)) + continue + } + else + echo "CREATE: worktree ${path} (branch ${branch})" + git worktree add -b "$branch" "$path" master 2>/dev/null || { + echo "FAIL: no se pudo crear worktree para ${slug}" + FAILED=$((FAILED + 1)) + continue + } + fi + + CREATED=$((CREATED + 1)) +done + +echo "" +echo "=== Resumen ===" +echo "Creados: ${CREATED}" +echo "Existentes: ${SKIPPED}" +echo "Fallidos: ${FAILED}" +echo "" +echo "=== Worktrees activos ===" +git worktree list diff --git a/.claude/skills/parallel-fix-issues/scripts/verify-worktree.sh b/.claude/skills/parallel-fix-issues/scripts/verify-worktree.sh new file mode 100755 index 0000000..c947b59 --- /dev/null +++ b/.claude/skills/parallel-fix-issues/scripts/verify-worktree.sh @@ -0,0 +1,88 @@ +#!/bin/bash +# verify-worktree.sh — Verifica build, tests y cierre de issue en un worktree +# +# Uso: ./verify-worktree.sh +# Ejemplo: ./verify-worktree.sh worktrees/0026-split-runtime +# +# Checks: +# 1. El worktree existe y tiene commits propios +# 2. go build -tags goolm ./... compila +# 3. go test -tags goolm ./... pasa +# 4. El issue fue movido a completed/ +# +# Exit codes: +# 0 = todo OK +# 1 = error de argumento +# 2 = build falló +# 3 = tests fallaron +# 4 = issue no cerrado +# 5 = sin commits propios + +set -euo pipefail + +if [ $# -lt 1 ]; then + echo "ERROR: se necesita el path del worktree" + echo "Uso: $0 " + exit 1 +fi + +WORKTREE="$1" + +# Resolver path absoluto +if [[ "$WORKTREE" != /* ]]; then + REPO_ROOT="$(git rev-parse --show-toplevel)" + WORKTREE="${REPO_ROOT}/${WORKTREE}" +fi + +if [ ! -d "$WORKTREE" ]; then + echo "ERROR: worktree no encontrado: ${WORKTREE}" + exit 1 +fi + +SLUG="$(basename "$WORKTREE")" +echo "=== Verificando: ${SLUG} ===" + +# 1. Verificar commits propios +echo "--- Commits propios ---" +COMMIT_COUNT=$(cd "$WORKTREE" && git log master..HEAD --oneline 2>/dev/null | wc -l) +if [ "$COMMIT_COUNT" -eq 0 ]; then + echo "FAIL: sin commits propios en la branch" + exit 5 +fi +echo "OK: ${COMMIT_COUNT} commits desde master" +cd "$WORKTREE" && git log master..HEAD --oneline + +# 2. Build +echo "" +echo "--- Build ---" +if (cd "$WORKTREE" && go build -tags goolm ./... 2>&1); then + echo "OK: build exitoso" +else + echo "FAIL: build falló" + exit 2 +fi + +# 3. Tests +echo "" +echo "--- Tests ---" +if (cd "$WORKTREE" && go test -tags goolm ./... 2>&1); then + echo "OK: tests pasaron" +else + echo "FAIL: tests fallaron" + exit 3 +fi + +# 4. Issue cerrado (movido a completed/) +echo "" +echo "--- Cierre de issue ---" +COMPLETED_FILES=$(cd "$WORKTREE" && git diff --name-only master -- dev/issues/completed/ 2>/dev/null | wc -l) +if [ "$COMPLETED_FILES" -gt 0 ]; then + echo "OK: issue movido a completed/" + cd "$WORKTREE" && git diff --name-only master -- dev/issues/completed/ +else + echo "WARN: no se detectó issue movido a completed/ (verificar manualmente)" + # No es un error fatal — puede que el issue no siga la convención exacta +fi + +echo "" +echo "=== RESULTADO: ${SLUG} — OK ==="