@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,335 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nextjs-experto
|
|
3
|
+
description: >
|
|
4
|
+
Next.js App Router: Server Components, Client Components, Server Actions,
|
|
5
|
+
streaming con Suspense, ISR, route handlers y middleware. Cargar cuando se
|
|
6
|
+
implementen páginas Next.js, data fetching, mutaciones o rutas de API.
|
|
7
|
+
version: "1.0.0"
|
|
8
|
+
herramientasPermitidas: [Read]
|
|
9
|
+
exclusiones:
|
|
10
|
+
- "No cargar para proyectos Next.js con Pages Router (pages/index.tsx) — el modelo de getServerSideProps y getStaticProps es diferente al App Router; este skill solo cubre App Router."
|
|
11
|
+
- "No cargar para errores de compilación next build — para esos cargar `build-errors-nextjs` que cubre hydration mismatch, Turbopack y errores de RSC."
|
|
12
|
+
- "No cargar cuando la pregunta es sobre patrones de arquitectura de App Router (nested layouts, parallel routes, caching strategies) — para diseño de arquitectura cargar `nextjs-patrones`."
|
|
13
|
+
- "No cargar para testing de componentes Next.js (Vitest, RTL, Playwright) — para escribir tests cargar `nextjs-testing`."
|
|
14
|
+
evolvable: true # default para skill estandar
|
|
15
|
+
---
|
|
16
|
+
# Next.js Experto — App Router Moderno
|
|
17
|
+
|
|
18
|
+
Next.js 13+ con App Router cambia el modelo mental: los componentes son Server
|
|
19
|
+
Components por defecto. El cliente solo recibe HTML renderizado y los fragments
|
|
20
|
+
de JS necesarios para interactividad. Este skill cubre los patrones del App Router,
|
|
21
|
+
data fetching con cache granular, Server Actions y middleware.
|
|
22
|
+
|
|
23
|
+
## Cuándo cargar este skill
|
|
24
|
+
|
|
25
|
+
Invoca `Skill("nextjs-experto")` cuando:
|
|
26
|
+
|
|
27
|
+
- Se implementen páginas, layouts o rutas en App Router
|
|
28
|
+
- Se configure data fetching con cache y revalidación
|
|
29
|
+
- Se implementen Server Actions para mutaciones
|
|
30
|
+
- Se creen route handlers (API routes en App Router)
|
|
31
|
+
- Se configure middleware para autenticación o i18n
|
|
32
|
+
- Se use `generateStaticParams` para SSG dinámico
|
|
33
|
+
|
|
34
|
+
## Cuándo NO cargar
|
|
35
|
+
|
|
36
|
+
- El proyecto usa Pages Router (`pages/index.tsx`, `getServerSideProps`, `getStaticProps`) — ese modelo es incompatible con App Router; las APIs de cache y Server Actions no aplican.
|
|
37
|
+
- La pregunta es sobre errores de compilación o hydration mismatch — esos son errores de plataforma; cargar `build-errors-nextjs`.
|
|
38
|
+
- La pregunta es sobre diseño de arquitectura (nested layouts, parallel routes, estrategias de cache) — para decisiones de diseño cargar `nextjs-patrones`.
|
|
39
|
+
- La pregunta es sobre escribir tests (Vitest, Playwright, RTL) — para testing cargar `nextjs-testing`.
|
|
40
|
+
|
|
41
|
+
## Conceptos clave
|
|
42
|
+
|
|
43
|
+
### Server Components vs Client Components
|
|
44
|
+
|
|
45
|
+
Server Components se ejecutan en el servidor, pueden ser async, acceden a BD
|
|
46
|
+
directamente, no tienen hooks ni eventos. Client Components se marcan con
|
|
47
|
+
`"use client"`, tienen acceso a hooks, browser APIs y estado local.
|
|
48
|
+
|
|
49
|
+
**Regla de oro**: usar Server Component por defecto. Agregar `"use client"` solo
|
|
50
|
+
cuando se necesita interactividad, hooks o browser APIs.
|
|
51
|
+
|
|
52
|
+
### Cache y Revalidación
|
|
53
|
+
|
|
54
|
+
`fetch()` en Next.js está extendido con opciones de cache. `no-store` deshabilita
|
|
55
|
+
cache (siempre fresco). `revalidate: N` revalida cada N segundos (ISR).
|
|
56
|
+
`tags` permite invalidación selectiva. Los Server Actions pueden llamar
|
|
57
|
+
`revalidateTag()` o `revalidatePath()` para invalidar después de mutaciones.
|
|
58
|
+
|
|
59
|
+
### Server Actions
|
|
60
|
+
|
|
61
|
+
Funciones marcadas con `"use server"` que se ejecutan en el servidor. Se pueden
|
|
62
|
+
llamar directamente desde formularios (`action={miAction}`) o desde Client
|
|
63
|
+
Components. Eliminan la necesidad de route handlers para mutaciones simples.
|
|
64
|
+
|
|
65
|
+
## Reglas obligatorias
|
|
66
|
+
|
|
67
|
+
### "use client" solo cuando sea absolutamente necesario
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
// MAL — todo marcado como client component sin necesidad
|
|
71
|
+
"use client";
|
|
72
|
+
export default function ListaProductos({ productos }) {
|
|
73
|
+
return <ul>{productos.map(p => <li key={p.id}>{p.nombre}</li>)}</ul>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// BIEN — Server Component, sin "use client"
|
|
77
|
+
export default function ListaProductos({ productos }: { productos: Producto[] }) {
|
|
78
|
+
return <ul>{productos.map(p => <li key={p.id}>{p.nombre}</li>)}</ul>;
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### fetch con error handling SIEMPRE en data fetching
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
// MAL — no maneja errores
|
|
86
|
+
async function obtenerProducto(id: string) {
|
|
87
|
+
const res = await fetch(`/api/productos/${id}`);
|
|
88
|
+
return res.json();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// BIEN — maneja HTTP errors y serializa correctamente
|
|
92
|
+
async function obtenerProducto(id: string): Promise<Producto> {
|
|
93
|
+
const res = await fetch(`${process.env.API_URL}/productos/${id}`, {
|
|
94
|
+
next: { revalidate: 3600, tags: [`producto-${id}`] },
|
|
95
|
+
});
|
|
96
|
+
if (!res.ok) throw new Error(`Error ${res.status}: ${res.statusText}`);
|
|
97
|
+
return res.json() as Promise<Producto>;
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Server Actions con validación antes de mutar
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
"use server";
|
|
105
|
+
|
|
106
|
+
export async function crearProducto(formData: FormData) {
|
|
107
|
+
// 1. Validar con zod antes de cualquier mutación
|
|
108
|
+
const resultado = ProductoSchema.safeParse({
|
|
109
|
+
nombre: formData.get('nombre'),
|
|
110
|
+
precio: Number(formData.get('precio')),
|
|
111
|
+
});
|
|
112
|
+
if (!resultado.success) {
|
|
113
|
+
return { error: resultado.error.flatten().fieldErrors };
|
|
114
|
+
}
|
|
115
|
+
// 2. Verificar autenticación
|
|
116
|
+
const sesion = await auth();
|
|
117
|
+
if (!sesion) redirect('/login');
|
|
118
|
+
// 3. Mutar
|
|
119
|
+
await db.producto.create({ data: resultado.data });
|
|
120
|
+
// 4. Invalidar cache
|
|
121
|
+
revalidateTag('productos');
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Suspense boundaries para streaming
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
// Envolver fetches lentos en Suspense para no bloquear la página completa
|
|
129
|
+
export default function PaginaProducto({ params }: { params: { id: string } }) {
|
|
130
|
+
return (
|
|
131
|
+
<main>
|
|
132
|
+
<h1>Producto</h1>
|
|
133
|
+
<Suspense fallback={<EsqueletoDetalle />}>
|
|
134
|
+
<DetalleProducto id={params.id} />
|
|
135
|
+
</Suspense>
|
|
136
|
+
<Suspense fallback={<EsqueletoResenas />}>
|
|
137
|
+
<ResenasProducto id={params.id} />
|
|
138
|
+
</Suspense>
|
|
139
|
+
</main>
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Patrones recomendados
|
|
145
|
+
|
|
146
|
+
### Convención de archivos App Router
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
app/
|
|
150
|
+
├── layout.tsx # Layout raíz (html, body)
|
|
151
|
+
├── page.tsx # Página /
|
|
152
|
+
├── loading.tsx # Skeleton mientras carga la página
|
|
153
|
+
├── error.tsx # Boundary de error ("use client")
|
|
154
|
+
├── not-found.tsx # 404 personalizado
|
|
155
|
+
├── (auth)/ # Route group — no afecta la URL
|
|
156
|
+
│ ├── login/page.tsx
|
|
157
|
+
│ └── registro/page.tsx
|
|
158
|
+
└── productos/
|
|
159
|
+
├── page.tsx # /productos
|
|
160
|
+
├── [id]/
|
|
161
|
+
│ └── page.tsx # /productos/[id]
|
|
162
|
+
└── route.ts # API route GET /productos
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### generateStaticParams para SSG con rutas dinámicas
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
export async function generateStaticParams() {
|
|
169
|
+
const productos = await db.producto.findMany({ select: { id: true } });
|
|
170
|
+
return productos.map(p => ({ id: p.id.toString() }));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export default async function PaginaProducto({ params }: { params: { id: string } }) {
|
|
174
|
+
const producto = await obtenerProducto(params.id);
|
|
175
|
+
// ...
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Route Handler con tipado
|
|
180
|
+
|
|
181
|
+
```tsx
|
|
182
|
+
// app/api/productos/route.ts
|
|
183
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
184
|
+
|
|
185
|
+
export async function GET(request: NextRequest) {
|
|
186
|
+
const searchParams = request.nextUrl.searchParams;
|
|
187
|
+
const pagina = Number(searchParams.get('pagina') ?? 1);
|
|
188
|
+
|
|
189
|
+
const productos = await db.producto.findMany({
|
|
190
|
+
skip: (pagina - 1) * 20,
|
|
191
|
+
take: 20,
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
return NextResponse.json({ data: productos, pagina });
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Middleware para autenticación
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
// middleware.ts (raiz del proyecto)
|
|
202
|
+
import { NextResponse } from 'next/server';
|
|
203
|
+
import type { NextRequest } from 'next/server';
|
|
204
|
+
|
|
205
|
+
export function middleware(request: NextRequest) {
|
|
206
|
+
const token = request.cookies.get('session')?.value;
|
|
207
|
+
const esRutaProtegida = request.nextUrl.pathname.startsWith('/dashboard');
|
|
208
|
+
|
|
209
|
+
if (esRutaProtegida && !token) {
|
|
210
|
+
return NextResponse.redirect(new URL('/login', request.url));
|
|
211
|
+
}
|
|
212
|
+
return NextResponse.next();
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export const config = {
|
|
216
|
+
matcher: ['/dashboard/:path*', '/api/privada/:path*'],
|
|
217
|
+
};
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Metadata API para SEO
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
// Estatica
|
|
224
|
+
export const metadata: Metadata = {
|
|
225
|
+
title: 'Tienda — Inicio',
|
|
226
|
+
description: 'Los mejores productos...',
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
// Dinámica por página
|
|
230
|
+
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
|
231
|
+
const producto = await obtenerProducto(params.id);
|
|
232
|
+
return {
|
|
233
|
+
title: producto.nombre,
|
|
234
|
+
openGraph: { images: [producto.imagen] },
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Anti-patrones conocidos
|
|
240
|
+
|
|
241
|
+
### useEffect para data fetching — NUNCA en App Router
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
// MAL — patrón de Pages Router que no aplica en App Router
|
|
245
|
+
"use client";
|
|
246
|
+
export default function Productos() {
|
|
247
|
+
const [productos, setProductos] = useState([]);
|
|
248
|
+
useEffect(() => {
|
|
249
|
+
fetch('/api/productos').then(r => r.json()).then(setProductos);
|
|
250
|
+
}, []);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// BIEN — Server Component con fetch directo
|
|
254
|
+
export default async function Productos() {
|
|
255
|
+
const productos = await obtenerProductos();
|
|
256
|
+
return <ListaProductos productos={productos} />;
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Layout para datos altamente dinámicos (tiempo real)
|
|
261
|
+
|
|
262
|
+
Los layouts se cachean agresivamente. Para datos que cambian por request,
|
|
263
|
+
usar `page.tsx` con `export const dynamic = 'force-dynamic'` o `no-store`.
|
|
264
|
+
|
|
265
|
+
### Dynamic imports para reducir bundle del cliente
|
|
266
|
+
|
|
267
|
+
```tsx
|
|
268
|
+
// Cargar componentes pesados solo cuando se necesitan
|
|
269
|
+
const Mapa = dynamic(() => import('@/components/Mapa'), {
|
|
270
|
+
loading: () => <p>Cargando mapa...</p>,
|
|
271
|
+
ssr: false, // no renderizar en servidor si usa browser APIs
|
|
272
|
+
});
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Hydration mismatch — causas comunes y solución
|
|
276
|
+
|
|
277
|
+
El servidor y el cliente deben producir HTML idéntico en el primer render.
|
|
278
|
+
Causas frecuentes de divergencia:
|
|
279
|
+
|
|
280
|
+
```tsx
|
|
281
|
+
// MAL — Date.now() produce valor distinto en servidor vs cliente
|
|
282
|
+
export default function Banner() {
|
|
283
|
+
return <p>Generado: {Date.now()}</p>; // hydration mismatch
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// MAL — Math.random() diverge entre servidor y cliente
|
|
287
|
+
<div style={{ order: Math.random() }}>...</div>
|
|
288
|
+
|
|
289
|
+
// MAL — typeof window produce HTML condicional
|
|
290
|
+
{typeof window !== 'undefined' && <ComponenteSoloCliente />}
|
|
291
|
+
|
|
292
|
+
// MAL — localStorage no existe en el servidor
|
|
293
|
+
<p>Tema: {localStorage.getItem('theme')}</p>
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Solución: mover valores dinámicos del cliente a un `useEffect` con estado
|
|
297
|
+
inicial neutro, o usar `suppressHydrationWarning` solo en nodos de texto que
|
|
298
|
+
intencionalmente difieren (timestamps mostrados al usuario):
|
|
299
|
+
|
|
300
|
+
```tsx
|
|
301
|
+
"use client";
|
|
302
|
+
export default function Reloj() {
|
|
303
|
+
const [hora, setHora] = useState<string>('');
|
|
304
|
+
useEffect(() => setHora(new Date().toLocaleTimeString()), []);
|
|
305
|
+
return <time suppressHydrationWarning>{hora}</time>;
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
## Gotchas / Errores comunes no obvios
|
|
310
|
+
|
|
311
|
+
**`cookies()` y `headers()` hacen opt-out del cache completo de la ruta**: llamar a `cookies()` o `headers()` en cualquier Server Component de una ruta convierte toda la ruta a dinámica (`force-dynamic`), incluso si el componente que los llama es un hijo no relacionado con el dato cacheado. Causa: Next.js marca la ruta entera como dinámica en el momento del análisis estático. Fix: aislar el componente que necesita cookies/headers en un Server Component dedicado e importarlo solo donde se use, o usar `export const dynamic = 'force-static'` en las páginas que no deben ser afectadas.
|
|
312
|
+
|
|
313
|
+
**Server Action llamada desde un formulario no revalida la UI después de éxito**: el formulario se envía y la acción ejecuta, pero la página no muestra los datos nuevos. Causa: la mutación se hizo pero no se llamó `revalidatePath()` o `revalidateTag()` dentro de la action. Fix: agregar `revalidatePath('/ruta-de-la-pagina')` al final de la Server Action, después de confirmar que la mutación fue exitosa.
|
|
314
|
+
|
|
315
|
+
**`"use client"` en un componente padre hace que todos sus imports sean Client Components**: si un layout o componente padre tiene `"use client"`, todos los componentes que importa son arrastrados al bundle del cliente aunque sean Server Components sin estado. Causa: el límite `"use client"` se aplica al subárbol completo. Fix: mover el estado o los event handlers a un componente hijo dedicado con `"use client"` y mantener el padre como Server Component.
|
|
316
|
+
|
|
317
|
+
**Variables de entorno sin `NEXT_PUBLIC_` no disponibles en el cliente en runtime**: `process.env.MI_VAR` en un Client Component retorna `undefined` en el browser aunque esté definida en `.env.local`. Causa: Next.js solo serializa al bundle del cliente las variables con prefijo `NEXT_PUBLIC_`. Fix: renombrar a `NEXT_PUBLIC_MI_VAR` si debe estar en el cliente, o leerla en un Server Component/Action y pasarla como prop.
|
|
318
|
+
|
|
319
|
+
## Checklist de verificación
|
|
320
|
+
|
|
321
|
+
- [ ] "use client" solo en componentes con hooks, eventos o browser APIs
|
|
322
|
+
- [ ] fetch con manejo de errores HTTP y tipado de respuesta
|
|
323
|
+
- [ ] Server Actions con validación Zod antes de mutar
|
|
324
|
+
- [ ] Suspense boundaries alrededor de fetches independientes
|
|
325
|
+
- [ ] Metadata generada para páginas públicas (SEO)
|
|
326
|
+
- [ ] Middleware en rutas protegidas
|
|
327
|
+
- [ ] generateStaticParams para rutas dinámicas conocidas en build time
|
|
328
|
+
|
|
329
|
+
## Referencias
|
|
330
|
+
|
|
331
|
+
- [Next.js App Router Docs](https://nextjs.org/docs/app)
|
|
332
|
+
- [Next.js Caching](https://nextjs.org/docs/app/building-your-application/caching)
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
*Skill creado con swl:crear-skill el 2026-03-31. Versión 1.0.0.*
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nextjs-patrones
|
|
3
|
+
description: >
|
|
4
|
+
Patrones Next.js App Router: nested layouts, parallel routes, intercepting
|
|
5
|
+
routes, caching strategies, Partial Prerendering y autenticación con middleware.
|
|
6
|
+
Cargar cuando se diseñe arquitectura de una app Next.js o se optimice caching.
|
|
7
|
+
version: "1.0.0"
|
|
8
|
+
herramientasPermitidas: [Read, Glob, Grep]
|
|
9
|
+
exclusiones:
|
|
10
|
+
- "No cargar para implementar un endpoint o página específica — para implementación concreta cargar `nextjs-experto`; este skill es para diseño de arquitectura y estrategia de caching."
|
|
11
|
+
- "No cargar para proyectos con Pages Router — los patrones de nested layouts, parallel routes y PPR son exclusivos del App Router."
|
|
12
|
+
- "No cargar para tests de páginas Next.js — para testing cargar `nextjs-testing`."
|
|
13
|
+
- "No cargar para errores de build o hydration — esos son errores de plataforma; cargar `build-errors-nextjs`."
|
|
14
|
+
evolvable: true # default para skill estandar
|
|
15
|
+
---
|
|
16
|
+
# Next.js Patrones — Arquitectura App Router
|
|
17
|
+
|
|
18
|
+
El App Router introduce patrones de composición que no existían en Pages Router.
|
|
19
|
+
Este skill cubre las decisiones de arquitectura: cuándo usar layouts anidados,
|
|
20
|
+
cómo aprovechar parallel routes para UI compleja, qué estrategia de cache elegir
|
|
21
|
+
para cada tipo de dato, y cómo estructurar autenticación con middleware.
|
|
22
|
+
|
|
23
|
+
## Cuándo cargar este skill
|
|
24
|
+
|
|
25
|
+
Invoca `Skill("nextjs-patrones")` cuando:
|
|
26
|
+
|
|
27
|
+
- Se diseñe la estructura de rutas de una app Next.js nueva
|
|
28
|
+
- Se implemente un modal que debe mantener la ruta anterior (intercepting routes)
|
|
29
|
+
- Se optimice el comportamiento de cache de páginas o datos
|
|
30
|
+
- Se configure autenticación o i18n con middleware
|
|
31
|
+
- Se evalúen las estrategias de rendering: SSR, SSG, ISR, PPR
|
|
32
|
+
|
|
33
|
+
## Cuándo NO cargar
|
|
34
|
+
|
|
35
|
+
- La pregunta es sobre implementar un endpoint o página específica — para implementación concreta cargar `nextjs-experto`; este skill cubre decisiones de arquitectura y estrategia.
|
|
36
|
+
- El proyecto usa Pages Router — los patrones de nested layouts, parallel routes y PPR son exclusivos del App Router.
|
|
37
|
+
- La pregunta es sobre tests de páginas Next.js — para testing cargar `nextjs-testing`.
|
|
38
|
+
- La pregunta es sobre errores de build o hydration — esos son errores de plataforma; cargar `build-errors-nextjs`.
|
|
39
|
+
|
|
40
|
+
## Conceptos clave
|
|
41
|
+
|
|
42
|
+
### Nested Layouts y composición
|
|
43
|
+
|
|
44
|
+
Cada segmento de ruta puede tener su propio `layout.tsx`. Los layouts se anidan:
|
|
45
|
+
el layout de `/dashboard` envuelve a todos los layouts y páginas bajo esa ruta.
|
|
46
|
+
Los layouts son Server Components y persisten entre navegaciones del mismo segmento.
|
|
47
|
+
|
|
48
|
+
### Route Groups
|
|
49
|
+
|
|
50
|
+
Los route groups (carpetas entre paréntesis como `(auth)`) agrupan rutas sin
|
|
51
|
+
afectar la URL. Sirven para aplicar layouts diferentes a segmentos del mismo
|
|
52
|
+
nivel, o para organizar el código sin impactar las rutas públicas.
|
|
53
|
+
|
|
54
|
+
### Parallel Routes y Slots
|
|
55
|
+
|
|
56
|
+
Los slots (`@nombre`) permiten renderizar múltiples páginas en el mismo layout
|
|
57
|
+
simultáneamente. El layout recibe los slots como props. Útil para dashboards
|
|
58
|
+
con secciones independientes o vistas divididas.
|
|
59
|
+
|
|
60
|
+
## Reglas obligatorias
|
|
61
|
+
|
|
62
|
+
### Layout solo para UI que persiste — no para datos dinámicos por usuario
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
// MAL — el layout hace fetch de datos que dependen del usuario
|
|
66
|
+
// Los layouts se cachean y puede servirse el mismo a distintos usuarios
|
|
67
|
+
export default async function DashboardLayout({ children }) {
|
|
68
|
+
const usuario = await obtenerUsuarioActual(); // PELIGROSO en layout
|
|
69
|
+
return <aside>{usuario.nombre}</aside>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// BIEN — datos dinamicos en el page.tsx o en un Client Component
|
|
73
|
+
// con fetch propio que respeta el contexto de la request
|
|
74
|
+
export default function DashboardLayout({ children }) {
|
|
75
|
+
return (
|
|
76
|
+
<div className="flex">
|
|
77
|
+
<NavegacionLateral /> {/* Server Component con su propio fetch */}
|
|
78
|
+
<main>{children}</main>
|
|
79
|
+
</div>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Cache con tags para invalidación granular — nunca `no-store` por comodidad
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
// MAL — deshabilitar cache para evitar pensar en invalidacion
|
|
88
|
+
const productos = await fetch('/api/productos', { cache: 'no-store' });
|
|
89
|
+
|
|
90
|
+
// BIEN — cache con revalidacion y tags especificos
|
|
91
|
+
const productos = await fetch('/api/productos', {
|
|
92
|
+
next: {
|
|
93
|
+
revalidate: 3600, // Revalidar cada hora como maximo
|
|
94
|
+
tags: ['productos'], // Invalidar con revalidateTag('productos')
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// En el Server Action al mutar:
|
|
99
|
+
revalidateTag('productos'); // Solo invalida lo necesario
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Composition pattern: Server Component envuelve Client Component
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
// Server Component puede pasar datos como props a Client Components
|
|
106
|
+
// pero NO puede importar un Client Component que use hooks en el servidor
|
|
107
|
+
// BIEN — composicion correcta
|
|
108
|
+
export default async function PaginaProducto({ params }) {
|
|
109
|
+
const producto = await obtenerProducto(params.id); // Server
|
|
110
|
+
return (
|
|
111
|
+
<div>
|
|
112
|
+
<DetalleProducto producto={producto} /> {/* Server */}
|
|
113
|
+
<BotonAgregarCarrito productoId={producto.id} /> {/* Client */}
|
|
114
|
+
</div>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Patrones recomendados
|
|
120
|
+
|
|
121
|
+
### Parallel Routes para dashboard con secciones independientes
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
app/dashboard/
|
|
125
|
+
├── layout.tsx # Recibe @analytics y @equipo como props
|
|
126
|
+
├── page.tsx
|
|
127
|
+
├── @analytics/
|
|
128
|
+
│ └── page.tsx # Carga independientemente
|
|
129
|
+
└── @equipo/
|
|
130
|
+
└── page.tsx # Carga independientemente
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```tsx
|
|
134
|
+
// layout.tsx
|
|
135
|
+
export default function DashboardLayout({
|
|
136
|
+
children,
|
|
137
|
+
analytics,
|
|
138
|
+
equipo,
|
|
139
|
+
}: {
|
|
140
|
+
children: React.ReactNode;
|
|
141
|
+
analytics: React.ReactNode;
|
|
142
|
+
equipo: React.ReactNode;
|
|
143
|
+
}) {
|
|
144
|
+
return (
|
|
145
|
+
<div className="grid grid-cols-3 gap-4">
|
|
146
|
+
<main className="col-span-2">{children}</main>
|
|
147
|
+
<aside>
|
|
148
|
+
<Suspense fallback={<Skeleton />}>{analytics}</Suspense>
|
|
149
|
+
<Suspense fallback={<Skeleton />}>{equipo}</Suspense>
|
|
150
|
+
</aside>
|
|
151
|
+
</div>
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Intercepting Routes para modales con URL propia
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
app/
|
|
160
|
+
├── productos/
|
|
161
|
+
│ ├── page.tsx # /productos — lista
|
|
162
|
+
│ ├── [id]/page.tsx # /productos/[id] — página completa
|
|
163
|
+
│ └── (.)foto/[id]/page.tsx # Intercepta /foto/[id] desde /productos
|
|
164
|
+
└── foto/
|
|
165
|
+
└── [id]/page.tsx # /foto/[id] — página completa si acceso directo
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
El `(.)` intercepta rutas en el mismo nivel. `(..)` intercepta un nivel arriba.
|
|
169
|
+
Al navegar desde `/productos`, abre el modal. Al acceder directo a `/foto/123`,
|
|
170
|
+
muestra la página completa — permite compartir URLs de modales.
|
|
171
|
+
|
|
172
|
+
### Estrategias de cache por tipo de contenido
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
// Contenido estático (documentación, landing pages)
|
|
176
|
+
// No especificar cache — Next.js cachea indefinidamente en build
|
|
177
|
+
export default async function PaginaMarketing() { ... }
|
|
178
|
+
|
|
179
|
+
// Contenido con actualizacion periodica (catalogo, precios)
|
|
180
|
+
async function obtenerCatalogo() {
|
|
181
|
+
return fetch('/api/catalogo', { next: { revalidate: 3600 } });
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Contenido personalizado por usuario (carrito, perfil)
|
|
185
|
+
async function obtenerCarrito(usuarioId: string) {
|
|
186
|
+
return fetch(`/api/carrito/${usuarioId}`, { cache: 'no-store' });
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Contenido en tiempo real (stock, precios live)
|
|
190
|
+
export const dynamic = 'force-dynamic'; // en el page.tsx
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Edge Runtime para middleware de autenticación
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
// middleware.ts
|
|
197
|
+
export const runtime = 'edge'; // más rápido, sin cold start
|
|
198
|
+
|
|
199
|
+
export async function middleware(request: NextRequest) {
|
|
200
|
+
const token = request.cookies.get('session')?.value;
|
|
201
|
+
|
|
202
|
+
if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
|
|
203
|
+
const loginUrl = new URL('/login', request.url);
|
|
204
|
+
loginUrl.searchParams.set('callbackUrl', request.nextUrl.pathname);
|
|
205
|
+
return NextResponse.redirect(loginUrl);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Agregar headers de usuario para Server Components downstream
|
|
209
|
+
const response = NextResponse.next();
|
|
210
|
+
response.headers.set('x-user-id', decodeToken(token)?.id ?? '');
|
|
211
|
+
return response;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export const config = {
|
|
215
|
+
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
|
|
216
|
+
};
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Partial Prerendering (PPR) — Next.js 14+
|
|
220
|
+
|
|
221
|
+
```tsx
|
|
222
|
+
// next.config.ts
|
|
223
|
+
export default {
|
|
224
|
+
experimental: { ppr: true },
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
// page.tsx — shell estático + partes dinámicas en Suspense
|
|
228
|
+
export default function PaginaProducto({ params }) {
|
|
229
|
+
return (
|
|
230
|
+
<>
|
|
231
|
+
{/* Estático — se precompila */}
|
|
232
|
+
<HeaderProducto />
|
|
233
|
+
<DescripcionProducto id={params.id} />
|
|
234
|
+
|
|
235
|
+
{/* Dinámico — se hace streaming por separado */}
|
|
236
|
+
<Suspense fallback={<SkeletonStock />}>
|
|
237
|
+
<StockEnTiempoReal id={params.id} />
|
|
238
|
+
</Suspense>
|
|
239
|
+
</>
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Anti-patrones conocidos
|
|
245
|
+
|
|
246
|
+
### Prop drilling de Server Components a través de múltiples niveles
|
|
247
|
+
|
|
248
|
+
```tsx
|
|
249
|
+
// MAL — pasar props a través de 4 niveles de Server Components
|
|
250
|
+
<Layout usuario={usuario}>
|
|
251
|
+
<Dashboard usuario={usuario}>
|
|
252
|
+
<Header usuario={usuario} />
|
|
253
|
+
|
|
254
|
+
// BIEN — cada Server Component hace su propio fetch o usa Context del lado cliente
|
|
255
|
+
// Los Server Components pueden colocarse directamente en el árbol
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Route Handler para todo cuando Server Actions son suficientes
|
|
259
|
+
|
|
260
|
+
Para mutaciones simples desde formularios o acciones de usuario, los Server Actions
|
|
261
|
+
son más simples que crear un route handler separado. Los route handlers tienen
|
|
262
|
+
sentido para endpoints que consumirán terceros, webhooks o necesitan headers HTTP.
|
|
263
|
+
|
|
264
|
+
### Imports de librerias pesadas en el bundle del cliente
|
|
265
|
+
|
|
266
|
+
```tsx
|
|
267
|
+
// MAL — lodash completo en el cliente
|
|
268
|
+
"use client";
|
|
269
|
+
import _ from 'lodash';
|
|
270
|
+
|
|
271
|
+
// BIEN — importar solo lo necesario, o mover la lógica al servidor
|
|
272
|
+
import debounce from 'lodash/debounce';
|
|
273
|
+
// O mejor: la transformación de datos en un Server Component
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Gotchas / Errores comunes no obvios
|
|
277
|
+
|
|
278
|
+
**`loading.tsx` en un segmento bloquea el loading de segmentos padre**: en una ruta `/dashboard/pedidos`, si `pedidos/loading.tsx` existe pero el fetch lento está en el layout de `/dashboard`, el spinner de pedidos aparece pero la UI de dashboard también queda pendiente. Causa: el `loading.tsx` solo envuelve la página del segmento donde vive, no los layouts padres. Fix: poner el `loading.tsx` al mismo nivel que el layout o componente que hace el fetch lento.
|
|
279
|
+
|
|
280
|
+
**Parallel routes con `@slot` que no tienen `default.tsx` causan 404 en navegación directa**: al navegar directamente a una URL (refresh o link externo) con parallel routes, Next.js necesita renderizar todos los slots — si alguno no tiene `default.tsx`, lanza 404. Causa: en navegación suave (client-side), el estado de los slots se mantiene; en navegación directa, Next.js busca `default.tsx` como fallback. Fix: crear `default.tsx` en cada `@slot` que no tenga una ruta correspondiente.
|
|
281
|
+
|
|
282
|
+
**`revalidateTag()` en Server Action no invalida el cache si el `fetch` no declaró el tag**: se llama `revalidateTag('productos')` pero la página no se refresca. Causa: el `fetch` correspondiente no tenía `next: { tags: ['productos'] }` — sin tag declarado, no hay entrada en el cache que invalidar. Fix: verificar que cada `fetch` que debe invalidarse declara explícitamente los tags con `next: { tags: ['nombre-del-tag'] }`.
|
|
283
|
+
|
|
284
|
+
**Intercepting routes `(..)ruta` no intercepta si el layout padre no coincide**: al configurar `(..)modal` para interceptar `/fotos/[id]` desde `/`, la intercepción no funciona si el archivo de intercepción está un nivel más arriba de lo esperado. Causa: la notación `(.)` intercepta el mismo segmento, `(..)` intercepta un nivel arriba, `(...)` intercepta desde la raíz — un error de conteo de puntos hace que la intercepción no se active y navega a la página completa. Fix: contar los segmentos de ruta entre el origen y el destino para elegir la notación correcta.
|
|
285
|
+
|
|
286
|
+
## Checklist de verificación
|
|
287
|
+
|
|
288
|
+
- [ ] Layouts solo contienen UI persistente, sin datos dinámicos por usuario
|
|
289
|
+
- [ ] Cache configurada con tags para invalidación granular
|
|
290
|
+
- [ ] Parallel routes con Suspense independiente por slot
|
|
291
|
+
- [ ] Intercepting routes cuando se necesitan modales con URL compartible
|
|
292
|
+
- [ ] Middleware en Edge Runtime para latencia mínima
|
|
293
|
+
- [ ] Server Components hacen fetch directamente — no prop drilling de datos
|
|
294
|
+
- [ ] PPR evaluado para páginas con mezcla de contenido estático y dinámico
|
|
295
|
+
|
|
296
|
+
## Referencias
|
|
297
|
+
|
|
298
|
+
- [Next.js Routing](https://nextjs.org/docs/app/building-your-application/routing)
|
|
299
|
+
- [Next.js Caching Deep Dive](https://nextjs.org/docs/app/building-your-application/caching)
|
|
300
|
+
- [Partial Prerendering](https://nextjs.org/docs/app/api-reference/next-config-js/ppr)
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
*Skill creado con swl:crear-skill el 2026-03-31. Versión 1.0.0.*
|