@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,238 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Genera CHANGELOG.md desde commits siguiendo la especificación Conventional Commits.
|
|
3
|
+
# Uso:
|
|
4
|
+
# bash habilidades/release-semver/scripts/generar-changelog.sh [tag-anterior] [tag-nuevo]
|
|
5
|
+
#
|
|
6
|
+
# Ejemplos:
|
|
7
|
+
# bash habilidades/release-semver/scripts/generar-changelog.sh # desde último tag hasta HEAD
|
|
8
|
+
# bash habilidades/release-semver/scripts/generar-changelog.sh v1.4.0 # desde v1.4.0 hasta HEAD
|
|
9
|
+
# bash habilidades/release-semver/scripts/generar-changelog.sh v1.4.0 v1.5.0 # entre dos tags
|
|
10
|
+
#
|
|
11
|
+
# Salida:
|
|
12
|
+
# CHANGELOG.md en el directorio actual (añade la nueva sección al inicio)
|
|
13
|
+
# Exit code 0 si OK, 1 si hay error
|
|
14
|
+
|
|
15
|
+
set -euo pipefail
|
|
16
|
+
|
|
17
|
+
# ─── Colores ────────────────────────────────────────────────────────────────────
|
|
18
|
+
C_OK="\033[0;32m" C_FAIL="\033[0;31m" C_INFO="\033[0;36m" C_RESET="\033[0m"
|
|
19
|
+
|
|
20
|
+
info() { printf "${C_INFO}INFO${C_RESET} %s\n" "$*"; }
|
|
21
|
+
ok() { printf "${C_OK}OK${C_RESET} %s\n" "$*"; }
|
|
22
|
+
fail() { printf "${C_FAIL}ERROR${C_RESET} %s\n" "$*" >&2; exit 1; }
|
|
23
|
+
|
|
24
|
+
# ─── Verificar dependencias ──────────────────────────────────────────────────────
|
|
25
|
+
command -v git >/dev/null 2>&1 || fail "git no está instalado o no está en PATH"
|
|
26
|
+
|
|
27
|
+
# ─── Verificar que estamos en un repositorio git ─────────────────────────────────
|
|
28
|
+
git rev-parse --git-dir >/dev/null 2>&1 || fail "No se detectó un repositorio git en el directorio actual"
|
|
29
|
+
|
|
30
|
+
# ─── Argumentos ─────────────────────────────────────────────────────────────────
|
|
31
|
+
TAG_ANTERIOR="${1:-}"
|
|
32
|
+
TAG_NUEVO="${2:-HEAD}"
|
|
33
|
+
|
|
34
|
+
# Si no se especificó tag anterior, usar el último tag disponible
|
|
35
|
+
if [[ -z "${TAG_ANTERIOR}" ]]; then
|
|
36
|
+
TAG_ANTERIOR="$(git describe --tags --abbrev=0 2>/dev/null || true)"
|
|
37
|
+
if [[ -z "${TAG_ANTERIOR}" ]]; then
|
|
38
|
+
info "No se encontró ningún tag previo — incluyendo todos los commits"
|
|
39
|
+
RANGO=""
|
|
40
|
+
else
|
|
41
|
+
info "Tag anterior detectado automáticamente: ${TAG_ANTERIOR}"
|
|
42
|
+
RANGO="${TAG_ANTERIOR}..${TAG_NUEVO}"
|
|
43
|
+
fi
|
|
44
|
+
else
|
|
45
|
+
RANGO="${TAG_ANTERIOR}..${TAG_NUEVO}"
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# ─── Detectar la versión nueva ────────────────────────────────────────────────────
|
|
49
|
+
if [[ "${TAG_NUEVO}" == "HEAD" ]]; then
|
|
50
|
+
# Inferir versión desde el tag anterior bumpeando según los commits
|
|
51
|
+
if [[ -z "${TAG_ANTERIOR}" ]]; then
|
|
52
|
+
VERSION_NUEVA="0.1.0"
|
|
53
|
+
else
|
|
54
|
+
VERSION_BASE="${TAG_ANTERIOR#v}" # Quitar el prefijo 'v' si existe
|
|
55
|
+
IFS='.' read -r MAJOR MINOR PATCH <<< "${VERSION_BASE}"
|
|
56
|
+
MAJOR="${MAJOR:-0}" MINOR="${MINOR:-0}" PATCH="${PATCH:-0}"
|
|
57
|
+
|
|
58
|
+
# Detectar si hay breaking changes (MAJOR bump)
|
|
59
|
+
TIENE_BREAKING=0
|
|
60
|
+
if git log ${RANGO:+${RANGO}} --pretty=format:"%s" 2>/dev/null | grep -qE '!:|BREAKING CHANGE'; then
|
|
61
|
+
TIENE_BREAKING=1
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
# Detectar si hay feat: (MINOR bump)
|
|
65
|
+
TIENE_FEAT=0
|
|
66
|
+
if git log ${RANGO:+${RANGO}} --pretty=format:"%s" 2>/dev/null | grep -qE '^feat(\([^)]+\))?:'; then
|
|
67
|
+
TIENE_FEAT=1
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
if [[ $TIENE_BREAKING -eq 1 ]]; then
|
|
71
|
+
VERSION_NUEVA="$((MAJOR+1)).0.0"
|
|
72
|
+
info "Breaking change detectado — bumpeando MAJOR: ${TAG_ANTERIOR} → v${VERSION_NUEVA}"
|
|
73
|
+
elif [[ $TIENE_FEAT -eq 1 ]]; then
|
|
74
|
+
VERSION_NUEVA="${MAJOR}.$((MINOR+1)).0"
|
|
75
|
+
info "Nueva funcionalidad detectada — bumpeando MINOR: ${TAG_ANTERIOR} → v${VERSION_NUEVA}"
|
|
76
|
+
else
|
|
77
|
+
VERSION_NUEVA="${MAJOR}.${MINOR}.$((PATCH+1))"
|
|
78
|
+
info "Solo fixes/chores detectados — bumpeando PATCH: ${TAG_ANTERIOR} → v${VERSION_NUEVA}"
|
|
79
|
+
fi
|
|
80
|
+
fi
|
|
81
|
+
else
|
|
82
|
+
VERSION_NUEVA="${TAG_NUEVO#v}"
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
FECHA_HOY="$(date '+%Y-%m-%d')"
|
|
86
|
+
|
|
87
|
+
info "Generando changelog para la versión v${VERSION_NUEVA} (${FECHA_HOY})"
|
|
88
|
+
[[ -n "${RANGO}" ]] && info "Rango de commits: ${RANGO}" || info "Rango de commits: todos"
|
|
89
|
+
|
|
90
|
+
# ─── Recolectar commits por categoría ────────────────────────────────────────────
|
|
91
|
+
|
|
92
|
+
# Función para obtener commits de un tipo específico
|
|
93
|
+
commits_por_tipo() {
|
|
94
|
+
local patron="$1"
|
|
95
|
+
if [[ -n "${RANGO}" ]]; then
|
|
96
|
+
git log "${RANGO}" --pretty=format:"%s|%h|%an" 2>/dev/null | grep -E "${patron}" || true
|
|
97
|
+
else
|
|
98
|
+
git log --pretty=format:"%s|%h|%an" 2>/dev/null | grep -E "${patron}" || true
|
|
99
|
+
fi
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
# Formatear una línea de commit como entrada de changelog
|
|
103
|
+
formatear_commit() {
|
|
104
|
+
local linea="$1"
|
|
105
|
+
local subject hash author scope descripcion
|
|
106
|
+
|
|
107
|
+
subject="$(echo "${linea}" | cut -d'|' -f1)"
|
|
108
|
+
hash="$(echo "${linea}" | cut -d'|' -f2)"
|
|
109
|
+
author="$(echo "${linea}" | cut -d'|' -f3)"
|
|
110
|
+
|
|
111
|
+
# Extraer scope y descripción del subject
|
|
112
|
+
# Formato: tipo(scope): descripcion O tipo: descripcion
|
|
113
|
+
scope="$(echo "${subject}" | grep -oP '(?<=\()([^)]+)(?=\))' || true)"
|
|
114
|
+
descripcion="$(echo "${subject}" | sed 's/^[a-z]*!\?\([^:]*\): *//')"
|
|
115
|
+
|
|
116
|
+
if [[ -n "${scope}" ]]; then
|
|
117
|
+
printf "- **%s**: %s (\`%s\`)\n" "${scope}" "${descripcion}" "${hash}"
|
|
118
|
+
else
|
|
119
|
+
printf "- %s (\`%s\`)\n" "${descripcion}" "${hash}"
|
|
120
|
+
fi
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
# ─── Construir las secciones ──────────────────────────────────────────────────────
|
|
124
|
+
|
|
125
|
+
SECCION_BREAKING=""
|
|
126
|
+
SECCION_FEAT=""
|
|
127
|
+
SECCION_FIX=""
|
|
128
|
+
SECCION_PERF=""
|
|
129
|
+
SECCION_REFACTOR=""
|
|
130
|
+
SECCION_DOCS=""
|
|
131
|
+
SECCION_CHORE=""
|
|
132
|
+
|
|
133
|
+
while IFS= read -r commit; do
|
|
134
|
+
[[ -z "${commit}" ]] && continue
|
|
135
|
+
SECCION_BREAKING="${SECCION_BREAKING}$(formatear_commit "${commit}")\n"
|
|
136
|
+
done < <(commits_por_tipo '^[a-z]+!:|BREAKING CHANGE')
|
|
137
|
+
|
|
138
|
+
while IFS= read -r commit; do
|
|
139
|
+
[[ -z "${commit}" ]] && continue
|
|
140
|
+
# Excluir breaking changes ya incluidos arriba
|
|
141
|
+
echo "${commit}" | grep -qE '!:|BREAKING CHANGE' && continue
|
|
142
|
+
SECCION_FEAT="${SECCION_FEAT}$(formatear_commit "${commit}")\n"
|
|
143
|
+
done < <(commits_por_tipo '^feat(\([^)]+\))?:')
|
|
144
|
+
|
|
145
|
+
while IFS= read -r commit; do
|
|
146
|
+
[[ -z "${commit}" ]] && continue
|
|
147
|
+
echo "${commit}" | grep -qE '!:|BREAKING CHANGE' && continue
|
|
148
|
+
SECCION_FIX="${SECCION_FIX}$(formatear_commit "${commit}")\n"
|
|
149
|
+
done < <(commits_por_tipo '^fix(\([^)]+\))?:')
|
|
150
|
+
|
|
151
|
+
while IFS= read -r commit; do
|
|
152
|
+
[[ -z "${commit}" ]] && continue
|
|
153
|
+
SECCION_PERF="${SECCION_PERF}$(formatear_commit "${commit}")\n"
|
|
154
|
+
done < <(commits_por_tipo '^perf(\([^)]+\))?:')
|
|
155
|
+
|
|
156
|
+
while IFS= read -r commit; do
|
|
157
|
+
[[ -z "${commit}" ]] && continue
|
|
158
|
+
SECCION_REFACTOR="${SECCION_REFACTOR}$(formatear_commit "${commit}")\n"
|
|
159
|
+
done < <(commits_por_tipo '^refactor(\([^)]+\))?:')
|
|
160
|
+
|
|
161
|
+
while IFS= read -r commit; do
|
|
162
|
+
[[ -z "${commit}" ]] && continue
|
|
163
|
+
SECCION_DOCS="${SECCION_DOCS}$(formatear_commit "${commit}")\n"
|
|
164
|
+
done < <(commits_por_tipo '^docs(\([^)]+\))?:')
|
|
165
|
+
|
|
166
|
+
while IFS= read -r commit; do
|
|
167
|
+
[[ -z "${commit}" ]] && continue
|
|
168
|
+
SECCION_CHORE="${SECCION_CHORE}$(formatear_commit "${commit}")\n"
|
|
169
|
+
done < <(commits_por_tipo '^(chore|ci|build|style|test)(\([^)]+\))?:')
|
|
170
|
+
|
|
171
|
+
# ─── Construir el bloque de la nueva versión ──────────────────────────────────────
|
|
172
|
+
|
|
173
|
+
NUEVA_SECCION="## [${VERSION_NUEVA}] - ${FECHA_HOY}\n\n"
|
|
174
|
+
|
|
175
|
+
[[ -n "${SECCION_BREAKING}" ]] && NUEVA_SECCION+="### Cambios incompatibles (Breaking Changes)\n\n${SECCION_BREAKING}\n"
|
|
176
|
+
[[ -n "${SECCION_FEAT}" ]] && NUEVA_SECCION+="### Nuevas funcionalidades\n\n${SECCION_FEAT}\n"
|
|
177
|
+
[[ -n "${SECCION_FIX}" ]] && NUEVA_SECCION+="### Correcciones\n\n${SECCION_FIX}\n"
|
|
178
|
+
[[ -n "${SECCION_PERF}" ]] && NUEVA_SECCION+="### Mejoras de rendimiento\n\n${SECCION_PERF}\n"
|
|
179
|
+
[[ -n "${SECCION_REFACTOR}" ]] && NUEVA_SECCION+="### Refactorizaciones\n\n${SECCION_REFACTOR}\n"
|
|
180
|
+
[[ -n "${SECCION_DOCS}" ]] && NUEVA_SECCION+="### Documentación\n\n${SECCION_DOCS}\n"
|
|
181
|
+
[[ -n "${SECCION_CHORE}" ]] && NUEVA_SECCION+="### Mantenimiento\n\n${SECCION_CHORE}\n"
|
|
182
|
+
|
|
183
|
+
# Verificar que hay al menos algo que registrar
|
|
184
|
+
TIENE_CONTENIDO=0
|
|
185
|
+
for seccion in "${SECCION_BREAKING}" "${SECCION_FEAT}" "${SECCION_FIX}" "${SECCION_PERF}" "${SECCION_REFACTOR}" "${SECCION_DOCS}" "${SECCION_CHORE}"; do
|
|
186
|
+
[[ -n "${seccion}" ]] && TIENE_CONTENIDO=1 && break
|
|
187
|
+
done
|
|
188
|
+
|
|
189
|
+
if [[ $TIENE_CONTENIDO -eq 0 ]]; then
|
|
190
|
+
info "No se encontraron commits con formato Conventional Commits en el rango especificado."
|
|
191
|
+
info "Asegúrate de que los commits siguen el formato: tipo(scope): descripcion"
|
|
192
|
+
exit 0
|
|
193
|
+
fi
|
|
194
|
+
|
|
195
|
+
# ─── Escribir o actualizar CHANGELOG.md ──────────────────────────────────────────
|
|
196
|
+
|
|
197
|
+
CHANGELOG_PATH="./CHANGELOG.md"
|
|
198
|
+
|
|
199
|
+
if [[ -f "${CHANGELOG_PATH}" ]]; then
|
|
200
|
+
# Preservar el encabezado existente e insertar la nueva sección después de él
|
|
201
|
+
ENCABEZADO="$(awk '/^## \[/{exit} {print}' "${CHANGELOG_PATH}")"
|
|
202
|
+
CONTENIDO_PREVIO="$(awk '/^## \[/{found=1} found{print}' "${CHANGELOG_PATH}")"
|
|
203
|
+
|
|
204
|
+
{
|
|
205
|
+
printf "%s" "${ENCABEZADO}"
|
|
206
|
+
printf "\n"
|
|
207
|
+
printf "%b" "${NUEVA_SECCION}"
|
|
208
|
+
printf "%s\n" "${CONTENIDO_PREVIO}"
|
|
209
|
+
} > "${CHANGELOG_PATH}.tmp"
|
|
210
|
+
|
|
211
|
+
mv "${CHANGELOG_PATH}.tmp" "${CHANGELOG_PATH}"
|
|
212
|
+
ok "Sección v${VERSION_NUEVA} insertada al inicio de CHANGELOG.md"
|
|
213
|
+
else
|
|
214
|
+
# Crear un CHANGELOG.md nuevo desde cero
|
|
215
|
+
{
|
|
216
|
+
printf "# Changelog\n\n"
|
|
217
|
+
printf "Todos los cambios relevantes del proyecto están documentados aquí.\n"
|
|
218
|
+
printf "Sigue el formato [Keep a Changelog](https://keepachangelog.com/es/1.0.0/)\n"
|
|
219
|
+
printf "y usa [Conventional Commits](https://www.conventionalcommits.org/).\n\n"
|
|
220
|
+
printf "---\n\n"
|
|
221
|
+
printf "%b" "${NUEVA_SECCION}"
|
|
222
|
+
} > "${CHANGELOG_PATH}"
|
|
223
|
+
ok "CHANGELOG.md creado con la versión v${VERSION_NUEVA}"
|
|
224
|
+
fi
|
|
225
|
+
|
|
226
|
+
# ─── Mostrar resumen ──────────────────────────────────────────────────────────────
|
|
227
|
+
printf "\n${C_OK}Changelog generado:${C_RESET}\n"
|
|
228
|
+
printf " Versión : v%s\n" "${VERSION_NUEVA}"
|
|
229
|
+
printf " Fecha : %s\n" "${FECHA_HOY}"
|
|
230
|
+
printf " Archivo : %s\n" "$(realpath "${CHANGELOG_PATH}")"
|
|
231
|
+
|
|
232
|
+
if [[ -n "${TAG_ANTERIOR}" ]]; then
|
|
233
|
+
printf "\nPróximos pasos recomendados:\n"
|
|
234
|
+
printf " git add CHANGELOG.md\n"
|
|
235
|
+
printf " git commit -m \"chore(release): v%s\"\n" "${VERSION_NUEVA}"
|
|
236
|
+
printf " git tag -a v%s -m \"Release v%s\"\n" "${VERSION_NUEVA}" "${VERSION_NUEVA}"
|
|
237
|
+
printf " git push origin HEAD --tags\n"
|
|
238
|
+
fi
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rust-experto
|
|
3
|
+
description: >
|
|
4
|
+
Rust idiomático: ownership, lifetimes, traits, async con Tokio y Axum/Actix-web.
|
|
5
|
+
Cubre SQLx, serde, clap, tracing y error handling con thiserror y anyhow.
|
|
6
|
+
Cargar cuando se implementen servicios Rust, APIs HTTP o lógica de sistemas.
|
|
7
|
+
version: "1.0.0"
|
|
8
|
+
herramientasPermitidas: [Read, Bash]
|
|
9
|
+
exclusiones:
|
|
10
|
+
- "No cargar para errores de compilación Rust (borrow checker, lifetimes) — para build errors cargar `build-errors-rust`."
|
|
11
|
+
- "No cargar para diseñar patrones idiomáticos Rust (newtype, builder, RAII) — para diseño cargar `rust-patrones`."
|
|
12
|
+
- "No cargar para escribir tests Rust (rstest, proptest, mockall) — para testing cargar `rust-testing`."
|
|
13
|
+
- "No cargar para C/C++ o sistemas no-Rust — este skill cubre el ecosistema Rust específicamente."
|
|
14
|
+
evolvable: true # default para skill estandar
|
|
15
|
+
---
|
|
16
|
+
# Rust Experto — Rust Idiomático y Servicios Async
|
|
17
|
+
|
|
18
|
+
Cubre el desarrollo Rust moderno: modelo de ownership y borrowing, lifetime
|
|
19
|
+
elision, trait design, async con Tokio, routing con Axum, acceso a base de datos
|
|
20
|
+
con SQLx y observabilidad con tracing.
|
|
21
|
+
|
|
22
|
+
## Cuándo cargar este skill
|
|
23
|
+
|
|
24
|
+
Invoca `Skill("rust-experto")` cuando:
|
|
25
|
+
|
|
26
|
+
- Se implementen endpoints HTTP con Axum o Actix-web
|
|
27
|
+
- Se usen queries de base de datos con SQLx
|
|
28
|
+
- Se diseñen traits con object safety
|
|
29
|
+
- Se configure async runtime con Tokio
|
|
30
|
+
- Se implemente error handling con thiserror o anyhow
|
|
31
|
+
- Se serialice/deserialice JSON con serde
|
|
32
|
+
|
|
33
|
+
## Cuándo NO cargar
|
|
34
|
+
|
|
35
|
+
- Los errores son de compilación Rust (borrow checker, lifetime annotations) — para build errors cargar `build-errors-rust`.
|
|
36
|
+
- La pregunta es sobre diseñar patrones idiomáticos Rust (newtype, builder con typestate, RAII) — para diseño cargar `rust-patrones`.
|
|
37
|
+
- La tarea es escribir tests Rust (rstest, proptest, mockall) — cargar `rust-testing`.
|
|
38
|
+
- El proyecto es C, C++ o un sistema no-Rust — este skill cubre el ecosistema Rust específicamente.
|
|
39
|
+
|
|
40
|
+
## Conceptos clave
|
|
41
|
+
|
|
42
|
+
### Ownership: cada valor tiene un único dueño
|
|
43
|
+
|
|
44
|
+
Cuando el dueño sale de scope, el valor se dropea. La transferencia (move) cede
|
|
45
|
+
la propiedad; el borrowing (`&T` o `&mut T`) presta sin ceder. El borrow checker
|
|
46
|
+
garantiza en tiempo de compilación que no hay data races ni use-after-free.
|
|
47
|
+
|
|
48
|
+
### Lifetime elision
|
|
49
|
+
|
|
50
|
+
El compilador infiere lifetimes en la mayoría de casos. Anotaciones explícitas
|
|
51
|
+
(`'a`) solo cuando el compilador no puede inferir la relación entre referencias
|
|
52
|
+
en firmas de funciones o structs que almacenan referencias.
|
|
53
|
+
|
|
54
|
+
### Traits y object safety
|
|
55
|
+
|
|
56
|
+
Un trait es object-safe si puede usarse como `dyn Trait`. Condiciones: no puede
|
|
57
|
+
tener métodos con `Self` en posición de retorno (excepto `Box<Self>`), ni generics
|
|
58
|
+
en métodos. Traits sin `dyn`: usar generics con bounds.
|
|
59
|
+
|
|
60
|
+
### async/await con Tokio
|
|
61
|
+
|
|
62
|
+
Rust no tiene runtime async incluido. Tokio es el runtime de producción. Las
|
|
63
|
+
funciones `async fn` retornan Futures; `tokio::spawn` lanza tareas en el threadpool.
|
|
64
|
+
|
|
65
|
+
## Reglas obligatorias
|
|
66
|
+
|
|
67
|
+
### .unwrap() y .expect() prohibidos en código de producción
|
|
68
|
+
|
|
69
|
+
`unwrap()` causa panic en producción. Usar `?` operator para propagar errores,
|
|
70
|
+
o manejar explícitamente con `match`/`if let`. `.expect("mensaje")` solo en tests.
|
|
71
|
+
|
|
72
|
+
```rust
|
|
73
|
+
// MAL
|
|
74
|
+
let conn = pool.acquire().await.unwrap();
|
|
75
|
+
|
|
76
|
+
// BIEN
|
|
77
|
+
let conn = pool.acquire().await
|
|
78
|
+
.map_err(|e| AppError::Database(e))?;
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Clone solo cuando ownership no es viable
|
|
82
|
+
|
|
83
|
+
`clone()` copia datos en heap, potencialmente costoso. Primero explorar si
|
|
84
|
+
borrowing o restructuring del código evita la necesidad.
|
|
85
|
+
|
|
86
|
+
```rust
|
|
87
|
+
// MAL — clone para evitar pensar en ownership
|
|
88
|
+
let nombre = usuario.nombre.clone();
|
|
89
|
+
procesar(nombre);
|
|
90
|
+
procesar_otro(usuario.nombre.clone());
|
|
91
|
+
|
|
92
|
+
// BIEN — borrowing cuando es posible
|
|
93
|
+
procesar(&usuario.nombre);
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Arc<Mutex<T>> como último recurso — evaluar alternativas primero
|
|
97
|
+
|
|
98
|
+
Para estado compartido entre threads, evaluar primero:
|
|
99
|
+
1. Pasar ownership por canal (mpsc)
|
|
100
|
+
2. Estado inmutable compartido con Arc<T>
|
|
101
|
+
3. Solo si mutacion concurrente es inevitable: Arc<Mutex<T>>
|
|
102
|
+
|
|
103
|
+
### Implementar thiserror en errores de libreria, anyhow en binarios
|
|
104
|
+
|
|
105
|
+
`thiserror` genera implementaciones de `Error` con mensajes descriptivos para
|
|
106
|
+
errores de dominio. `anyhow` provee contexto en binarios sin forzar tipos de error.
|
|
107
|
+
|
|
108
|
+
## Patrones recomendados
|
|
109
|
+
|
|
110
|
+
### Axum router con estado compartido
|
|
111
|
+
|
|
112
|
+
```rust
|
|
113
|
+
#[derive(Clone)]
|
|
114
|
+
struct AppState {
|
|
115
|
+
db: PgPool,
|
|
116
|
+
config: Arc<Config>,
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
#[tokio::main]
|
|
120
|
+
async fn main() -> anyhow::Result<()> {
|
|
121
|
+
let pool = PgPoolOptions::new()
|
|
122
|
+
.max_connections(10)
|
|
123
|
+
.connect(&config.database_url).await?;
|
|
124
|
+
|
|
125
|
+
let state = AppState { db: pool, config: Arc::new(config) };
|
|
126
|
+
|
|
127
|
+
let app = Router::new()
|
|
128
|
+
.route("/v1/pedidos", get(listar_pedidos).post(crear_pedido))
|
|
129
|
+
.route("/v1/pedidos/:id", get(obtener_pedido))
|
|
130
|
+
.with_state(state)
|
|
131
|
+
.layer(TraceLayer::new_for_http());
|
|
132
|
+
|
|
133
|
+
let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await?;
|
|
134
|
+
axum::serve(listener, app).await?;
|
|
135
|
+
Ok(())
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Handler Axum con extractor y error handling
|
|
140
|
+
|
|
141
|
+
```rust
|
|
142
|
+
async fn crear_pedido(
|
|
143
|
+
State(state): State<AppState>,
|
|
144
|
+
Json(req): Json<CrearPedidoRequest>,
|
|
145
|
+
) -> Result<(StatusCode, Json<PedidoResponse>), AppError> {
|
|
146
|
+
req.validate()?;
|
|
147
|
+
|
|
148
|
+
let pedido = sqlx::query_as!(
|
|
149
|
+
Pedido,
|
|
150
|
+
"INSERT INTO pedidos (cliente_id, total) VALUES ($1, $2) RETURNING *",
|
|
151
|
+
req.cliente_id,
|
|
152
|
+
req.calcular_total()
|
|
153
|
+
)
|
|
154
|
+
.fetch_one(&state.db)
|
|
155
|
+
.await
|
|
156
|
+
.map_err(AppError::Database)?;
|
|
157
|
+
|
|
158
|
+
Ok((StatusCode::CREATED, Json(pedido.into())))
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Error handling con thiserror
|
|
163
|
+
|
|
164
|
+
```rust
|
|
165
|
+
#[derive(Debug, thiserror::Error)]
|
|
166
|
+
pub enum AppError {
|
|
167
|
+
#[error("recurso no encontrado: {0}")]
|
|
168
|
+
NotFound(String),
|
|
169
|
+
|
|
170
|
+
#[error("error de base de datos")]
|
|
171
|
+
Database(#[from] sqlx::Error),
|
|
172
|
+
|
|
173
|
+
#[error("validacion fallida: {0}")]
|
|
174
|
+
Validation(String),
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// IntoResponse para Axum
|
|
178
|
+
impl IntoResponse for AppError {
|
|
179
|
+
fn into_response(self) -> Response {
|
|
180
|
+
let (status, mensaje) = match &self {
|
|
181
|
+
AppError::NotFound(_) => (StatusCode::NOT_FOUND, self.to_string()),
|
|
182
|
+
AppError::Validation(_) => (StatusCode::BAD_REQUEST, self.to_string()),
|
|
183
|
+
AppError::Database(_) => (StatusCode::INTERNAL_SERVER_ERROR, "error interno".into()),
|
|
184
|
+
};
|
|
185
|
+
(status, Json(json!({ "error": mensaje }))).into_response()
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Serde con rename y skip
|
|
191
|
+
|
|
192
|
+
```rust
|
|
193
|
+
#[derive(Debug, Serialize, Deserialize)]
|
|
194
|
+
#[serde(rename_all = "camelCase")]
|
|
195
|
+
pub struct PedidoResponse {
|
|
196
|
+
pub id: Uuid,
|
|
197
|
+
pub cliente_id: Uuid,
|
|
198
|
+
pub total: Decimal,
|
|
199
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
200
|
+
pub notas: Option<String>,
|
|
201
|
+
#[serde(with = "time::serde::rfc3339")]
|
|
202
|
+
pub creado_en: OffsetDateTime,
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Tokio select! para concurrencia con cancelacion
|
|
207
|
+
|
|
208
|
+
```rust
|
|
209
|
+
tokio::select! {
|
|
210
|
+
resultado = procesar_pedido(pedido_id) => {
|
|
211
|
+
resultado?;
|
|
212
|
+
}
|
|
213
|
+
_ = tokio::time::sleep(Duration::from_secs(30)) => {
|
|
214
|
+
return Err(AppError::Timeout);
|
|
215
|
+
}
|
|
216
|
+
_ = shutdown_signal.recv() => {
|
|
217
|
+
tracing::info!("shutdown solicitado, cancelando operacion");
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Tracing para observabilidad
|
|
223
|
+
|
|
224
|
+
```rust
|
|
225
|
+
#[instrument(skip(state), fields(cliente_id = %req.cliente_id))]
|
|
226
|
+
async fn crear_pedido(
|
|
227
|
+
State(state): State<AppState>,
|
|
228
|
+
Json(req): Json<CrearPedidoRequest>,
|
|
229
|
+
) -> Result<Json<PedidoResponse>, AppError> {
|
|
230
|
+
tracing::info!("creando pedido");
|
|
231
|
+
let pedido = state.pedido_service.crear(req).await?;
|
|
232
|
+
tracing::info!(pedido_id = %pedido.id, "pedido creado");
|
|
233
|
+
Ok(Json(pedido))
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Anti-patrones conocidos
|
|
238
|
+
|
|
239
|
+
### transmute para castear tipos
|
|
240
|
+
|
|
241
|
+
```rust
|
|
242
|
+
// MAL — undefined behavior, bypass del type system
|
|
243
|
+
let bytes: &[u8] = unsafe { std::mem::transmute(mi_struct) };
|
|
244
|
+
|
|
245
|
+
// BIEN — implementar From/Into o usar serde para serializar
|
|
246
|
+
let bytes = bincode::serialize(&mi_struct)?;
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Exceso de cloning para satisfacer al borrow checker
|
|
250
|
+
|
|
251
|
+
```rust
|
|
252
|
+
// MAL — clone en cada iteracion
|
|
253
|
+
for item in &items {
|
|
254
|
+
procesar(item.nombre.clone(), item.id.clone());
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// BIEN — borrowing o referencias
|
|
258
|
+
for item in &items {
|
|
259
|
+
procesar(&item.nombre, item.id);
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Checklist de verificación
|
|
264
|
+
|
|
265
|
+
- [ ] Sin .unwrap() en código de producción: usar ? o match
|
|
266
|
+
- [ ] Clone explícito y justificado, no como solución rápida al borrow checker
|
|
267
|
+
- [ ] Errores de dominio con thiserror; propagación en binarios con anyhow
|
|
268
|
+
- [ ] Handlers Axum retornan Result<_, AppError> con IntoResponse implementado
|
|
269
|
+
- [ ] Tracing con #[instrument] en funciones de servicio y handlers
|
|
270
|
+
- [ ] Arc<Mutex<T>> solo cuando la alternativa con canales no aplica
|
|
271
|
+
- [ ] SQLx con query_as! para types chequeados en compilación
|
|
272
|
+
|
|
273
|
+
## Rosetta Stone: Python → Rust
|
|
274
|
+
|
|
275
|
+
Tabla de equivalencias para devs que migran desde Python:
|
|
276
|
+
|
|
277
|
+
| Python | Rust | Notas |
|
|
278
|
+
|--------|------|-------|
|
|
279
|
+
| `list` | `Vec<T>` | Dinámico, tipado en compilación |
|
|
280
|
+
| `dict` | `HashMap<K,V>` | Requiere `K: Hash + Eq` |
|
|
281
|
+
| `set` | `HashSet<T>` | Mismo requerimiento |
|
|
282
|
+
| `tuple` | `(T1, T2, ...)` | Inmutable por defecto |
|
|
283
|
+
| `class` | `struct` + `impl` | Sin herencia — composición via traits |
|
|
284
|
+
| `@dataclass` | `#[derive(Debug, Clone, PartialEq)]` | Derivación en compilación |
|
|
285
|
+
| `Enum` | `enum` | Con datos en variantes — mucho más poderoso |
|
|
286
|
+
| `None` | `Option<T>` | El compilador obliga a manejar el caso vacío |
|
|
287
|
+
| `raise` / `try` / `except` | `Result<T, E>` + `?` | Sin excepciones — errores como valores |
|
|
288
|
+
| `Protocol` (PEP 544) | `trait` | Polimorfismo en compilación |
|
|
289
|
+
| `TypeVar` | Genéricos `<T>` | Monomorphización — cero overhead |
|
|
290
|
+
| `__dunder__` methods | Traits (`Display`, `Add`, `Eq`...) | Implementar el trait correcto |
|
|
291
|
+
| `lambda` | `\|args\| body` | Closures — capturan el ambiente |
|
|
292
|
+
| `generator yield` | `impl Iterator` | Lazy por defecto, sin runtime extra |
|
|
293
|
+
| `[x for x in data if x > 0]` | `.iter().filter(...).map(...).collect()` | Más verboso, type-safe, más rápido |
|
|
294
|
+
| `@decorator` | Higher-order fn o macro | `#[tracing::instrument]` es un decorador |
|
|
295
|
+
| `asyncio` | `tokio` | Rust no incluye runtime — Tokio es el estándar |
|
|
296
|
+
| `threading` | `std::thread` | Sin GIL — data races bloqueadas en compilación |
|
|
297
|
+
| `multiprocessing` | `rayon` | Paralelismo de datos idiomático |
|
|
298
|
+
| `unittest.mock` | `mockall` | Mocking basado en traits |
|
|
299
|
+
| `pytest` | `cargo test` + `rstest` | Tests inline en el mismo archivo |
|
|
300
|
+
| `pip install` | `cargo add` | Modifica Cargo.toml |
|
|
301
|
+
| `requirements.txt` | `Cargo.lock` | Lockfile determinístico |
|
|
302
|
+
| `pyproject.toml` | `Cargo.toml` | Metadatos del crate |
|
|
303
|
+
| `with` (context manager) | Scope-based `Drop` | RAII — sin `with`, el compilador lo hace |
|
|
304
|
+
| `json.dumps` / `loads` | `serde_json::to_string` / `from_str` | Type-safe en compilación |
|
|
305
|
+
| `dataclasses.field(default_factory=list)` | `#[serde(default)]` + `Vec::new()` | |
|
|
306
|
+
|
|
307
|
+
**Errores comunes al llegar desde Python:**
|
|
308
|
+
|
|
309
|
+
| Error | Por qué | Fix |
|
|
310
|
+
|-------|---------|-----|
|
|
311
|
+
| `.unwrap()` en todo | Pánico en runtime | Usar `?` o `match` |
|
|
312
|
+
| `String` en parámetros | Allocación innecesaria | Usar `&str` — acepta ambos |
|
|
313
|
+
| `for i in 0..vec.len()` | No idiomático | `for item in &vec` |
|
|
314
|
+
| Clones para evitar el borrow checker | Overhead de memoria | Refactorizar ownership |
|
|
315
|
+
| Función `main()` gigante | Hard to test | Separar en `lib.rs` y `main.rs` |
|
|
316
|
+
| Ignorar warnings de clippy | Pierde correcciones fáciles | `cargo clippy` como `ruff` |
|
|
317
|
+
|
|
318
|
+
**Referencia completa:** `temp/RustTraining-main/python-book/src/ch15-migration-patterns.md` y `ch16-best-practices.md`
|
|
319
|
+
|
|
320
|
+
## Rosetta Stone: C# → Rust
|
|
321
|
+
|
|
322
|
+
Tabla de equivalencias para devs que migran desde C#:
|
|
323
|
+
|
|
324
|
+
| C# | Rust | Diferencia clave |
|
|
325
|
+
|----|------|-----------------|
|
|
326
|
+
| `class` | `struct` + `impl` | Sin herencia de implementación |
|
|
327
|
+
| `interface` | `trait` | Traits son más potentes (default impls, blanket impls) |
|
|
328
|
+
| `abstract class` | `trait` con métodos default | Sin estado en el trait |
|
|
329
|
+
| `class Dog : Animal, IFlyable` | `impl Animal for Dog` + `impl Flyable for Dog` | Composición explícita |
|
|
330
|
+
| `record` (inmutabilidad aparente) | `struct` (inmutabilidad real) | `let x = ...` es inmutable; `mut` es explícito |
|
|
331
|
+
| `string` | `String` (owned) / `&str` (borrowed) | Dos tipos distintos — `&str` para parámetros |
|
|
332
|
+
| `string?` | `Option<String>` | El compilador fuerza el manejo de `None` |
|
|
333
|
+
| `int?` / `Nullable<T>` | `Option<T>` | Mismo concepto, sin boxing |
|
|
334
|
+
| `try` / `catch` | `Result<T, E>` + `?` | Errores como valores — no excepciones de control |
|
|
335
|
+
| `throw new X()` | `return Err(X)` | Explícito en la firma de la función |
|
|
336
|
+
| `List<T>` | `Vec<T>` | Sin carga de GC |
|
|
337
|
+
| `Dictionary<K,V>` | `HashMap<K,V>` | Requiere `K: Hash + Eq` |
|
|
338
|
+
| `IEnumerable<T>` | `impl Iterator<Item=T>` | Lazy, zero-cost |
|
|
339
|
+
| `LINQ .Where().Select()` | `.iter().filter().map().collect()` | Sin boxing, tipo comprobado |
|
|
340
|
+
| `async Task<T>` | `async fn() -> T` | Sin runtime incluido — requiere Tokio |
|
|
341
|
+
| `await task` | `.await` | Mismo concepto, distinta sintaxis |
|
|
342
|
+
| `IDisposable` + `using` | `Drop` trait + scope | RAII automático — no se puede olvidar |
|
|
343
|
+
| `lock(obj)` | `Mutex<T>`, `RwLock<T>` | El dato está dentro del lock — no se puede acceder sin él |
|
|
344
|
+
| `static readonly` | `static` + `OnceLock<T>` | Inicialización lazy thread-safe |
|
|
345
|
+
| `partial class` | Múltiples `impl` blocks | Sin limitación de archivos |
|
|
346
|
+
| `sealed class` | Sealed traits (patrón manual) | Con `mod` privado y trait privado |
|
|
347
|
+
| `null` | No existe | `Option<T>` lo reemplaza completamente |
|
|
348
|
+
| Generics `where T : IFoo` | `fn f<T: Foo>(...)` | Bounds en compilación — monomorphización |
|
|
349
|
+
| `NuGet` | `cargo add` / `Cargo.toml` | Registry centralizado (crates.io) |
|
|
350
|
+
| `packages.lock.json` | `Cargo.lock` | Lockfile determinístico |
|
|
351
|
+
|
|
352
|
+
**Diferencias conceptuales críticas:**
|
|
353
|
+
|
|
354
|
+
| Concepto C# | Comportamiento C# | Comportamiento Rust |
|
|
355
|
+
|------------|------------------|-------------------|
|
|
356
|
+
| Inmutabilidad en `record` | Shallow — referencias mutables filtran | Real — el compilador bloquea mutación |
|
|
357
|
+
| GC | Automático, latencia impredecible | Sin GC — Drop determinístico |
|
|
358
|
+
| Herencia | `class Dog : Animal` reutiliza implementación | No existe — usar composición con traits |
|
|
359
|
+
| Nulos | `NullReferenceException` en runtime | Imposible — `Option<T>` obliga al manejo |
|
|
360
|
+
| Excepciones | Stack unwinding — control de flujo | `Result<T,E>` — errores en la firma |
|
|
361
|
+
|
|
362
|
+
**Referencia completa:** `temp/RustTraining-main/csharp-book/src/` — Ch3-1, Ch7-1, Ch9-1, Ch10-2
|
|
363
|
+
|
|
364
|
+
## Integración con wiki del proyecto (Fase 3)
|
|
365
|
+
|
|
366
|
+
Para indexar el conocimiento de RustTraining en el wiki del proyecto usando el patrón Karpathy:
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
# Ingerir libro de patrones de ingeniería
|
|
370
|
+
/swl:wiki ingest temp/RustTraining-main/engineering-book/src/
|
|
371
|
+
|
|
372
|
+
# Ingerir libro de type-driven correctness
|
|
373
|
+
/swl:wiki ingest temp/RustTraining-main/type-driven-correctness-book/src/
|
|
374
|
+
|
|
375
|
+
# Ingerir libro de patrones Rust
|
|
376
|
+
/swl:wiki ingest temp/RustTraining-main/rust-patterns-book/src/
|
|
377
|
+
|
|
378
|
+
# Consultar el wiki tras el ingest
|
|
379
|
+
/swl:wiki query "¿cuándo usar type-state vs enum dispatch?"
|
|
380
|
+
/swl:wiki query "cómo configurar cargo-deny para licencias comerciales"
|
|
381
|
+
/swl:wiki query "benchmarking con criterion vs divan"
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
**Cuándo hacer el ingest:**
|
|
385
|
+
- Al iniciar un proyecto Rust nuevo con swl-ses
|
|
386
|
+
- Antes de una sesión de code review con `revisor-rust-swl`
|
|
387
|
+
- Cuando el equipo tiene devs migrando desde Python o C#
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
## Gotchas / Errores comunes no obvios
|
|
391
|
+
|
|
392
|
+
**`async fn` en un trait no es directamente usable como `dyn Trait`**: en Rust estable, `trait MiTrait { async fn hacer(&self); }` no puede usarse como `Box<dyn MiTrait>` porque el compilador necesita conocer el tamaño del Future retornado. Fix: usar la crate `async-trait` con `#[async_trait]`, o en Rust 1.75+ usar `impl Trait` en la firma del trait si el objeto dinámico no es necesario.
|
|
393
|
+
|
|
394
|
+
**`sqlx::query!` macro falla en CI si `DATABASE_URL` no está disponible en compile time**: la macro `query!` verifica el SQL contra la BD en tiempo de compilación — si el CI no tiene acceso a la BD, el build falla. Fix: usar `DATABASE_URL` en `.env` para desarrollo local, y configurar en CI usando `sqlx::query_as!` con archivos de snapshot (`sqlx prepare`) o deshabilitar la verificación en línea con `SQLX_OFFLINE=true` y committear `.sqlx/`.
|
|
395
|
+
|
|
396
|
+
**`Arc<Mutex<T>>` con `.lock().unwrap()` en código async causa deadlock con Tokio**: si el MutexGuard cruza un await point, el guard se mantiene bloqueado durante toda la operación async. Fix: usar `tokio::sync::Mutex` en lugar de `std::sync::Mutex` en código async — `tokio::sync::Mutex` puede ser mantenido a través de await points sin deadlock.
|
|
397
|
+
|
|
398
|
+
**`#[derive(Serialize)]` con campos `Option<Vec<T>>` serializa como `null` en lugar de omitir el campo**: `serde` serializa `None` como `null` por defecto — si el receptor espera que el campo esté ausente (no presente como `null`), la deserialización puede fallar. Fix: usar `#[serde(skip_serializing_if = "Option::is_none")]` en el campo para omitirlo cuando es `None`.
|
|
399
|
+
|
|
400
|
+
*Skill creado con swl:crear-skill el 2026-03-31. Versión 1.1.0 — rosetta stones Python/C# y wiki integration añadidos el 2026-04-09.*
|