@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,305 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Módulo: schedule-parser.js
|
|
6
|
+
* Parser de lenguaje natural a expresiones cron.
|
|
7
|
+
*
|
|
8
|
+
* Convierte frases en inglés y expresiones cron crudas a un objeto estructurado.
|
|
9
|
+
* Zero dependencias externas — basado exclusivamente en regex y Node.js stdlib.
|
|
10
|
+
*
|
|
11
|
+
* Patrones soportados:
|
|
12
|
+
* "every N minutes" → cron (asterisco)/N * * * *
|
|
13
|
+
* "every N hours" → cron 0 (asterisco)/N * * *
|
|
14
|
+
* "hourly" → 0 * * * *
|
|
15
|
+
* "daily" / "every day" → 0 9 * * *
|
|
16
|
+
* "weekly" → 0 9 * * 1
|
|
17
|
+
* "every morning at TIME" → 0 H * * *
|
|
18
|
+
* "every evening at TIME" → 0 H * * *
|
|
19
|
+
* "daily at TIME" → 0 H * * *
|
|
20
|
+
* "at TIME every day" → 0 H * * *
|
|
21
|
+
* "weekly on DAYNAME" → 0 9 * * DOW
|
|
22
|
+
* "every DAYNAME" → 0 9 * * DOW
|
|
23
|
+
* "every DAYNAME at TIME" → M H * * DOW
|
|
24
|
+
* Expresión cron cruda (5 campos) → passthrough
|
|
25
|
+
*
|
|
26
|
+
* Fuente original: mission-control-main/src/lib/schedule-parser.ts (MIT)
|
|
27
|
+
* Portado 2026-04-19 a JavaScript zero-deps para swl-ses.
|
|
28
|
+
*
|
|
29
|
+
* @module schedule-parser
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Mapa de nombres de día a número de día-de-semana cron (0=domingo, 1=lunes…)
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
/** @type {Object.<string, number>} */
|
|
37
|
+
const MAPA_DIAS = {
|
|
38
|
+
sunday: 0, sun: 0,
|
|
39
|
+
monday: 1, mon: 1,
|
|
40
|
+
tuesday: 2, tue: 2,
|
|
41
|
+
wednesday: 3, wed: 3,
|
|
42
|
+
thursday: 4, thu: 4,
|
|
43
|
+
friday: 5, fri: 5,
|
|
44
|
+
saturday: 6, sat: 6,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Convierte un nombre de día (en inglés) a número de día-de-semana cron.
|
|
49
|
+
* Retorna null si el nombre no se reconoce.
|
|
50
|
+
*
|
|
51
|
+
* @param {string} entrada
|
|
52
|
+
* @returns {number|null}
|
|
53
|
+
*/
|
|
54
|
+
function parsearNombreDia(entrada) {
|
|
55
|
+
const valor = MAPA_DIAS[entrada.toLowerCase()];
|
|
56
|
+
return valor !== undefined ? valor : null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Parsea una expresión de hora como "9am", "9:30am", "14:00", "9:30 pm".
|
|
61
|
+
* Retorna { hora, minuto } o null si el formato no se reconoce o los valores
|
|
62
|
+
* están fuera de rango.
|
|
63
|
+
*
|
|
64
|
+
* @param {string} entrada
|
|
65
|
+
* @returns {{ hora: number, minuto: number }|null}
|
|
66
|
+
*/
|
|
67
|
+
function parsearHora(entrada) {
|
|
68
|
+
// Acepta: "9", "9am", "9:30am", "9:30 pm", "14:00", "21"
|
|
69
|
+
const coincidencia = entrada.match(/^(\d{1,2})(?::(\d{2}))?\s*(am|pm)?$/i);
|
|
70
|
+
if (!coincidencia) return null;
|
|
71
|
+
|
|
72
|
+
let hora = parseInt(coincidencia[1], 10);
|
|
73
|
+
const minuto = coincidencia[2] ? parseInt(coincidencia[2], 10) : 0;
|
|
74
|
+
const ampm = coincidencia[3] ? coincidencia[3].toLowerCase() : null;
|
|
75
|
+
|
|
76
|
+
if (ampm === 'pm' && hora < 12) hora += 12;
|
|
77
|
+
if (ampm === 'am' && hora === 12) hora = 0;
|
|
78
|
+
|
|
79
|
+
if (hora < 0 || hora > 23 || minuto < 0 || minuto > 59) return null;
|
|
80
|
+
return { hora, minuto };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Formatea la hora para descripción legible en inglés (para consistencia con origen).
|
|
85
|
+
* Ej: hora=9, minuto=0 → "9:00 AM"; hora=14, minuto=30 → "2:30 PM"
|
|
86
|
+
*
|
|
87
|
+
* @param {number} hora
|
|
88
|
+
* @param {number} minuto
|
|
89
|
+
* @returns {string}
|
|
90
|
+
*/
|
|
91
|
+
function formatearHoraLegible(hora, minuto) {
|
|
92
|
+
const sufijo = hora < 12 ? 'AM' : 'PM';
|
|
93
|
+
const horaDisplay = hora % 12 || 12;
|
|
94
|
+
const minutoDisplay = minuto > 0 ? `:${String(minuto).padStart(2, '0')}` : '';
|
|
95
|
+
return `${horaDisplay}${minutoDisplay} ${sufijo}`;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Regex para detectar expresiones cron crudas de 5 campos
|
|
99
|
+
const REGEX_CRON = /^(\*|[\d,\-\/]+)\s+(\*|[\d,\-\/]+)\s+(\*|[\d,\-\/]+)\s+(\*|[\d,\-\/]+)\s+(\*|[\d,\-\/]+)$/;
|
|
100
|
+
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
// Función principal de parseo
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Parsea una expresión de schedule en lenguaje natural o cron crudo.
|
|
107
|
+
*
|
|
108
|
+
* Retorna un objeto con la expresión cron equivalente y una descripción
|
|
109
|
+
* legible en inglés. Retorna null si la expresión no se reconoce.
|
|
110
|
+
*
|
|
111
|
+
* @param {string} texto - Frase en lenguaje natural o expresión cron cruda.
|
|
112
|
+
* @returns {{ cron: string, descripcion: string }|null}
|
|
113
|
+
*/
|
|
114
|
+
function parseNaturalSchedule(texto) {
|
|
115
|
+
if (!texto || typeof texto !== 'string') return null;
|
|
116
|
+
const entrada = texto.trim();
|
|
117
|
+
if (!entrada) return null;
|
|
118
|
+
|
|
119
|
+
// Passthrough: expresión cron cruda de 5 campos
|
|
120
|
+
if (REGEX_CRON.test(entrada)) {
|
|
121
|
+
return { cron: entrada, descripcion: `Programación personalizada (${entrada})` };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const lower = entrada.toLowerCase();
|
|
125
|
+
|
|
126
|
+
// "hourly"
|
|
127
|
+
if (lower === 'hourly') {
|
|
128
|
+
return { cron: '0 * * * *', descripcion: 'Cada hora' };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// "daily" / "every day"
|
|
132
|
+
if (lower === 'daily' || lower === 'every day') {
|
|
133
|
+
return { cron: '0 9 * * *', descripcion: 'Diariamente a las 9:00 AM' };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// "weekly" (sin día específico)
|
|
137
|
+
if (lower === 'weekly') {
|
|
138
|
+
return { cron: '0 9 * * 1', descripcion: 'Cada lunes a las 9:00 AM' };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// "every N minutes"
|
|
142
|
+
const cadaNMinutos = lower.match(/^every\s+(\d+)\s+minutes?$/);
|
|
143
|
+
if (cadaNMinutos) {
|
|
144
|
+
const n = parseInt(cadaNMinutos[1], 10);
|
|
145
|
+
if (n > 0 && n <= 59) {
|
|
146
|
+
return {
|
|
147
|
+
cron: `*/${n} * * * *`,
|
|
148
|
+
descripcion: `Cada ${n} minuto${n > 1 ? 's' : ''}`,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// "every N hours"
|
|
154
|
+
const cadaNHoras = lower.match(/^every\s+(\d+)\s+hours?$/);
|
|
155
|
+
if (cadaNHoras) {
|
|
156
|
+
const n = parseInt(cadaNHoras[1], 10);
|
|
157
|
+
if (n > 0 && n <= 23) {
|
|
158
|
+
return {
|
|
159
|
+
cron: `0 */${n} * * *`,
|
|
160
|
+
descripcion: `Cada ${n} hora${n > 1 ? 's' : ''}`,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// "every morning at TIME" / "every evening at TIME" / "every day at TIME" / "daily at TIME"
|
|
166
|
+
const diarioA = lower.match(/^(?:every\s+(?:morning|evening|day)|daily)\s+at\s+(.+)$/);
|
|
167
|
+
if (diarioA) {
|
|
168
|
+
const tiempo = parsearHora(diarioA[1]);
|
|
169
|
+
if (tiempo) {
|
|
170
|
+
return {
|
|
171
|
+
cron: `${tiempo.minuto} ${tiempo.hora} * * *`,
|
|
172
|
+
descripcion: `Diariamente a las ${formatearHoraLegible(tiempo.hora, tiempo.minuto)}`,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// "at TIME every day"
|
|
178
|
+
const aTiempoCadaDia = lower.match(/^at\s+(.+?)\s+every\s+day$/);
|
|
179
|
+
if (aTiempoCadaDia) {
|
|
180
|
+
const tiempo = parsearHora(aTiempoCadaDia[1]);
|
|
181
|
+
if (tiempo) {
|
|
182
|
+
return {
|
|
183
|
+
cron: `${tiempo.minuto} ${tiempo.hora} * * *`,
|
|
184
|
+
descripcion: `Diariamente a las ${formatearHoraLegible(tiempo.hora, tiempo.minuto)}`,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// "weekly on DAYNAME" / "every DAYNAME" (sin hora)
|
|
190
|
+
const semanalEn = lower.match(/^(?:weekly\s+on|every)\s+(\w+)$/);
|
|
191
|
+
if (semanalEn) {
|
|
192
|
+
const numDia = parsearNombreDia(semanalEn[1]);
|
|
193
|
+
if (numDia !== null) {
|
|
194
|
+
const nombreDia = semanalEn[1].charAt(0).toUpperCase() + semanalEn[1].slice(1);
|
|
195
|
+
return {
|
|
196
|
+
cron: `0 9 * * ${numDia}`,
|
|
197
|
+
descripcion: `Cada ${nombreDia} a las 9:00 AM`,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// "every DAYNAME at TIME"
|
|
203
|
+
const cadaDiaA = lower.match(/^every\s+(\w+)\s+at\s+(.+)$/);
|
|
204
|
+
if (cadaDiaA) {
|
|
205
|
+
const numDia = parsearNombreDia(cadaDiaA[1]);
|
|
206
|
+
if (numDia !== null) {
|
|
207
|
+
const tiempo = parsearHora(cadaDiaA[2]);
|
|
208
|
+
if (tiempo) {
|
|
209
|
+
const nombreDia = cadaDiaA[1].charAt(0).toUpperCase() + cadaDiaA[1].slice(1);
|
|
210
|
+
return {
|
|
211
|
+
cron: `${tiempo.minuto} ${tiempo.hora} * * ${numDia}`,
|
|
212
|
+
descripcion: `Cada ${nombreDia} a las ${formatearHoraLegible(tiempo.hora, tiempo.minuto)}`,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// ---------------------------------------------------------------------------
|
|
222
|
+
// Verificación de ejecución pendiente
|
|
223
|
+
// ---------------------------------------------------------------------------
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Evalúa si una expresión cron está pendiente de ejecutarse en la fecha dada,
|
|
227
|
+
* evitando lanzamientos duplicados dentro del mismo minuto.
|
|
228
|
+
*
|
|
229
|
+
* @param {string} cronExpr - Expresión cron de 5 campos.
|
|
230
|
+
* @param {number} ahoraMs - Timestamp actual en milisegundos.
|
|
231
|
+
* @param {number} [ultimoLanzadoMs=0] - Timestamp de la última ejecución en ms.
|
|
232
|
+
* @returns {boolean}
|
|
233
|
+
*/
|
|
234
|
+
function isCronDue(cronExpr, ahoraMs, ultimoLanzadoMs = 0) {
|
|
235
|
+
const ahora = new Date(ahoraMs);
|
|
236
|
+
const partes = cronExpr.split(/\s+/);
|
|
237
|
+
if (partes.length !== 5) return false;
|
|
238
|
+
|
|
239
|
+
const [exprMin, exprHora, , , exprDow] = partes;
|
|
240
|
+
|
|
241
|
+
if (!coincideCampoCron(exprMin, ahora.getMinutes())) return false;
|
|
242
|
+
if (!coincideCampoCron(exprHora, ahora.getHours())) return false;
|
|
243
|
+
if (!coincideCampoCron(exprDow, ahora.getDay())) return false;
|
|
244
|
+
|
|
245
|
+
// Prevenir doble lanzamiento dentro del mismo minuto
|
|
246
|
+
if (ultimoLanzadoMs > 0) {
|
|
247
|
+
const ultimo = new Date(ultimoLanzadoMs);
|
|
248
|
+
if (
|
|
249
|
+
ultimo.getFullYear() === ahora.getFullYear() &&
|
|
250
|
+
ultimo.getMonth() === ahora.getMonth() &&
|
|
251
|
+
ultimo.getDate() === ahora.getDate() &&
|
|
252
|
+
ultimo.getHours() === ahora.getHours() &&
|
|
253
|
+
ultimo.getMinutes() === ahora.getMinutes()
|
|
254
|
+
) {
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Evalúa si un campo cron (ej: "(asterisco)/5", "1,3,5", "9-17", "*") coincide con
|
|
264
|
+
* el valor numérico dado.
|
|
265
|
+
*
|
|
266
|
+
* @param {string} expr - Campo cron.
|
|
267
|
+
* @param {number} valor - Valor actual (ej: hora, minuto, día).
|
|
268
|
+
* @returns {boolean}
|
|
269
|
+
*/
|
|
270
|
+
function coincideCampoCron(expr, valor) {
|
|
271
|
+
if (expr === '*') return true;
|
|
272
|
+
|
|
273
|
+
// Paso: */N
|
|
274
|
+
if (expr.startsWith('*/')) {
|
|
275
|
+
const paso = parseInt(expr.slice(2), 10);
|
|
276
|
+
return paso > 0 && valor % paso === 0;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Valores separados por coma
|
|
280
|
+
const segmentos = expr.split(',');
|
|
281
|
+
for (const seg of segmentos) {
|
|
282
|
+
// Rango: N-M
|
|
283
|
+
if (seg.includes('-')) {
|
|
284
|
+
const [inicio, fin] = seg.split('-').map(Number);
|
|
285
|
+
if (valor >= inicio && valor <= fin) return true;
|
|
286
|
+
} else {
|
|
287
|
+
if (parseInt(seg, 10) === valor) return true;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// ---------------------------------------------------------------------------
|
|
295
|
+
// Exports
|
|
296
|
+
// ---------------------------------------------------------------------------
|
|
297
|
+
|
|
298
|
+
module.exports = {
|
|
299
|
+
parseNaturalSchedule,
|
|
300
|
+
isCronDue,
|
|
301
|
+
// Exponer helpers para tests y uso avanzado
|
|
302
|
+
parsearNombreDia,
|
|
303
|
+
parsearHora,
|
|
304
|
+
coincideCampoCron,
|
|
305
|
+
};
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* scoring-instintos.js
|
|
5
|
+
*
|
|
6
|
+
* Sistema de decay exponencial + maturity transitions para instintos.
|
|
7
|
+
*
|
|
8
|
+
* Patrón adaptado de ACE (Agentic Context Engineering) en
|
|
9
|
+
* `temp/cass_memory_system-main/src/scoring.ts`. Diferencias:
|
|
10
|
+
* - Funciones puras zero-deps (Node stdlib only).
|
|
11
|
+
* - Backward compatible: instintos sin los campos nuevos siguen siendo válidos.
|
|
12
|
+
* - No persiste — el caller decide cuándo escribir el resultado.
|
|
13
|
+
*
|
|
14
|
+
* Modelo:
|
|
15
|
+
* - `confidence` original es estática (asignada al crear).
|
|
16
|
+
* - `effective_confidence` se calcula dinámicamente:
|
|
17
|
+
* confidence × decay_factor − harmful_penalty
|
|
18
|
+
* - `decay_factor` = 2^(-days_since_validated / half_life_days) (default 90d).
|
|
19
|
+
* - `harmful_penalty` = HARMFUL_PENALTY_WEIGHT × harmful_ratio.
|
|
20
|
+
* - `maturity` se deriva de effective_confidence + evidence_count + harmful_ratio.
|
|
21
|
+
* - `shouldAutoDeprecate` cuando harmful_ratio > HARMFUL_RATIO_THRESHOLD
|
|
22
|
+
* con al menos MIN_FEEDBACK_FOR_DEPRECATION eventos.
|
|
23
|
+
*
|
|
24
|
+
* Campos NUEVOS opcionales en instintos (todos con defaults seguros):
|
|
25
|
+
* - decay_half_life_days (default: 90)
|
|
26
|
+
* - helpful_count (default: 0)
|
|
27
|
+
* - harmful_count (default: 0)
|
|
28
|
+
* - last_validated_at (default: last_validated, o created_at)
|
|
29
|
+
*
|
|
30
|
+
* @module scripts/lib/scoring-instintos
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
// ── constantes ────────────────────────────────────────────────────────────────
|
|
34
|
+
|
|
35
|
+
const HALF_LIFE_DEFAULT_DAYS = 90;
|
|
36
|
+
const HARMFUL_RATIO_THRESHOLD = 0.3;
|
|
37
|
+
const MIN_FEEDBACK_FOR_DEPRECATION = 3;
|
|
38
|
+
const HARMFUL_PENALTY_WEIGHT = 0.5;
|
|
39
|
+
const PROVEN_CONFIDENCE_THRESHOLD = 0.7;
|
|
40
|
+
const ESTABLISHED_THRESHOLD = 0.5;
|
|
41
|
+
const PROVEN_EVIDENCE_THRESHOLD = 3;
|
|
42
|
+
|
|
43
|
+
// ── helpers ───────────────────────────────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Días enteros entre dos fechas YYYY-MM-DD (o Date).
|
|
47
|
+
* Tolerante a formato inválido: devuelve 0 si no parsea.
|
|
48
|
+
*/
|
|
49
|
+
function daysBetween(d1, d2) {
|
|
50
|
+
const t1 = d1 instanceof Date ? d1.getTime() : Date.parse(String(d1));
|
|
51
|
+
const t2 = d2 instanceof Date ? d2.getTime() : Date.parse(String(d2));
|
|
52
|
+
if (Number.isNaN(t1) || Number.isNaN(t2)) return 0;
|
|
53
|
+
const diffMs = Math.abs(t2 - t1);
|
|
54
|
+
return Math.floor(diffMs / (24 * 3600 * 1000));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function clamp(n, min, max) {
|
|
58
|
+
if (Number.isNaN(n)) return min;
|
|
59
|
+
return Math.max(min, Math.min(max, n));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function getValidatedDate(instinto) {
|
|
63
|
+
return instinto.last_validated_at
|
|
64
|
+
|| instinto.last_validated
|
|
65
|
+
|| instinto.created_at
|
|
66
|
+
|| null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ── funciones puras de scoring ────────────────────────────────────────────────
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Factor de decay exponencial.
|
|
73
|
+
*
|
|
74
|
+
* decay(0) = 1.0
|
|
75
|
+
* decay(half) = 0.5
|
|
76
|
+
* decay(2×half) = 0.25
|
|
77
|
+
*
|
|
78
|
+
* @param {number} daysSinceValidated
|
|
79
|
+
* @param {number} [halfLifeDays=90]
|
|
80
|
+
* @returns {number} factor en [0, 1]
|
|
81
|
+
*/
|
|
82
|
+
function decayFactor(daysSinceValidated, halfLifeDays = HALF_LIFE_DEFAULT_DAYS) {
|
|
83
|
+
if (daysSinceValidated <= 0) return 1.0;
|
|
84
|
+
if (halfLifeDays <= 0) return 1.0;
|
|
85
|
+
return Math.pow(2, -daysSinceValidated / halfLifeDays);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Ratio de feedback dañino sobre el total de feedback recibido.
|
|
90
|
+
* Devuelve 0 si no hay feedback.
|
|
91
|
+
*/
|
|
92
|
+
function harmfulRatio(instinto) {
|
|
93
|
+
const helpful = instinto.helpful_count || 0;
|
|
94
|
+
const harmful = instinto.harmful_count || 0;
|
|
95
|
+
const total = helpful + harmful;
|
|
96
|
+
if (total === 0) return 0;
|
|
97
|
+
return harmful / total;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Confianza efectiva considerando decay temporal y feedback negativo.
|
|
102
|
+
*
|
|
103
|
+
* @param {object} instinto
|
|
104
|
+
* @param {string|Date} [currentDate=now] — fecha de referencia
|
|
105
|
+
* @returns {number} en [0, 1]
|
|
106
|
+
*/
|
|
107
|
+
function effectiveConfidence(instinto, currentDate) {
|
|
108
|
+
const now = currentDate || new Date();
|
|
109
|
+
const validatedAt = getValidatedDate(instinto);
|
|
110
|
+
const halfLife = instinto.decay_half_life_days || HALF_LIFE_DEFAULT_DAYS;
|
|
111
|
+
|
|
112
|
+
const days = validatedAt ? daysBetween(validatedAt, now) : 0;
|
|
113
|
+
const decay = decayFactor(days, halfLife);
|
|
114
|
+
const baseConfidence = clamp(instinto.confidence || 0, 0, 1);
|
|
115
|
+
const penalty = HARMFUL_PENALTY_WEIGHT * harmfulRatio(instinto);
|
|
116
|
+
|
|
117
|
+
return clamp(baseConfidence * decay - penalty, 0, 1);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Si el feedback negativo supera el umbral, recomendar auto-deprecación.
|
|
122
|
+
* Requiere al menos MIN_FEEDBACK_FOR_DEPRECATION eventos para evitar
|
|
123
|
+
* sobre-reaccionar a un solo voto.
|
|
124
|
+
*/
|
|
125
|
+
function shouldAutoDeprecate(instinto) {
|
|
126
|
+
const helpful = instinto.helpful_count || 0;
|
|
127
|
+
const harmful = instinto.harmful_count || 0;
|
|
128
|
+
const total = helpful + harmful;
|
|
129
|
+
if (total < MIN_FEEDBACK_FOR_DEPRECATION) return false;
|
|
130
|
+
return harmfulRatio(instinto) > HARMFUL_RATIO_THRESHOLD;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Estado de maduración derivado de effective_confidence + evidencia + feedback.
|
|
135
|
+
*
|
|
136
|
+
* Estados:
|
|
137
|
+
* - candidate : effective < 0.5 (recién aprendido o decaído)
|
|
138
|
+
* - established : 0.5 ≤ effective < 0.7
|
|
139
|
+
* - proven : effective ≥ 0.7 AND evidence_count ≥ 3
|
|
140
|
+
* - deprecated : shouldAutoDeprecate, status === 'archived', o
|
|
141
|
+
* status === 'degraded' con contradictions ≥ 3
|
|
142
|
+
*/
|
|
143
|
+
function maturityState(instinto, currentDate) {
|
|
144
|
+
if (instinto.status === 'archived') return 'deprecated';
|
|
145
|
+
if (shouldAutoDeprecate(instinto)) return 'deprecated';
|
|
146
|
+
if (instinto.status === 'degraded' && (instinto.contradictions || 0) >= 3) {
|
|
147
|
+
return 'deprecated';
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const eff = effectiveConfidence(instinto, currentDate);
|
|
151
|
+
const evidence = instinto.evidence_count || 0;
|
|
152
|
+
|
|
153
|
+
if (eff >= PROVEN_CONFIDENCE_THRESHOLD && evidence >= PROVEN_EVIDENCE_THRESHOLD) {
|
|
154
|
+
return 'proven';
|
|
155
|
+
}
|
|
156
|
+
if (eff >= ESTABLISHED_THRESHOLD) return 'established';
|
|
157
|
+
return 'candidate';
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Aplicar feedback al instinto (pure: devuelve copia).
|
|
162
|
+
* type: 'helpful' | 'harmful'
|
|
163
|
+
*
|
|
164
|
+
* Refresca last_validated_at — un feedback es una validación implícita.
|
|
165
|
+
*/
|
|
166
|
+
function applyFeedback(instinto, type, currentDate) {
|
|
167
|
+
if (type !== 'helpful' && type !== 'harmful') {
|
|
168
|
+
throw new Error(`Tipo de feedback inválido: ${type}`);
|
|
169
|
+
}
|
|
170
|
+
const now = (currentDate instanceof Date)
|
|
171
|
+
? currentDate.toISOString().slice(0, 10)
|
|
172
|
+
: (currentDate || new Date().toISOString().slice(0, 10));
|
|
173
|
+
|
|
174
|
+
const next = { ...instinto };
|
|
175
|
+
if (type === 'helpful') next.helpful_count = (next.helpful_count || 0) + 1;
|
|
176
|
+
else next.harmful_count = (next.harmful_count || 0) + 1;
|
|
177
|
+
next.last_validated_at = now;
|
|
178
|
+
return next;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Recomputa status legacy + maturity como vista unificada.
|
|
183
|
+
* Pure: devuelve un objeto enriquecido sin mutar el original.
|
|
184
|
+
*
|
|
185
|
+
* Si shouldAutoDeprecate, propone status='degraded' (no archive — el archive
|
|
186
|
+
* es decisión humana). El caller decide si persistir el cambio.
|
|
187
|
+
*/
|
|
188
|
+
function recomputeStatus(instinto, currentDate) {
|
|
189
|
+
const maturity = maturityState(instinto, currentDate);
|
|
190
|
+
const effective = effectiveConfidence(instinto, currentDate);
|
|
191
|
+
const proposed = { ...instinto, maturity, effective_confidence: Math.round(effective * 1000) / 1000 };
|
|
192
|
+
|
|
193
|
+
if (shouldAutoDeprecate(instinto) && instinto.status !== 'archived') {
|
|
194
|
+
proposed.status_proposed = 'degraded';
|
|
195
|
+
proposed.deprecation_reason = `harmful_ratio=${harmfulRatio(instinto).toFixed(2)} con ${(instinto.helpful_count||0)+(instinto.harmful_count||0)} eventos`;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return proposed;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Adjuntar source tracing a un instinto (pure: devuelve copia).
|
|
203
|
+
* Mantiene unicidad y orden de inserción.
|
|
204
|
+
*/
|
|
205
|
+
function addSource(instinto, { sessionId, agentName } = {}) {
|
|
206
|
+
const next = { ...instinto };
|
|
207
|
+
if (sessionId) {
|
|
208
|
+
const s = new Set(next.source_sessions || []);
|
|
209
|
+
s.add(sessionId);
|
|
210
|
+
next.source_sessions = [...s];
|
|
211
|
+
}
|
|
212
|
+
if (agentName) {
|
|
213
|
+
const a = new Set(next.source_agents || []);
|
|
214
|
+
a.add(agentName);
|
|
215
|
+
next.source_agents = [...a];
|
|
216
|
+
}
|
|
217
|
+
return next;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// ── exports ───────────────────────────────────────────────────────────────────
|
|
221
|
+
|
|
222
|
+
module.exports = {
|
|
223
|
+
daysBetween,
|
|
224
|
+
decayFactor,
|
|
225
|
+
harmfulRatio,
|
|
226
|
+
effectiveConfidence,
|
|
227
|
+
shouldAutoDeprecate,
|
|
228
|
+
maturityState,
|
|
229
|
+
applyFeedback,
|
|
230
|
+
recomputeStatus,
|
|
231
|
+
addSource,
|
|
232
|
+
// constantes exportadas para tests y configuración
|
|
233
|
+
HALF_LIFE_DEFAULT_DAYS,
|
|
234
|
+
HARMFUL_RATIO_THRESHOLD,
|
|
235
|
+
MIN_FEEDBACK_FOR_DEPRECATION,
|
|
236
|
+
HARMFUL_PENALTY_WEIGHT,
|
|
237
|
+
PROVEN_CONFIDENCE_THRESHOLD,
|
|
238
|
+
ESTABLISHED_THRESHOLD,
|
|
239
|
+
PROVEN_EVIDENCE_THRESHOLD,
|
|
240
|
+
};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Módulo de seguridad SWL
|
|
5
|
+
* Prevención de path traversal, prompt injection y comandos peligrosos.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
// Patrones de path traversal
|
|
11
|
+
const PATRONES_TRAVERSAL = [
|
|
12
|
+
/\.\.\//g,
|
|
13
|
+
/\.\.\\/g,
|
|
14
|
+
/~\//g,
|
|
15
|
+
/%2e%2e/gi,
|
|
16
|
+
/%252e%252e/gi,
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
// Comandos peligrosos que requieren confirmación
|
|
20
|
+
const COMANDOS_PELIGROSOS = [
|
|
21
|
+
/rm\s+(-rf?|--recursive)/i,
|
|
22
|
+
/rmdir/i,
|
|
23
|
+
/del\s+\/[sfq]/i,
|
|
24
|
+
/format\s+[a-z]:/i,
|
|
25
|
+
/drop\s+(table|database|schema)/i,
|
|
26
|
+
/truncate\s+table/i,
|
|
27
|
+
/delete\s+from\s+\w+\s*(;|\s*$)/i,
|
|
28
|
+
/git\s+push\s+.*--force/i,
|
|
29
|
+
/git\s+reset\s+--hard/i,
|
|
30
|
+
/chmod\s+777/i,
|
|
31
|
+
/curl.*\|\s*(bash|sh|zsh)/i,
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
// Patrones de prompt injection
|
|
35
|
+
const PATRONES_INJECTION = [
|
|
36
|
+
/ignore\s+(all\s+)?previous\s+instructions/i,
|
|
37
|
+
/you\s+are\s+now\s+/i,
|
|
38
|
+
/forget\s+(all\s+)?your\s+(previous\s+)?instructions/i,
|
|
39
|
+
/system\s*:\s*you\s+are/i,
|
|
40
|
+
/\[INST\]/i,
|
|
41
|
+
/<\|im_start\|>/i,
|
|
42
|
+
/\{\{.*system.*\}\}/i,
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
// Lista de archivos/patrones sensibles
|
|
46
|
+
// NOTA: Los patrones deben ser específicos para evitar falsos positivos
|
|
47
|
+
// con nombres de skills/hooks del sistema (ej. "design-tokens", "iam-secretos")
|
|
48
|
+
const ARCHIVOS_SENSIBLES = [
|
|
49
|
+
/\.env$/,
|
|
50
|
+
/\.env\.\w+$/,
|
|
51
|
+
/credentials\.json$/,
|
|
52
|
+
/\.pem$/,
|
|
53
|
+
/\.key$/,
|
|
54
|
+
/id_rsa/,
|
|
55
|
+
/\.ssh\//,
|
|
56
|
+
/^\.?password$/i,
|
|
57
|
+
/\.secret$/i,
|
|
58
|
+
/secret[_-]?key/i,
|
|
59
|
+
/\.token$/i,
|
|
60
|
+
/access[_-]?token/i,
|
|
61
|
+
/auth[_-]?token/i,
|
|
62
|
+
/\.npmrc$/,
|
|
63
|
+
/\.netrc$/,
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Valida que una ruta no contenga path traversal
|
|
68
|
+
*/
|
|
69
|
+
function validarRuta(rutaBase, rutaDestino) {
|
|
70
|
+
const resuelta = path.resolve(rutaBase, rutaDestino);
|
|
71
|
+
const baseNormalizada = path.resolve(rutaBase);
|
|
72
|
+
|
|
73
|
+
if (!resuelta.startsWith(baseNormalizada)) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
`Ruta bloqueada por seguridad: "${rutaDestino}" intenta salir de "${rutaBase}"`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for (const patron of PATRONES_TRAVERSAL) {
|
|
80
|
+
if (patron.test(rutaDestino)) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
`Path traversal detectado en: "${rutaDestino}"`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return resuelta;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Verifica si un comando es potencialmente peligroso
|
|
92
|
+
*/
|
|
93
|
+
function esComandoPeligroso(comando) {
|
|
94
|
+
for (const patron of COMANDOS_PELIGROSOS) {
|
|
95
|
+
if (patron.test(comando)) {
|
|
96
|
+
return {
|
|
97
|
+
peligroso: true,
|
|
98
|
+
razon: `Comando coincide con patrón peligroso: ${patron}`,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return { peligroso: false };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Detecta intentos de prompt injection en contenido
|
|
107
|
+
*/
|
|
108
|
+
function detectarInjection(contenido) {
|
|
109
|
+
const hallazgos = [];
|
|
110
|
+
for (const patron of PATRONES_INJECTION) {
|
|
111
|
+
if (patron.test(contenido)) {
|
|
112
|
+
hallazgos.push({
|
|
113
|
+
patron: patron.toString(),
|
|
114
|
+
tipo: 'prompt_injection',
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return hallazgos;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Verifica si un archivo es sensible (no debería commitearse)
|
|
123
|
+
*/
|
|
124
|
+
function esArchivoSensible(nombreArchivo) {
|
|
125
|
+
return ARCHIVOS_SENSIBLES.some(patron => patron.test(nombreArchivo));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Sanitiza texto para prevenir inyección en plantillas
|
|
130
|
+
*/
|
|
131
|
+
function sanitizar(texto) {
|
|
132
|
+
if (typeof texto !== 'string') return '';
|
|
133
|
+
return texto
|
|
134
|
+
.replace(/</g, '<')
|
|
135
|
+
.replace(/>/g, '>')
|
|
136
|
+
.replace(/\$/g, '$')
|
|
137
|
+
.replace(/`/g, '`');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Filtra secretos de un texto de log
|
|
142
|
+
*/
|
|
143
|
+
function filtrarSecretos(texto) {
|
|
144
|
+
if (typeof texto !== 'string') return '';
|
|
145
|
+
// Reemplazar patrones comunes de tokens/keys
|
|
146
|
+
return texto
|
|
147
|
+
.replace(/(api[_-]?key|token|secret|password|credential)['":\s]*[=:]\s*['"]?[\w\-./+=]{8,}['"]?/gi, '$1=***FILTRADO***')
|
|
148
|
+
.replace(/Bearer\s+[\w\-./+=]+/g, 'Bearer ***FILTRADO***')
|
|
149
|
+
.replace(/ghp_[\w]+/g, 'ghp_***FILTRADO***')
|
|
150
|
+
.replace(/sk-[\w]+/g, 'sk-***FILTRADO***');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
module.exports = {
|
|
154
|
+
validarRuta,
|
|
155
|
+
esComandoPeligroso,
|
|
156
|
+
detectarInjection,
|
|
157
|
+
esArchivoSensible,
|
|
158
|
+
sanitizar,
|
|
159
|
+
filtrarSecretos,
|
|
160
|
+
};
|