Integracion con Herramientas de Calidad
Integracion con Herramientas de Calidad
Por que integrar
OpenSpec genera planes y la IA implementa codigo. Pero el codigo generado por IA necesita las mismas validaciones que el codigo humano. Husky, Biome y SonarQube son tus guardianes: atrapan problemas antes de que lleguen al repositorio.
La integracion funciona en dos niveles:
- En config.yaml: Para que los planes incluyan tareas de configuracion de herramientas
- En el proyecto: Para que el codigo generado por
/opsx:applypase las validaciones automaticamente
Husky + lint-staged
Setup
bun add -d husky lint-staged
bunx husky init
Configurar pre-commit
echo 'bunx lint-staged' > .husky/pre-commit
lint-staged en package.json
{
"lint-staged": {
"*.{ts,tsx,js,jsx}": [
"biome check --write",
"vitest related --run"
],
"*.{json,md,yaml}": [
"biome format --write"
]
}
}
Este hook hace que cada commit ejecute:
- Biome para formateo y linting
- Vitest en modo
related(solo tests afectados por los archivos cambiados)
Cuando /opsx:apply genera codigo y la IA intenta hacer commit, el hook se ejecuta automaticamente. Si el codigo no pasa Biome o los tests fallan, el commit se rechaza.
Reflejar en config.yaml
context: |
## CI local
- Pre-commit: Husky + lint-staged
- Al commitear se ejecuta: biome check + vitest related
- El codigo DEBE pasar biome y tests antes de commitear
- Si un test falla, corregir antes de continuar
Esto le dice a la IA que el codigo que genere sera validado por Husky. La IA ajustara su output para cumplir con Biome desde el inicio en vez de generar codigo que falle en el hook.
Biome
Setup
bun add -d @biomejs/biome
bunx biome init
Configuracion recomendada (biome.json)
{
"$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
"organizeImports": { "enabled": true },
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"security": {
"noDangerouslySetInnerHTML": "error",
"noGlobalEval": "error"
},
"suspicious": {
"noExplicitAny": "error",
"noConsoleLog": "warn"
},
"complexity": {
"noExcessiveCognitiveComplexity": {
"level": "error",
"options": { "maxAllowedComplexity": 15 }
}
}
}
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100
}
}
En config.yaml
context: |
## Linting
- Biome para formateo y lint (reemplaza ESLint + Prettier)
- Reglas activas: security, suspicious, complexity
- noExplicitAny: error (no usar any)
- Complejidad cognitiva maxima: 15
- Line width: 100 caracteres
rules:
tasks:
- Si el cambio introduce archivos nuevos, verificar que pasan biome check
- "No usar 'any' como tipo, definir tipos o interfaces explicitas"
Ahora la IA sabe que no debe generar any, debe mantener funciones simples y respetar el formato.
SonarQube
Contexto
SonarQube analiza el codigo en busca de bugs, vulnerabilidades, code smells y deuda tecnica. Normalmente corre en CI/CD, pero puedes correrlo localmente con SonarQube Community Edition o SonarCloud.
Setup con Docker (local)
docker run -d --name sonarqube \
-p 9000:9000 \
sonarqube:community
Scanner en el proyecto
bun add -d sonarqube-scanner
{
"scripts": {
"sonar": "sonar-scanner"
}
}
sonar-project.properties
sonar.projectKey=mi-proyecto
sonar.sources=src
sonar.tests=src
sonar.test.inclusions=**/*.test.ts,**/*.spec.ts
sonar.typescript.lcov.reportPaths=coverage/lcov.info
sonar.qualitygate.wait=true
Quality Gate personalizado
En SonarQube, crea un Quality Gate con estas condiciones:
| Metrica | Condicion | Valor |
|---|---|---|
| Coverage | >= | 80% |
| Duplicated Lines | <= | 3% |
| Bugs | = | 0 |
| Vulnerabilities | = | 0 |
| Security Hotspots Reviewed | = | 100% |
| Maintainability Rating | <= | A |
En config.yaml
context: |
## Analisis estatico
- SonarQube para analisis de codigo (bugs, vulnerabilidades, code smells)
- Quality Gate: 80% coverage, 0 bugs, 0 vulnerabilities, rating A
- El codigo debe pasar el Quality Gate antes de merge
rules:
design:
- No hardcodear credenciales o secretos
- No usar algoritmos criptograficos debiles
- No dejar recursos abiertos (conexiones, streams)
tasks:
- Si el cambio es significativo, incluir tarea de ejecutar analisis SonarQube
- Resolver findings criticos antes de merge
Pipeline CI/CD completo
La integracion mas potente es combinar todo en un pipeline que corra automaticamente:
GitLab CI
stages:
- quality
- test
- analyze
lint:
stage: quality
image: node:20-alpine
script:
- bun install
- bunx biome check src/
test:
stage: test
image: node:20-alpine
script:
- bun install
- bun run test:coverage
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
sonar:
stage: analyze
image: sonarsource/sonar-scanner-cli:latest
script:
- sonar-scanner
needs: [test]
GitHub Actions
name: Quality
on: [push, pull_request]
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install
- run: bunx biome check src/
- run: bun run test:coverage
- uses: SonarSource/sonarqube-scan-action@v5
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
Reflejar en config.yaml
context: |
## CI/CD
- Pipeline: lint → test → sonar
- Todo PR debe pasar: Biome lint, tests con coverage > 80%, SonarQube Quality Gate
- No se puede mergear con tests fallando o coverage bajo
Patron: Validar specs contra tests
Una tecnica avanzada es usar los escenarios Gherkin de las delta specs como base para los tests:
## User Registration [ADDED]
### REQ-001: Valid registration
GIVEN a valid email and password >= 8 characters
WHEN the user submits the registration form
THEN the system creates an account and returns a JWT
### REQ-002: Duplicate email
GIVEN an email that already exists in the system
WHEN the user submits the registration form
THEN the system returns 409 Conflict
Estos escenarios se traducen directamente a tests:
describe("UserRegistration", () => {
it("should create account and return JWT with valid data", async () => {
// REQ-001
});
it("should return 409 when email already exists", async () => {
// REQ-002
});
});
Para que la IA haga esto automaticamente, agrega en rules:
rules:
tasks:
- Para cada escenario Gherkin en las delta specs, generar una tarea de test que lo implemente
- Referenciar el REQ-ID en el nombre del test
Patron: pre-commit como safety net del apply
Cuando /opsx:apply genera codigo, Claude Code puede intentar correr los tests o hacer commit. Con Husky configurado, el flujo se convierte en:
/opsx:apply
→ IA genera codigo
→ IA corre tests (si task lo pide)
→ IA hace commit
→ Husky intercepta:
→ Biome check: formatea y valida
→ Vitest related: corre tests afectados
→ Si falla: IA recibe el error y corrige
→ Si pasa: commit exitoso
El pre-commit hook actua como safety net automatica. Incluso si la IA olvida correr tests, el hook los ejecuta.
Importante: Para que esto funcione, Claude Code debe tener permiso de ejecutar commits. Revisa tus permisos en la configuracion de Claude Code.
Checklist de integracion
-
config.yamlcon context que describe stack, testing y seguridad -
config.yamlcon rules que fuerzan tests y seguridad en artefactos -
CLAUDE.mdcon prioridades y convenciones de codigo - Husky + lint-staged con Biome y Vitest
- Biome configurado con reglas de seguridad
- SonarQube Quality Gate configurado (80% coverage, 0 vulns)
- Pipeline CI/CD que ejecuta lint, test y analisis
Resumen
- Husky + lint-staged actuan como safety net: validan cada commit automaticamente
- Biome reemplaza ESLint + Prettier con reglas de seguridad y complejidad
- SonarQube analiza bugs, vulnerabilidades y deuda tecnica en CI
- config.yaml es la clave:
contextyrulesaseguran que los planes incluyan tests y seguridad - Los escenarios Gherkin de las specs se traducen directamente a tests
- El pre-commit hook atrapa problemas incluso si la IA los ignora
← Capitulo 12: Personalizacion Avanzada | Capitulo 14: Flujos y Patrones de Trabajo →