@saulwade/swl-ses 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +238 -0
- package/README.md +560 -0
- package/_userland/agentes/.gitkeep +0 -0
- package/_userland/habilidades/.gitkeep +0 -0
- package/agentes/.evolved.json +9 -0
- package/agentes/accesibilidad-wcag-swl.md +692 -0
- package/agentes/arquitecto-swl.md +238 -0
- package/agentes/auto-evolucion-swl.md +854 -0
- package/agentes/backend-api-swl.md +470 -0
- package/agentes/backend-csharp-swl.md +418 -0
- package/agentes/backend-go-swl.md +388 -0
- package/agentes/backend-java-swl.md +279 -0
- package/agentes/backend-node-swl.md +477 -0
- package/agentes/backend-python-swl.md +608 -0
- package/agentes/backend-rust-swl.md +362 -0
- package/agentes/backend-workers-swl.md +480 -0
- package/agentes/cloud-infra-swl.md +485 -0
- package/agentes/consolidador-swl.md +539 -0
- package/agentes/datos-swl.md +584 -0
- package/agentes/depurador-swl.md +349 -0
- package/agentes/devops-ci-swl.md +374 -0
- package/agentes/disenador-ui-swl.md +558 -0
- package/agentes/documentador-swl.md +343 -0
- package/agentes/evals/arquitecto-swl.evals.json +56 -0
- package/agentes/evals/auto-evolucion-swl.evals.json +68 -0
- package/agentes/evals/implementador-swl.evals.json +56 -0
- package/agentes/evals/orquestador-swl.evals.json +60 -0
- package/agentes/evals/perfilador-usuario-swl.evals.json +60 -0
- package/agentes/evals/red-team-swl.evals.json +59 -0
- package/agentes/evals/revisor-codigo-swl.evals.json +59 -0
- package/agentes/frontend-angular-swl.md +627 -0
- package/agentes/frontend-css-swl.md +720 -0
- package/agentes/frontend-react-swl.md +696 -0
- package/agentes/frontend-swl.md +500 -0
- package/agentes/frontend-tailwind-swl.md +830 -0
- package/agentes/implementador-swl.md +328 -0
- package/agentes/investigador-swl.md +430 -0
- package/agentes/investigador-ux-swl.md +500 -0
- package/agentes/llm-apps-swl.md +276 -0
- package/agentes/migrador-swl.md +417 -0
- package/agentes/mobile-android-swl.md +509 -0
- package/agentes/mobile-cross-swl.md +539 -0
- package/agentes/mobile-ios-swl.md +500 -0
- package/agentes/mobile-testing-swl.md +300 -0
- package/agentes/notificador-swl.md +916 -0
- package/agentes/observabilidad-swl.md +436 -0
- package/agentes/orquestador-swl.md +884 -0
- package/agentes/pagos-swl.md +283 -0
- package/agentes/perfilador-usuario-swl.md +306 -0
- package/agentes/planificador-swl.md +402 -0
- package/agentes/producto-prd-swl.md +587 -0
- package/agentes/red-team-swl.md +216 -0
- package/agentes/release-manager-swl.md +568 -0
- package/agentes/rendimiento-swl.md +714 -0
- package/agentes/resolutor-build-swl.md +243 -0
- package/agentes/revisor-angular-swl.md +276 -0
- package/agentes/revisor-codigo-swl.md +348 -0
- package/agentes/revisor-csharp-swl.md +262 -0
- package/agentes/revisor-go-swl.md +257 -0
- package/agentes/revisor-java-swl.md +255 -0
- package/agentes/revisor-kotlin-swl.md +271 -0
- package/agentes/revisor-nextjs-swl.md +279 -0
- package/agentes/revisor-php-swl.md +269 -0
- package/agentes/revisor-react-swl.md +276 -0
- package/agentes/revisor-rust-swl.md +344 -0
- package/agentes/revisor-seguridad-swl.md +390 -0
- package/agentes/revisor-swift-swl.md +266 -0
- package/agentes/revisor-typescript-swl.md +344 -0
- package/agentes/sre-swl.md +265 -0
- package/agentes/tdd-qa-swl.md +354 -0
- package/agentes/ux-disenador-swl.md +501 -0
- package/bin/lib/bot-comandos.js +1030 -0
- package/bin/lib/bot-discovery.js +182 -0
- package/bin/lib/bot-git.js +142 -0
- package/bin/swl-ses.js +325 -0
- package/bin/swl-telegram-bot.js +442 -0
- package/bin/swl-telegram-bot.plist +21 -0
- package/bin/swl-telegram-bot.service +14 -0
- package/comandos/swl/.evolved.json +23 -0
- package/comandos/swl/actualizar.md +174 -0
- package/comandos/swl/adoptar-proyecto.md +207 -0
- package/comandos/swl/aprender.md +701 -0
- package/comandos/swl/auditar-deps.md +134 -0
- package/comandos/swl/autoresearch.md +170 -0
- package/comandos/swl/ayuda.md +224 -0
- package/comandos/swl/brainstorm.md +50 -0
- package/comandos/swl/checkpoint.md +330 -0
- package/comandos/swl/compactar.md +283 -0
- package/comandos/swl/configurar-ci.md +227 -0
- package/comandos/swl/contexto.md +112 -0
- package/comandos/swl/contribuir.md +233 -0
- package/comandos/swl/crear-skill.md +292 -0
- package/comandos/swl/cron.md +196 -0
- package/comandos/swl/dashboard.md +146 -0
- package/comandos/swl/discutir-fase.md +230 -0
- package/comandos/swl/ejecutar-fase.md +135 -0
- package/comandos/swl/evaluar-skill.md +487 -0
- package/comandos/swl/evolucion-estado.md +142 -0
- package/comandos/swl/evolucionar.md +259 -0
- package/comandos/swl/exportar-vault.md +189 -0
- package/comandos/swl/gateway.md +158 -0
- package/comandos/swl/inbox.md +116 -0
- package/comandos/swl/instalar.md +220 -0
- package/comandos/swl/instintos.md +86 -0
- package/comandos/swl/mapear-codebase.md +312 -0
- package/comandos/swl/mcp-status.md +175 -0
- package/comandos/swl/metricas.md +270 -0
- package/comandos/swl/modelo.md +102 -0
- package/comandos/swl/notificaciones.md +396 -0
- package/comandos/swl/nuevo-proyecto.md +154 -0
- package/comandos/swl/planear-fase.md +221 -0
- package/comandos/swl/plugins.md +256 -0
- package/comandos/swl/reflect-skills.md +125 -0
- package/comandos/swl/release.md +217 -0
- package/comandos/swl/revisar-impacto.md +206 -0
- package/comandos/swl/revisar.md +330 -0
- package/comandos/swl/salud.md +363 -0
- package/comandos/swl/sesiones.md +200 -0
- package/comandos/swl/skill-search.md +113 -0
- package/comandos/swl/verificar.md +585 -0
- package/comandos/swl/wiki.md +620 -0
- package/contextos/dev.md +32 -0
- package/contextos/research.md +30 -0
- package/contextos/review.md +31 -0
- package/habilidades/accesibilidad-a11y/SKILL.md +201 -0
- package/habilidades/accesibilidad-a11y/evals/evals.json +56 -0
- package/habilidades/accesibilidad-a11y/recursos/ejemplos-y-checklist-completo.md +441 -0
- package/habilidades/agent-browser/SKILL.md +218 -0
- package/habilidades/agentes-como-servicio/SKILL.md +218 -0
- package/habilidades/ai-runtime-security/SKILL.md +273 -0
- package/habilidades/angular-avanzado/SKILL.md +164 -0
- package/habilidades/angular-avanzado/recursos/ejemplos-avanzados.md +219 -0
- package/habilidades/angular-moderno/SKILL.md +186 -0
- package/habilidades/angular-moderno/evals/evals.json +45 -0
- package/habilidades/angular-moderno/recursos/ejemplos-avanzados.md +106 -0
- package/habilidades/api-rest-diseno/SKILL.md +191 -0
- package/habilidades/api-rest-diseno/recursos/openapi-template.yaml +506 -0
- package/habilidades/api-rest-diseno/recursos/referencia-api.md +140 -0
- package/habilidades/aprendizaje-continuo/SKILL.md +151 -0
- package/habilidades/aprendizaje-continuo/evals/evals.json +53 -0
- package/habilidades/aprendizaje-continuo/recursos/referencia-instintos.md +290 -0
- package/habilidades/async-python/SKILL.md +149 -0
- package/habilidades/async-python/evals/evals.json +47 -0
- package/habilidades/async-python/recursos/patrones-y-ejemplos-completos.md +292 -0
- package/habilidades/auth-patrones/.evolved.json +9 -0
- package/habilidades/auth-patrones/SKILL.md +413 -0
- package/habilidades/auth-patrones/recursos/implementaciones-completas.md +229 -0
- package/habilidades/auto-evolucion-protocolo/SKILL.md +276 -0
- package/habilidades/auto-evolucion-protocolo/evals/evals.json +55 -0
- package/habilidades/auto-evolucion-protocolo/recursos/referencia-completa.md +145 -0
- package/habilidades/autoresearch/SKILL.md +268 -0
- package/habilidades/autoresearch/evals/evals.json +41 -0
- package/habilidades/autoresearch/recursos/checklist-template.md +191 -0
- package/habilidades/autoresearch/scripts/calcular-score.js +88 -0
- package/habilidades/azure-cloud/SKILL.md +308 -0
- package/habilidades/azure-cloud/recursos/aks.md +327 -0
- package/habilidades/backend-mcp-servidor/SKILL.md +270 -0
- package/habilidades/backend-production-resilience/SKILL.md +288 -0
- package/habilidades/brainstorming/SKILL.md +295 -0
- package/habilidades/brainstorming/recursos/componentes-html.md +247 -0
- package/habilidades/build-errors-cpp/SKILL.md +270 -0
- package/habilidades/build-errors-csharp/SKILL.md +265 -0
- package/habilidades/build-errors-go/SKILL.md +306 -0
- package/habilidades/build-errors-java/SKILL.md +278 -0
- package/habilidades/build-errors-kotlin/SKILL.md +303 -0
- package/habilidades/build-errors-nextjs/SKILL.md +312 -0
- package/habilidades/build-errors-php/SKILL.md +270 -0
- package/habilidades/build-errors-python/SKILL.md +292 -0
- package/habilidades/build-errors-rust/SKILL.md +284 -0
- package/habilidades/build-errors-swift/SKILL.md +272 -0
- package/habilidades/build-errors-typescript/SKILL.md +369 -0
- package/habilidades/checklist-calidad/SKILL.md +271 -0
- package/habilidades/checklist-calidad/recursos/quality-report-template.md +148 -0
- package/habilidades/checklist-seguridad/SKILL.md +285 -0
- package/habilidades/checkpoints-verificacion/SKILL.md +298 -0
- package/habilidades/checkpoints-verificacion/recursos/checkpoint-templates.md +360 -0
- package/habilidades/ci-cd-pipelines/SKILL.md +157 -0
- package/habilidades/ci-cd-pipelines/recursos/github-actions-template.yaml +403 -0
- package/habilidades/ci-cd-pipelines/recursos/pipelines-completos.md +487 -0
- package/habilidades/cloud-aws/SKILL.md +142 -0
- package/habilidades/cloud-aws/recursos/servicios-aws-referencia.md +321 -0
- package/habilidades/compactacion-contexto/SKILL.md +247 -0
- package/habilidades/contenedores-docker/SKILL.md +137 -0
- package/habilidades/contenedores-docker/recursos/dockerfile-template.dockerfile +160 -0
- package/habilidades/contenedores-docker/recursos/ejemplos-y-configuraciones.md +327 -0
- package/habilidades/context-builder/SKILL.md +170 -0
- package/habilidades/control-profundidad/SKILL.md +128 -0
- package/habilidades/csharp-experto/SKILL.md +322 -0
- package/habilidades/csharp-patrones/SKILL.md +316 -0
- package/habilidades/csharp-testing/SKILL.md +286 -0
- package/habilidades/css-moderno/SKILL.md +166 -0
- package/habilidades/css-moderno/evals/evals.json +43 -0
- package/habilidades/css-moderno/recursos/ejemplos-y-patrones-completos.md +337 -0
- package/habilidades/datos-etl/SKILL.md +129 -0
- package/habilidades/datos-etl/recursos/implementaciones-completas.md +322 -0
- package/habilidades/dbml-experto/SKILL.md +339 -0
- package/habilidades/dbml-experto/evals/evals.json +56 -0
- package/habilidades/dependencias-auditoria/SKILL.md +320 -0
- package/habilidades/deprecacion-migracion/SKILL.md +169 -0
- package/habilidades/deprecacion-migracion/recursos/implementaciones-completas.md +220 -0
- package/habilidades/design-tokens/SKILL.md +158 -0
- package/habilidades/design-tokens/recursos/tokens-y-configuracion.md +363 -0
- package/habilidades/devsecops-pipeline-security/SKILL.md +309 -0
- package/habilidades/diagrama-arquitectura/SKILL.md +165 -0
- package/habilidades/diagrama-arquitectura/assets/template.html +276 -0
- package/habilidades/discutir-fase/SKILL.md +188 -0
- package/habilidades/diseno-herramientas-agente/SKILL.md +199 -0
- package/habilidades/diseno-responsivo/SKILL.md +186 -0
- package/habilidades/diseno-responsivo/recursos/ejemplos-layouts.md +156 -0
- package/habilidades/django-experto/SKILL.md +205 -0
- package/habilidades/django-experto/recursos/async-django.md +390 -0
- package/habilidades/django-experto/recursos/drf-patrones.md +438 -0
- package/habilidades/django-experto/recursos/orm-avanzado.md +382 -0
- package/habilidades/django-experto/recursos/referencia-completa.md +188 -0
- package/habilidades/django-experto/recursos/testing-django.md +415 -0
- package/habilidades/doc-sync/SKILL.md +280 -0
- package/habilidades/drift-detection/SKILL.md +179 -0
- package/habilidades/ejecutar-fase/SKILL.md +468 -0
- package/habilidades/estilo-sin-ai-isms/SKILL.md +775 -0
- package/habilidades/estilo-sin-ai-isms/evals/evals.json +63 -0
- package/habilidades/estilo-sin-ai-isms/scripts/detectar_aiisms.py +500 -0
- package/habilidades/estructura-proyecto-claude/SKILL.md +215 -0
- package/habilidades/estructura-proyecto-claude/recursos/claude-md-template.md +261 -0
- package/habilidades/estructura-proyecto-claude/recursos/configuracion-y-extensiones.md +176 -0
- package/habilidades/estructura-proyecto-claude/recursos/frontmatter-y-hooks-referencia.md +289 -0
- package/habilidades/estructura-proyecto-claude/recursos/mcp-json-template.json +77 -0
- package/habilidades/estructura-proyecto-claude/recursos/variantes-por-stack.md +177 -0
- package/habilidades/evaluacion-agentes/SKILL.md +314 -0
- package/habilidades/event-driven/SKILL.md +153 -0
- package/habilidades/event-driven/recursos/implementaciones-completas.md +423 -0
- package/habilidades/extraccion-documentos/SKILL.md +221 -0
- package/habilidades/extractor-de-aprendizajes/.evolved.json +9 -0
- package/habilidades/extractor-de-aprendizajes/SKILL.md +311 -0
- package/habilidades/extractor-de-aprendizajes/evals/evals.json +55 -0
- package/habilidades/fastapi-experto/SKILL.md +221 -0
- package/habilidades/fastapi-experto/recursos/async-patterns.md +438 -0
- package/habilidades/fastapi-experto/recursos/dependency-injection.md +330 -0
- package/habilidades/fastapi-experto/recursos/referencia-completa.md +79 -0
- package/habilidades/fastapi-experto/recursos/testing-httpx.md +420 -0
- package/habilidades/filament-admin/SKILL.md +290 -0
- package/habilidades/frontend-avanzado/SKILL.md +257 -0
- package/habilidades/frontend-avanzado/recursos/apis-nativas-ejemplos.md +341 -0
- package/habilidades/gcp-cloud/SKILL.md +260 -0
- package/habilidades/gcp-cloud/recursos/gke.md +234 -0
- package/habilidades/gcp-cloud/recursos/terraform-gcp.md +307 -0
- package/habilidades/generacion-mermaid/SKILL.md +229 -0
- package/habilidades/git-worktrees-paralelo/SKILL.md +270 -0
- package/habilidades/go-experto/SKILL.md +305 -0
- package/habilidades/go-patrones/SKILL.md +299 -0
- package/habilidades/go-testing/SKILL.md +291 -0
- package/habilidades/graphql-experto/SKILL.md +323 -0
- package/habilidades/guardrail-semantico/SKILL.md +282 -0
- package/habilidades/harness-claude-code/SKILL.md +299 -0
- package/habilidades/iam-secretos/SKILL.md +265 -0
- package/habilidades/iam-secretos/recursos/implementaciones-completas.md +356 -0
- package/habilidades/infra-github-actions/SKILL.md +166 -0
- package/habilidades/instalar-sistema/.evolved.json +9 -0
- package/habilidades/instalar-sistema/SKILL.md +221 -0
- package/habilidades/java-experto/SKILL.md +290 -0
- package/habilidades/java-patrones/SKILL.md +275 -0
- package/habilidades/java-testing/SKILL.md +288 -0
- package/habilidades/kotlin-compose/SKILL.md +278 -0
- package/habilidades/kotlin-compose/recursos/animaciones-performance.md +93 -0
- package/habilidades/kotlin-experto/SKILL.md +318 -0
- package/habilidades/kotlin-testing/SKILL.md +267 -0
- package/habilidades/kotlin-testing/recursos/testing-avanzado.md +74 -0
- package/habilidades/kubernetes-orquestacion/SKILL.md +152 -0
- package/habilidades/kubernetes-orquestacion/recursos/manifiestos-completos.md +452 -0
- package/habilidades/langchain-langraph/SKILL.md +386 -0
- package/habilidades/langchain-langraph/recursos/evaluacion-rag.md +321 -0
- package/habilidades/langchain-langraph/recursos/rag-maturity-model.md +225 -0
- package/habilidades/langchain-langraph/recursos/vectorstores.md +306 -0
- package/habilidades/legacy-code-rescue/SKILL.md +267 -0
- package/habilidades/likec4-experto/SKILL.md +412 -0
- package/habilidades/likec4-experto/evals/evals.json +69 -0
- package/habilidades/manejo-errores/.evolved.json +9 -0
- package/habilidades/manejo-errores/SKILL.md +407 -0
- package/habilidades/manejo-errores/recursos/implementaciones-completas.md +248 -0
- package/habilidades/mapear-codebase/SKILL.md +275 -0
- package/habilidades/memoria-busqueda/SKILL.md +194 -0
- package/habilidades/memoria-busqueda/evals/evals.json +44 -0
- package/habilidades/meta-skills-estandar/SKILL.md +298 -0
- package/habilidades/meta-skills-estandar/recursos/anti-patrones-y-leyes.md +205 -0
- package/habilidades/meta-skills-estandar/recursos/frameworks-seguridad.md +107 -0
- package/habilidades/meta-skills-estandar/recursos/idiomas-framework.md +60 -0
- package/habilidades/meta-skills-estandar/recursos/skills-as-agents.md +163 -0
- package/habilidades/microservicios/SKILL.md +155 -0
- package/habilidades/microservicios/recursos/patrones-y-ejemplos-completos.md +325 -0
- package/habilidades/mobile-flutter/SKILL.md +199 -0
- package/habilidades/mobile-flutter/recursos/ejemplos-completos.md +319 -0
- package/habilidades/mobile-react-native/SKILL.md +176 -0
- package/habilidades/mobile-react-native/recursos/ejemplos-completos.md +216 -0
- package/habilidades/mongodb-experto/SKILL.md +302 -0
- package/habilidades/monitoring-alertas/SKILL.md +201 -0
- package/habilidades/monitoring-alertas/recursos/instrumentacion-y-alertas.md +301 -0
- package/habilidades/nestjs-experto/SKILL.md +307 -0
- package/habilidades/nestjs-experto/recursos/guards-interceptors.md +339 -0
- package/habilidades/nestjs-experto/recursos/modulos-di.md +287 -0
- package/habilidades/nestjs-experto/recursos/testing-nestjs.md +354 -0
- package/habilidades/nextjs-experto/SKILL.md +335 -0
- package/habilidades/nextjs-patrones/SKILL.md +303 -0
- package/habilidades/nextjs-testing/SKILL.md +331 -0
- package/habilidades/node-experto/.evolved.json +9 -0
- package/habilidades/node-experto/SKILL.md +266 -0
- package/habilidades/node-experto/recursos/patrones-completos.md +283 -0
- package/habilidades/notificaciones-multicanal/SKILL.md +159 -0
- package/habilidades/notificaciones-multicanal/recursos/config-template.json +115 -0
- package/habilidades/notificaciones-multicanal/recursos/configuracion-y-templates.md +303 -0
- package/habilidades/nuevo-proyecto/SKILL.md +204 -0
- package/habilidades/orquestacion-async/SKILL.md +303 -0
- package/habilidades/paid-media-tracking/SKILL.md +269 -0
- package/habilidades/paid-media-tracking/recursos/auditoria-tracking.md +220 -0
- package/habilidades/paid-media-tracking/recursos/google-ads-api.md +215 -0
- package/habilidades/patrones-python/SKILL.md +228 -0
- package/habilidades/patrones-python/evals/evals.json +56 -0
- package/habilidades/patrones-python/recursos/patrones-avanzados.md +469 -0
- package/habilidades/patrones-python/recursos/referencia-completa.md +202 -0
- package/habilidades/perfil-usuario/SKILL.md +200 -0
- package/habilidades/perfil-usuario/evals/evals.json +55 -0
- package/habilidades/performance-baseline/SKILL.md +297 -0
- package/habilidades/php-experto/SKILL.md +291 -0
- package/habilidades/php-patrones/SKILL.md +306 -0
- package/habilidades/php-testing/SKILL.md +280 -0
- package/habilidades/planear-fase/SKILL.md +269 -0
- package/habilidades/postgresql-experto/SKILL.md +151 -0
- package/habilidades/postgresql-experto/evals/evals.json +53 -0
- package/habilidades/postgresql-experto/recursos/referencia-completa.md +215 -0
- package/habilidades/prevencion-racionalizacion/SKILL.md +175 -0
- package/habilidades/prevencion-sobreingenieria/SKILL.md +323 -0
- package/habilidades/privacy-memoria/SKILL.md +141 -0
- package/habilidades/privacy-memoria/evals/evals.json +43 -0
- package/habilidades/prompt-engineering/SKILL.md +518 -0
- package/habilidades/prompt-engineering/recursos/patrones-avanzados.md +467 -0
- package/habilidades/rag-arquitectura/SKILL.md +338 -0
- package/habilidades/rails-experto/SKILL.md +237 -0
- package/habilidades/rails-experto/recursos/active-record.md +260 -0
- package/habilidades/rails-experto/recursos/hotwire-turbo.md +293 -0
- package/habilidades/rails-experto/recursos/testing-rspec.md +362 -0
- package/habilidades/react-experto/SKILL.md +209 -0
- package/habilidades/react-experto/evals/evals.json +55 -0
- package/habilidades/react-experto/recursos/patrones-y-ejemplos-completos.md +240 -0
- package/habilidades/react-optimizacion/SKILL.md +174 -0
- package/habilidades/react-optimizacion/recursos/patrones-avanzados.md +138 -0
- package/habilidades/redis-experto/SKILL.md +305 -0
- package/habilidades/release-semver/.evolved.json +9 -0
- package/habilidades/release-semver/SKILL.md +248 -0
- package/habilidades/release-semver/scripts/generar-changelog.sh +238 -0
- package/habilidades/rust-experto/SKILL.md +400 -0
- package/habilidades/rust-patrones/SKILL.md +296 -0
- package/habilidades/rust-testing/SKILL.md +311 -0
- package/habilidades/seguridad-skills-ia/SKILL.md +262 -0
- package/habilidades/sql-optimizacion/SKILL.md +200 -0
- package/habilidades/sql-optimizacion/evals/evals.json +54 -0
- package/habilidades/sql-optimizacion/recursos/patrones-sql-avanzados.md +131 -0
- package/habilidades/sre-patrones/SKILL.md +333 -0
- package/habilidades/sre-patrones/recursos/chaos-engineering.md +241 -0
- package/habilidades/sre-patrones/recursos/oncall-design.md +236 -0
- package/habilidades/stripe-pagos/SKILL.md +550 -0
- package/habilidades/stripe-pagos/recursos/errores-reintentos.md +390 -0
- package/habilidades/stripe-pagos/recursos/stripe-connect.md +290 -0
- package/habilidades/structured-outputs/SKILL.md +343 -0
- package/habilidades/swift-experto/SKILL.md +320 -0
- package/habilidades/swift-experto/recursos/keychain-y-wrappers.md +110 -0
- package/habilidades/swift-patrones/SKILL.md +313 -0
- package/habilidades/swift-patrones/recursos/tca-ejemplo-completo.md +113 -0
- package/habilidades/swift-testing/SKILL.md +254 -0
- package/habilidades/swift-testing/recursos/xcuitest-planes.md +143 -0
- package/habilidades/swl-dashboard/SKILL.md +370 -0
- package/habilidades/swl-markitdown/SKILL.md +285 -0
- package/habilidades/swl-markitdown/evals/evals.json +52 -0
- package/habilidades/swl-revisar-impacto/SKILL.md +233 -0
- package/habilidades/tailwind-experto/SKILL.md +240 -0
- package/habilidades/tailwind-experto/recursos/referencia-completa.md +184 -0
- package/habilidades/tdd-workflow/SKILL.md +293 -0
- package/habilidades/terraform-experto/SKILL.md +321 -0
- package/habilidades/testing-python/SKILL.md +340 -0
- package/habilidades/testing-python/recursos/ejemplos-completos.md +167 -0
- package/habilidades/threat-model-lite/SKILL.md +246 -0
- package/habilidades/tracing-processor/SKILL.md +212 -0
- package/habilidades/tracking-measurement/SKILL.md +239 -0
- package/habilidades/tracking-measurement/recursos/consent-mode.md +231 -0
- package/habilidades/tracking-measurement/recursos/gtm-datalayer.md +216 -0
- package/habilidades/tracking-measurement/recursos/meta-capi.md +262 -0
- package/habilidades/typescript-avanzado/SKILL.md +144 -0
- package/habilidades/typescript-avanzado/evals/evals.json +55 -0
- package/habilidades/typescript-avanzado/recursos/patrones-y-ejemplos-completos.md +298 -0
- package/habilidades/typescript-diagnosticos/SKILL.md +513 -0
- package/habilidades/ux-diseno/SKILL.md +116 -0
- package/habilidades/ux-diseno/evals/evals.json +43 -0
- package/habilidades/ux-diseno/recursos/patrones-ux-referencia.md +214 -0
- package/habilidades/validacion-ci-sistema/SKILL.md +136 -0
- package/habilidades/validacion-ci-sistema/recursos/validadores-completos.md +369 -0
- package/habilidades/validacion-ci-sistema/scripts/validar-sistema.sh +286 -0
- package/habilidades/verificacion-evidencia/SKILL.md +160 -0
- package/habilidades/verificar-trabajo/SKILL.md +303 -0
- package/habilidades/verificar-trabajo/recursos/plantilla-verificacion.md +60 -0
- package/habilidades/wiki-conocimiento/SKILL.md +276 -0
- package/habilidades/wireframes-flujos/SKILL.md +212 -0
- package/habilidades/wireframes-flujos/recursos/referencia-completa.md +192 -0
- package/habilidades/workflow-claude-code/SKILL.md +260 -0
- package/habilidades/workflow-claude-code/recursos/referencia-completa.md +109 -0
- package/hooks/_run-hook.sh +57 -0
- package/hooks/actualizar-perfil-usuario.js +364 -0
- package/hooks/agente-lifecycle.js +71 -0
- package/hooks/aiisms-detector.js +173 -0
- package/hooks/audit-trail.js +204 -0
- package/hooks/auto-background.js +97 -0
- package/hooks/auto-consolidacion.js +178 -0
- package/hooks/auto-evolucion.js +666 -0
- package/hooks/auto-restaurar-settings.js +360 -0
- package/hooks/calidad-pre-commit.js +929 -0
- package/hooks/calidad-typescript.js +511 -0
- package/hooks/captura-feedback-usuario.js +148 -0
- package/hooks/check-update.js +211 -0
- package/hooks/clasificador-mensajes.js +271 -0
- package/hooks/degradacion-instintos.js +272 -0
- package/hooks/escaneo-secretos.js +389 -0
- package/hooks/extraccion-aprendizajes.js +763 -0
- package/hooks/grafo-contexto.js +129 -0
- package/hooks/graph-update.js +67 -0
- package/hooks/guardrail-modelo.js +247 -0
- package/hooks/inbox-aviso.js +75 -0
- package/hooks/inyeccion-contexto.js +246 -0
- package/hooks/lib/abort-registry.js +214 -0
- package/hooks/lib/agent-backend.js +210 -0
- package/hooks/lib/agent-comms.js +263 -0
- package/hooks/lib/agent-issue-codes.js +284 -0
- package/hooks/lib/agent-matcher.js +189 -0
- package/hooks/lib/async-hook-registry.js +252 -0
- package/hooks/lib/atomic-write.js +130 -0
- package/hooks/lib/auto-consolidator.js +335 -0
- package/hooks/lib/canary-skills.js +187 -0
- package/hooks/lib/consolidation-lock.js +291 -0
- package/hooks/lib/context-builder.js +430 -0
- package/hooks/lib/context-compressor.js +657 -0
- package/hooks/lib/convergence-detector.js +105 -0
- package/hooks/lib/delegation-tracker.js +198 -0
- package/hooks/lib/detectar-package-manager.js +423 -0
- package/hooks/lib/edit-accumulator.js +171 -0
- package/hooks/lib/error-classifier.js +308 -0
- package/hooks/lib/event-bus.js +112 -0
- package/hooks/lib/evolution-tracker.js +442 -0
- package/hooks/lib/execution-state.js +316 -0
- package/hooks/lib/fingerprint-id.js +135 -0
- package/hooks/lib/gateway-notify.js +116 -0
- package/hooks/lib/graph-security.js +75 -0
- package/hooks/lib/guardrail-metrics.js +202 -0
- package/hooks/lib/hook-circuit-breaker.js +206 -0
- package/hooks/lib/loop-detector.js +267 -0
- package/hooks/lib/mcp-health.js +184 -0
- package/hooks/lib/mcp-pool.js +436 -0
- package/hooks/lib/memory-search.js +506 -0
- package/hooks/lib/merkle-audit.js +96 -0
- package/hooks/lib/model-router.js +222 -0
- package/hooks/lib/normalize-error.js +324 -0
- package/hooks/lib/normalize-input.js +65 -0
- package/hooks/lib/nudge-tracker.js +306 -0
- package/hooks/lib/otlp-exporter.js +365 -0
- package/hooks/lib/performance-marks.js +239 -0
- package/hooks/lib/privacy-filter.js +128 -0
- package/hooks/lib/prompt-injection-scanner.js +209 -0
- package/hooks/lib/provenance-tracker.js +183 -0
- package/hooks/lib/rate-limit-tracker.js +253 -0
- package/hooks/lib/reflect-classifier.js +164 -0
- package/hooks/lib/resource-quota.js +122 -0
- package/hooks/lib/retry-jitter.js +165 -0
- package/hooks/lib/risk-engine.js +368 -0
- package/hooks/lib/run-log.js +408 -0
- package/hooks/lib/session-fts.js +379 -0
- package/hooks/lib/session-store.js +293 -0
- package/hooks/lib/singleton-guard.js +159 -0
- package/hooks/lib/skill-auditor.js +588 -0
- package/hooks/lib/sync-status.js +228 -0
- package/hooks/lib/taint-tracker.js +107 -0
- package/hooks/lib/task-service.js +295 -0
- package/hooks/lib/tech-skills-map.js +146 -0
- package/hooks/lib/telegram-cliente.js +159 -0
- package/hooks/lib/telegram-config.js +170 -0
- package/hooks/lib/token-budget.js +156 -0
- package/hooks/lib/token-estimator.js +420 -0
- package/hooks/lib/toon-compressor.js +245 -0
- package/hooks/lib/usage-model.js +183 -0
- package/hooks/lib/variable-resolver.js +230 -0
- package/hooks/linea-estado.js +324 -0
- package/hooks/metricas-evolucion.js +209 -0
- package/hooks/monitor-contexto.js +325 -0
- package/hooks/notificacion-sesion-stop.js +198 -0
- package/hooks/notificacion-telegram-notification.js +4 -0
- package/hooks/notificacion-telegram-subagent.js +4 -0
- package/hooks/notificacion-telegram.js +267 -0
- package/hooks/preservar-estado-pre-compact.js +150 -0
- package/hooks/proteccion-rutas.js +366 -0
- package/hooks/registro-turnos.js +209 -0
- package/hooks/resumen-sesion.js +249 -0
- package/hooks/risk-scoring.js +323 -0
- package/hooks/rotar-audit-auto.js +122 -0
- package/hooks/sugerir-regenerar-inventario.js +170 -0
- package/hooks/telemetria-agentes.js +167 -0
- package/hooks/tracking-costos.js +688 -0
- package/instintos/global.yaml +8 -0
- package/instintos/perfil-usuario.yaml +53 -0
- package/instintos/prompt-appendices.yaml +57 -0
- package/instintos/proyecto.yaml +372 -0
- package/manifiestos/gateway-config.json +77 -0
- package/manifiestos/handoff-context.json +223 -0
- package/manifiestos/hook-profiles.json +44 -0
- package/manifiestos/hooks-config.json +360 -0
- package/manifiestos/modulos.json +1173 -0
- package/manifiestos/perfiles.json +404 -0
- package/package.json +86 -0
- package/plantillas/ESTADO.md +109 -0
- package/plantillas/HOJA-RUTA.md +143 -0
- package/plantillas/PROYECTO.md +122 -0
- package/plantillas/REQUISITOS.md +132 -0
- package/plantillas/auditor-veto-template.md +105 -0
- package/plantillas/github-workflows/README.md +47 -0
- package/plantillas/github-workflows/release-please.yml +44 -0
- package/plantillas/github-workflows/swl-ci.yml +107 -0
- package/plantillas/github-workflows/swl-security.yml +51 -0
- package/plantillas/mcp-mineru.json +13 -0
- package/plantillas/research/ARQUITECTURA.md +220 -0
- package/plantillas/research/FUNCIONALIDADES.md +175 -0
- package/plantillas/research/RESUMEN.md +165 -0
- package/plantillas/research/STACK.md +233 -0
- package/plantillas/research/TRAMPAS.md +299 -0
- package/plantillas/skill-evals-template.json +44 -0
- package/plugin.json +343 -0
- package/reglas/accesibilidad.md +269 -0
- package/reglas/api-diseno.md +400 -0
- package/reglas/arquitectura.md +352 -0
- package/reglas/brevedad-output.md +124 -0
- package/reglas/cloud-infra.md +247 -0
- package/reglas/docs.md +245 -0
- package/reglas/estilo-codigo.md +201 -0
- package/reglas/git-workflow.md +245 -0
- package/reglas/gobernanza.md +271 -0
- package/reglas/harness-claude-code.md +213 -0
- package/reglas/hooks.md +186 -0
- package/reglas/lenguajes/csharp/estilo-codigo.md +231 -0
- package/reglas/lenguajes/csharp/hooks.md +281 -0
- package/reglas/lenguajes/csharp/patrones.md +226 -0
- package/reglas/lenguajes/csharp/seguridad.md +258 -0
- package/reglas/lenguajes/csharp/testing.md +176 -0
- package/reglas/lenguajes/go/estilo-codigo.md +195 -0
- package/reglas/lenguajes/go/hooks.md +249 -0
- package/reglas/lenguajes/go/patrones.md +249 -0
- package/reglas/lenguajes/go/seguridad.md +225 -0
- package/reglas/lenguajes/go/testing.md +272 -0
- package/reglas/lenguajes/java/estilo-codigo.md +217 -0
- package/reglas/lenguajes/java/hooks.md +251 -0
- package/reglas/lenguajes/java/patrones.md +226 -0
- package/reglas/lenguajes/java/seguridad.md +233 -0
- package/reglas/lenguajes/java/testing.md +238 -0
- package/reglas/lenguajes/kotlin/estilo-codigo.md +208 -0
- package/reglas/lenguajes/kotlin/hooks.md +245 -0
- package/reglas/lenguajes/kotlin/patrones.md +201 -0
- package/reglas/lenguajes/kotlin/seguridad.md +202 -0
- package/reglas/lenguajes/kotlin/testing.md +236 -0
- package/reglas/lenguajes/nextjs/estilo-codigo.md +175 -0
- package/reglas/lenguajes/nextjs/hooks.md +186 -0
- package/reglas/lenguajes/nextjs/patrones.md +225 -0
- package/reglas/lenguajes/nextjs/seguridad.md +216 -0
- package/reglas/lenguajes/nextjs/testing.md +193 -0
- package/reglas/lenguajes/php/estilo-codigo.md +228 -0
- package/reglas/lenguajes/php/hooks.md +165 -0
- package/reglas/lenguajes/php/patrones.md +233 -0
- package/reglas/lenguajes/php/seguridad.md +186 -0
- package/reglas/lenguajes/php/testing.md +205 -0
- package/reglas/lenguajes/rust/estilo-codigo.md +207 -0
- package/reglas/lenguajes/rust/hooks.md +240 -0
- package/reglas/lenguajes/rust/patrones.md +250 -0
- package/reglas/lenguajes/rust/seguridad.md +221 -0
- package/reglas/lenguajes/rust/testing.md +194 -0
- package/reglas/lenguajes/swift/estilo-codigo.md +238 -0
- package/reglas/lenguajes/swift/hooks.md +257 -0
- package/reglas/lenguajes/swift/patrones.md +235 -0
- package/reglas/lenguajes/swift/seguridad.md +248 -0
- package/reglas/lenguajes/swift/testing.md +242 -0
- package/reglas/markitdown.md +60 -0
- package/reglas/memoria-consolidada.md +209 -0
- package/reglas/patrones.md +225 -0
- package/reglas/performance.md +195 -0
- package/reglas/pruebas.md +159 -0
- package/reglas/seguridad-agentes.md +351 -0
- package/reglas/seguridad.md +151 -0
- package/reglas/skills-estandar.md +373 -0
- package/reglas/testing.md +193 -0
- package/schemas/agent-contract.json +176 -0
- package/schemas/agent-frontmatter.schema.json +149 -0
- package/schemas/agent-message.schema.json +53 -0
- package/schemas/agent-output-implementacion.schema.json +85 -0
- package/schemas/agent-output-planificacion.schema.json +113 -0
- package/schemas/agent-output-review.schema.json +78 -0
- package/schemas/diary-entry.schema.json +80 -0
- package/schemas/hook-profiles.schema.json +39 -0
- package/schemas/hooks-config.schema.json +74 -0
- package/schemas/instinct.schema.json +115 -0
- package/schemas/modulos.schema.json +29 -0
- package/schemas/perfiles.schema.json +28 -0
- package/schemas/plugin.schema.json +64 -0
- package/schemas/skill-evals.schema.json +95 -0
- package/schemas/skill-frontmatter.schema.json +170 -0
- package/scripts/actualizar.js +145 -0
- package/scripts/audit-skills.sh +78 -0
- package/scripts/auditar-agentes-gaps.js +149 -0
- package/scripts/auditar-cobertura-frameworks.js +241 -0
- package/scripts/auditar-skills-gaps.js +206 -0
- package/scripts/bootstrap-instintos.js +259 -0
- package/scripts/check-update.js +109 -0
- package/scripts/comandos/agents.js +105 -0
- package/scripts/comandos/info.js +108 -0
- package/scripts/comandos/install-asistido.js +186 -0
- package/scripts/comandos/skills.js +211 -0
- package/scripts/configurar-branch-protection.js +418 -0
- package/scripts/daemon-swl.py +388 -0
- package/scripts/desinstalar.js +130 -0
- package/scripts/doctor.js +559 -0
- package/scripts/field-report.js +199 -0
- package/scripts/generar-inventario.js +317 -0
- package/scripts/inbox-tmux-inject.js +161 -0
- package/scripts/inferir-herramientas-permitidas.js +586 -0
- package/scripts/inicializar.js +133 -0
- package/scripts/instalador.js +1031 -0
- package/scripts/instalar-git-hook.js +122 -0
- package/scripts/lib/agp-frontmatter.js +222 -0
- package/scripts/lib/append-con-marcadores.js +199 -0
- package/scripts/lib/artefactos-python.js +43 -0
- package/scripts/lib/audit-query.js +221 -0
- package/scripts/lib/autostart-linux.js +347 -0
- package/scripts/lib/autostart-macos.js +360 -0
- package/scripts/lib/autostart-windows.js +307 -0
- package/scripts/lib/budget-enforcer.js +252 -0
- package/scripts/lib/claude-sessions.js +285 -0
- package/scripts/lib/configurar-ci.js +380 -0
- package/scripts/lib/console-span-exporter.js +92 -0
- package/scripts/lib/contadores-inventario.js +217 -0
- package/scripts/lib/dashboard-widgets.js +290 -0
- package/scripts/lib/detectar-runtime.js +279 -0
- package/scripts/lib/detectar-stack.js +187 -0
- package/scripts/lib/diary-entry.js +234 -0
- package/scripts/lib/drift-detector.js +545 -0
- package/scripts/lib/estado.js +124 -0
- package/scripts/lib/gestor-componentes.js +243 -0
- package/scripts/lib/gitignore-manifest.js +305 -0
- package/scripts/lib/graph-analyze.py +556 -0
- package/scripts/lib/graph-builder.py +485 -0
- package/scripts/lib/graph-cluster.py +259 -0
- package/scripts/lib/health-row.js +168 -0
- package/scripts/lib/hooks-settings.js +789 -0
- package/scripts/lib/manifiestos.js +138 -0
- package/scripts/lib/mc-client.js +137 -0
- package/scripts/lib/notificaciones-telegram.js +1107 -0
- package/scripts/lib/npm-version.js +261 -0
- package/scripts/lib/paquetes-conocidos.js +50 -0
- package/scripts/lib/preservar-usuario.js +586 -0
- package/scripts/lib/prompt-builder.js +264 -0
- package/scripts/lib/resolver-externo.js +332 -0
- package/scripts/lib/schedule-parser.js +305 -0
- package/scripts/lib/scoring-instintos.js +240 -0
- package/scripts/lib/seguridad.js +160 -0
- package/scripts/lib/selector-interactivo.js +152 -0
- package/scripts/lib/semantic-search.js +242 -0
- package/scripts/lib/skill-discovery.js +234 -0
- package/scripts/lib/skill-metrics.js +246 -0
- package/scripts/lib/skill-normalizer.js +112 -0
- package/scripts/lib/skills-hub.js +340 -0
- package/scripts/lib/span-schema.js +134 -0
- package/scripts/lib/tool-cost-analyzer.js +255 -0
- package/scripts/lib/tracing-processor-interface.js +286 -0
- package/scripts/lib/transformadores/base.js +80 -0
- package/scripts/lib/transformadores/claude.js +124 -0
- package/scripts/lib/transformadores/codex.js +115 -0
- package/scripts/lib/transformadores/copilot.js +106 -0
- package/scripts/lib/transformadores/gemini.js +74 -0
- package/scripts/lib/transformadores/index.js +35 -0
- package/scripts/lib/transformadores/opencode.js +75 -0
- package/scripts/lib/ui.js +259 -0
- package/scripts/limpiar-artefactos-python.js +131 -0
- package/scripts/mcp-orchestrator.py +386 -0
- package/scripts/mcp-pool-manager.py +352 -0
- package/scripts/mcp-telemetry.py +378 -0
- package/scripts/poblar-evolvable.js +226 -0
- package/scripts/publicar.js +287 -0
- package/scripts/reflect-skills.js +403 -0
- package/scripts/rotar-audit-logs.js +185 -0
- package/scripts/run-skill-evals.js +242 -0
- package/scripts/smoke-test.js +374 -0
- package/scripts/token-analysis.py +471 -0
- package/scripts/validar-manifest.js +195 -0
- package/scripts/validar-memoria.js +321 -0
- package/scripts/validar-tests-aislamiento.js +184 -0
- package/scripts/validar-tokens-test.js +208 -0
- package/scripts/validar.js +147 -0
- package/scripts/validate-markdown.py +339 -0
- package/scripts/validate-skills.py +385 -0
- package/scripts/vendor/claude-usage/README.md +116 -0
- package/scripts/vendor/claude-usage/cli.py +334 -0
- package/scripts/vendor/claude-usage/dashboard.py +795 -0
- package/scripts/vendor/claude-usage/scanner.py +467 -0
- package/scripts/vendor/markitdown/cli.py +194 -0
- package/scripts/verificar-evolucion.js +289 -0
- package/scripts/verificar-release.js +494 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rag-arquitectura
|
|
3
|
+
description: >
|
|
4
|
+
Arquitectura de sistemas RAG (Retrieval-Augmented Generation): diseño de pipelines
|
|
5
|
+
de ingestión, estrategias de chunking, selección de vector stores, reranking,
|
|
6
|
+
evaluación con RAGAS y patrones de producción. Cargar cuando se diseñe o implemente
|
|
7
|
+
un sistema RAG completo, se optimice la precisión de recuperación, o se evalúe
|
|
8
|
+
la calidad de un pipeline existente.
|
|
9
|
+
version: "1.0.0"
|
|
10
|
+
herramientasPermitidas: [Read, Grep]
|
|
11
|
+
user-invocable: false
|
|
12
|
+
evolvable: true # default para skill estandar
|
|
13
|
+
exclusiones:
|
|
14
|
+
- "No cargar para construcción de agentes LangGraph con memoria y herramientas — para agentes orquestados con LangGraph cargar `langchain-langraph`."
|
|
15
|
+
- "No cargar para extracción de documentos Office/PDF sin pipeline de recuperación (sin búsqueda vectorial) — para extracción puntual de documentos cargar `extraccion-documentos`."
|
|
16
|
+
- "No cargar para búsqueda de texto completo en bases de datos SQL sin componente vectorial — para full-text search en PostgreSQL usar `tsvector`/`tsquery` directamente."
|
|
17
|
+
- "No cargar para fine-tuning de modelos de embedding en dominios específicos — este skill cubre RAG con modelos de embedding pre-entrenados, no el proceso de ajuste de pesos."
|
|
18
|
+
---
|
|
19
|
+
# RAG — Retrieval-Augmented Generation
|
|
20
|
+
|
|
21
|
+
## Cuándo NO cargar
|
|
22
|
+
|
|
23
|
+
- La tarea es construir agentes con estado y herramientas usando LangGraph: cargar `langchain-langraph`.
|
|
24
|
+
- La tarea es extracción puntual de un documento (sin búsqueda vectorial posterior): cargar `extraccion-documentos`.
|
|
25
|
+
- La tarea es full-text search en PostgreSQL sin componente vectorial: usar `tsvector`/`tsquery` del skill `postgresql-experto`.
|
|
26
|
+
- La tarea es fine-tuning de modelos de embedding: usar la documentación del proveedor de embeddings.
|
|
27
|
+
|
|
28
|
+
## Arquitectura de referencia
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
Documentos → Ingestión → Chunking → Embeddings → Vector Store
|
|
32
|
+
↓
|
|
33
|
+
Usuario → Query → Retriever → Reranker → LLM → Respuesta
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Pipeline de ingestión
|
|
39
|
+
|
|
40
|
+
### Loaders por tipo de fuente
|
|
41
|
+
|
|
42
|
+
| Fuente | Loader recomendado | Notas |
|
|
43
|
+
|--------|-------------------|-------|
|
|
44
|
+
| PDF | `PyPDFLoader` / `UnstructuredPDFLoader` | Unstructured para PDFs con tablas complejas |
|
|
45
|
+
| Web | `WebBaseLoader` / `RecursiveUrlLoader` | Recursive para crawl de sitios completos |
|
|
46
|
+
| Markdown | `UnstructuredMarkdownLoader` | Preserva headers para chunking semántico |
|
|
47
|
+
| CSV / Excel | `CSVLoader` / `UnstructuredExcelLoader` | Cada fila como documento independiente |
|
|
48
|
+
| Base de datos | `SQLDatabaseLoader` | Query SQL → documentos |
|
|
49
|
+
| Código fuente | `GenericLoader` + `LanguageParser` | Preserva estructura de funciones/clases |
|
|
50
|
+
|
|
51
|
+
### Limpieza pre-chunking
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
def limpiar_documento(texto: str) -> str:
|
|
55
|
+
"""Normalización antes de chunking."""
|
|
56
|
+
import re
|
|
57
|
+
# Eliminar saltos de línea excesivos
|
|
58
|
+
texto = re.sub(r'\n{3,}', '\n\n', texto)
|
|
59
|
+
# Normalizar espacios
|
|
60
|
+
texto = re.sub(r'[ \t]+', ' ', texto)
|
|
61
|
+
# Eliminar headers/footers repetitivos de PDFs
|
|
62
|
+
texto = re.sub(r'Página \d+ de \d+', '', texto)
|
|
63
|
+
return texto.strip()
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Estrategias de chunking
|
|
69
|
+
|
|
70
|
+
### Tabla de decisión
|
|
71
|
+
|
|
72
|
+
| Tipo de documento | Estrategia | chunk_size | overlap | Razón |
|
|
73
|
+
|-------------------|-----------|------------|---------|-------|
|
|
74
|
+
| Texto general | `RecursiveCharacterTextSplitter` | 1000 | 200 | Balance general entre contexto y precisión |
|
|
75
|
+
| Documentación técnica | `MarkdownHeaderTextSplitter` | — | — | Preserva estructura de secciones |
|
|
76
|
+
| Código fuente | `RecursiveCharacterTextSplitter(language=...)` | 500 | 50 | Funciones/clases como unidades |
|
|
77
|
+
| Contratos/legal | `RecursiveCharacterTextSplitter` | 1500 | 300 | Cláusulas largas necesitan más contexto |
|
|
78
|
+
| FAQ / Q&A | `CharacterTextSplitter(separator="\n\n")` | — | 0 | Cada pregunta-respuesta es un chunk |
|
|
79
|
+
|
|
80
|
+
### Chunking semántico (avanzado)
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from langchain_experimental.text_splitter import SemanticChunker
|
|
84
|
+
from langchain_openai import OpenAIEmbeddings
|
|
85
|
+
|
|
86
|
+
# Agrupa oraciones por similitud semántica
|
|
87
|
+
chunker = SemanticChunker(
|
|
88
|
+
OpenAIEmbeddings(),
|
|
89
|
+
breakpoint_threshold_type="percentile",
|
|
90
|
+
breakpoint_threshold_amount=95,
|
|
91
|
+
)
|
|
92
|
+
chunks = chunker.create_documents([texto])
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Cuándo usar chunking semántico**: documentos heterogéneos donde los separadores
|
|
96
|
+
textuales no reflejan cambios de tema. Más costoso (requiere embedding por oración).
|
|
97
|
+
|
|
98
|
+
### Reglas estrictas de chunking
|
|
99
|
+
|
|
100
|
+
- Usar `tiktoken` para contar tokens reales, no `len(texto)`
|
|
101
|
+
- overlap > 0 para evitar pérdida de contexto en bordes
|
|
102
|
+
- chunk_size demasiado grande → ruido en recuperación
|
|
103
|
+
- chunk_size demasiado pequeño → fragmentos sin contexto suficiente
|
|
104
|
+
- Siempre incluir metadata: `source`, `page`, `section` para trazabilidad
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Vector stores — criterios de selección
|
|
109
|
+
|
|
110
|
+
| Vector store | Cuándo usar | Ventajas | Limitaciones |
|
|
111
|
+
|-------------|-------------|----------|-------------|
|
|
112
|
+
| **pgvector** | Ya tienes PostgreSQL, < 10M vectores | Una sola BD, SQL familiar, transacciones ACID | Rendimiento baja con > 10M vectores |
|
|
113
|
+
| **Chroma** | Prototipado local, desarrollo | Zero config, in-memory o persistente | No escala a producción con alta carga |
|
|
114
|
+
| **Pinecone** | Serverless, equipo sin DevOps | Escala automática, filtrado por metadata | Vendor lock-in, costo por volumen |
|
|
115
|
+
| **Weaviate** | Búsqueda híbrida vectorial + keyword | Módulos de vectorización, GraphQL API | Complejidad operativa |
|
|
116
|
+
| **Qdrant** | Alto rendimiento, filtrado avanzado | Filtros combinados eficientes, Rust core | Menos integraciones que Pinecone |
|
|
117
|
+
| **FAISS** | Batch processing, no necesitas persistencia | Ultra rápido en memoria, Facebook Research | Sin persistencia nativa, sin filtros |
|
|
118
|
+
|
|
119
|
+
### Patrón de inicialización con pgvector
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
from langchain_postgres import PGVector
|
|
123
|
+
|
|
124
|
+
vector_store = PGVector(
|
|
125
|
+
embeddings=embeddings,
|
|
126
|
+
collection_name="mi_coleccion",
|
|
127
|
+
connection=DATABASE_URL,
|
|
128
|
+
use_jsonb=True, # metadata como JSONB para filtros eficientes
|
|
129
|
+
)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Modelos de embedding
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
text-embedding-3-small (OpenAI) → Bajo costo ($0.02/1M tokens), suficiente para mayoría
|
|
138
|
+
text-embedding-3-large (OpenAI) → Alta precisión ($0.13/1M tokens), documentos técnicos
|
|
139
|
+
voyage-3 (Anthropic/Voyage) → Óptimo con Claude, buen balance
|
|
140
|
+
all-MiniLM-L6-v2 (HuggingFace) → Gratuito, on-premise, calidad base aceptable
|
|
141
|
+
nomic-embed-text (Ollama) → 100% local, sin costo de API, privacidad total
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Regla**: nunca mezclar modelos de embedding entre ingestión y búsqueda. El modelo
|
|
145
|
+
que generó los embeddings debe ser el mismo que transforma la query.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Retrieval — estrategias de recuperación
|
|
150
|
+
|
|
151
|
+
### Búsqueda básica vs avanzada
|
|
152
|
+
|
|
153
|
+
| Estrategia | Implementación | Cuándo usar |
|
|
154
|
+
|-----------|---------------|-------------|
|
|
155
|
+
| Similarity search | `vectorstore.similarity_search(query, k=4)` | Caso base, consultas directas |
|
|
156
|
+
| MMR (Maximal Marginal Relevance) | `vectorstore.max_marginal_relevance_search(query, k=4, fetch_k=20)` | Evitar chunks redundantes |
|
|
157
|
+
| Búsqueda híbrida | Vectorial + BM25 keyword | Documentos técnicos con terminología específica |
|
|
158
|
+
| Multi-query | Generar N variantes de la query con LLM | Queries ambiguas o cortas |
|
|
159
|
+
| Parent document | Recuperar chunk hijo, devolver documento padre | Necesitas contexto amplio pero búsqueda precisa |
|
|
160
|
+
|
|
161
|
+
### Reranking
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from langchain.retrievers import ContextualCompressionRetriever
|
|
165
|
+
from langchain_cohere import CohereRerank
|
|
166
|
+
|
|
167
|
+
reranker = CohereRerank(model="rerank-v3.5", top_n=3)
|
|
168
|
+
retriever_con_rerank = ContextualCompressionRetriever(
|
|
169
|
+
base_compressor=reranker,
|
|
170
|
+
base_retriever=vectorstore.as_retriever(search_kwargs={"k": 20}),
|
|
171
|
+
)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**Patrón retrieve-wide-rerank-narrow**: recuperar 20 chunks con similarity search,
|
|
175
|
+
rerankecar a los 3 más relevantes. Mejora precisión sin aumentar tokens de contexto.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Evaluación con RAGAS
|
|
180
|
+
|
|
181
|
+
### Métricas obligatorias antes de producción
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
from ragas import evaluate
|
|
185
|
+
from ragas.metrics import (
|
|
186
|
+
faithfulness,
|
|
187
|
+
answer_relevancy,
|
|
188
|
+
context_precision,
|
|
189
|
+
context_recall,
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
resultado = evaluate(
|
|
193
|
+
dataset=dataset_evaluacion, # mínimo 50 preguntas con ground truth
|
|
194
|
+
metrics=[faithfulness, answer_relevancy, context_precision, context_recall],
|
|
195
|
+
)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Umbrales mínimos aceptables
|
|
199
|
+
|
|
200
|
+
| Métrica | Umbral mínimo | Qué indica si falla |
|
|
201
|
+
|---------|:----------:|-------------------|
|
|
202
|
+
| `faithfulness` | > 0.8 | El LLM alucina — revisar retriever y prompt |
|
|
203
|
+
| `answer_relevancy` | > 0.7 | La respuesta no atiende la pregunta — revisar prompt |
|
|
204
|
+
| `context_precision` | > 0.7 | Se recuperan chunks irrelevantes — ajustar chunking/k |
|
|
205
|
+
| `context_recall` | > 0.7 | Falta contexto — aumentar k o mejorar embeddings |
|
|
206
|
+
|
|
207
|
+
Si `faithfulness < 0.6` después de optimizar → evaluar fine-tuning del retriever.
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Patrones de producción
|
|
212
|
+
|
|
213
|
+
### Caching de embeddings
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
from langchain.storage import LocalFileStore
|
|
217
|
+
from langchain.embeddings import CacheBackedEmbeddings
|
|
218
|
+
|
|
219
|
+
store = LocalFileStore("./cache/embeddings/")
|
|
220
|
+
cached_embeddings = CacheBackedEmbeddings.from_bytes_store(
|
|
221
|
+
underlying_embeddings=embeddings,
|
|
222
|
+
document_embedding_cache=store,
|
|
223
|
+
namespace=embeddings.model, # invalida cache si cambia el modelo
|
|
224
|
+
)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Streaming de respuestas
|
|
228
|
+
|
|
229
|
+
```python
|
|
230
|
+
async for chunk in cadena_rag.astream({"question": pregunta}):
|
|
231
|
+
yield chunk # Enviar al cliente vía SSE o WebSocket
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Guardrails obligatorios
|
|
235
|
+
|
|
236
|
+
- Rate limiting por usuario (máx. 10 queries/min para APIs públicas)
|
|
237
|
+
- Límite de tokens de contexto: `k` entre 3 y 6 chunks
|
|
238
|
+
- Timeout en llamadas al LLM: 30s máximo
|
|
239
|
+
- Logging de query + contexto recuperado + respuesta para auditoría
|
|
240
|
+
- Nunca incluir PII en embeddings sin cifrar o consentimiento
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## RAG con grafo de conocimiento (patrón LightRAG)
|
|
245
|
+
|
|
246
|
+
### Arquitectura híbrida: Vector + Knowledge Graph
|
|
247
|
+
|
|
248
|
+
A diferencia del RAG tradicional (solo vectores), LightRAG combina:
|
|
249
|
+
|
|
250
|
+
```
|
|
251
|
+
Documentos → Chunking → [Extracción de entidades/relaciones] → Knowledge Graph
|
|
252
|
+
→ [Embeddings] → Vector Store
|
|
253
|
+
↓
|
|
254
|
+
Consulta → Keywords → [Retrieval híbrido: KG + Vector] → Reranker → LLM → Respuesta
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**Ventaja clave**: el KG captura relaciones explícitas entre entidades que la búsqueda
|
|
258
|
+
vectorial sola no puede representar. Ejemplo: "Bug X fue causado por Patrón Y que
|
|
259
|
+
se adoptó en ADR-003" — esta cadena causal se pierde en similaridad de embeddings.
|
|
260
|
+
|
|
261
|
+
### 5 modos de retrieval (adoptar según caso de uso)
|
|
262
|
+
|
|
263
|
+
| Modo | Estrategia | Cuándo usar |
|
|
264
|
+
|------|-----------|-------------|
|
|
265
|
+
| **local** | Keywords de bajo nivel → entidades cercanas → relaciones | Preguntas específicas sobre un componente |
|
|
266
|
+
| **global** | Keywords de alto nivel → relaciones agregadas/comunidades | Preguntas amplias sobre patrones o tendencias |
|
|
267
|
+
| **hybrid** | Local + global fusionados | Cuando no se sabe el nivel de especificidad |
|
|
268
|
+
| **naive** | Solo similarity search (sin KG) | Búsqueda rápida cuando se conoce el texto |
|
|
269
|
+
| **mix** | KG + vector + reranking (recomendado) | Default para producción — mejor precisión |
|
|
270
|
+
|
|
271
|
+
### Extracción de entidades y relaciones
|
|
272
|
+
|
|
273
|
+
```python
|
|
274
|
+
async def extract_entities(chunk: str, llm) -> dict:
|
|
275
|
+
"""LLM extrae entidades y relaciones del chunk."""
|
|
276
|
+
# El LLM identifica:
|
|
277
|
+
# - Entidades: personas, tecnologías, componentes, conceptos
|
|
278
|
+
# - Relaciones: causa, dependencia, uso, implementación
|
|
279
|
+
# - Keywords: alto nivel (temas) y bajo nivel (términos específicos)
|
|
280
|
+
prompt = f"""Extrae entidades y relaciones del siguiente texto.
|
|
281
|
+
Formato: ENTITY|||TYPE|||DESCRIPTION y RELATION|||SOURCE|||TARGET|||DESCRIPTION
|
|
282
|
+
Texto: {chunk}"""
|
|
283
|
+
return await llm(prompt)
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**Gleaning**: ejecutar extracción 2-3 veces con "¿falta algo?" para mejorar cobertura.
|
|
287
|
+
|
|
288
|
+
### Configuración recomendada
|
|
289
|
+
|
|
290
|
+
```python
|
|
291
|
+
# Parámetros optimizados para proyectos de software
|
|
292
|
+
chunk_token_size = 1200 # Balance contexto/precisión
|
|
293
|
+
chunk_overlap_token_size = 100 # Continuidad entre chunks
|
|
294
|
+
top_k = 60 # Entidades/relaciones a recuperar
|
|
295
|
+
chunk_top_k = 20 # Chunks post-reranking
|
|
296
|
+
max_entity_tokens = 6000 # Límite tokens por entidad
|
|
297
|
+
max_relation_tokens = 8000 # Límite tokens por relación
|
|
298
|
+
max_total_tokens = 30000 # Límite total de contexto
|
|
299
|
+
cosine_threshold = 0.2 # Mínimo de similaridad para incluir
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Cuándo usar RAG + KG vs RAG solo vectores
|
|
303
|
+
|
|
304
|
+
| Criterio | Solo vectores | Vector + KG |
|
|
305
|
+
|----------|:-------------:|:-----------:|
|
|
306
|
+
| Preguntas factuales directas | Suficiente | Overkill |
|
|
307
|
+
| Relaciones causales entre documentos | Pierde relaciones | Captura cadenas causales |
|
|
308
|
+
| Corpus < 100 documentos | Óptimo | KG no aporta mucho |
|
|
309
|
+
| Corpus > 1000 documentos | Pierde contexto global | KG organiza conocimiento |
|
|
310
|
+
| Preguntas multi-hop (A→B→C) | Falla frecuente | Sigue relaciones en el grafo |
|
|
311
|
+
| Costo de ingestión | Bajo (solo embeddings) | Alto (LLM extrae entidades) |
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## Reglas estrictas
|
|
316
|
+
|
|
317
|
+
- **Evaluar con RAGAS** antes de desplegar — mínimo 50 preguntas con ground truth
|
|
318
|
+
- **Nunca mezclar** modelos de embedding entre ingestión y búsqueda
|
|
319
|
+
- **Siempre incluir metadata** en chunks: source, page, section
|
|
320
|
+
- **Reranking obligatorio** cuando k > 5 en producción
|
|
321
|
+
- **Cachear embeddings** para evitar recálculos en re-ingestión
|
|
322
|
+
- **Nunca hacer embedding en loops** — usar `embed_documents(chunks)` en lote
|
|
323
|
+
- **Monitorear drift**: re-evaluar con RAGAS cada 2 semanas o tras cambios en el corpus
|
|
324
|
+
- **KG: gleaning obligatorio** — mínimo 2 pasadas de extracción para cobertura ≥ 80%
|
|
325
|
+
- **KG: merge de entidades** — entidades con nombre similar deben fusionarse automáticamente
|
|
326
|
+
- **KG: caché de LLM** — habilitar para reducir costo en re-ingestión de documentos sin cambios
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
## Gotchas / Errores comunes no obvios
|
|
331
|
+
|
|
332
|
+
**`similarity_search(query, k=4)` devuelve documentos con score > 0.9 pero la respuesta del LLM alucina información no presente en ningún chunk**: el score de similitud coseno mide afinidad semántica del embedding, no relevancia para la pregunta. Un chunk sobre "autenticación JWT" con alta similitud a la query "cómo funciona OAuth2" puede no contener la respuesta real. Causa: los embeddings capturan temas relacionados, no respuestas precisas; la similitud semántica y la completitud factual son dimensiones independientes. Fix: agregar un paso de reranking con un modelo cross-encoder (Cohere rerank, Jina reranker) después del retrieval vectorial. El cross-encoder evalúa relevancia query→documento directamente, no por similitud de embedding.
|
|
333
|
+
|
|
334
|
+
**`RecursiveCharacterTextSplitter` con `chunk_overlap=200` en documentos de soporte técnico crea chunks que empiezan con la respuesta de la pregunta anterior pero sin la pregunta, haciendo que el retriever recupere contextos semánticamente incoherentes**: un chunk que comienza con "...solución: actualizar el driver a la versión 4.2" sin el contexto del problema tiene alto overlap con queries generales sobre drivers pero no responde ninguna pregunta concreta correctamente. Causa: el overlap de caracteres corta oraciones sin considerar la estructura semántica del documento. Fix: para documentos de Q&A o tickets de soporte, usar `CharacterTextSplitter(separator="\n\n", chunk_overlap=0)` con cada par pregunta-respuesta como chunk atómico, añadiendo la pregunta como prefijo en el metadata para boosting en el retrieval.
|
|
335
|
+
|
|
336
|
+
**`CacheBackedEmbeddings` con `LocalFileStore` produce inconsistencias cuando dos procesos del servidor escriben simultáneamente al mismo archivo de cache porque `LocalFileStore` no usa file locking**: bajo carga concurrente en un servidor uvicorn con múltiples workers, el cache de embeddings se corrompe ocasionalmente generando embeddings parciales que fallan silenciosamente en la búsqueda vectorial (el vector store retorna k=0 resultados para esas queries). Causa: `LocalFileStore` usa escrituras directas sin sincronización entre procesos. Fix: en producción con múltiples workers, usar Redis como backend de cache de embeddings en lugar de `LocalFileStore`, o limitar la app a un solo worker y usar async concurrente en lugar de multiprocessing.
|
|
337
|
+
|
|
338
|
+
**RAGAS reporta `faithfulness > 0.85` en el test set pero el sistema alucina en producción porque el test set fue generado con el mismo LLM que ahora se evalúa**: el LLM genera preguntas cuyas respuestas están claramente en los documentos de entrenamiento, sesgando los scores hacia arriba. Causa: la distribución de queries reales de usuarios es diferente al test set sintético — los usuarios hacen preguntas sobre brechas, casos edge y contradicciones que el LLM generador evita. Fix: mezclar el test set sintético (50%) con queries reales anonimizadas de usuarios (50%). Si no hay queries reales disponibles, usar personas adversariales explícitas en la generación: "genera preguntas que el sistema probablemente no pueda responder correctamente".
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rails-experto
|
|
3
|
+
description: >
|
|
4
|
+
Ruby on Rails 7+ con Active Record, Hotwire (Turbo Frames/Streams), Action Cable,
|
|
5
|
+
Sidekiq y RSpec. Patrones idiomáticos de Rails: convención sobre configuración,
|
|
6
|
+
fat models/thin controllers, service objects. Cargar cuando se implemente
|
|
7
|
+
cualquier componente Rails: modelos, controladores, jobs, WebSockets o al
|
|
8
|
+
migrar a Rails 7+ con Hotwire desde vistas tradicionales.
|
|
9
|
+
version: "1.0.0"
|
|
10
|
+
herramientasPermitidas: [Read]
|
|
11
|
+
exclusiones:
|
|
12
|
+
- "No cargar para escribir specs RSpec o configurar FactoryBot — los patrones de testing Rails están en el recurso `recursos/testing-rspec.md` de este mismo skill; para testing standalone cargar el recurso."
|
|
13
|
+
- "No cargar para optimizaciones de base de datos SQL fuera de Active Record — para queries SQL avanzadas y plan de ejecución cargar `sql-optimizacion`."
|
|
14
|
+
- "No cargar para APIs Django, FastAPI o Laravel — Rails tiene convenciones y naming completamente distintos."
|
|
15
|
+
- "No cargar para errores de compilación Ruby o bundler — para errores de build Ruby cargar el skill de errores correspondiente."
|
|
16
|
+
evolvable: true # default para skill estandar
|
|
17
|
+
---
|
|
18
|
+
# Rails Experto
|
|
19
|
+
|
|
20
|
+
## Cuándo NO cargar
|
|
21
|
+
|
|
22
|
+
- La pregunta es específicamente sobre escribir specs RSpec o configurar FactoryBot — el recurso `recursos/testing-rspec.md` de este skill cubre ese tema; para testing de otro framework cargar su skill.
|
|
23
|
+
- La pregunta es sobre optimizaciones SQL fuera de Active Record (índices, EXPLAIN, partitioning) — cargar `sql-optimizacion`.
|
|
24
|
+
- El framework es Django, FastAPI o Laravel — Rails tiene convenciones (naming, estructura, ORM) completamente distintas.
|
|
25
|
+
- Los errores son de bundler o gemas Ruby — diagnosticar con el skill de build errors de Ruby.
|
|
26
|
+
|
|
27
|
+
## Cuándo cargar este skill
|
|
28
|
+
|
|
29
|
+
- Implementar modelos Active Record con validaciones, scopes o asociaciones
|
|
30
|
+
- Crear controladores Rails y sus actions CRUD
|
|
31
|
+
- Construir service objects para lógica de negocio compleja
|
|
32
|
+
- Integrar Hotwire (Turbo Frames, Turbo Streams, Stimulus)
|
|
33
|
+
- Configurar Action Cable o canales de WebSocket
|
|
34
|
+
- Crear jobs con ActiveJob o Sidekiq
|
|
35
|
+
- Escribir tests con RSpec (modelos, requests, system specs)
|
|
36
|
+
- Migrar vistas ERB tradicionales a Hotwire
|
|
37
|
+
- Optimizar queries con eager loading para prevenir N+1
|
|
38
|
+
- Configurar ActiveRecord::Encryption para campos sensibles (Rails 7+)
|
|
39
|
+
|
|
40
|
+
## Estructura de proyecto Rails 7+
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
app/
|
|
44
|
+
├── controllers/
|
|
45
|
+
│ ├── application_controller.rb
|
|
46
|
+
│ └── api/v1/
|
|
47
|
+
├── models/
|
|
48
|
+
│ ├── concerns/ # Módulos compartidos entre modelos
|
|
49
|
+
│ └── application_record.rb
|
|
50
|
+
├── services/ # Service objects para lógica compleja
|
|
51
|
+
├── jobs/ # ActiveJob / Sidekiq
|
|
52
|
+
├── views/
|
|
53
|
+
│ └── components/ # ViewComponent
|
|
54
|
+
├── javascript/
|
|
55
|
+
│ ├── controllers/ # Stimulus controllers
|
|
56
|
+
│ └── application.js
|
|
57
|
+
└── channels/ # Action Cable
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Regla crítica: prevenir N+1 con includes
|
|
61
|
+
|
|
62
|
+
```ruby
|
|
63
|
+
# NUNCA — N+1 query (1 + N queries en la vista)
|
|
64
|
+
@posts = Post.all
|
|
65
|
+
# En la vista: post.author.nombre → query por cada post
|
|
66
|
+
|
|
67
|
+
# SIEMPRE — eager loading
|
|
68
|
+
@posts = Post.includes(:author, :tags).order(created_at: :desc)
|
|
69
|
+
|
|
70
|
+
# Con condición en asociación (usa JOIN, no subquery)
|
|
71
|
+
@posts = Post.eager_load(:author).where(authors: { verified: true })
|
|
72
|
+
|
|
73
|
+
# Bullet gem para detectar N+1 en desarrollo
|
|
74
|
+
# config/environments/development.rb:
|
|
75
|
+
# config.after_initialize { Bullet.enable = true; Bullet.rails_logger = true }
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Model con validaciones, scopes y asociaciones
|
|
79
|
+
|
|
80
|
+
```ruby
|
|
81
|
+
class Post < ApplicationRecord
|
|
82
|
+
belongs_to :author, class_name: 'User'
|
|
83
|
+
has_many :comments, dependent: :destroy
|
|
84
|
+
has_many_attached :images
|
|
85
|
+
has_rich_text :body
|
|
86
|
+
|
|
87
|
+
enum :status, { borrador: 0, publicado: 1, archivado: 2 }, prefix: true
|
|
88
|
+
|
|
89
|
+
validates :titulo, presence: true, length: { maximum: 200 }
|
|
90
|
+
validates :cuerpo, presence: true
|
|
91
|
+
|
|
92
|
+
scope :publicados, -> { where(status: :publicado) }
|
|
93
|
+
scope :recientes, -> { order(created_at: :desc) }
|
|
94
|
+
scope :del_autor, ->(user) { where(author: user) }
|
|
95
|
+
|
|
96
|
+
before_save :normalizar_titulo
|
|
97
|
+
|
|
98
|
+
private
|
|
99
|
+
|
|
100
|
+
def normalizar_titulo
|
|
101
|
+
self.titulo = titulo.strip.capitalize
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Controller delgado con service objects
|
|
107
|
+
|
|
108
|
+
```ruby
|
|
109
|
+
class PostsController < ApplicationController
|
|
110
|
+
before_action :authenticate_user!
|
|
111
|
+
before_action :set_post, only: [:show, :edit, :update, :destroy]
|
|
112
|
+
|
|
113
|
+
def create
|
|
114
|
+
result = Posts::CrearService.call(
|
|
115
|
+
autor: current_user,
|
|
116
|
+
parametros: post_params
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
if result.exitoso?
|
|
120
|
+
redirect_to result.post, notice: 'Publicación creada'
|
|
121
|
+
else
|
|
122
|
+
@post = result.post
|
|
123
|
+
render :new, status: :unprocessable_entity
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
private
|
|
128
|
+
|
|
129
|
+
def set_post
|
|
130
|
+
@post = Post.find(params[:id])
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def post_params
|
|
134
|
+
params.require(:post).permit(:titulo, :cuerpo, :status, images: [])
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Service Object pattern
|
|
140
|
+
|
|
141
|
+
```ruby
|
|
142
|
+
# app/services/posts/crear_service.rb
|
|
143
|
+
module Posts
|
|
144
|
+
class CrearService
|
|
145
|
+
Result = Struct.new(:exitoso?, :post, :errores, keyword_init: true)
|
|
146
|
+
|
|
147
|
+
def self.call(autor:, parametros:)
|
|
148
|
+
new(autor: autor, parametros: parametros).call
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def initialize(autor:, parametros:)
|
|
152
|
+
@autor = autor
|
|
153
|
+
@parametros = parametros
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def call
|
|
157
|
+
post = Post.new(@parametros.merge(author: @autor))
|
|
158
|
+
|
|
159
|
+
if post.save
|
|
160
|
+
NotificarSeguidoresJob.perform_later(post.id)
|
|
161
|
+
Result.new(exitoso?: true, post: post, errores: [])
|
|
162
|
+
else
|
|
163
|
+
Result.new(exitoso?: false, post: post, errores: post.errors.full_messages)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Sidekiq Job
|
|
171
|
+
|
|
172
|
+
```ruby
|
|
173
|
+
class NotificarSeguidoresJob < ApplicationJob
|
|
174
|
+
queue_as :default
|
|
175
|
+
sidekiq_options retry: 3, dead: false, backtrace: 5
|
|
176
|
+
|
|
177
|
+
def perform(post_id)
|
|
178
|
+
post = Post.find_by(id: post_id)
|
|
179
|
+
return unless post # El post puede haberse eliminado
|
|
180
|
+
|
|
181
|
+
post.author.seguidores.find_each do |seguidor|
|
|
182
|
+
NotificacionMailer.nueva_publicacion(seguidor, post).deliver_later
|
|
183
|
+
end
|
|
184
|
+
rescue StandardError => e
|
|
185
|
+
Rails.logger.error("NotificarSeguidoresJob falló para post #{post_id}: #{e.message}")
|
|
186
|
+
raise # Re-raise para que Sidekiq reintente
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## MUST DO / MUST NOT DO
|
|
192
|
+
|
|
193
|
+
**MUST DO:**
|
|
194
|
+
- `includes`/`eager_load` para prevenir N+1 en toda relación accedida fuera del modelo
|
|
195
|
+
- `strong_parameters` en todos los controllers (`permit` explícito, nunca `permit!`)
|
|
196
|
+
- Service objects para lógica de negocio compleja (más de 3 pasos o con side effects)
|
|
197
|
+
- `find_by` en lugar de `find` cuando el registro puede no existir
|
|
198
|
+
- Migraciones reversibles (`change` cuando es reversible, `up`/`down` cuando no)
|
|
199
|
+
- Tests con RSpec — cobertura >90% en modelos y services
|
|
200
|
+
- `perform_later` para jobs (async). `perform_now` solo en tests o CLIs
|
|
201
|
+
|
|
202
|
+
**MUST NOT DO:**
|
|
203
|
+
- Lógica de negocio en controllers ni en views
|
|
204
|
+
- `User.all` sin paginación en listas grandes (usar `kaminari` o `pagy`)
|
|
205
|
+
- Queries N+1 — instalar `bullet` gem en desarrollo para detectarlas
|
|
206
|
+
- `rescue Exception` — usar `rescue StandardError`
|
|
207
|
+
- `update_attribute` (omite validaciones) — usar `update` o `save`
|
|
208
|
+
- Secrets en código fuente — usar `rails credentials:edit` o variables de entorno
|
|
209
|
+
- Requests HTTP ni IO en callbacks de modelo (`after_save`, `after_create`)
|
|
210
|
+
|
|
211
|
+
## Checklist de verificación
|
|
212
|
+
|
|
213
|
+
- [ ] Toda relación accedida en vista o serialización usa `includes`/`eager_load`
|
|
214
|
+
- [ ] `post_params` usa `permit` explícito (sin `permit!`)
|
|
215
|
+
- [ ] Lógica compleja extraída a service object en `app/services/`
|
|
216
|
+
- [ ] Jobs reintentables, idempotentes y con `find_by` (no `find`)
|
|
217
|
+
- [ ] Migraciones con `change` o pareja `up`/`down`
|
|
218
|
+
- [ ] Tests de modelo, request y (si hay JS) system specs cubren el happy path y errores
|
|
219
|
+
- [ ] Sin secrets hardcodeados (usar `Rails.application.credentials` o `ENV`)
|
|
220
|
+
|
|
221
|
+
## Gotchas / Errores comunes no obvios
|
|
222
|
+
|
|
223
|
+
**Callbacks de modelo (`after_save`, `after_create`) con llamadas HTTP o IO bloquean la transacción completa**: Rails ejecuta los callbacks dentro de la transacción del `save`. Si el callback llama a un servicio externo (Stripe, Slack, S3) y falla, la transacción hace rollback pero el efecto externo ya ocurrió — estado inconsistente. Causa: los callbacks son síncronos y viven dentro del bloque de transacción de ActiveRecord. Fix: mover efectos secundarios externos a jobs (`after_create_commit { MyJob.perform_later(id) }`) o usar el patrón service object donde el commit ocurre antes de los side effects.
|
|
224
|
+
|
|
225
|
+
**`counter_cache` con `increment_counter` directo no dispara validaciones ni callbacks**: `Post.increment_counter(:comments_count, post_id)` actualiza la columna directamente con SQL sin pasar por el modelo, ignorando `before_save`, `after_save` y validaciones. Causa: es una operación SQL cruda para eficiencia. Fix: si se necesitan callbacks, usar `update` en la instancia del modelo; si solo se necesita el conteo sin callbacks, `increment_counter` es correcto y más eficiente.
|
|
226
|
+
|
|
227
|
+
**Migraciones con `add_index` en tablas grandes bloquean escrituras en PostgreSQL**: `add_index :facturas, :cliente_id` adquiere un `AccessExclusiveLock` durante toda la creación del índice — en tablas con millones de filas esto puede durar minutos bloqueando inserts y updates. Causa: el comportamiento por defecto de PostgreSQL. Fix: usar `add_index :facturas, :cliente_id, algorithm: :concurrently` en la migración, y separar la migración en su propio deployment sin otras operaciones DDL. Requiere que la migración sea irreversible o usar `disable_ddl_transaction!`.
|
|
228
|
+
|
|
229
|
+
**Turbo Frames requieren IDs de DOM únicos en toda la página — duplicados causan actualizaciones incorrectas**: si dos `turbo_frame_tag "comentario"` con el mismo id existen en la página (ej: en un listado), Turbo actualiza solo el primero que encuentra al recibir la respuesta. Causa: Turbo usa `document.getElementById()` que retorna el primer match. Fix: usar IDs compuestos con el `id` del registro: `turbo_frame_tag dom_id(comentario)` que genera `comentario_42`, `comentario_43`, etc.
|
|
230
|
+
|
|
231
|
+
## Referencias a recursos extendidos
|
|
232
|
+
|
|
233
|
+
| Tema | Archivo |
|
|
234
|
+
|------|---------|
|
|
235
|
+
| Active Record avanzado: concerns, counter_cache, STI, bulk ops, encryption | [recursos/active-record.md](recursos/active-record.md) |
|
|
236
|
+
| Hotwire: Turbo Frames, Turbo Streams, Stimulus, Action Cable, morphing | [recursos/hotwire-turbo.md](recursos/hotwire-turbo.md) |
|
|
237
|
+
| RSpec: factories, request specs, system specs, mocking, coverage | [recursos/testing-rspec.md](recursos/testing-rspec.md) |
|