@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,146 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Tech Skills Map — Conecta tecnologías detectadas con skills SWL recomendados.
|
|
5
|
+
*
|
|
6
|
+
* Usa el resultado de detectarTecnologias() para generar una lista priorizada
|
|
7
|
+
* de skills que deberian cargarse automaticamente al inicio de sesion.
|
|
8
|
+
*
|
|
9
|
+
* Integración:
|
|
10
|
+
* - inyeccion-contexto.js puede usar sugerirSkills() para recomendar skills
|
|
11
|
+
* - agent-matcher.js puede usar obtenerAgentesPorStack() para routing
|
|
12
|
+
* - orquestador-swl puede consultar al asignar agentes a tareas
|
|
13
|
+
*
|
|
14
|
+
* @module hooks/lib/tech-skills-map
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const { detectarTecnologias } = require('./detectar-package-manager');
|
|
18
|
+
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// API pública
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Genera lista de skills recomendados basandose en las tecnologias detectadas.
|
|
25
|
+
* Los skills se deduplican y se ordenan por frecuencia (mas tecnologias lo referencian = mas arriba).
|
|
26
|
+
*
|
|
27
|
+
* @param {string} dir - Directorio raiz del proyecto.
|
|
28
|
+
* @returns {{ skills: Array<{name: string, sources: string[], priority: number}>, agentes: Array<{name: string, source: string}>, combos: Array<{id: string, skills: string[], pipeline: string}> }}
|
|
29
|
+
*/
|
|
30
|
+
function sugerirSkills(dir) {
|
|
31
|
+
const { tecnologias, combos } = detectarTecnologias(dir);
|
|
32
|
+
|
|
33
|
+
// Agrupar skills con sus fuentes
|
|
34
|
+
const skillMap = new Map(); // skillName → { sources: Set, priority: number }
|
|
35
|
+
|
|
36
|
+
for (const tech of tecnologias) {
|
|
37
|
+
for (const skill of tech.skills) {
|
|
38
|
+
if (!skillMap.has(skill)) {
|
|
39
|
+
skillMap.set(skill, { sources: new Set(), priority: 0 });
|
|
40
|
+
}
|
|
41
|
+
const entry = skillMap.get(skill);
|
|
42
|
+
entry.sources.add(tech.name);
|
|
43
|
+
entry.priority++;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Agregar skills de combos con prioridad bonus
|
|
48
|
+
for (const combo of combos) {
|
|
49
|
+
for (const skill of combo.skills) {
|
|
50
|
+
if (!skillMap.has(skill)) {
|
|
51
|
+
skillMap.set(skill, { sources: new Set(), priority: 0 });
|
|
52
|
+
}
|
|
53
|
+
const entry = skillMap.get(skill);
|
|
54
|
+
entry.sources.add(`combo:${combo.id}`);
|
|
55
|
+
entry.priority += 2; // bonus por ser combo
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Convertir a array y ordenar por prioridad descendente
|
|
60
|
+
const skills = Array.from(skillMap.entries())
|
|
61
|
+
.map(([name, { sources, priority }]) => ({
|
|
62
|
+
name,
|
|
63
|
+
sources: Array.from(sources),
|
|
64
|
+
priority,
|
|
65
|
+
}))
|
|
66
|
+
.sort((a, b) => b.priority - a.priority);
|
|
67
|
+
|
|
68
|
+
// Agentes recomendados (deduplicados)
|
|
69
|
+
const agenteSet = new Map();
|
|
70
|
+
for (const tech of tecnologias) {
|
|
71
|
+
if (tech.agente && !agenteSet.has(tech.agente)) {
|
|
72
|
+
agenteSet.set(tech.agente, tech.name);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const agentes = Array.from(agenteSet.entries())
|
|
76
|
+
.map(([name, source]) => ({ name, source }));
|
|
77
|
+
|
|
78
|
+
return { skills, agentes, combos };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Obtiene los agentes recomendados para el stack del proyecto.
|
|
83
|
+
*
|
|
84
|
+
* @param {string} dir
|
|
85
|
+
* @returns {Array<{agente: string, tecnologia: string, skills: string[]}>}
|
|
86
|
+
*/
|
|
87
|
+
function obtenerAgentesPorStack(dir) {
|
|
88
|
+
const { tecnologias } = detectarTecnologias(dir);
|
|
89
|
+
const agenteMap = new Map(); // agenteName → { tecnologias: [], skills: Set }
|
|
90
|
+
|
|
91
|
+
for (const tech of tecnologias) {
|
|
92
|
+
if (!tech.agente) continue;
|
|
93
|
+
if (!agenteMap.has(tech.agente)) {
|
|
94
|
+
agenteMap.set(tech.agente, { tecnologias: [], skills: new Set() });
|
|
95
|
+
}
|
|
96
|
+
const entry = agenteMap.get(tech.agente);
|
|
97
|
+
entry.tecnologias.push(tech.name);
|
|
98
|
+
tech.skills.forEach(s => entry.skills.add(s));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return Array.from(agenteMap.entries())
|
|
102
|
+
.map(([agente, { tecnologias: techs, skills }]) => ({
|
|
103
|
+
agente,
|
|
104
|
+
tecnologia: techs.join(', '),
|
|
105
|
+
skills: Array.from(skills),
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Genera un resumen compacto del stack para inyectar en contexto.
|
|
111
|
+
* Formato: una linea por tecnologia con skills recomendados.
|
|
112
|
+
*
|
|
113
|
+
* @param {string} dir
|
|
114
|
+
* @returns {string} Resumen en texto plano, vacio si no detecta nada.
|
|
115
|
+
*/
|
|
116
|
+
function generarResumenStack(dir) {
|
|
117
|
+
const { skills, agentes, combos } = sugerirSkills(dir);
|
|
118
|
+
if (skills.length === 0) return '';
|
|
119
|
+
|
|
120
|
+
const lines = ['## Stack detectado'];
|
|
121
|
+
|
|
122
|
+
if (agentes.length > 0) {
|
|
123
|
+
lines.push('Agentes recomendados: ' + agentes.map(a => a.name).join(', '));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (skills.length > 0) {
|
|
127
|
+
const top = skills.slice(0, 10).map(s => s.name);
|
|
128
|
+
lines.push('Skills sugeridos: ' + top.join(', '));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (combos.length > 0) {
|
|
132
|
+
lines.push('Combos: ' + combos.map(c => c.id + ' (' + c.pipeline + ')').join(', '));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return lines.join('\n');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// ---------------------------------------------------------------------------
|
|
139
|
+
// Exports
|
|
140
|
+
// ---------------------------------------------------------------------------
|
|
141
|
+
|
|
142
|
+
module.exports = {
|
|
143
|
+
sugerirSkills,
|
|
144
|
+
obtenerAgentesPorStack,
|
|
145
|
+
generarResumenStack,
|
|
146
|
+
};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Cliente HTTP Telegram — zero-deps.
|
|
5
|
+
*
|
|
6
|
+
* Provee `enviarMensaje(token, chatId, texto, opts)` con:
|
|
7
|
+
* - Escape HTML automático
|
|
8
|
+
* - Truncado a 3500 chars con sufijo "… [truncado]"
|
|
9
|
+
* - Reintentos con backoff exponencial (100/200/400ms) para respuestas 5xx
|
|
10
|
+
* - Sin reintento para respuestas 4xx
|
|
11
|
+
* - Timeout de 8 segundos
|
|
12
|
+
*
|
|
13
|
+
* Dependencias: solo módulos node: (https, fs, path, os).
|
|
14
|
+
*
|
|
15
|
+
* @module hooks/lib/telegram-cliente
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const https = require('node:https');
|
|
19
|
+
|
|
20
|
+
// Límite de Telegram es 4096 chars; usamos 3500 para dar margen al wrapper HTML.
|
|
21
|
+
const LIMITE_CHARS = 3500;
|
|
22
|
+
const SUFIJO_TRUNCADO = '\n… [truncado]';
|
|
23
|
+
const TIMEOUT_MS = 8000;
|
|
24
|
+
const REINTENTOS_MAX = 3;
|
|
25
|
+
const BACKOFF_BASE_MS = 100;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Escapa caracteres HTML especiales para parse_mode HTML de Telegram.
|
|
29
|
+
*
|
|
30
|
+
* @param {string} texto - Texto a escapar.
|
|
31
|
+
* @returns {string} Texto con &, < y > escapados.
|
|
32
|
+
*/
|
|
33
|
+
function escaparHtml(texto) {
|
|
34
|
+
return String(texto)
|
|
35
|
+
.replace(/&/g, '&')
|
|
36
|
+
.replace(/</g, '<')
|
|
37
|
+
.replace(/>/g, '>');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Trunca el texto si supera el límite, agregando el sufijo de truncado.
|
|
42
|
+
*
|
|
43
|
+
* @param {string} texto - Texto a truncar.
|
|
44
|
+
* @param {number} limite - Límite máximo de caracteres.
|
|
45
|
+
* @returns {string} Texto truncado o el original si cabe.
|
|
46
|
+
*/
|
|
47
|
+
function truncar(texto, limite) {
|
|
48
|
+
const s = String(texto);
|
|
49
|
+
if (s.length <= limite) return s;
|
|
50
|
+
const corte = limite - SUFIJO_TRUNCADO.length;
|
|
51
|
+
return s.slice(0, corte).trimEnd() + SUFIJO_TRUNCADO;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Realiza un intento de envío HTTP hacia la API de Telegram.
|
|
56
|
+
*
|
|
57
|
+
* @param {string} token - Token del bot de Telegram.
|
|
58
|
+
* @param {string} chatId - ID del chat destinatario.
|
|
59
|
+
* @param {string} texto - Texto del mensaje (ya preparado para enviar).
|
|
60
|
+
* @param {object} opts - Opciones adicionales del mensaje.
|
|
61
|
+
* @returns {Promise<{ok: boolean, statusCode: number, cuerpo: string}>}
|
|
62
|
+
*/
|
|
63
|
+
function _intentarEnvio(token, chatId, texto, opts) {
|
|
64
|
+
const payload = JSON.stringify({
|
|
65
|
+
chat_id: chatId,
|
|
66
|
+
text: texto,
|
|
67
|
+
parse_mode: 'HTML',
|
|
68
|
+
disable_web_page_preview: true,
|
|
69
|
+
...opts,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
return new Promise((resolve) => {
|
|
73
|
+
const req = https.request(
|
|
74
|
+
{
|
|
75
|
+
method: 'POST',
|
|
76
|
+
hostname: 'api.telegram.org',
|
|
77
|
+
path: `/bot${token}/sendMessage`,
|
|
78
|
+
headers: {
|
|
79
|
+
'Content-Type': 'application/json',
|
|
80
|
+
'Content-Length': Buffer.byteLength(payload),
|
|
81
|
+
},
|
|
82
|
+
timeout: TIMEOUT_MS,
|
|
83
|
+
},
|
|
84
|
+
(res) => {
|
|
85
|
+
let cuerpo = '';
|
|
86
|
+
res.on('data', (chunk) => { cuerpo += chunk; });
|
|
87
|
+
res.on('end', () => {
|
|
88
|
+
resolve({ ok: res.statusCode >= 200 && res.statusCode < 300, statusCode: res.statusCode, cuerpo });
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
req.on('timeout', () => {
|
|
94
|
+
req.destroy();
|
|
95
|
+
resolve({ ok: false, statusCode: 0, cuerpo: 'timeout' });
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
req.on('error', (err) => {
|
|
99
|
+
resolve({ ok: false, statusCode: 0, cuerpo: err.message });
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
req.write(payload);
|
|
103
|
+
req.end();
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Pausa durante `ms` milisegundos.
|
|
109
|
+
*
|
|
110
|
+
* @param {number} ms - Milisegundos a esperar.
|
|
111
|
+
* @returns {Promise<void>}
|
|
112
|
+
*/
|
|
113
|
+
function _esperar(ms) {
|
|
114
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Envía un mensaje de Telegram con escape HTML, truncado y reintentos.
|
|
119
|
+
*
|
|
120
|
+
* Solo reintenta en errores 5xx (falla de servidor). Los errores 4xx
|
|
121
|
+
* (credenciales inválidas, chat no encontrado) no se reintentan porque
|
|
122
|
+
* volver a intentar no resolvería el problema.
|
|
123
|
+
*
|
|
124
|
+
* @param {string} token - Token del bot (`123:ABC...`).
|
|
125
|
+
* @param {string} chatId - ID numérico del chat destino.
|
|
126
|
+
* @param {string} texto - Texto del mensaje. Se escapa y trunca automáticamente.
|
|
127
|
+
* @param {object} [opts] - Campos adicionales para el body de sendMessage.
|
|
128
|
+
* @returns {Promise<{ok: boolean, statusCode: number, error?: string}>}
|
|
129
|
+
*/
|
|
130
|
+
async function enviarMensaje(token, chatId, texto, opts = {}) {
|
|
131
|
+
const textoPrepado = truncar(escaparHtml(texto), LIMITE_CHARS);
|
|
132
|
+
|
|
133
|
+
for (let intento = 0; intento < REINTENTOS_MAX; intento++) {
|
|
134
|
+
const resultado = await _intentarEnvio(token, chatId, textoPrepado, opts);
|
|
135
|
+
|
|
136
|
+
if (resultado.cuerpo === 'timeout') {
|
|
137
|
+
return { ok: false, statusCode: 0, error: 'timeout' };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (resultado.ok) {
|
|
141
|
+
return { ok: true, statusCode: resultado.statusCode };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Errores 4xx: no reintentar (credenciales inválidas, chat inexistente, etc.)
|
|
145
|
+
if (resultado.statusCode >= 400 && resultado.statusCode < 500) {
|
|
146
|
+
const etiqueta = resultado.statusCode === 401 ? 'unauthorized' : `http-${resultado.statusCode}`;
|
|
147
|
+
return { ok: false, statusCode: resultado.statusCode, error: etiqueta };
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Error de red (statusCode 0) o 5xx: reintento con backoff exponencial
|
|
151
|
+
if (intento < REINTENTOS_MAX - 1) {
|
|
152
|
+
await _esperar(BACKOFF_BASE_MS * Math.pow(2, intento));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return { ok: false, statusCode: 0, error: 'max-retries-exceeded' };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
module.exports = { enviarMensaje, escaparHtml, truncar };
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Configuración de notificaciones Telegram — zero-deps.
|
|
5
|
+
*
|
|
6
|
+
* Lee credenciales desde `~/.claude/notifications/.env`, valida campos
|
|
7
|
+
* requeridos y gestiona la lista de proyectos silenciados (`muted.json`).
|
|
8
|
+
*
|
|
9
|
+
* Convenciones del parser .env:
|
|
10
|
+
* - Líneas que comienzan con # son comentarios y se ignoran.
|
|
11
|
+
* - El separador es el PRIMER `=` de la línea; el valor puede contener `=`.
|
|
12
|
+
* - Las comillas simples y dobles se eliminan solo si envuelven el valor completo.
|
|
13
|
+
* - Los espacios alrededor de nombre y valor se recortan.
|
|
14
|
+
*
|
|
15
|
+
* @module hooks/lib/telegram-config
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const fs = require('node:fs');
|
|
19
|
+
const path = require('node:path');
|
|
20
|
+
const os = require('node:os');
|
|
21
|
+
|
|
22
|
+
const { atomicWriteJSON } = require('./atomic-write');
|
|
23
|
+
|
|
24
|
+
// Directorio donde viven las credenciales y estado
|
|
25
|
+
const DIR_NOTIFICACIONES = path.join(os.homedir(), '.claude', 'notifications');
|
|
26
|
+
const RUTA_ENV = path.join(DIR_NOTIFICACIONES, '.env');
|
|
27
|
+
const RUTA_MUTED = path.join(DIR_NOTIFICACIONES, 'muted.json');
|
|
28
|
+
|
|
29
|
+
// Campos que deben estar presentes para que las notificaciones funcionen
|
|
30
|
+
const CAMPOS_REQUERIDOS = ['TELEGRAM_BOT_TOKEN', 'TELEGRAM_CHAT_ID'];
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Parsea el contenido de un archivo .env.
|
|
34
|
+
*
|
|
35
|
+
* Respeta el primer `=` como separador, de modo que valores como
|
|
36
|
+
* `TOKEN=abc=def` producen `{ TOKEN: "abc=def" }`.
|
|
37
|
+
*
|
|
38
|
+
* @param {string} contenido - Texto completo del archivo .env.
|
|
39
|
+
* @returns {Record<string, string>} Mapa de variables.
|
|
40
|
+
*/
|
|
41
|
+
function _parsearEnv(contenido) {
|
|
42
|
+
const resultado = {};
|
|
43
|
+
|
|
44
|
+
for (const linea of contenido.split(/\r?\n/)) {
|
|
45
|
+
const recortada = linea.trim();
|
|
46
|
+
|
|
47
|
+
// Ignorar líneas vacías y comentarios
|
|
48
|
+
if (!recortada || recortada.startsWith('#')) continue;
|
|
49
|
+
|
|
50
|
+
// El nombre es todo hasta el primer `=`
|
|
51
|
+
const posIgual = recortada.indexOf('=');
|
|
52
|
+
if (posIgual === -1) continue;
|
|
53
|
+
|
|
54
|
+
const nombre = recortada.slice(0, posIgual).trim();
|
|
55
|
+
let valor = recortada.slice(posIgual + 1).trim();
|
|
56
|
+
|
|
57
|
+
// Eliminar comillas envolventes (simples o dobles)
|
|
58
|
+
if (
|
|
59
|
+
(valor.startsWith('"') && valor.endsWith('"')) ||
|
|
60
|
+
(valor.startsWith("'") && valor.endsWith("'"))
|
|
61
|
+
) {
|
|
62
|
+
valor = valor.slice(1, -1);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Solo guardar si el nombre es un identificador de variable válido
|
|
66
|
+
if (/^[A-Z_][A-Z0-9_]*$/.test(nombre)) {
|
|
67
|
+
resultado[nombre] = valor;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return resultado;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Carga la configuración de notificaciones desde `~/.claude/notifications/.env`.
|
|
76
|
+
*
|
|
77
|
+
* Las variables del proceso (`process.env`) tienen precedencia sobre el archivo
|
|
78
|
+
* para permitir inyección en entornos CI o de prueba.
|
|
79
|
+
*
|
|
80
|
+
* @returns {{ config: Record<string, string>, valido: boolean, errores: string[] }}
|
|
81
|
+
*/
|
|
82
|
+
function cargarConfig() {
|
|
83
|
+
let configArchivo = {};
|
|
84
|
+
|
|
85
|
+
if (fs.existsSync(RUTA_ENV)) {
|
|
86
|
+
try {
|
|
87
|
+
const contenido = fs.readFileSync(RUTA_ENV, 'utf8');
|
|
88
|
+
configArchivo = _parsearEnv(contenido);
|
|
89
|
+
} catch (_) {
|
|
90
|
+
// Si el archivo no se puede leer, continuar con vacío
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Las variables de entorno del proceso tienen precedencia
|
|
95
|
+
const config = { ...configArchivo };
|
|
96
|
+
for (const campo of CAMPOS_REQUERIDOS) {
|
|
97
|
+
if (process.env[campo]) config[campo] = process.env[campo];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const errores = CAMPOS_REQUERIDOS.filter((c) => !config[c] || !config[c].trim());
|
|
101
|
+
return { config, valido: errores.length === 0, errores };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Lee la lista actual de proyectos silenciados.
|
|
106
|
+
*
|
|
107
|
+
* @returns {string[]} Lista de nombres de proyecto silenciados.
|
|
108
|
+
*/
|
|
109
|
+
function _leerMuted() {
|
|
110
|
+
try {
|
|
111
|
+
if (!fs.existsSync(RUTA_MUTED)) return [];
|
|
112
|
+
const contenido = fs.readFileSync(RUTA_MUTED, 'utf8');
|
|
113
|
+
const datos = JSON.parse(contenido);
|
|
114
|
+
return Array.isArray(datos) ? datos : [];
|
|
115
|
+
} catch (_) {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Agrega un proyecto a la lista de silenciados.
|
|
122
|
+
*
|
|
123
|
+
* Idempotente: si el proyecto ya estaba silenciado, no lo duplica.
|
|
124
|
+
*
|
|
125
|
+
* @param {string} proyecto - Nombre del proyecto a silenciar.
|
|
126
|
+
*/
|
|
127
|
+
function agregarMute(proyecto) {
|
|
128
|
+
const actuales = _leerMuted();
|
|
129
|
+
if (!actuales.includes(proyecto)) {
|
|
130
|
+
actuales.push(proyecto);
|
|
131
|
+
atomicWriteJSON(RUTA_MUTED, actuales);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Elimina un proyecto de la lista de silenciados.
|
|
137
|
+
*
|
|
138
|
+
* Idempotente: si el proyecto no estaba silenciado, no hace nada.
|
|
139
|
+
*
|
|
140
|
+
* @param {string} proyecto - Nombre del proyecto a des-silenciar.
|
|
141
|
+
*/
|
|
142
|
+
function eliminarMute(proyecto) {
|
|
143
|
+
const actuales = _leerMuted();
|
|
144
|
+
const nuevos = actuales.filter((p) => p !== proyecto);
|
|
145
|
+
// Solo escribir si cambió algo
|
|
146
|
+
if (nuevos.length !== actuales.length) {
|
|
147
|
+
atomicWriteJSON(RUTA_MUTED, nuevos);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Verifica si un proyecto está actualmente silenciado.
|
|
153
|
+
*
|
|
154
|
+
* @param {string} proyecto - Nombre del proyecto a verificar.
|
|
155
|
+
* @returns {boolean} `true` si el proyecto está en la lista de silenciados.
|
|
156
|
+
*/
|
|
157
|
+
function estaMuted(proyecto) {
|
|
158
|
+
return _leerMuted().includes(proyecto);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
module.exports = {
|
|
162
|
+
cargarConfig,
|
|
163
|
+
agregarMute,
|
|
164
|
+
eliminarMute,
|
|
165
|
+
estaMuted,
|
|
166
|
+
// Exportar rutas para facilitar pruebas
|
|
167
|
+
RUTA_ENV,
|
|
168
|
+
RUTA_MUTED,
|
|
169
|
+
DIR_NOTIFICACIONES,
|
|
170
|
+
};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* token-budget.js — Calculador de presupuesto de tokens para inyección de contexto
|
|
3
|
+
*
|
|
4
|
+
* Estima tokens y distribuye un presupuesto limitado entre bloques de contexto
|
|
5
|
+
* priorizados por recencia e importancia. Inspirado en el sistema de token
|
|
6
|
+
* budget de agentmemory.
|
|
7
|
+
* Zero dependencias externas — aritmética pura de Node.js.
|
|
8
|
+
*
|
|
9
|
+
* Uso:
|
|
10
|
+
* const { estimateTokens, allocateBudget } = require('./token-budget');
|
|
11
|
+
* const tokens = estimateTokens('texto de ejemplo');
|
|
12
|
+
* const bloques = allocateBudget(candidatos, 2000);
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Estima el número de tokens en un texto.
|
|
19
|
+
* Heurística: ~4 caracteres por token en inglés/español, ~3 para código.
|
|
20
|
+
* No es exacta pero es suficiente para presupuestación sin dependencias externas.
|
|
21
|
+
*
|
|
22
|
+
* @param {string} text - Texto a estimar
|
|
23
|
+
* @param {'prose'|'code'|'mixed'} [type='mixed'] - Tipo de contenido
|
|
24
|
+
* @returns {number} Estimación de tokens
|
|
25
|
+
*/
|
|
26
|
+
function estimateTokens(text, type) {
|
|
27
|
+
if (!text || typeof text !== 'string') return 0;
|
|
28
|
+
|
|
29
|
+
const len = text.length;
|
|
30
|
+
switch (type) {
|
|
31
|
+
case 'prose': return Math.ceil(len / 4.2);
|
|
32
|
+
case 'code': return Math.ceil(len / 3.0);
|
|
33
|
+
case 'mixed':
|
|
34
|
+
default: return Math.ceil(len / 3.5);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Bloque de contexto candidato para inyección.
|
|
40
|
+
* @typedef {Object} ContextBlock
|
|
41
|
+
* @property {string} type - Tipo: 'summary'|'observation'|'memory'|'rule'|'skill'
|
|
42
|
+
* @property {string} content - Contenido del bloque
|
|
43
|
+
* @property {number} [tokens] - Tokens pre-calculados (se estima si no se da)
|
|
44
|
+
* @property {number} [recency] - Timestamp Unix de última relevancia (más reciente = mayor prioridad)
|
|
45
|
+
* @property {number} [importance] - Importancia 0.0-1.0 (default 0.5)
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Calcula el score de prioridad de un bloque.
|
|
50
|
+
* Combina recencia (60%) e importancia (40%) para ordenar candidatos.
|
|
51
|
+
*
|
|
52
|
+
* @param {ContextBlock} block - Bloque a evaluar
|
|
53
|
+
* @param {number} now - Timestamp actual en ms
|
|
54
|
+
* @returns {number} Score normalizado 0.0-1.0
|
|
55
|
+
*/
|
|
56
|
+
function scoreBlock(block, now) {
|
|
57
|
+
const importance = typeof block.importance === 'number'
|
|
58
|
+
? Math.max(0, Math.min(1, block.importance))
|
|
59
|
+
: 0.5;
|
|
60
|
+
|
|
61
|
+
let recencyScore = 0.5;
|
|
62
|
+
if (typeof block.recency === 'number' && block.recency > 0) {
|
|
63
|
+
const ageMs = now - block.recency;
|
|
64
|
+
const ageHours = ageMs / (1000 * 60 * 60);
|
|
65
|
+
// Decaimiento exponencial: pierde 50% de recencia cada 24 horas
|
|
66
|
+
recencyScore = Math.exp(-0.693 * ageHours / 24);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return recencyScore * 0.6 + importance * 0.4;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Distribuye un presupuesto de tokens entre bloques candidatos.
|
|
74
|
+
* Prioriza por score (recencia + importancia). Incluye bloques completos
|
|
75
|
+
* hasta agotar el presupuesto — no corta bloques a la mitad.
|
|
76
|
+
*
|
|
77
|
+
* @param {ContextBlock[]} candidates - Bloques candidatos
|
|
78
|
+
* @param {number} budget - Presupuesto total de tokens
|
|
79
|
+
* @param {Object} [options] - Opciones de configuración
|
|
80
|
+
* @param {number} [options.reserveTokens=200] - Tokens reservados para overhead del prompt
|
|
81
|
+
* @param {number} [options.maxBlocks=20] - Máximo de bloques a incluir
|
|
82
|
+
* @returns {{ selected: ContextBlock[], totalTokens: number, rejected: number }}
|
|
83
|
+
*/
|
|
84
|
+
function allocateBudget(candidates, budget, options) {
|
|
85
|
+
const opts = options || {};
|
|
86
|
+
const reserve = typeof opts.reserveTokens === 'number' ? opts.reserveTokens : 200;
|
|
87
|
+
const maxBlocks = typeof opts.maxBlocks === 'number' ? opts.maxBlocks : 20;
|
|
88
|
+
const effectiveBudget = Math.max(0, budget - reserve);
|
|
89
|
+
const now = Date.now();
|
|
90
|
+
|
|
91
|
+
if (!Array.isArray(candidates) || candidates.length === 0) {
|
|
92
|
+
return { selected: [], totalTokens: 0, rejected: 0 };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Estimar tokens si no están pre-calculados
|
|
96
|
+
const scored = candidates.map(block => {
|
|
97
|
+
const tokens = typeof block.tokens === 'number'
|
|
98
|
+
? block.tokens
|
|
99
|
+
: estimateTokens(block.content);
|
|
100
|
+
return {
|
|
101
|
+
...block,
|
|
102
|
+
tokens,
|
|
103
|
+
_score: scoreBlock(block, now)
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Ordenar por score descendente
|
|
108
|
+
scored.sort((a, b) => b._score - a._score);
|
|
109
|
+
|
|
110
|
+
const selected = [];
|
|
111
|
+
let totalTokens = 0;
|
|
112
|
+
|
|
113
|
+
for (const block of scored) {
|
|
114
|
+
if (selected.length >= maxBlocks) break;
|
|
115
|
+
if (totalTokens + block.tokens > effectiveBudget) continue;
|
|
116
|
+
|
|
117
|
+
selected.push({
|
|
118
|
+
type: block.type,
|
|
119
|
+
content: block.content,
|
|
120
|
+
tokens: block.tokens,
|
|
121
|
+
recency: block.recency,
|
|
122
|
+
importance: block.importance
|
|
123
|
+
});
|
|
124
|
+
totalTokens += block.tokens;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
selected,
|
|
129
|
+
totalTokens,
|
|
130
|
+
rejected: candidates.length - selected.length
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Calcula estadísticas de uso de tokens para un conjunto de contenidos.
|
|
136
|
+
* Útil para reportes de eficiencia y diagnóstico.
|
|
137
|
+
*
|
|
138
|
+
* @param {Object.<string, string>} namedContents - Mapa nombre→contenido
|
|
139
|
+
* @returns {Object.<string, number>} Mapa nombre→tokens estimados
|
|
140
|
+
*/
|
|
141
|
+
function tokenBreakdown(namedContents) {
|
|
142
|
+
const result = {};
|
|
143
|
+
if (!namedContents || typeof namedContents !== 'object') return result;
|
|
144
|
+
|
|
145
|
+
for (const [name, content] of Object.entries(namedContents)) {
|
|
146
|
+
result[name] = estimateTokens(content);
|
|
147
|
+
}
|
|
148
|
+
return result;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
module.exports = {
|
|
152
|
+
estimateTokens,
|
|
153
|
+
scoreBlock,
|
|
154
|
+
allocateBudget,
|
|
155
|
+
tokenBreakdown
|
|
156
|
+
};
|