@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,220 @@
|
|
|
1
|
+
# Auditoría técnica de cuentas Google Ads
|
|
2
|
+
|
|
3
|
+
## Checklist técnico de auditoría
|
|
4
|
+
|
|
5
|
+
Una auditoría técnica verifica que la infraestructura de medición está
|
|
6
|
+
correctamente configurada — no evalúa la estrategia de campañas.
|
|
7
|
+
|
|
8
|
+
### Conversiones
|
|
9
|
+
|
|
10
|
+
- [ ] **Conversiones primarias configuradas**: al menos una acción de conversión
|
|
11
|
+
marcada como "Primaria" en la cuenta. Las conversiones secundarias no se usan
|
|
12
|
+
en las estrategias de puja automática.
|
|
13
|
+
- [ ] **Enhanced Conversions activadas**: en Configuración de conversiones,
|
|
14
|
+
"Enhanced conversions for web" debe estar habilitado con hash SHA-256.
|
|
15
|
+
- [ ] **Auto-tagging habilitado**: en Configuración de la cuenta, permite que
|
|
16
|
+
Google Ads agregue `gclid` a las URLs de destino para importación a GA4.
|
|
17
|
+
- [ ] **Sin conversiones duplicadas**: verificar que el mismo evento de compra
|
|
18
|
+
no esté configurado dos veces (una en GA4-importada y otra en etiqueta directa).
|
|
19
|
+
- [ ] **Ventana de conversión correcta**: campañas de búsqueda usan 30 días;
|
|
20
|
+
campañas de display o video pueden requerir ventanas más largas (90 días).
|
|
21
|
+
|
|
22
|
+
### Audiencias y remarketing
|
|
23
|
+
|
|
24
|
+
- [ ] **Etiqueta de remarketing activa**: Google Ads Tag o GA4 Audience deben
|
|
25
|
+
estar recibiendo datos (verificar en Audience Manager > Fuentes de audiencia).
|
|
26
|
+
- [ ] **Audiencias de remarketing creadas**: al menos "Todos los visitantes",
|
|
27
|
+
"Visitantes de producto" y "Compradores anteriores" para campañas RLSA.
|
|
28
|
+
- [ ] **Customer Match habilitado**: si se usa lista de clientes, la cuenta debe
|
|
29
|
+
tener historial suficiente y cumplimiento de políticas.
|
|
30
|
+
|
|
31
|
+
### Shopping (si aplica)
|
|
32
|
+
|
|
33
|
+
- [ ] **Feed de productos aprobado** en Merchant Center: sin errores de
|
|
34
|
+
disponibilidad, precio o imagen. Los items rechazados no aparecen en anuncios.
|
|
35
|
+
- [ ] **Vinculación Merchant Center — Google Ads**: confirmada en ambas cuentas.
|
|
36
|
+
- [ ] **Etiquetas personalizadas configuradas**: para segmentación por margen,
|
|
37
|
+
temporada o prioridad de inventario.
|
|
38
|
+
|
|
39
|
+
### Estructura técnica de la cuenta
|
|
40
|
+
|
|
41
|
+
- [ ] **Naming convention consistente**: campañas, ad groups y keywords siguen
|
|
42
|
+
una nomenclatura que permite filtrar y reportar programáticamente.
|
|
43
|
+
- [ ] **UTM parameters en URLs finales**: `utm_source=google&utm_medium=cpc&utm_campaign={campaignid}`
|
|
44
|
+
para atribución correcta en GA4 sin depender solo del auto-tagging.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Métricas de calidad de cuenta
|
|
49
|
+
|
|
50
|
+
Estas métricas indican la salud técnica de la implementación, no el
|
|
51
|
+
desempeño de negocio:
|
|
52
|
+
|
|
53
|
+
| Métrica | Objetivo | Señal de problema |
|
|
54
|
+
|---------|----------|------------------|
|
|
55
|
+
| Quality Score promedio (búsqueda) | ≥ 7/10 | < 5 indica relevancia baja o landing page deficiente |
|
|
56
|
+
| Impression Share de marca | ≥ 85% | < 70% indica competencia capturando tráfico de marca |
|
|
57
|
+
| Invalid click rate | < 2% | > 5% indica fraude de clics o tráfico de baja calidad |
|
|
58
|
+
| Discrepancia GA4 vs Google Ads | < 15% | > 15% indica problema de tracking o atribución |
|
|
59
|
+
| Conversiones con valor cero | 0% | Cualquier conversión primaria sin valor = ROAS incalculable |
|
|
60
|
+
|
|
61
|
+
### Query para Quality Score promedio
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
def obtener_quality_score_promedio(customer_id: str) -> dict:
|
|
65
|
+
"""Obtiene Quality Score promedio de keywords activas."""
|
|
66
|
+
ga_service = client.get_service("GoogleAdsService")
|
|
67
|
+
|
|
68
|
+
query = """
|
|
69
|
+
SELECT
|
|
70
|
+
ad_group_criterion.keyword.text,
|
|
71
|
+
ad_group_criterion.quality_info.quality_score,
|
|
72
|
+
ad_group_criterion.quality_info.creative_quality_score,
|
|
73
|
+
ad_group_criterion.quality_info.post_click_quality_score,
|
|
74
|
+
ad_group_criterion.quality_info.search_predicted_ctr,
|
|
75
|
+
metrics.impressions
|
|
76
|
+
FROM keyword_view
|
|
77
|
+
WHERE campaign.status = 'ENABLED'
|
|
78
|
+
AND ad_group.status = 'ENABLED'
|
|
79
|
+
AND ad_group_criterion.status = 'ENABLED'
|
|
80
|
+
AND ad_group_criterion.quality_info.quality_score > 0
|
|
81
|
+
AND segments.date DURING LAST_30_DAYS
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
response = ga_service.search(customer_id=customer_id, query=query)
|
|
85
|
+
|
|
86
|
+
scores = []
|
|
87
|
+
impresiones_total = 0
|
|
88
|
+
suma_ponderada = 0
|
|
89
|
+
|
|
90
|
+
for row in response:
|
|
91
|
+
qs = row.ad_group_criterion.quality_info.quality_score
|
|
92
|
+
imp = row.metrics.impressions
|
|
93
|
+
scores.append(qs)
|
|
94
|
+
suma_ponderada += qs * imp
|
|
95
|
+
impresiones_total += imp
|
|
96
|
+
|
|
97
|
+
if not scores:
|
|
98
|
+
return {"error": "sin_keywords_con_quality_score"}
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
"promedio_simple": round(sum(scores) / len(scores), 1),
|
|
102
|
+
"promedio_ponderado_impresiones": round(
|
|
103
|
+
suma_ponderada / impresiones_total, 1
|
|
104
|
+
) if impresiones_total > 0 else 0,
|
|
105
|
+
"total_keywords": len(scores),
|
|
106
|
+
"distribucion": {
|
|
107
|
+
"excelente_8_10": sum(1 for s in scores if s >= 8),
|
|
108
|
+
"bueno_6_7": sum(1 for s in scores if 6 <= s <= 7),
|
|
109
|
+
"bajo_1_5": sum(1 for s in scores if s <= 5),
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Herramientas de diagnóstico
|
|
117
|
+
|
|
118
|
+
### Google Tag Assistant
|
|
119
|
+
|
|
120
|
+
Extensión de Chrome para verificar que la etiqueta de Google Ads está
|
|
121
|
+
disparando correctamente en el sitio:
|
|
122
|
+
|
|
123
|
+
1. Activar grabación en la página objetivo
|
|
124
|
+
2. Completar el flujo de conversión (compra, registro, etc.)
|
|
125
|
+
3. Verificar que el evento aparece en el historial con los parámetros correctos
|
|
126
|
+
4. Confirmar que no hay errores de "Tag not found" o "Tag fired multiple times"
|
|
127
|
+
|
|
128
|
+
### Google Ads Diagnostics Tool
|
|
129
|
+
|
|
130
|
+
En la consola de Google Ads: Herramientas > Diagnóstico y vista previa
|
|
131
|
+
de anuncios. Permite verificar por qué un anuncio no aparece para una
|
|
132
|
+
búsqueda específica (presupuesto agotado, keyword pausada, policy violation).
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Reporte automático de auditoría con Python
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
import json
|
|
140
|
+
from dataclasses import dataclass, field
|
|
141
|
+
|
|
142
|
+
@dataclass
|
|
143
|
+
class ResultadoAuditoria:
|
|
144
|
+
customer_id: str
|
|
145
|
+
quality_score: dict = field(default_factory=dict)
|
|
146
|
+
discrepancia_conversiones: dict = field(default_factory=dict)
|
|
147
|
+
candidatos_negative: list = field(default_factory=list)
|
|
148
|
+
alertas: list[str] = field(default_factory=list)
|
|
149
|
+
|
|
150
|
+
def ejecutar_auditoria_completa(
|
|
151
|
+
customer_id: str,
|
|
152
|
+
ga4_conversiones: float,
|
|
153
|
+
campaign_ids: list[str],
|
|
154
|
+
) -> ResultadoAuditoria:
|
|
155
|
+
"""
|
|
156
|
+
Ejecuta auditoría técnica completa de una cuenta Google Ads.
|
|
157
|
+
|
|
158
|
+
Retorna un ResultadoAuditoria con métricas de calidad,
|
|
159
|
+
discrepancias de conversiones y candidatos a negative keywords.
|
|
160
|
+
"""
|
|
161
|
+
resultado = ResultadoAuditoria(customer_id=customer_id)
|
|
162
|
+
|
|
163
|
+
# 1. Quality Score
|
|
164
|
+
resultado.quality_score = obtener_quality_score_promedio(customer_id)
|
|
165
|
+
qs_prom = resultado.quality_score.get("promedio_simple", 0)
|
|
166
|
+
if qs_prom < 7:
|
|
167
|
+
resultado.alertas.append(
|
|
168
|
+
f"Quality Score promedio bajo: {qs_prom}/10 (objetivo ≥ 7)"
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
# 2. Rendimiento de campañas y discrepancia de conversiones
|
|
172
|
+
campanas = obtener_rendimiento_campanas(customer_id)
|
|
173
|
+
google_ads_conv = sum(c["conversiones"] for c in campanas)
|
|
174
|
+
resultado.discrepancia_conversiones = detectar_discrepancia_conversiones(
|
|
175
|
+
google_ads_conv, ga4_conversiones
|
|
176
|
+
) # Nota: esta función es async en SKILL.md, adaptar según contexto
|
|
177
|
+
|
|
178
|
+
if resultado.discrepancia_conversiones.get("estado") != "ok":
|
|
179
|
+
pct = resultado.discrepancia_conversiones.get("discrepancia_porcentual", 0)
|
|
180
|
+
resultado.alertas.append(
|
|
181
|
+
f"Discrepancia de conversiones: {pct}% (umbral: 15%)"
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
# 3. Search terms con desperdicio
|
|
185
|
+
analisis = analizar_search_terms(customer_id, campaign_ids)
|
|
186
|
+
resultado.candidatos_negative = analisis["candidatos_negative"][:10]
|
|
187
|
+
if resultado.candidatos_negative:
|
|
188
|
+
total_desperdicio = sum(
|
|
189
|
+
t["costo_desperdiciado"] for t in resultado.candidatos_negative
|
|
190
|
+
)
|
|
191
|
+
resultado.alertas.append(
|
|
192
|
+
f"{len(resultado.candidatos_negative)} términos candidatos a negative, "
|
|
193
|
+
f"costo desperdiciado estimado: ${total_desperdicio:,.2f}"
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
return resultado
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def exportar_reporte_json(resultado: ResultadoAuditoria, ruta: str) -> None:
|
|
200
|
+
"""Exporta el resultado de la auditoría como JSON."""
|
|
201
|
+
import dataclasses
|
|
202
|
+
with open(ruta, "w", encoding="utf-8") as f:
|
|
203
|
+
json.dump(dataclasses.asdict(resultado), f, ensure_ascii=False, indent=2)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Ejemplo de uso
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
resultado = ejecutar_auditoria_completa(
|
|
210
|
+
customer_id="1234567890",
|
|
211
|
+
ga4_conversiones=142.0,
|
|
212
|
+
campaign_ids=["111222333", "444555666"],
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
print(f"Alertas encontradas: {len(resultado.alertas)}")
|
|
216
|
+
for alerta in resultado.alertas:
|
|
217
|
+
print(f" - {alerta}")
|
|
218
|
+
|
|
219
|
+
exportar_reporte_json(resultado, "auditoria_2026_04.json")
|
|
220
|
+
```
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# Google Ads API — Referencia técnica
|
|
2
|
+
|
|
3
|
+
## Autenticación
|
|
4
|
+
|
|
5
|
+
### Tipos de credenciales
|
|
6
|
+
|
|
7
|
+
| Tipo | Cuándo usar | Configuración requerida |
|
|
8
|
+
|------|-------------|------------------------|
|
|
9
|
+
| OAuth2 con refresh token | Acceso en nombre de un usuario | `client_id`, `client_secret`, `refresh_token` |
|
|
10
|
+
| Service Account | Procesos server-side sin interacción humana | Archivo JSON de service account + acceso delegado en MCC |
|
|
11
|
+
| Developer Token | Obligatorio en todos los casos | Aprobado por Google en la cuenta MCC principal |
|
|
12
|
+
|
|
13
|
+
### Niveles del Developer Token
|
|
14
|
+
|
|
15
|
+
| Nivel | Quota diaria | Cuentas accesibles |
|
|
16
|
+
|-------|-------------|-------------------|
|
|
17
|
+
| Test | 15,000 ops/día | Solo cuentas de prueba |
|
|
18
|
+
| Basic | 1,000 ops/día | Todas las cuentas vinculadas al MCC |
|
|
19
|
+
| Standard | 10,000 ops/día | Requiere solicitud y aprobación de Google |
|
|
20
|
+
|
|
21
|
+
En producción con reportes diarios, **Standard es necesario** si se tienen
|
|
22
|
+
más de 50 cuentas o consultas de más de 30 días de datos.
|
|
23
|
+
|
|
24
|
+
### Configuración con diccionario Python
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from google.ads.googleads.client import GoogleAdsClient
|
|
28
|
+
|
|
29
|
+
config = {
|
|
30
|
+
"developer_token": settings.GOOGLE_ADS_DEVELOPER_TOKEN,
|
|
31
|
+
"client_id": settings.GOOGLE_ADS_CLIENT_ID,
|
|
32
|
+
"client_secret": settings.GOOGLE_ADS_CLIENT_SECRET,
|
|
33
|
+
"refresh_token": settings.GOOGLE_ADS_REFRESH_TOKEN,
|
|
34
|
+
"login_customer_id": settings.GOOGLE_ADS_MCC_ID, # ID del MCC, sin guiones
|
|
35
|
+
"use_proto_plus": True, # Objetos Python nativos en lugar de protobuf raw
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
client = GoogleAdsClient.load_from_dict(config)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Configuración con archivo YAML (alternativa)
|
|
42
|
+
|
|
43
|
+
```yaml
|
|
44
|
+
# google-ads.yaml (NO subir a repositorio)
|
|
45
|
+
developer_token: "Tu_Developer_Token"
|
|
46
|
+
client_id: "client_id.apps.googleusercontent.com"
|
|
47
|
+
client_secret: "client_secret"
|
|
48
|
+
refresh_token: "1//0g..."
|
|
49
|
+
login_customer_id: "1234567890"
|
|
50
|
+
use_proto_plus: true
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
client = GoogleAdsClient.load_from_storage("google-ads.yaml")
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## GAQL — Google Ads Query Language
|
|
60
|
+
|
|
61
|
+
### Estructura básica
|
|
62
|
+
|
|
63
|
+
```sql
|
|
64
|
+
SELECT campo1, campo2, metrica1
|
|
65
|
+
FROM recurso_principal
|
|
66
|
+
WHERE condicion1 AND condicion2
|
|
67
|
+
ORDER BY metrica1 DESC
|
|
68
|
+
LIMIT 100
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Recursos principales
|
|
72
|
+
|
|
73
|
+
| Recurso | Qué contiene |
|
|
74
|
+
|---------|-------------|
|
|
75
|
+
| `campaign` | Campañas: nombre, status, tipo, presupuesto |
|
|
76
|
+
| `ad_group` | Grupos de anuncios dentro de campañas |
|
|
77
|
+
| `ad_group_ad` | Anuncios individuales con sus métricas |
|
|
78
|
+
| `keyword_view` | Keywords configuradas con Quality Score |
|
|
79
|
+
| `search_term_view` | Términos exactos que activaron anuncios |
|
|
80
|
+
| `geographic_view` | Rendimiento por ubicación geográfica |
|
|
81
|
+
| `audience_view` | Rendimiento por audiencia configurada |
|
|
82
|
+
| `shopping_performance_view` | Rendimiento de campañas Shopping |
|
|
83
|
+
|
|
84
|
+
### Segmentos comunes
|
|
85
|
+
|
|
86
|
+
Los segmentos dividen las métricas por dimensión. No todos son compatibles
|
|
87
|
+
con todos los recursos — la API retorna error si se combina incorrectamente.
|
|
88
|
+
|
|
89
|
+
```sql
|
|
90
|
+
-- Segmentar por fecha
|
|
91
|
+
SELECT campaign.name, metrics.clicks, segments.date
|
|
92
|
+
FROM campaign
|
|
93
|
+
WHERE segments.date DURING LAST_30_DAYS
|
|
94
|
+
|
|
95
|
+
-- Segmentar por dispositivo
|
|
96
|
+
SELECT campaign.name, metrics.clicks, segments.device
|
|
97
|
+
FROM campaign
|
|
98
|
+
WHERE segments.date DURING LAST_7_DAYS
|
|
99
|
+
|
|
100
|
+
-- Rangos de fecha explícitos
|
|
101
|
+
WHERE segments.date BETWEEN '2026-01-01' AND '2026-03-31'
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Períodos predefinidos útiles
|
|
105
|
+
|
|
106
|
+
| Constante GAQL | Equivalente |
|
|
107
|
+
|----------------|-------------|
|
|
108
|
+
| `LAST_7_DAYS` | Últimos 7 días |
|
|
109
|
+
| `LAST_30_DAYS` | Últimos 30 días |
|
|
110
|
+
| `LAST_MONTH` | Mes calendario anterior completo |
|
|
111
|
+
| `THIS_MONTH` | Mes calendario actual hasta hoy |
|
|
112
|
+
| `LAST_YEAR` | Año anterior completo |
|
|
113
|
+
|
|
114
|
+
### Filtros de status importantes
|
|
115
|
+
|
|
116
|
+
```sql
|
|
117
|
+
-- Solo campañas activas (ENABLED)
|
|
118
|
+
WHERE campaign.status = 'ENABLED'
|
|
119
|
+
|
|
120
|
+
-- Campañas activas y pausadas (excluye eliminadas)
|
|
121
|
+
WHERE campaign.status IN ('ENABLED', 'PAUSED')
|
|
122
|
+
|
|
123
|
+
-- Search terms de campañas activas únicamente
|
|
124
|
+
WHERE campaign.status = 'ENABLED'
|
|
125
|
+
AND ad_group.status = 'ENABLED'
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Paginación y streaming
|
|
131
|
+
|
|
132
|
+
### `search` vs `search_stream`
|
|
133
|
+
|
|
134
|
+
| Método | Cuándo usar | Comportamiento |
|
|
135
|
+
|--------|-------------|----------------|
|
|
136
|
+
| `search` | Resultados esperados < 10,000 filas | Devuelve páginas de 10,000 resultados |
|
|
137
|
+
| `search_stream` | Resultados esperados > 10,000 filas | Stream de chunks, más eficiente en memoria |
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
# Para datasets grandes (search terms de cuentas con alto volumen)
|
|
141
|
+
stream = ga_service.search_stream(customer_id=customer_id, query=query)
|
|
142
|
+
resultados = []
|
|
143
|
+
for batch in stream:
|
|
144
|
+
for row in batch.results:
|
|
145
|
+
resultados.append(procesar_fila(row))
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Batch operations con `MutateGoogleAdsRequest`
|
|
151
|
+
|
|
152
|
+
Para operaciones de escritura (agregar negative keywords, pausar campañas),
|
|
153
|
+
agrupar en un solo request reduce el consumo de quota.
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
from google.ads.googleads.client import GoogleAdsClient
|
|
157
|
+
|
|
158
|
+
def agregar_negative_keywords(
|
|
159
|
+
customer_id: str,
|
|
160
|
+
campaign_id: str,
|
|
161
|
+
terminos: list[str],
|
|
162
|
+
) -> None:
|
|
163
|
+
"""Agrega lista de negative keywords a una campaña en un solo request."""
|
|
164
|
+
campaign_criterion_service = client.get_service("CampaignCriterionService")
|
|
165
|
+
|
|
166
|
+
operaciones = []
|
|
167
|
+
for termino in terminos:
|
|
168
|
+
operacion = client.get_type("CampaignCriterionOperation")
|
|
169
|
+
criterio = operacion.create
|
|
170
|
+
criterio.campaign = f"customers/{customer_id}/campaigns/{campaign_id}"
|
|
171
|
+
criterio.negative = True
|
|
172
|
+
criterio.keyword.text = termino
|
|
173
|
+
criterio.keyword.match_type = client.enums.KeywordMatchTypeEnum.BROAD
|
|
174
|
+
operaciones.append(operacion)
|
|
175
|
+
|
|
176
|
+
campaign_criterion_service.mutate_campaign_criteria(
|
|
177
|
+
customer_id=customer_id,
|
|
178
|
+
operations=operaciones,
|
|
179
|
+
)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Errores comunes y solución
|
|
185
|
+
|
|
186
|
+
| Error | Causa probable | Solución |
|
|
187
|
+
|-------|----------------|----------|
|
|
188
|
+
| `PERMISSION_DENIED` | `login_customer_id` incorrecto o sin acceso | Verificar que el MCC tiene acceso a la sub-cuenta |
|
|
189
|
+
| `QUOTA_ERROR` | Quota diaria agotada | Implementar caché, solicitar nivel Standard |
|
|
190
|
+
| `NOT_FOUND` | `customer_id` o `campaign_id` no existe | Verificar IDs sin guiones |
|
|
191
|
+
| `INVALID_CUSTOMER_ID` | `customer_id` con guiones | `customer_id.replace("-", "")` |
|
|
192
|
+
| `AUTHENTICATION_ERROR` | `refresh_token` vencido o revocado | Regenerar refresh token en Google OAuth Playground |
|
|
193
|
+
| `RESOURCE_EXHAUSTED` | Demasiados requests en poco tiempo | Implementar retry con backoff exponencial |
|
|
194
|
+
|
|
195
|
+
### Retry con backoff exponencial
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
import time
|
|
199
|
+
from google.ads.googleads.errors import GoogleAdsException
|
|
200
|
+
|
|
201
|
+
def ejecutar_con_retry(fn, max_reintentos: int = 3):
|
|
202
|
+
"""Ejecuta una llamada a la API con retry y backoff exponencial."""
|
|
203
|
+
for intento in range(max_reintentos):
|
|
204
|
+
try:
|
|
205
|
+
return fn()
|
|
206
|
+
except GoogleAdsException as ex:
|
|
207
|
+
es_quota = any(
|
|
208
|
+
"QUOTA" in str(e.error_code) for e in ex.failure.errors
|
|
209
|
+
)
|
|
210
|
+
if es_quota and intento < max_reintentos - 1:
|
|
211
|
+
espera = 2 ** intento # 1s, 2s, 4s
|
|
212
|
+
time.sleep(espera)
|
|
213
|
+
continue
|
|
214
|
+
raise
|
|
215
|
+
```
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: patrones-python
|
|
3
|
+
description: Idiomas pythonicos, PEP 8, type hints modernos, dataclasses, async/await, context managers, decorators y generators. Patrones de código limpio en Python.
|
|
4
|
+
version: "1.3.0"
|
|
5
|
+
evolved: true
|
|
6
|
+
evolved-from: "1.2.0"
|
|
7
|
+
evolved-at: "2026-04-27"
|
|
8
|
+
evolved-by: "aprender"
|
|
9
|
+
evolved-note: "3 secciones nuevas (regex multi-pattern al extender scope, tracer/replicador con marca SYNC, fixtures crudos vs condensados) + refinamiento de la sección caché content-addressable (sharding, bypass env var, key multi-dimensión, tests obligatorios). Preserva F401 en soft imports. Patrones avanzados extraídos a recursos/patrones-avanzados.md para respetar el límite de 300 líneas de SKILL.md."
|
|
10
|
+
herramientasPermitidas: [Read, Glob, Grep]
|
|
11
|
+
exclusiones:
|
|
12
|
+
- "No cargar para patrones de un framework específico (FastAPI, Django, Celery) — los idiomas generales de este skill aplican, pero los patrones de framework tienen restricciones adicionales; cargar el skill del framework correspondiente."
|
|
13
|
+
- "No cargar para errores de instalación o dependencias Python — si el problema es pip, virtualenv o incompatibilidad de versiones, cargar `build-errors-python`."
|
|
14
|
+
- "No cargar para patrones de concurrencia avanzados (TaskGroup, semáforos, event loops) — para esos cargar `async-python` que cubre asyncio en profundidad."
|
|
15
|
+
- "No cargar para testing pytest (fixtures, mocking, cobertura) — ese dominio está en `testing-python` que cubre la toolchain completa de tests."
|
|
16
|
+
evolvable: true # default para skill estandar
|
|
17
|
+
---
|
|
18
|
+
# Patrones Python
|
|
19
|
+
|
|
20
|
+
## Cuándo NO cargar
|
|
21
|
+
|
|
22
|
+
- La tarea es específica de FastAPI o Django — cargar el skill del framework que tiene restricciones adicionales a los patrones generales.
|
|
23
|
+
- El problema es de instalación de dependencias Python — cargar `build-errors-python`.
|
|
24
|
+
- La pregunta es sobre concurrencia avanzada con asyncio — cargar `async-python`.
|
|
25
|
+
|
|
26
|
+
## PEP 8 — Convenciones de estilo
|
|
27
|
+
|
|
28
|
+
### Nomenclatura
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
# Módulos y paquetes: snake_case minúsculas
|
|
32
|
+
import mi_modulo
|
|
33
|
+
|
|
34
|
+
# Clases: PascalCase
|
|
35
|
+
class FacturaElectronica:
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
# Funciones y variables: snake_case
|
|
39
|
+
def calcular_iva(monto: float) -> float:
|
|
40
|
+
tasa_iva = 0.16
|
|
41
|
+
return monto * tasa_iva
|
|
42
|
+
|
|
43
|
+
# Constantes: UPPER_SNAKE_CASE
|
|
44
|
+
MAX_REINTENTOS = 3
|
|
45
|
+
URL_BASE_API = "https://api.ejemplo.com/v1"
|
|
46
|
+
|
|
47
|
+
# Variables privadas de instancia: prefijo _
|
|
48
|
+
class Factura:
|
|
49
|
+
def __init__(self):
|
|
50
|
+
self._numero_interno = None # privado por convención
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Longitud de línea y formato
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
# Máximo 88 caracteres (configuración Black estándar)
|
|
57
|
+
|
|
58
|
+
# Importaciones agrupadas:
|
|
59
|
+
# 1. Stdlib
|
|
60
|
+
import os
|
|
61
|
+
from pathlib import Path
|
|
62
|
+
|
|
63
|
+
# 2. Terceros
|
|
64
|
+
from fastapi import FastAPI, Depends
|
|
65
|
+
from sqlalchemy.orm import Session
|
|
66
|
+
|
|
67
|
+
# 3. Módulos locales
|
|
68
|
+
from app.models.usuario import Usuario
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Type Hints modernos (Python 3.10+)
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
# Union con | en vez de Union[X, Y]
|
|
77
|
+
def procesar(valor: int | str | None) -> str:
|
|
78
|
+
return str(valor or "")
|
|
79
|
+
|
|
80
|
+
# list, dict, tuple nativos (no de typing)
|
|
81
|
+
def filtrar(items: list[str], lookup: dict[str, int]) -> list[str]:
|
|
82
|
+
return [i for i in items if i in lookup]
|
|
83
|
+
|
|
84
|
+
# TypeAlias explícito
|
|
85
|
+
type JSON = dict[str, "JSON"] | list["JSON"] | str | int | float | bool | None
|
|
86
|
+
|
|
87
|
+
# ParamSpec para decoradores que preservan firma
|
|
88
|
+
from typing import ParamSpec, Callable
|
|
89
|
+
P = ParamSpec("P")
|
|
90
|
+
|
|
91
|
+
def con_log(fn: Callable[P, T]) -> Callable[P, T]:
|
|
92
|
+
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
|
|
93
|
+
print(f"Llamando {fn.__name__}")
|
|
94
|
+
return fn(*args, **kwargs)
|
|
95
|
+
return wrapper
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Dataclasses
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
from dataclasses import dataclass, field
|
|
104
|
+
from datetime import datetime
|
|
105
|
+
|
|
106
|
+
@dataclass
|
|
107
|
+
class Producto:
|
|
108
|
+
id: str
|
|
109
|
+
nombre: str
|
|
110
|
+
precio: float
|
|
111
|
+
activo: bool = True
|
|
112
|
+
etiquetas: list[str] = field(default_factory=list)
|
|
113
|
+
|
|
114
|
+
def __post_init__(self) -> None:
|
|
115
|
+
if self.precio < 0:
|
|
116
|
+
raise ValueError(f"Precio no puede ser negativo: {self.precio}")
|
|
117
|
+
self.nombre = self.nombre.strip()
|
|
118
|
+
|
|
119
|
+
# Dataclass inmutable
|
|
120
|
+
@dataclass(frozen=True)
|
|
121
|
+
class Coordenada:
|
|
122
|
+
latitud: float
|
|
123
|
+
longitud: float
|
|
124
|
+
|
|
125
|
+
# Dataclass con slots (Python 3.10+) — ahorra memoria
|
|
126
|
+
@dataclass(slots=True)
|
|
127
|
+
class EventoAuditoria:
|
|
128
|
+
usuario_id: str
|
|
129
|
+
accion: str
|
|
130
|
+
timestamp: datetime
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Context Managers
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
from contextlib import contextmanager, asynccontextmanager
|
|
139
|
+
|
|
140
|
+
# Context manager con generador
|
|
141
|
+
@contextmanager
|
|
142
|
+
def medir_tiempo(nombre: str):
|
|
143
|
+
inicio = time.perf_counter()
|
|
144
|
+
try:
|
|
145
|
+
yield
|
|
146
|
+
finally:
|
|
147
|
+
transcurrido = time.perf_counter() - inicio
|
|
148
|
+
print(f"{nombre}: {transcurrido:.4f}s")
|
|
149
|
+
|
|
150
|
+
# Context manager async
|
|
151
|
+
@asynccontextmanager
|
|
152
|
+
async def sesion_db(engine):
|
|
153
|
+
async with engine.begin() as conn:
|
|
154
|
+
try:
|
|
155
|
+
yield conn
|
|
156
|
+
await conn.commit()
|
|
157
|
+
except Exception:
|
|
158
|
+
await conn.rollback()
|
|
159
|
+
raise
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Anti-patrones Python Críticos
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
# MAL: argumento mutable como default
|
|
168
|
+
def agregar(item, lista=[]): # La lista persiste entre llamadas
|
|
169
|
+
lista.append(item)
|
|
170
|
+
|
|
171
|
+
# BIEN: usar None como centinela
|
|
172
|
+
def agregar(item, lista=None):
|
|
173
|
+
if lista is None:
|
|
174
|
+
lista = []
|
|
175
|
+
lista.append(item)
|
|
176
|
+
|
|
177
|
+
# MAL: bare except
|
|
178
|
+
try:
|
|
179
|
+
operacion_riesgosa()
|
|
180
|
+
except:
|
|
181
|
+
pass # silencia KeyboardInterrupt y SystemExit
|
|
182
|
+
|
|
183
|
+
# BIEN: excepción específica
|
|
184
|
+
try:
|
|
185
|
+
operacion_riesgosa()
|
|
186
|
+
except ValueError as e:
|
|
187
|
+
logger.error(f"Valor inválido: {e}")
|
|
188
|
+
|
|
189
|
+
# MAL: concatenación en loop (O(n²))
|
|
190
|
+
resultado = ""
|
|
191
|
+
for parte in partes:
|
|
192
|
+
resultado += parte
|
|
193
|
+
|
|
194
|
+
# BIEN: join (O(n))
|
|
195
|
+
resultado = "".join(partes)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Para generators, decoradores avanzados, async/await y manejo de errores idiomático,
|
|
199
|
+
ver [recursos/referencia-completa.md](recursos/referencia-completa.md).
|
|
200
|
+
|
|
201
|
+
## Gotchas / Errores comunes no obvios
|
|
202
|
+
|
|
203
|
+
- **`dataclass` con campo mutable como default (`field: list = []`) produce un objeto compartido entre todas las instancias**: Python reutiliza el objeto por defecto en vez de crear uno nuevo. Causa: los defaults de dataclass se evalúan en tiempo de definición de la clase, no en cada instanciación — una lista mutable como default es el mismo objeto en memoria para todas las instancias. Solución: usar `field(default_factory=list)` para campos mutables: `from dataclasses import field; tags: list = field(default_factory=list)`.
|
|
204
|
+
- **Decorator que usa `functools.wraps` pero no preserva type hints si la función decorada tiene anotaciones genéricas**: el `@wraps` copia `__wrapped__`, `__doc__` y `__name__`, pero el tipo de retorno inferido por `mypy` es el del wrapper, no el del wrapped. Causa: `functools.wraps` no puede preservar el tipado estático del wrapped — mypy ve el tipo del wrapper `Callable[..., Any]`. Solución: usar `TypeVar` y tipado genérico en el decorator con `ParamSpec` (Python 3.10+): `P = ParamSpec('P'); T = TypeVar('T')` y tipar el wrapper como `Callable[P, T]`.
|
|
205
|
+
- **`__slots__` en clase Python produce `TypeError: multiple bases have instance lay-out conflict`** al heredar de otra clase con `__slots__`: las subclases con `__slots__` requieren que todos los ancestros también tengan `__slots__`, o que el ancestro directo sea `object`. Causa: si `ClaseBase` no tiene `__slots__`, tiene un `__dict__` implícito; si `ClaseHija` tiene `__slots__`, hay conflicto de layout de memoria. Solución: o agregar `__slots__ = ()` vacío a la clase base, o eliminar `__slots__` de la subclase — no mezclar clases con y sin `__slots__` en la misma jerarquía.
|
|
206
|
+
- **`property` setter que modifica un campo privado no refleja el cambio en `__repr__` generado por dataclass**: el `@property` en un dataclass crea un campo de clase que conflictúa con el campo de instancia del dataclass. Causa: `@dataclass` genera `__repr__` basado en los campos declarados en `__init__` — si el setter modifica un atributo con nombre diferente (ej: `_valor`), `__repr__` muestra el campo original sin la modificación. Solución: usar `field(init=False, repr=False)` para el campo interno y exponer solo la `property` en la interfaz pública.
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Patrones avanzados (carga bajo demanda)
|
|
211
|
+
|
|
212
|
+
Los siguientes patrones aparecen al integrar Python con pipelines reales
|
|
213
|
+
(conversores de documentos, clientes heterogéneos, cachés determinísticos,
|
|
214
|
+
detectores de texto, duplicación deliberada de lógica). El detalle completo
|
|
215
|
+
está en [recursos/patrones-avanzados.md](recursos/patrones-avanzados.md).
|
|
216
|
+
|
|
217
|
+
| # | Patrón | Cargar cuando |
|
|
218
|
+
|---|--------|---------------|
|
|
219
|
+
| 1 | Normalizadores: colapsar al formato canónico del PROYECTO | escribir `_normalizar(texto)` después de un conversor externo (MarkItDown, Pandoc, mammoth) |
|
|
220
|
+
| 2 | kwargs opcionales entre clientes hermanos: try/except TypeError | propagar un kwarg nuevo a clientes con signature heterogénea sin romper la interfaz |
|
|
221
|
+
| 3 | Caché content-addressable por SHA256 | función pura costosa (>1 s) que se invoca repetidamente con los mismos inputs |
|
|
222
|
+
| 4 | F401 en archivos con soft imports es intencional | módulo importa una dependencia opcional dentro de `try/except ImportError` |
|
|
223
|
+
| 5 | Detectores regex multi-pattern: extender scope sin refinar genera FP | un detector con OR de patterns se va a aplicar a un texto más ruidoso que el original |
|
|
224
|
+
| 6 | Tracer/replicador paralelo del motor: marca SYNC obligatoria | duplicar lógica del motor para telemetría, explainability o shadow runs |
|
|
225
|
+
| 7 | Fixtures con datos pre-procesados NO ejercen el path crudo | el motor prefiere leer un campo crudo opcional sobre uno condensado, y los fixtures son condensados |
|
|
226
|
+
|
|
227
|
+
Cargar la sección específica del recurso cuando aplique al problema en mano —
|
|
228
|
+
no cargar el archivo completo si solo se necesita un patrón.
|