@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,306 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Nudge Tracker — Ciclo de vida de los nudges del sistema SWL.
|
|
5
|
+
*
|
|
6
|
+
* Un "nudge" es un mensaje que un hook emite por stderr sugiriendo una acción
|
|
7
|
+
* al modelo o al usuario (ej: "invoca perfilador-usuario-swl", "ejecuta
|
|
8
|
+
* /swl:evolucionar X"). Sin trackear, los nudges ignorados se pierden
|
|
9
|
+
* silenciosamente — el sistema parece dar sugerencias pero no sabe si alguien
|
|
10
|
+
* las accionó.
|
|
11
|
+
*
|
|
12
|
+
* Este módulo centraliza:
|
|
13
|
+
* - emit(kind, target, payload) → registra nudge en JSONL append-only
|
|
14
|
+
* - markAccionado(id) → marca que fue accionado (llamado por el consumer)
|
|
15
|
+
* - escalar(kind, target) → si >= N nudges del mismo tipo sin accionar,
|
|
16
|
+
* escribe una alerta persistente
|
|
17
|
+
* - resumen() → estadísticas por tipo/target
|
|
18
|
+
*
|
|
19
|
+
* Zero-deps. Append-only para eventos, atomic-write para alertas.
|
|
20
|
+
*
|
|
21
|
+
* @module hooks/lib/nudge-tracker
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
const fs = require('fs');
|
|
25
|
+
const path = require('path');
|
|
26
|
+
const crypto = require('crypto');
|
|
27
|
+
|
|
28
|
+
let atomicWriteJSON;
|
|
29
|
+
try {
|
|
30
|
+
({ atomicWriteJSON } = require('./atomic-write'));
|
|
31
|
+
} catch {
|
|
32
|
+
atomicWriteJSON = (p, obj) => fs.writeFileSync(p, JSON.stringify(obj, null, 2), 'utf8');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Configuración
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
const DIR_EVOL = path.join(process.cwd(), '.planning', 'evolucion');
|
|
40
|
+
const LOG_PATH = path.join(DIR_EVOL, 'nudges.jsonl');
|
|
41
|
+
const ALERT_PATH = path.join(DIR_EVOL, 'alertas-persistentes.json');
|
|
42
|
+
|
|
43
|
+
/** Umbral por defecto para escalar a alerta persistente. */
|
|
44
|
+
const DEFAULT_ESCALATION_THRESHOLD = 5;
|
|
45
|
+
|
|
46
|
+
/** Ventana de "recientes" para decidir escalamiento (ms). */
|
|
47
|
+
const WINDOW_MS = 14 * 24 * 3600 * 1000; // 14 días
|
|
48
|
+
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Utilidades
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
|
|
53
|
+
function ensureDir() {
|
|
54
|
+
try { fs.mkdirSync(DIR_EVOL, { recursive: true }); } catch { /* ignore */ }
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function genId() {
|
|
58
|
+
return crypto.randomBytes(8).toString('hex');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function leerLog() {
|
|
62
|
+
try {
|
|
63
|
+
return fs.readFileSync(LOG_PATH, 'utf8')
|
|
64
|
+
.split(/\r?\n/)
|
|
65
|
+
.filter(Boolean)
|
|
66
|
+
.map(l => { try { return JSON.parse(l); } catch { return null; } })
|
|
67
|
+
.filter(Boolean);
|
|
68
|
+
} catch {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// API
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Categorías de mutación según intent del cambio propuesto.
|
|
79
|
+
* Patrón adaptado de evolver GEP (temp/evolver-main/src/gep/mutation.js).
|
|
80
|
+
*
|
|
81
|
+
* - repair: corrige un bug o regresión ya observada (retrospectivo)
|
|
82
|
+
* - optimize: mejora performance, claridad o cobertura sin corregir bug
|
|
83
|
+
* - innovate: añade capacidad nueva no cubierta antes (prospectivo)
|
|
84
|
+
*/
|
|
85
|
+
const MUTATION_CATEGORIES = Object.freeze(['repair', 'optimize', 'innovate']);
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Nivel de riesgo de aplicar la mutación sugerida.
|
|
89
|
+
*
|
|
90
|
+
* - low: cambio autocontenido, reversible, bajo impacto (ej: doc, comment)
|
|
91
|
+
* - medium: cambio en 1-2 módulos, reversible con git revert
|
|
92
|
+
* - high: cambio estructural, afecta múltiples módulos o interfaces públicas
|
|
93
|
+
*/
|
|
94
|
+
const RISK_LEVELS = Object.freeze(['low', 'medium', 'high']);
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Emite y registra un nudge.
|
|
98
|
+
*
|
|
99
|
+
* @param {object} opts
|
|
100
|
+
* @param {string} opts.kind - Tipo de nudge (ej: 'perfil-usuario', 'auto-evolucion').
|
|
101
|
+
* @param {string} opts.target - Sujeto (ej: nombre de agente, skill, componente).
|
|
102
|
+
* @param {string} opts.message - Texto sugerido (solo para log; el hook caller emite a stderr).
|
|
103
|
+
* @param {string} [opts.source] - Hook o agente que lo emitió.
|
|
104
|
+
* @param {object} [opts.data] - Payload adicional.
|
|
105
|
+
* @param {string} [opts.mutation_category] - 'repair' | 'optimize' | 'innovate' (ver MUTATION_CATEGORIES).
|
|
106
|
+
* @param {string} [opts.risk_level] - 'low' | 'medium' | 'high' (ver RISK_LEVELS).
|
|
107
|
+
* @returns {{ id: string, ts: string }}
|
|
108
|
+
*/
|
|
109
|
+
function emit(opts) {
|
|
110
|
+
ensureDir();
|
|
111
|
+
|
|
112
|
+
// Validar mutation_category y risk_level si se proveen (silencioso: si vienen
|
|
113
|
+
// con valor desconocido, se normaliza a undefined en lugar de crashear).
|
|
114
|
+
const mutationCategory = opts.mutation_category && MUTATION_CATEGORIES.includes(opts.mutation_category)
|
|
115
|
+
? opts.mutation_category
|
|
116
|
+
: undefined;
|
|
117
|
+
const riskLevel = opts.risk_level && RISK_LEVELS.includes(opts.risk_level)
|
|
118
|
+
? opts.risk_level
|
|
119
|
+
: undefined;
|
|
120
|
+
|
|
121
|
+
const entry = {
|
|
122
|
+
id: genId(),
|
|
123
|
+
kind: String(opts.kind || 'unknown'),
|
|
124
|
+
target: String(opts.target || ''),
|
|
125
|
+
source: String(opts.source || ''),
|
|
126
|
+
message: String(opts.message || ''),
|
|
127
|
+
data: opts.data || {},
|
|
128
|
+
ts: new Date().toISOString(),
|
|
129
|
+
accionado: false,
|
|
130
|
+
accionado_ts: null,
|
|
131
|
+
accionado_por: null,
|
|
132
|
+
};
|
|
133
|
+
if (mutationCategory) entry.mutation_category = mutationCategory;
|
|
134
|
+
if (riskLevel) entry.risk_level = riskLevel;
|
|
135
|
+
|
|
136
|
+
try {
|
|
137
|
+
fs.appendFileSync(LOG_PATH, JSON.stringify(entry) + '\n', 'utf8');
|
|
138
|
+
} catch { /* silencioso */ }
|
|
139
|
+
return { id: entry.id, ts: entry.ts };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Marca un nudge como accionado. El consumer (comando, agente) llama a esto
|
|
144
|
+
* cuando toma la acción sugerida.
|
|
145
|
+
*
|
|
146
|
+
* @param {string} id - ID retornado por emit().
|
|
147
|
+
* @param {string} [by] - Quién lo accionó ('usuario', 'auto', nombre del agente).
|
|
148
|
+
* @returns {boolean} - true si se encontró y marcó.
|
|
149
|
+
*/
|
|
150
|
+
function markAccionado(id, by = 'desconocido') {
|
|
151
|
+
const entries = leerLog();
|
|
152
|
+
const idx = entries.findIndex(e => e.id === id);
|
|
153
|
+
if (idx === -1) return false;
|
|
154
|
+
|
|
155
|
+
entries[idx].accionado = true;
|
|
156
|
+
entries[idx].accionado_ts = new Date().toISOString();
|
|
157
|
+
entries[idx].accionado_por = String(by);
|
|
158
|
+
|
|
159
|
+
// Reescribimos el JSONL completo (compromiso vs append-only: el marcado de
|
|
160
|
+
// accionado es raro comparado con emit, vale la pena para claridad).
|
|
161
|
+
ensureDir();
|
|
162
|
+
const lines = entries.map(e => JSON.stringify(e)).join('\n') + '\n';
|
|
163
|
+
try {
|
|
164
|
+
fs.writeFileSync(LOG_PATH, lines, 'utf8');
|
|
165
|
+
return true;
|
|
166
|
+
} catch {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Calcula estadísticas de nudges en la ventana reciente y escala si corresponde.
|
|
173
|
+
*
|
|
174
|
+
* Si hay >= threshold nudges del mismo (kind, target) sin accionar en la
|
|
175
|
+
* ventana, escribe una alerta persistente en alertas-persistentes.json.
|
|
176
|
+
*
|
|
177
|
+
* @param {object} [opts]
|
|
178
|
+
* @param {number} [opts.threshold=5]
|
|
179
|
+
* @returns {{ alertasNuevas: number, totalAlertas: number }}
|
|
180
|
+
*/
|
|
181
|
+
function escalarSiAplica(opts = {}) {
|
|
182
|
+
const threshold = opts.threshold || DEFAULT_ESCALATION_THRESHOLD;
|
|
183
|
+
const limite = Date.now() - WINDOW_MS;
|
|
184
|
+
const entries = leerLog().filter(e => {
|
|
185
|
+
const t = Date.parse(e.ts);
|
|
186
|
+
return Number.isFinite(t) && t >= limite && !e.accionado;
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// Agrupar por (kind, target)
|
|
190
|
+
const buckets = {};
|
|
191
|
+
for (const e of entries) {
|
|
192
|
+
const key = `${e.kind}::${e.target}`;
|
|
193
|
+
if (!buckets[key]) buckets[key] = [];
|
|
194
|
+
buckets[key].push(e);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Leer alertas existentes
|
|
198
|
+
let alertas = {};
|
|
199
|
+
try {
|
|
200
|
+
alertas = JSON.parse(fs.readFileSync(ALERT_PATH, 'utf8'));
|
|
201
|
+
} catch { alertas = {}; }
|
|
202
|
+
|
|
203
|
+
let alertasNuevas = 0;
|
|
204
|
+
for (const [key, lista] of Object.entries(buckets)) {
|
|
205
|
+
if (lista.length >= threshold) {
|
|
206
|
+
const [kind, target] = key.split('::');
|
|
207
|
+
const prevAlerta = alertas[key];
|
|
208
|
+
if (!prevAlerta || prevAlerta.count < lista.length) {
|
|
209
|
+
alertas[key] = {
|
|
210
|
+
kind,
|
|
211
|
+
target,
|
|
212
|
+
count: lista.length,
|
|
213
|
+
primera: lista[0].ts,
|
|
214
|
+
ultima: lista[lista.length - 1].ts,
|
|
215
|
+
mensaje: `${lista.length} nudges tipo "${kind}" para "${target}" ignorados en 14 días`,
|
|
216
|
+
estado: 'activa',
|
|
217
|
+
};
|
|
218
|
+
if (!prevAlerta) alertasNuevas++;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
ensureDir();
|
|
224
|
+
try {
|
|
225
|
+
atomicWriteJSON(ALERT_PATH, alertas);
|
|
226
|
+
} catch { /* silencioso */ }
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
alertasNuevas,
|
|
230
|
+
totalAlertas: Object.values(alertas).filter(a => a.estado === 'activa').length,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Resumen de nudges para el comando /swl:evolucion-estado.
|
|
236
|
+
*
|
|
237
|
+
* @param {object} [opts]
|
|
238
|
+
* @param {number} [opts.dias=14]
|
|
239
|
+
* @returns {object} estadísticas agregadas
|
|
240
|
+
*/
|
|
241
|
+
function resumen(opts = {}) {
|
|
242
|
+
const dias = opts.dias || 14;
|
|
243
|
+
const limite = Date.now() - dias * 24 * 3600 * 1000;
|
|
244
|
+
const entries = leerLog().filter(e => {
|
|
245
|
+
const t = Date.parse(e.ts);
|
|
246
|
+
return Number.isFinite(t) && t >= limite;
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
const total = entries.length;
|
|
250
|
+
const accionados = entries.filter(e => e.accionado).length;
|
|
251
|
+
const pendientes = total - accionados;
|
|
252
|
+
|
|
253
|
+
const porKind = {};
|
|
254
|
+
for (const e of entries) {
|
|
255
|
+
if (!porKind[e.kind]) porKind[e.kind] = { total: 0, accionados: 0 };
|
|
256
|
+
porKind[e.kind].total++;
|
|
257
|
+
if (e.accionado) porKind[e.kind].accionados++;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
let alertas = {};
|
|
261
|
+
try {
|
|
262
|
+
alertas = JSON.parse(fs.readFileSync(ALERT_PATH, 'utf8'));
|
|
263
|
+
} catch { alertas = {}; }
|
|
264
|
+
const alertasActivas = Object.values(alertas).filter(a => a.estado === 'activa');
|
|
265
|
+
|
|
266
|
+
return {
|
|
267
|
+
ventanaDias: dias,
|
|
268
|
+
total,
|
|
269
|
+
accionados,
|
|
270
|
+
pendientes,
|
|
271
|
+
tasaAccion: total > 0 ? Math.round(accionados / total * 100) / 100 : null,
|
|
272
|
+
porKind,
|
|
273
|
+
alertasActivas,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Resuelve una alerta (cuando el tipo de nudge ya se accionó o se descartó).
|
|
279
|
+
*/
|
|
280
|
+
function resolverAlerta(kind, target, razon = 'resuelta') {
|
|
281
|
+
const key = `${kind}::${target}`;
|
|
282
|
+
let alertas = {};
|
|
283
|
+
try {
|
|
284
|
+
alertas = JSON.parse(fs.readFileSync(ALERT_PATH, 'utf8'));
|
|
285
|
+
} catch { return false; }
|
|
286
|
+
if (!alertas[key]) return false;
|
|
287
|
+
alertas[key].estado = 'resuelta';
|
|
288
|
+
alertas[key].resuelta_ts = new Date().toISOString();
|
|
289
|
+
alertas[key].razon = razon;
|
|
290
|
+
ensureDir();
|
|
291
|
+
try {
|
|
292
|
+
atomicWriteJSON(ALERT_PATH, alertas);
|
|
293
|
+
return true;
|
|
294
|
+
} catch { return false; }
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
module.exports = {
|
|
298
|
+
emit,
|
|
299
|
+
markAccionado,
|
|
300
|
+
escalarSiAplica,
|
|
301
|
+
resumen,
|
|
302
|
+
resolverAlerta,
|
|
303
|
+
MUTATION_CATEGORIES,
|
|
304
|
+
RISK_LEVELS,
|
|
305
|
+
_paths: { LOG_PATH, ALERT_PATH, DIR_EVOL },
|
|
306
|
+
};
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* OTLP Exporter — Exportador de trazas compatible con OpenTelemetry.
|
|
5
|
+
* Zero-deps. Solo módulos nativos de Node.js.
|
|
6
|
+
*
|
|
7
|
+
* Almacena trazas en .planning/traces/YYYY-MM-DD.jsonl (append-only).
|
|
8
|
+
* Exportación opcional a endpoint HTTP/HTTPS vía variable OTLP_ENDPOINT.
|
|
9
|
+
*
|
|
10
|
+
* Formato de traza (OTLP-lite):
|
|
11
|
+
* { traceId, spanId, nombre, inicio, fin, duracionMs, estado, atributos }
|
|
12
|
+
*
|
|
13
|
+
* Desde v2.0.0 expone también la clase OtlpLocalProcessor que implementa
|
|
14
|
+
* la interfaz TracingProcessor (scripts/lib/tracing-processor-interface.js).
|
|
15
|
+
* Las funciones sueltas originales (crearSpan, finalizarSpan, etc.) se
|
|
16
|
+
* mantienen como wrappers delgados para preservar compatibilidad hacia atrás.
|
|
17
|
+
*
|
|
18
|
+
* @module hooks/lib/otlp-exporter
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const fs = require('fs');
|
|
22
|
+
const path = require('path');
|
|
23
|
+
const crypto = require('crypto');
|
|
24
|
+
const http = require('http');
|
|
25
|
+
const https = require('https');
|
|
26
|
+
|
|
27
|
+
// Carga la interfaz TracingProcessor con try/catch para robustez:
|
|
28
|
+
// si el archivo no existe (entorno degradado) las funciones sueltas
|
|
29
|
+
// siguen funcionando igual que antes.
|
|
30
|
+
let TracingProcessor;
|
|
31
|
+
try {
|
|
32
|
+
({ TracingProcessor } = require('../../scripts/lib/tracing-processor-interface'));
|
|
33
|
+
} catch (_) {
|
|
34
|
+
// Fallback: clase vacía que no rompe la herencia en OtlpLocalProcessor
|
|
35
|
+
TracingProcessor = class TracingProcessorFallback {};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const TRACES_DIR = '.planning/traces';
|
|
39
|
+
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Generadores de IDs
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Genera un trace ID de 32 caracteres hexadecimales (128 bits).
|
|
46
|
+
* @returns {string}
|
|
47
|
+
*/
|
|
48
|
+
function generarTraceId() {
|
|
49
|
+
return crypto.randomBytes(16).toString('hex');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Genera un span ID de 16 caracteres hexadecimales (64 bits).
|
|
54
|
+
* @returns {string}
|
|
55
|
+
*/
|
|
56
|
+
function generarSpanId() {
|
|
57
|
+
return crypto.randomBytes(8).toString('hex');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
// Persistencia
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Asegura que el directorio de trazas exista.
|
|
66
|
+
* @param {string} cwd - Directorio raíz del proyecto.
|
|
67
|
+
* @returns {string} Ruta absoluta al directorio.
|
|
68
|
+
*/
|
|
69
|
+
function asegurarDirectorio(cwd) {
|
|
70
|
+
const dir = path.join(cwd, TRACES_DIR);
|
|
71
|
+
if (!fs.existsSync(dir)) {
|
|
72
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
73
|
+
}
|
|
74
|
+
return dir;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Ruta del archivo JSONL para la fecha actual (YYYY-MM-DD.jsonl).
|
|
79
|
+
* @param {string} cwd
|
|
80
|
+
* @returns {string}
|
|
81
|
+
*/
|
|
82
|
+
function rutaHoy(cwd) {
|
|
83
|
+
const fecha = new Date().toISOString().slice(0, 10);
|
|
84
|
+
return path.join(asegurarDirectorio(cwd), `${fecha}.jsonl`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// API pública
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Crea un nuevo span (inicio de una operación a medir).
|
|
93
|
+
*
|
|
94
|
+
* @param {string} nombre - Nombre de la operación (ej. "agent:revisor-codigo-swl").
|
|
95
|
+
* @param {object} [atributos] - Metadatos adicionales clave-valor.
|
|
96
|
+
* @returns {{ traceId: string, spanId: string, nombre: string, inicio: string, atributos: object }}
|
|
97
|
+
*/
|
|
98
|
+
function crearSpan(nombre, atributos = {}) {
|
|
99
|
+
return {
|
|
100
|
+
traceId: generarTraceId(),
|
|
101
|
+
spanId: generarSpanId(),
|
|
102
|
+
nombre: String(nombre),
|
|
103
|
+
inicio: new Date().toISOString(),
|
|
104
|
+
atributos: { ...atributos },
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Finaliza un span y lo escribe al archivo JSONL del día.
|
|
110
|
+
* También envía al endpoint OTLP si OTLP_ENDPOINT está definido.
|
|
111
|
+
*
|
|
112
|
+
* @param {string} cwd - Directorio raíz del proyecto.
|
|
113
|
+
* @param {object} span - Span creado con crearSpan().
|
|
114
|
+
* @param {object} [atributosExtra] - Atributos adicionales (resultado, error, etc.).
|
|
115
|
+
* @param {'OK'|'ERROR'} [estado] - Estado de la operación.
|
|
116
|
+
* @returns {object} Traza completa.
|
|
117
|
+
*/
|
|
118
|
+
function finalizarSpan(cwd, span, atributosExtra = {}, estado = 'OK') {
|
|
119
|
+
const fin = new Date().toISOString();
|
|
120
|
+
const inicioMs = new Date(span.inicio).getTime();
|
|
121
|
+
const finMs = new Date(fin).getTime();
|
|
122
|
+
|
|
123
|
+
const traza = {
|
|
124
|
+
traceId: span.traceId,
|
|
125
|
+
spanId: span.spanId,
|
|
126
|
+
nombre: span.nombre,
|
|
127
|
+
inicio: span.inicio,
|
|
128
|
+
fin,
|
|
129
|
+
duracionMs: finMs - inicioMs,
|
|
130
|
+
estado,
|
|
131
|
+
atributos: { ...span.atributos, ...atributosExtra },
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
// Persistir en JSONL (append-only, sin escritura atómica para no bloquear)
|
|
135
|
+
try {
|
|
136
|
+
fs.appendFileSync(rutaHoy(cwd), JSON.stringify(traza) + '\n', 'utf8');
|
|
137
|
+
} catch (_) {
|
|
138
|
+
// Silencioso — la telemetría no debe interrumpir la sesión
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
exportarAsync(traza);
|
|
142
|
+
return traza;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Registra una traza completa de forma instantánea (sin inicio/fin separados).
|
|
147
|
+
* Útil para eventos puntuales donde la duración no importa.
|
|
148
|
+
*
|
|
149
|
+
* @param {string} cwd
|
|
150
|
+
* @param {string} nombre
|
|
151
|
+
* @param {object} [atributos]
|
|
152
|
+
* @param {'OK'|'ERROR'} [estado]
|
|
153
|
+
* @returns {object} Traza registrada.
|
|
154
|
+
*/
|
|
155
|
+
function registrar(cwd, nombre, atributos = {}, estado = 'OK') {
|
|
156
|
+
const span = crearSpan(nombre, atributos);
|
|
157
|
+
return finalizarSpan(cwd, span, {}, estado);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Envía la traza a un endpoint HTTP/HTTPS de forma asíncrona (fire-and-forget).
|
|
162
|
+
* Solo se activa si la variable de entorno OTLP_ENDPOINT está definida.
|
|
163
|
+
*
|
|
164
|
+
* @param {object} traza
|
|
165
|
+
*/
|
|
166
|
+
function exportarAsync(traza) {
|
|
167
|
+
const endpoint = process.env.OTLP_ENDPOINT;
|
|
168
|
+
if (!endpoint) return;
|
|
169
|
+
|
|
170
|
+
try {
|
|
171
|
+
const body = JSON.stringify(traza);
|
|
172
|
+
const url = new URL(endpoint);
|
|
173
|
+
const modulo = url.protocol === 'https:' ? https : http;
|
|
174
|
+
const opts = {
|
|
175
|
+
hostname: url.hostname,
|
|
176
|
+
port: url.port || (url.protocol === 'https:' ? 443 : 80),
|
|
177
|
+
path: url.pathname + (url.search || ''),
|
|
178
|
+
method: 'POST',
|
|
179
|
+
headers: {
|
|
180
|
+
'Content-Type': 'application/json',
|
|
181
|
+
'Content-Length': Buffer.byteLength(body),
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const req = modulo.request(opts);
|
|
186
|
+
req.on('error', () => {}); // Silencioso
|
|
187
|
+
req.write(body);
|
|
188
|
+
req.end();
|
|
189
|
+
} catch (_) {
|
|
190
|
+
// Silencioso
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
// Lectura de trazas
|
|
196
|
+
// ---------------------------------------------------------------------------
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Lee y parsea las trazas del día actual.
|
|
200
|
+
*
|
|
201
|
+
* @param {string} cwd
|
|
202
|
+
* @returns {object[]} Array de objetos de traza (puede estar vacío).
|
|
203
|
+
*/
|
|
204
|
+
function leerHoy(cwd) {
|
|
205
|
+
try {
|
|
206
|
+
return fs.readFileSync(rutaHoy(cwd), 'utf8')
|
|
207
|
+
.split('\n')
|
|
208
|
+
.filter(Boolean)
|
|
209
|
+
.map(l => JSON.parse(l));
|
|
210
|
+
} catch (_) {
|
|
211
|
+
return [];
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Lee y parsea las trazas de una fecha específica.
|
|
217
|
+
*
|
|
218
|
+
* @param {string} cwd
|
|
219
|
+
* @param {string} fecha - Formato YYYY-MM-DD.
|
|
220
|
+
* @returns {object[]}
|
|
221
|
+
*/
|
|
222
|
+
function leerFecha(cwd, fecha) {
|
|
223
|
+
try {
|
|
224
|
+
const filePath = path.join(asegurarDirectorio(cwd), `${fecha}.jsonl`);
|
|
225
|
+
return fs.readFileSync(filePath, 'utf8')
|
|
226
|
+
.split('\n')
|
|
227
|
+
.filter(Boolean)
|
|
228
|
+
.map(l => JSON.parse(l));
|
|
229
|
+
} catch (_) {
|
|
230
|
+
return [];
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Genera un resumen de trazas del día: total, por nombre, por estado.
|
|
236
|
+
*
|
|
237
|
+
* @param {string} cwd
|
|
238
|
+
* @returns {{ total: number, porNombre: object, errores: number }}
|
|
239
|
+
*/
|
|
240
|
+
function resumenHoy(cwd) {
|
|
241
|
+
const trazas = leerHoy(cwd);
|
|
242
|
+
const porNombre = {};
|
|
243
|
+
let errores = 0;
|
|
244
|
+
|
|
245
|
+
for (const t of trazas) {
|
|
246
|
+
porNombre[t.nombre] = (porNombre[t.nombre] || 0) + 1;
|
|
247
|
+
if (t.estado === 'ERROR') errores++;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return { total: trazas.length, porNombre, errores };
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// ---------------------------------------------------------------------------
|
|
254
|
+
// OtlpLocalProcessor — implementación de TracingProcessor
|
|
255
|
+
// ---------------------------------------------------------------------------
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Procesador OTLP local que implementa la interfaz TracingProcessor.
|
|
259
|
+
*
|
|
260
|
+
* Encapsula la lógica de persistencia JSONL existente bajo el contrato
|
|
261
|
+
* formal de TracingProcessor, permitiendo su uso con MultiProcessor y
|
|
262
|
+
* otros exportadores compuestos.
|
|
263
|
+
*
|
|
264
|
+
* Compatibilidad hacia atrás: las funciones sueltas del módulo (crearSpan,
|
|
265
|
+
* finalizarSpan, etc.) siguen funcionando y delegan en esta misma lógica.
|
|
266
|
+
*
|
|
267
|
+
* @extends TracingProcessor
|
|
268
|
+
*
|
|
269
|
+
* @example
|
|
270
|
+
* const procesador = new OtlpLocalProcessor('/ruta/proyecto');
|
|
271
|
+
* procesador.onSpanEnd(span); // persiste en .planning/traces/YYYY-MM-DD.jsonl
|
|
272
|
+
*/
|
|
273
|
+
class OtlpLocalProcessor extends TracingProcessor {
|
|
274
|
+
/**
|
|
275
|
+
* @param {string} cwd - Directorio raíz del proyecto.
|
|
276
|
+
*/
|
|
277
|
+
constructor(cwd) {
|
|
278
|
+
super();
|
|
279
|
+
/** @type {string} */
|
|
280
|
+
this._cwd = String(cwd || process.cwd());
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Invocado al iniciar una traza. Sin efecto en persistencia local;
|
|
285
|
+
* el registro ocurre al finalizar spans individuales.
|
|
286
|
+
*
|
|
287
|
+
* @param {object} traza
|
|
288
|
+
*/
|
|
289
|
+
onTraceStart(traza) { // eslint-disable-line no-unused-vars
|
|
290
|
+
// Sin persistencia en inicio de traza — la traza se reconstruye desde spans
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Invocado al finalizar una traza. Cierra cualquier buffer asociado.
|
|
295
|
+
* En el exportador local no hay buffer de traza activo, por lo que
|
|
296
|
+
* esta operación es un no-op con efecto de flush implícito.
|
|
297
|
+
*
|
|
298
|
+
* @param {object} traza
|
|
299
|
+
*/
|
|
300
|
+
onTraceEnd(traza) { // eslint-disable-line no-unused-vars
|
|
301
|
+
// No-op: el JSONL es append-only y no requiere cierre de traza
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Invocado al iniciar un span. Sin persistencia en el exportador local;
|
|
306
|
+
* los spans incompletos no se registran.
|
|
307
|
+
*
|
|
308
|
+
* @param {object} span
|
|
309
|
+
*/
|
|
310
|
+
onSpanStart(span) { // eslint-disable-line no-unused-vars
|
|
311
|
+
// Sin persistencia en inicio de span
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Invocado al finalizar un span. Persiste el span en el archivo JSONL
|
|
316
|
+
* del día actual y dispara exportación HTTP asíncrona si aplica.
|
|
317
|
+
*
|
|
318
|
+
* @param {object} span - Span completo con al menos { traceId, spanId, nombre,
|
|
319
|
+
* inicio, fin, duracionMs, estado, atributos }.
|
|
320
|
+
*/
|
|
321
|
+
onSpanEnd(span) {
|
|
322
|
+
try {
|
|
323
|
+
fs.appendFileSync(
|
|
324
|
+
rutaHoy(this._cwd),
|
|
325
|
+
JSON.stringify(span) + '\n',
|
|
326
|
+
'utf8'
|
|
327
|
+
);
|
|
328
|
+
} catch (_) {
|
|
329
|
+
// La telemetría no debe interrumpir la sesión
|
|
330
|
+
}
|
|
331
|
+
exportarAsync(span);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Cierre limpio del procesador. El JSONL es append-only y no requiere
|
|
336
|
+
* flush explícito; este método existe para cumplir el contrato de la interfaz.
|
|
337
|
+
*/
|
|
338
|
+
shutdown() {
|
|
339
|
+
// No-op: no hay buffers ni conexiones persistentes que cerrar
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Fuerza el volcado de buffers pendientes. Sin buffers internos en el
|
|
344
|
+
* exportador local — operación garantizada como no-op seguro.
|
|
345
|
+
*/
|
|
346
|
+
forceFlush() {
|
|
347
|
+
// No-op: escrituras son síncronas (appendFileSync)
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// ---------------------------------------------------------------------------
|
|
352
|
+
// Exports
|
|
353
|
+
// ---------------------------------------------------------------------------
|
|
354
|
+
|
|
355
|
+
module.exports = {
|
|
356
|
+
// API original — compatibilidad hacia atrás garantizada
|
|
357
|
+
crearSpan,
|
|
358
|
+
finalizarSpan,
|
|
359
|
+
registrar,
|
|
360
|
+
leerHoy,
|
|
361
|
+
leerFecha,
|
|
362
|
+
resumenHoy,
|
|
363
|
+
// Nueva clase TracingProcessor
|
|
364
|
+
OtlpLocalProcessor,
|
|
365
|
+
};
|