chore: sync local config — caveman plugin, command/skill tweaks

- settings.json: enable caveman marketplace+plugin, effortLevel=high
- commands/git-branch + git-push: refactor docs
- skills/parallel-fix-issues: SKILL.md + scripts updates
This commit is contained in:
2026-05-08 20:44:50 +02:00
parent bf8651020e
commit 25eefbd5e3
6 changed files with 279 additions and 255 deletions
+40 -67
View File
@@ -1,86 +1,59 @@
# Command: git branch (TBD)
Crea una rama de trabajo. **Nunca trabajar directamente en master.**
Wrapper sobre `tbd_branch_create_bash_infra`. La función del registry maneja toda la lógica determinista (verificar limpio, autodetectar master/main, pull --rebase, validar slug + número de issue, crear rama). Este comando solo decide los inputs.
Soporta dos tipos de rama:
- `issue/<NNNN>-<slug>` — para implementar un issue existente de `dev/issues/`
- `quick/<slug>` — para cambios pequeños sin issue asociado (fixes, config, docs, etc.)
## Inputs
Preguntar al usuario si el cambio esta asociado a un issue o no.
### Si es un issue:
- `issue_number`: numero de 4 digitos (e.g. `0020`)
- `slug`: nombre corto separado por guiones (e.g. `hot-reload`)
### Si es un cambio rapido (sin issue):
- `slug`: nombre corto descriptivo separado por guiones (e.g. `fix-typo-readme`)
## Flujo obligatorio
1. Verificar que estamos en master y limpio:
```bash
git branch --show-current
git status --short
```
Si no estamos en master, cambiar primero:
```bash
git checkout master
```
Si hay cambios sin commitear, **avisar al usuario** y no continuar hasta resolver.
2. Actualizar master desde remoto:
```bash
git pull --rebase
```
3. Crear la rama y cambiar a ella:
**Para issues:**
```bash
git checkout -b issue/<issue_number>-<slug>
```
Ejemplo: `git checkout -b issue/0013-hot-reload`
**Para cambios rapidos:**
```bash
git checkout -b quick/<slug>
```
Ejemplo: `git checkout -b quick/fix-typo-readme`
4. Confirmar al usuario:
## Uso
```
Rama `<nombre-rama>` creada desde master actualizado.
Puedes empezar a trabajar. Cuando termines, usa `/git-push` para integrar a master.
/git-branch # preguntar al usuario
/git-branch issue 0021 hot-reload
/git-branch quick fix-typo-readme
```
## Pasos del asistente
1. **Decidir modo e inputs**:
- Preguntar si el cambio está asociado a un issue o no.
- Si es issue: pedir `<NNNN>` (4 dígitos) y `<slug>` kebab-case.
- Si es quick: pedir `<slug>` kebab-case descriptivo.
2. **Llamar la función del registry**:
```bash
source /home/lucas/fn_registry/bash/functions/infra/tbd_branch_create.sh
tbd_branch_create issue 0021 hot-reload
# o
tbd_branch_create quick fix-typo-readme
```
La función:
- Verifica que el working tree esté limpio (aborta si dirty).
- Cambia a master/main (autodetecta).
- `git pull --rebase` desde la rama base.
- Valida `<NNNN>` (regex 4 dígitos) y `<slug>` (kebab-case ASCII).
- `git checkout -b <rama>`.
- Imprime confirmación.
## Convenciones
- **Formato de rama issue**: `issue/<NNNN>-<slug>` (siempre 4 digitos)
- **Formato de rama quick**: `quick/<slug>` (sin numero)
- **Ramas cortas**: idealmente horas, no dias
- **Una rama por issue**: no mezclar issues en la misma rama
- **Nunca pushear la rama al remoto**: el push se hace desde master despues 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 atomico y con mensaje real (ver convencion en `/git-push`)
- **Formato issue**: `issue/<NNNN>-<slug>` (4 dígitos siempre).
- **Formato 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 (ver `/git-push`).
- **No commits WIP**: cada commit atómico con mensaje real.
## Features multi-issue
Para features que no caben en una sola rama, usar sub-issues con sufijo letra:
Para features que no caben en una sola rama, 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 codigo parcial se protege con **feature flags** en `dev/feature_flags.json` (no con commits WIP).
Cada sub-rama sigue el mismo flujo. El código parcial se protege con **feature flags** en `dev/feature_flags.json`.
## Para tocar la lógica
Editar `tbd_branch_create_bash_infra` en `bash/functions/infra/tbd_branch_create.sh`, no este wrapper.
+66 -96
View File
@@ -1,8 +1,10 @@
# Command: git push
# Command: git push (TBD)
Integra cambios a master y publica. Soporta ramas `issue/*` y `quick/*`.
## Flujo obligatorio
La fase final (`pull --rebase` master + `merge --no-ff` + `git push` + `git branch -d`) la hace `tbd_branch_finish_bash_infra` del registry. Tests y commits **no** los hace la función — los corre el asistente porque dependen del stack.
## Pasos del asistente
### 1. Verificar rama actual y estado
@@ -11,34 +13,24 @@ git branch --show-current
git status --short
```
#### Si estamos en una rama `issue/*` o `quick/*`
#### Si estamos en `issue/*` o `quick/*`
Continuar directamente al paso 2.
Continuar al paso 2.
#### Si estamos en `master` con cambios pendientes
#### Si estamos en master con cambios pendientes
Crear una rama automaticamente antes de continuar:
Crear rama primero:
1. Preguntar si el cambio está asociado a un issue.
2. Si es issue: pedir `<NNNN>` y `<slug>`, llamar `/git-branch issue <NNNN> <slug>`.
3. Si es quick: pedir `<slug>`, llamar `/git-branch quick <slug>`.
1. Preguntar al usuario: **¿Este cambio esta asociado a un issue existente?**
2. **Si es un issue**: pedir el numero y slug, crear rama `issue/<NNNN>-<slug>`.
3. **Si NO es un issue**: pedir un slug descriptivo, crear rama `quick/<slug>`.
**No inventar números de issue.** Solo usar `issue/` si existe en `dev/issues/`.
```bash
# Para issues:
git checkout -b issue/<NNNN>-<slug>
# Para cambios rapidos:
git checkout -b quick/<slug>
```
#### Si estamos en master sin cambios
4. Continuar al paso 2 con los cambios ya en la rama nueva.
**STOP**: nada que publicar.
**IMPORTANTE**: No inventar numeros de issue. Solo usar `issue/` si el issue existe en `dev/issues/`.
#### Si estamos en `master` sin cambios
**STOP**: no hay nada que publicar.
### 2. Revisar cambios y crear commits por bloque
### 2. Revisar cambios y crear commits atómicos
```bash
git status --short
@@ -46,112 +38,90 @@ git diff --stat
git diff
```
Crear commits **atomicos por bloque logico**. Cada commit agrupa cambios de la misma naturaleza:
Crear commits atómicos por bloque lógico. Cada commit agrupa cambios de la misma naturaleza:
```bash
git add <archivos_del_bloque_1>
git commit -m "<tipo>: <resumen breve>" -m "Descripcion larga en espanol explicando que cambia, por que se hizo, impacto esperado y alcance del bloque."
git commit -m "<tipo>: <resumen breve>" -m "Descripción larga en español: qué cambia, por qué, impacto, alcance."
git add <archivos_del_bloque_2>
git commit -m "<tipo>: <resumen breve>" -m "Descripcion larga en espanol."
git commit -m "<tipo>: <resumen breve>" -m "Descripción larga en español."
```
**Reglas criticas de commits:**
- **No WIP**: nunca commitear "wip", "tmp", "fix fix" ni codigo a medias. Cada commit debe ser atomico y completo.
- **No mezclar tipos**: no combinar `feat:` + `test:` en un mismo commit. Separar por bloque logico.
- **No squash**: los commits individuales se preservan en master via `--no-ff`. Usar `git log --first-parent master` para ver solo merge commits.
- **No rebase interactivo**: si los commits ya son limpios, no reescribir historia.
**Reglas críticas**:
- **No WIP**: nunca commitear "wip", "tmp", código a medias.
- **No mezclar tipos**: no combinar `feat:` + `test:` en un mismo commit.
- **No squash**: los commits individuales se preservan via `--no-ff`. Usar `git log --first-parent master` para ver merges.
- **No rebase interactivo**.
### 3. Ejecutar tests
**Obligatorio antes de mergear.** Si el proyecto tiene tests, ejecutarlos:
Obligatorio antes de mergear. Comando depende del stack:
```bash
go test -tags goolm ./...
```
| Stack | Comando |
|---|---|
| Go | `go test ./...` (o con tags si aplica: `-tags goolm` / `-tags fts5`) |
| C++ | `ctest --test-dir cpp/build` |
| Python | `pytest` |
| Sin tests aplicables (solo docs/config) | indicar al usuario y continuar |
- Si los tests **fallan****STOP**: corregir antes de continuar. No mergear codigo roto.
- Si los tests **pasan** → continuar al paso 4.
- Si no hay tests aplicables (e.g. solo cambios de docs/config) → indicar al usuario y continuar.
Si fallan → **STOP** y corregir. Si pasan → 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 codigo terminado y testeado, no codigo a medias.
Feature flag = código terminado y testeado, **no** código a medias.
Si se modifico `dev/feature_flags.json` o si los cambios son parte de una feature que se despliega en fases:
Si se modificó `dev/feature_flags.json` o el cambio es parte de feature multi-fase:
1. Verificar que `dev/feature_flags.json` esté actualizado.
2. Confirmar estado correcto del flag (`enabled: true/false`).
3. Incluir el archivo en el commit correspondiente (no commit separado).
1. Verificar que `dev/feature_flags.json` existe y esta 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 autocontenido, saltar.
Si el issue es autocontenido (se completa en esta rama), no necesita flag. Saltar este paso.
### 5. Actualizar master y hacer merge --no-ff
### 5. Cerrar la rama (registry)
```bash
git checkout master
git pull --rebase
git merge --no-ff <rama> -m "merge: <rama> — <titulo breve>"
source /home/lucas/fn_registry/bash/functions/infra/tbd_branch_finish.sh
tbd_branch_finish "<descripción corta del merge>"
```
El merge commit debe tener formato:
- Titulo: `merge: <rama> — <descripcion corta>`
- Cuerpo (opcional): resumen de lo que entra
La función:
- Verifica working tree limpio.
- Autodetecta `master`/`main`.
- `git checkout <base>` + `git pull --rebase`.
- `git merge --no-ff <rama> -m "merge: <rama> — <título>"`.
- Si conflicto → exit 2, deja al usuario resolver con `git add` + `git commit` + retry.
- `git push`.
- `git branch -d <rama>`.
Ejemplos:
- `merge: issue/0021-threads-default-config — habilitar threads en agentes`
- `merge: quick/fix-typo-readme — corregir typo en README`
### 6. Confirmar al usuario
Si hay conflictos durante el merge:
1. Resolver los conflictos
2. `git add` los archivos resueltos
3. `git commit` (sin -m, para mantener el mensaje de merge)
La función ya imprime `Rama '<rama>' integrada a <base> y publicada. Rama local eliminada.` Repetirlo al usuario.
### 6. Push a remoto
```bash
git push
```
### 7. Limpiar rama local
```bash
git branch -d <rama>
```
### 8. Confirmar al usuario
```
Rama `<rama>` integrada a master y publicada.
Rama local eliminada.
```
## Convencion de commits
## Convención de commits
- `feat:` nueva funcionalidad
- `fix:` correccion de error
- `fix:` corrección de error
- `refactor:` cambio estructural sin cambio funcional
- `docs:` documentacion
- `docs:` documentación
- `chore:` mantenimiento
- `test:` tests nuevos o modificados
- `merge:` commit de merge (generado por --no-ff)
- `merge:` commit de merge (lo genera `tbd_branch_finish` con `--no-ff`)
## Regla de mensajes
- El titulo (`-m` corto) debe resumir el bloque.
- El cuerpo (`-m` largo) debe estar en espanol y explicar:
- que se cambio,
- por que se cambio,
- que impacto tiene,
- que no se toco.
- Título corto resume el bloque.
- Cuerpo en español: qué se cambió, por qué, qué impacto, qué no se tocó.
## Checklist rapido
## Checklist
- [ ] Todos los cambios estan commiteados en una rama `issue/*` o `quick/*`.
- [ ] Se separaron cambios distintos en commits diferentes.
- [ ] Cada commit tiene descripcion larga en espanol.
- [ ] Tests ejecutados y pasando (o no aplican).
- [ ] Cambios commiteados en rama `issue/*` o `quick/*`.
- [ ] Cambios distintos en commits diferentes.
- [ ] Cada commit con descripción larga en español.
- [ ] Tests pasando (o no aplican).
- [ ] Feature flags evaluados (o no aplican).
- [ ] `git merge --no-ff` ejecutado desde master.
- [ ] `git push` ejecutado correctamente.
- [ ] Rama local eliminada.
- [ ] `tbd_branch_finish` ejecutado con éxito.
## Para tocar la lógica de cierre
Editar `tbd_branch_finish_bash_infra` en `bash/functions/infra/tbd_branch_finish.sh`. La parte de tests y commits se queda en este comando porque depende del stack.
+12 -3
View File
@@ -19,8 +19,17 @@
"padding": 1
},
"enabledPlugins": {
"gopls-lsp@claude-plugins-official": true
"gopls-lsp@claude-plugins-official": true,
"caveman@caveman": true
},
"skipDangerousModePermissionPrompt": true,
"effortLevel": "medium"
"extraKnownMarketplaces": {
"caveman": {
"source": {
"source": "github",
"repo": "JuliusBrussee/caveman"
}
}
},
"effortLevel": "high",
"skipDangerousModePermissionPrompt": true
}
+52 -33
View File
@@ -89,20 +89,27 @@ El prompt de cada agente debe incluir:
3. **Contenido completo del issue** (copiar el markdown entero)
4. **Instrucciones de ejecución** (ver template abajo)
#### Detección del build tag
#### Detección del stack y comandos build/test
Antes de lanzar los agentes, detectar el build tag del proyecto para los comandos `go build`/`go test`:
Antes de lanzar los agentes, detectar el stack del proyecto y los comandos correspondientes. La skill es **agnostica del lenguaje**: soporta Go, C++, Rust, Node, Python o cualquier otro stack via override.
```bash
# Heurísticas (en orden):
# 1. grep en go files por comentarios //go:build <tag>
# 2. Makefile con -tags <tag>
# 3. README con mención explícita
# Si no se encuentra ninguno, dejar la variable vacía (go build/test sin -tags)
BUILD_TAG=$(grep -rh "//go:build " --include="*.go" . 2>/dev/null | head -1 | sed -E 's|^.*//go:build ([^ ]+).*|\1|' || true)
```
**Resolucion de comandos** (en orden de prioridad):
Pasar `BUILD_TAG` al agente. Si está vacío, el agente usa `go build ./...` sin `-tags`.
1. **Override explicito** del usuario (env vars `BUILD_CMD` y `TEST_CMD` o argumentos al invocar la skill).
2. **Manifest opcional** `.parallel-fix-issues.yml` en la raiz del repo:
```yaml
build: "cmake -S cpp -B cpp/build && cmake --build cpp/build -j"
test: "ctest --test-dir cpp/build --output-on-failure"
```
3. **Auto-deteccion** segun ficheros raiz:
- `go.mod` → `go build [-tags X] ./...` + `go test [-tags X] ./...` (X auto-detectado de `//go:build`)
- `CMakeLists.txt` (raiz o `cpp/`) → `cmake -S <dir> -B <dir>/build -DCMAKE_BUILD_TYPE=Release && cmake --build <dir>/build -j` + `ctest --test-dir <dir>/build --output-on-failure || true`
- `Cargo.toml` → `cargo build` + `cargo test`
- `package.json` → `npm run build --if-present` + `npm test --if-present`
- `pyproject.toml` / `setup.py` → (sin build) + `pytest`
4. Si nada se detecta, **preguntar al usuario** que comandos usar antes de continuar.
**Mostrar al usuario los comandos resueltos** y pedir confirmacion antes de seguir. Pasar tanto `BUILD_CMD` como `TEST_CMD` (ya resueltos) al prompt de cada agente.
#### Template de prompt para cada agente
@@ -117,13 +124,19 @@ Usa SIEMPRE esta ruta como prefijo en paths absolutos.
Variable de conveniencia para comandos:
W=<RUTA_ABSOLUTA_DEL_WORKTREE>
## Build tag Go
## Comandos build/test del proyecto
BUILD_TAG=<VALOR_DETECTADO_O_VACIO> # ej: fts5, goolm, o vacío
BUILD_CMD=<COMANDO_RESUELTO> # ej: "cmake -S cpp -B cpp/build && cmake --build cpp/build -j"
TEST_CMD=<COMANDO_RESUELTO> # ej: "ctest --test-dir cpp/build --output-on-failure"
Úsalo solo si está definido:
GO_BUILD="go build ${BUILD_TAG:+-tags $BUILD_TAG} ./..."
GO_TEST="go test ${BUILD_TAG:+-tags $BUILD_TAG} ./..."
Estos comandos ya estan resueltos por el orquestador (auto-deteccion, override o manifest
.parallel-fix-issues.yml). Usalos tal cual desde la raiz del worktree:
Bash({ command: "cd $W && eval \"$BUILD_CMD\"", dangerouslyDisableSandbox: true })
Bash({ command: "cd $W && eval \"$TEST_CMD\"", dangerouslyDisableSandbox: true })
Si el issue requiere comandos adicionales (ej. `./fn index` tras añadir funciones, `npm install`,
`uv sync`), ejecutalos antes/despues segun corresponda.
## Permisos
@@ -144,18 +157,20 @@ 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
- Respetar las convenciones del proyecto (pure core / impure shell si aplica)
- Hacer commits atomicos por bloque logico
- Prefijos: feat:, fix:, test:, docs:, refactor:, chore:
- NO hacer commits WIP ni código a medias
- NO hacer commits WIP ni codigo a medias
- Compilar frecuentemente:
Bash({ command: "cd $W && $GO_BUILD", dangerouslyDisableSandbox: true })
Bash({ command: "cd $W && eval \"$BUILD_CMD\"", dangerouslyDisableSandbox: true })
3. **Tests obligatorios**:
- Escribir tests para todo código nuevo
3. **Tests obligatorios** (en el lenguaje/framework apropiado del stack):
- Escribir tests para todo codigo nuevo. Usar el framework convencional del lenguaje:
Go → testing pkg, C++ → ctest/Catch2/gtest, Rust → cargo test, Python → pytest, etc.
- Ejecutar:
Bash({ command: "cd $W && $GO_TEST", dangerouslyDisableSandbox: true })
Bash({ command: "cd $W && eval \"$TEST_CMD\"", dangerouslyDisableSandbox: true })
- NO continuar si los tests fallan
- Si el issue requiere paso de indexacion u otros (ej. `./fn index`, `npm install`), ejecutarlo aqui
4. **Cerrar el issue** — solo mover el archivo, NO tocar README:
- Bash({ command: "cd $W && git mv dev/issues/<NNNN>-<slug>.md dev/issues/completed/", dangerouslyDisableSandbox: true })
@@ -182,19 +197,22 @@ Después de cada wave, verificar TODOS los worktrees completados:
```
El script verifica:
- `go build ${BUILD_TAG:+-tags $BUILD_TAG} ./...` — compila sin errores
- `go test ${BUILD_TAG:+-tags $BUILD_TAG} ./...` — tests pasan
- `$BUILD_CMD` — compila sin errores (auto-detectado o pasado por env/arg)
- `$TEST_CMD` — tests pasan
- Issue movido a `dev/issues/completed/`
- Al menos 1 commit en la branch
El script acepta `BUILD_TAG` como variable de entorno (detectada en Fase 3) o como segundo argumento:
Pasar `BUILD_CMD` y `TEST_CMD` como variables de entorno o argumentos posicionales:
```bash
BUILD_TAG=fts5 .claude/skills/parallel-fix-issues/scripts/verify-worktree.sh worktrees/<slug>
# o
.claude/skills/parallel-fix-issues/scripts/verify-worktree.sh worktrees/<slug> fts5
BUILD_CMD="cmake --build cpp/build" TEST_CMD="ctest --test-dir cpp/build" \
.claude/skills/parallel-fix-issues/scripts/verify-worktree.sh worktrees/<slug>
# o posicionales
.claude/skills/parallel-fix-issues/scripts/verify-worktree.sh worktrees/<slug> "go build ./..." "go test ./..."
```
Si no se pasan, el script auto-detecta el stack (go.mod, CMakeLists.txt, Cargo.toml, package.json, pyproject.toml).
**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
@@ -213,13 +231,14 @@ El script hace para cada branch:
2. `git merge --no-ff issue/<slug>` con mensaje descriptivo
3. Si hay **merge conflict**: PARAR e informar al usuario
**Después de cada merge**, re-verificar que master compila:
**Despues de cada merge**, re-verificar que master compila usando los `BUILD_CMD`/`TEST_CMD` resueltos:
```bash
go build ${BUILD_TAG:+-tags $BUILD_TAG} ./... && go test ${BUILD_TAG:+-tags $BUILD_TAG} ./...
eval "$BUILD_CMD" && eval "$TEST_CMD"
```
Si falla después de un merge, PARAR e informar — no continuar con más merges.
`integrate-worktrees.sh` ya verifica el build post-merge si `BUILD_CMD` esta exportado.
Si falla despues de un merge, PARAR e informar — no continuar con mas merges.
### Fase 6: Actualizar README de issues
@@ -275,7 +294,7 @@ Ejecutar: git push
## Notas importantes
- **Build tag Go**: detectar del proyecto en Fase 3 (ver "Detección del build tag"). Si el proyecto no usa build tags, omitir `-tags` en todos los comandos
- **Stack agnostico**: la skill detecta el stack (Go, C++, Rust, Node, Python) en Fase 3. Si la auto-deteccion falla o el proyecto es exotico, el usuario puede pasar `BUILD_CMD`/`TEST_CMD` por env var o crear `.parallel-fix-issues.yml` en la raiz. Si el proyecto no tiene build/test, esos pasos se omiten con WARN
- **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
@@ -70,17 +70,21 @@ for slug in "$@"; do
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
# Verificar que master sigue compilando (si BUILD_CMD esta definido)
if [ -n "${BUILD_CMD:-}" ]; then
echo "--- Verificando build post-merge ($BUILD_CMD) ---"
if ! (cd "$REPO_ROOT" && bash -c "$BUILD_CMD" 2>&1); then
echo ""
echo "FAIL: master no compila despues 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"
else
echo "--- Build post-merge SKIPPED (BUILD_CMD no definido) ---"
fi
echo "OK: build post-merge exitoso"
MERGED=$((MERGED + 1))
done
@@ -1,42 +1,47 @@
#!/bin/bash
# verify-worktree.sh — Verifica build, tests y cierre de issue en un worktree
# verify-worktree.sh — Verifica build, tests y cierre de issue en un worktree.
#
# Uso:
# ./verify-worktree.sh <worktree-path> [build-cmd] [test-cmd]
#
# Uso: ./verify-worktree.sh <worktree-path> [build-tag]
# Ejemplos:
# ./verify-worktree.sh worktrees/0026-split-runtime fts5
# BUILD_TAG=goolm ./verify-worktree.sh worktrees/0026-split-runtime
# ./verify-worktree.sh worktrees/0026-split-runtime # sin -tags
# ./verify-worktree.sh worktrees/0026-foo
# ./verify-worktree.sh worktrees/0026-foo "go build -tags fts5 ./..." "go test -tags fts5 ./..."
# BUILD_CMD="cmake --build cpp/build" TEST_CMD="ctest --test-dir cpp/build" ./verify-worktree.sh worktrees/0026-foo
#
# El build tag se puede pasar como:
# - segundo argumento posicional
# - variable de entorno BUILD_TAG
# - auto-detección via //go:build en los .go del worktree
# - si sigue vacío, ejecuta sin -tags
# Resolucion de comandos (en orden de prioridad):
# 1. Argumentos posicionales (build-cmd, test-cmd)
# 2. Variables de entorno BUILD_CMD / TEST_CMD
# 3. Archivo .parallel-fix-issues.yml en la raiz del worktree (claves: build, test)
# 4. Auto-deteccion segun ficheros del proyecto:
# - go.mod → "go build ./..." + "go test ./..."
# - CMakeLists.txt → "cmake -S . -B build && cmake --build build" + "ctest --test-dir build"
# - Cargo.toml → "cargo build" + "cargo test"
# - package.json → "npm run build" + "npm test"
# - pyproject.toml → "" + "pytest"
# 5. Si nada se detecta, salta build/test con WARN.
#
# Checks:
# 1. El worktree existe y tiene commits propios
# 2. go build ${BUILD_TAG:+-tags $BUILD_TAG} ./... compila
# 3. go test ${BUILD_TAG:+-tags $BUILD_TAG} ./... pasa
# 4. El issue fue movido a completed/
# Auto-deteccion adicional: si hay go.mod, intenta extraer build tag de //go:build.
#
# Exit codes:
# 0 = todo OK
# 1 = error de argumento
# 2 = build falló
# 2 = build fallo
# 3 = tests fallaron
# 4 = issue no cerrado
# 4 = issue no cerrado (solo WARN, no falla)
# 5 = sin commits propios
set -euo pipefail
if [ $# -lt 1 ]; then
echo "ERROR: se necesita el path del worktree"
echo "Uso: $0 <worktree-path> [build-tag]"
echo "Uso: $0 <worktree-path> [build-cmd] [test-cmd]"
exit 1
fi
WORKTREE="$1"
BUILD_TAG="${2:-${BUILD_TAG:-}}"
ARG_BUILD_CMD="${2:-}"
ARG_TEST_CMD="${3:-}"
# Resolver path absoluto
if [[ "$WORKTREE" != /* ]]; then
@@ -52,26 +57,62 @@ fi
SLUG="$(basename "$WORKTREE")"
echo "=== Verificando: ${SLUG} ==="
# Auto-detectar build tag si no se pasó
if [ -z "$BUILD_TAG" ]; then
AUTO_TAG=$(grep -rh "^//go:build " --include="*.go" "$WORKTREE" 2>/dev/null \
| sed -E 's|^//go:build ([a-zA-Z0-9_]+).*|\1|' \
| sort -u \
| head -1 || true)
if [ -n "$AUTO_TAG" ]; then
BUILD_TAG="$AUTO_TAG"
echo "INFO: build tag auto-detectado: ${BUILD_TAG}"
else
echo "INFO: sin build tag (go build/test sin -tags)"
fi
# --- Resolver build/test commands ---
BUILD_CMD="${ARG_BUILD_CMD:-${BUILD_CMD:-}}"
TEST_CMD="${ARG_TEST_CMD:-${TEST_CMD:-}}"
# Manifest opcional
MANIFEST="${WORKTREE}/.parallel-fix-issues.yml"
if [ -z "$BUILD_CMD" ] && [ -f "$MANIFEST" ]; then
M_BUILD=$(grep -E "^build:" "$MANIFEST" 2>/dev/null | sed -E 's/^build:[[:space:]]*"?([^"]*)"?[[:space:]]*$/\1/' | head -1 || true)
if [ -n "$M_BUILD" ]; then BUILD_CMD="$M_BUILD"; echo "INFO: build desde manifest"; fi
fi
if [ -z "$TEST_CMD" ] && [ -f "$MANIFEST" ]; then
M_TEST=$(grep -E "^test:" "$MANIFEST" 2>/dev/null | sed -E 's/^test:[[:space:]]*"?([^"]*)"?[[:space:]]*$/\1/' | head -1 || true)
if [ -n "$M_TEST" ]; then TEST_CMD="$M_TEST"; echo "INFO: test desde manifest"; fi
fi
TAG_FLAG=""
if [ -n "$BUILD_TAG" ]; then
TAG_FLAG="-tags $BUILD_TAG"
# Auto-deteccion
if [ -z "$BUILD_CMD" ] || [ -z "$TEST_CMD" ]; then
AUTO_BUILD=""
AUTO_TEST=""
if [ -f "${WORKTREE}/go.mod" ]; then
# Detectar build tag
AUTO_TAG=$(grep -rh "^//go:build " --include="*.go" "$WORKTREE" 2>/dev/null \
| sed -E 's|^//go:build ([a-zA-Z0-9_]+).*|\1|' \
| sort -u | head -1 || true)
TAG_FLAG=""
[ -n "$AUTO_TAG" ] && TAG_FLAG="-tags $AUTO_TAG"
AUTO_BUILD="go build $TAG_FLAG ./..."
AUTO_TEST="go test $TAG_FLAG ./..."
echo "INFO: stack detectado: Go${TAG_FLAG:+ ($TAG_FLAG)}"
elif [ -f "${WORKTREE}/CMakeLists.txt" ] || ls "${WORKTREE}"/cpp/CMakeLists.txt >/dev/null 2>&1; then
CMAKE_DIR="."
[ -f "${WORKTREE}/cpp/CMakeLists.txt" ] && [ ! -f "${WORKTREE}/CMakeLists.txt" ] && CMAKE_DIR="cpp"
AUTO_BUILD="cmake -S ${CMAKE_DIR} -B ${CMAKE_DIR}/build -DCMAKE_BUILD_TYPE=Release && cmake --build ${CMAKE_DIR}/build -j"
AUTO_TEST="ctest --test-dir ${CMAKE_DIR}/build --output-on-failure || true"
echo "INFO: stack detectado: C++/CMake (dir=${CMAKE_DIR})"
elif [ -f "${WORKTREE}/Cargo.toml" ]; then
AUTO_BUILD="cargo build"
AUTO_TEST="cargo test"
echo "INFO: stack detectado: Rust"
elif [ -f "${WORKTREE}/package.json" ]; then
AUTO_BUILD="npm run build --if-present"
AUTO_TEST="npm test --if-present"
echo "INFO: stack detectado: Node"
elif [ -f "${WORKTREE}/pyproject.toml" ] || [ -f "${WORKTREE}/setup.py" ]; then
AUTO_BUILD="" # python normalmente no tiene build step
AUTO_TEST="pytest"
echo "INFO: stack detectado: Python"
else
echo "WARN: no se detecto stack; usar BUILD_CMD/TEST_CMD env o manifest .parallel-fix-issues.yml"
fi
[ -z "$BUILD_CMD" ] && BUILD_CMD="$AUTO_BUILD"
[ -z "$TEST_CMD" ] && TEST_CMD="$AUTO_TEST"
fi
# 1. Verificar commits propios
echo ""
echo "--- Commits propios ---"
COMMIT_COUNT=$(cd "$WORKTREE" && git log master..HEAD --oneline 2>/dev/null | wc -l)
if [ "$COMMIT_COUNT" -eq 0 ]; then
@@ -83,25 +124,33 @@ cd "$WORKTREE" && git log master..HEAD --oneline
# 2. Build
echo ""
echo "--- Build (go build $TAG_FLAG ./...) ---"
if (cd "$WORKTREE" && go build $TAG_FLAG ./... 2>&1); then
echo "OK: build exitoso"
if [ -n "$BUILD_CMD" ]; then
echo "--- Build ($BUILD_CMD) ---"
if (cd "$WORKTREE" && bash -c "$BUILD_CMD" 2>&1); then
echo "OK: build exitoso"
else
echo "FAIL: build fallo"
exit 2
fi
else
echo "FAIL: build falló"
exit 2
echo "--- Build SKIPPED (sin comando) ---"
fi
# 3. Tests
echo ""
echo "--- Tests (go test $TAG_FLAG ./...) ---"
if (cd "$WORKTREE" && go test $TAG_FLAG ./... 2>&1); then
echo "OK: tests pasaron"
if [ -n "$TEST_CMD" ]; then
echo "--- Tests ($TEST_CMD) ---"
if (cd "$WORKTREE" && bash -c "$TEST_CMD" 2>&1); then
echo "OK: tests pasaron"
else
echo "FAIL: tests fallaron"
exit 3
fi
else
echo "FAIL: tests fallaron"
exit 3
echo "--- Tests SKIPPED (sin comando) ---"
fi
# 4. Issue cerrado (movido a completed/)
# 4. Issue cerrado
echo ""
echo "--- Cierre de issue ---"
COMPLETED_FILES=$(cd "$WORKTREE" && git diff --name-only master -- dev/issues/completed/ 2>/dev/null | wc -l)
@@ -109,7 +158,7 @@ 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)"
echo "WARN: no se detecto issue movido a completed/ (verificar manualmente)"
fi
echo ""