@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,239 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* performance-marks.js — Sistema de marks/measures para hooks de swl-ses.
|
|
5
|
+
*
|
|
6
|
+
* Patrón adoptado directamente del compilador TypeScript (microsoft/TypeScript,
|
|
7
|
+
* src/compiler/performance.ts). Abstrae la medición de duración de operaciones
|
|
8
|
+
* con marks nombrados, acumulando duraciones entre llamadas y permitiendo
|
|
9
|
+
* reportes al final de la sesión.
|
|
10
|
+
*
|
|
11
|
+
* Ventajas sobre Date.now() directo:
|
|
12
|
+
* - Acumulación automática: medir la misma operación N veces y obtener total
|
|
13
|
+
* - Conteo de invocaciones por mark
|
|
14
|
+
* - API simétrica: mark(start) → operación → mark(end) → measure(name, start, end)
|
|
15
|
+
* - Zero-overhead cuando está deshabilitado
|
|
16
|
+
* - Compatible con Performance API de Node.js si está disponible
|
|
17
|
+
*
|
|
18
|
+
* Equivalente JS del patrón:
|
|
19
|
+
* mark("beforeParse");
|
|
20
|
+
* // ... operación costosa
|
|
21
|
+
* mark("afterParse");
|
|
22
|
+
* measure("Parse", "beforeParse", "afterParse");
|
|
23
|
+
* console.log(getDuration("Parse")); // ms acumulados
|
|
24
|
+
* console.log(getCount("beforeParse")); // veces que se ejecutó
|
|
25
|
+
*
|
|
26
|
+
* Zero-dependencies: solo usa process.hrtime.bigint() o Date.now() de Node.js.
|
|
27
|
+
*
|
|
28
|
+
* @module hooks/lib/performance-marks
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// Internos
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
/** @type {Map<string, bigint>} Timestamps de marks en nanosegundos */
|
|
36
|
+
const marks = new Map();
|
|
37
|
+
|
|
38
|
+
/** @type {Map<string, number>} Conteo de invocaciones por mark */
|
|
39
|
+
const counts = new Map();
|
|
40
|
+
|
|
41
|
+
/** @type {Map<string, number>} Duraciones acumuladas en milisegundos */
|
|
42
|
+
const durations = new Map();
|
|
43
|
+
|
|
44
|
+
/** Soporte nativo de hrtime.bigint para mayor precisión */
|
|
45
|
+
const hasHrtime = typeof process !== 'undefined' && typeof process.hrtime === 'function';
|
|
46
|
+
|
|
47
|
+
/** Estado: habilitado por defecto para hooks */
|
|
48
|
+
let enabled = true;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Retorna el timestamp actual en nanosegundos.
|
|
52
|
+
* Usa process.hrtime.bigint() si está disponible, fallback a Date.now().
|
|
53
|
+
* @returns {bigint}
|
|
54
|
+
*/
|
|
55
|
+
function timestamp() {
|
|
56
|
+
if (hasHrtime) {
|
|
57
|
+
return process.hrtime.bigint();
|
|
58
|
+
}
|
|
59
|
+
return BigInt(Date.now()) * 1_000_000n;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Convierte nanosegundos a milisegundos como número flotante.
|
|
64
|
+
* @param {bigint} ns
|
|
65
|
+
* @returns {number}
|
|
66
|
+
*/
|
|
67
|
+
function nsToMs(ns) {
|
|
68
|
+
return Number(ns) / 1_000_000;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
// API pública — compatible con performance.ts del compilador TypeScript
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Registra una marca de performance.
|
|
77
|
+
* Si se llama múltiples veces con el mismo nombre, acumula el conteo
|
|
78
|
+
* y sobreescribe el timestamp (para medir la última ejecución).
|
|
79
|
+
*
|
|
80
|
+
* @param {string} markName — Nombre del mark (ej: "beforeCheck", "afterParse")
|
|
81
|
+
*/
|
|
82
|
+
function mark(markName) {
|
|
83
|
+
if (!enabled) return;
|
|
84
|
+
const count = counts.get(markName) ?? 0;
|
|
85
|
+
counts.set(markName, count + 1);
|
|
86
|
+
marks.set(markName, timestamp());
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Calcula y acumula la duración entre dos marks.
|
|
91
|
+
* Si startMarkName es omitido, usa el origen de tiempo.
|
|
92
|
+
* Si endMarkName es omitido, usa el momento actual.
|
|
93
|
+
*
|
|
94
|
+
* @param {string} measureName — Nombre de la medida (ej: "Parse", "TypeCheck")
|
|
95
|
+
* @param {string} [startMarkName] — Mark de inicio
|
|
96
|
+
* @param {string} [endMarkName] — Mark de fin
|
|
97
|
+
*/
|
|
98
|
+
function measure(measureName, startMarkName, endMarkName) {
|
|
99
|
+
if (!enabled) return;
|
|
100
|
+
const end = endMarkName ? marks.get(endMarkName) : timestamp();
|
|
101
|
+
const start = startMarkName ? marks.get(startMarkName) : 0n;
|
|
102
|
+
if (end === undefined || start === undefined) return;
|
|
103
|
+
const prev = durations.get(measureName) || 0;
|
|
104
|
+
durations.set(measureName, prev + nsToMs(end - start));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Retorna la duración acumulada en milisegundos de una medida.
|
|
109
|
+
*
|
|
110
|
+
* @param {string} measureName
|
|
111
|
+
* @returns {number}
|
|
112
|
+
*/
|
|
113
|
+
function getDuration(measureName) {
|
|
114
|
+
return durations.get(measureName) || 0;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Retorna el número de veces que se registró un mark.
|
|
119
|
+
*
|
|
120
|
+
* @param {string} markName
|
|
121
|
+
* @returns {number}
|
|
122
|
+
*/
|
|
123
|
+
function getCount(markName) {
|
|
124
|
+
return counts.get(markName) || 0;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Itera sobre todas las medidas acumuladas.
|
|
129
|
+
*
|
|
130
|
+
* @param {function(string, number): void} cb — (measureName, durationMs)
|
|
131
|
+
*/
|
|
132
|
+
function forEachMeasure(cb) {
|
|
133
|
+
durations.forEach((dur, name) => cb(name, dur));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Habilita el sistema de marks. Activo por defecto.
|
|
138
|
+
*/
|
|
139
|
+
function enable() {
|
|
140
|
+
enabled = true;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Deshabilita el sistema. Las llamadas a mark/measure son no-op.
|
|
145
|
+
*/
|
|
146
|
+
function disable() {
|
|
147
|
+
enabled = false;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Limpia todos los marks, conteos y duraciones acumulados.
|
|
152
|
+
* Llamar al inicio de cada sesión si se quieren métricas independientes.
|
|
153
|
+
*/
|
|
154
|
+
function clearAll() {
|
|
155
|
+
marks.clear();
|
|
156
|
+
counts.clear();
|
|
157
|
+
durations.clear();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Limpia las marcas y conteos, pero preserva las duraciones acumuladas.
|
|
162
|
+
* Útil para reutilizar medidas entre fases de la misma sesión.
|
|
163
|
+
*/
|
|
164
|
+
function clearMarks() {
|
|
165
|
+
marks.clear();
|
|
166
|
+
counts.clear();
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Genera un reporte de texto con todas las medidas acumuladas.
|
|
171
|
+
* Formateado para incluir en logs de sesión o resumen de métricas.
|
|
172
|
+
*
|
|
173
|
+
* @param {object} [opts]
|
|
174
|
+
* @param {number} [opts.umbralMs=0] — Solo incluir medidas con duración >= umbralMs
|
|
175
|
+
* @param {boolean} [opts.ordenarDesc=true] — Ordenar de mayor a menor duración
|
|
176
|
+
* @returns {string}
|
|
177
|
+
*/
|
|
178
|
+
function formatReporte(opts) {
|
|
179
|
+
const { umbralMs = 0, ordenarDesc = true } = opts || {};
|
|
180
|
+
|
|
181
|
+
const entradas = [];
|
|
182
|
+
durations.forEach((dur, name) => {
|
|
183
|
+
if (dur >= umbralMs) {
|
|
184
|
+
entradas.push({ name, durMs: dur });
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
if (entradas.length === 0) return '';
|
|
189
|
+
|
|
190
|
+
if (ordenarDesc) {
|
|
191
|
+
entradas.sort((a, b) => b.durMs - a.durMs);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const lineas = entradas.map(({ name, durMs }) => {
|
|
195
|
+
const invocaciones = getCount(name + 'Start') || getCount(name) || 1;
|
|
196
|
+
return ` ${name.padEnd(30)} ${durMs.toFixed(2).padStart(8)} ms (${invocaciones}×)`;
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
return [
|
|
200
|
+
'Performance marks:',
|
|
201
|
+
...lineas,
|
|
202
|
+
].join('\n');
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Helper: ejecuta una función síncrona midiéndola con el patrón mark/measure.
|
|
207
|
+
*
|
|
208
|
+
* @template T
|
|
209
|
+
* @param {string} measureName — Nombre de la medida
|
|
210
|
+
* @param {function(): T} fn — Función a ejecutar
|
|
211
|
+
* @returns {T}
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* const resultado = timed("ParseArchivo", () => parsear(contenido));
|
|
215
|
+
* console.log(getDuration("ParseArchivo")); // ms que tardó
|
|
216
|
+
*/
|
|
217
|
+
function timed(measureName, fn) {
|
|
218
|
+
const startMark = measureName + '_start';
|
|
219
|
+
const endMark = measureName + '_end';
|
|
220
|
+
mark(startMark);
|
|
221
|
+
const resultado = fn();
|
|
222
|
+
mark(endMark);
|
|
223
|
+
measure(measureName, startMark, endMark);
|
|
224
|
+
return resultado;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
module.exports = {
|
|
228
|
+
mark,
|
|
229
|
+
measure,
|
|
230
|
+
getDuration,
|
|
231
|
+
getCount,
|
|
232
|
+
forEachMeasure,
|
|
233
|
+
enable,
|
|
234
|
+
disable,
|
|
235
|
+
clearAll,
|
|
236
|
+
clearMarks,
|
|
237
|
+
formatReporte,
|
|
238
|
+
timed,
|
|
239
|
+
};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Privacy Filter — Filtra contenido marcado como privado antes de almacenar.
|
|
5
|
+
*
|
|
6
|
+
* Soporte para tags <private>...</private>, <secreto>...</secreto> y
|
|
7
|
+
* <privado>...</privado> que excluyen contenido sensible del storage de
|
|
8
|
+
* aprendizajes y sesiones.
|
|
9
|
+
*
|
|
10
|
+
* Inspirado en claude-mem's privacy tag system.
|
|
11
|
+
*
|
|
12
|
+
* Seguridad:
|
|
13
|
+
* - Limite de tags por texto (MAX_TAGS = 100) para prevenir ReDoS
|
|
14
|
+
* - Stripping iterativo, no basado en regex greedy
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const MAX_TAGS = 100;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Remueve bloques <private>...</private>, <secreto>...</secreto> y
|
|
21
|
+
* <privado>...</privado> del texto.
|
|
22
|
+
*
|
|
23
|
+
* @param {string} texto
|
|
24
|
+
* @returns {{ textoFiltrado: string, tagsRemovidos: number }}
|
|
25
|
+
*/
|
|
26
|
+
function filtrarPrivacidad(texto) {
|
|
27
|
+
if (!texto || typeof texto !== 'string') return { textoFiltrado: texto, tagsRemovidos: 0 };
|
|
28
|
+
|
|
29
|
+
let resultado = texto;
|
|
30
|
+
let tagsRemovidos = 0;
|
|
31
|
+
|
|
32
|
+
// Tags soportados
|
|
33
|
+
const tags = ['private', 'secreto', 'privado'];
|
|
34
|
+
|
|
35
|
+
for (const tag of tags) {
|
|
36
|
+
let intentos = 0;
|
|
37
|
+
while (intentos < MAX_TAGS) {
|
|
38
|
+
const openTag = `<${tag}>`;
|
|
39
|
+
const closeTag = `</${tag}>`;
|
|
40
|
+
const start = resultado.indexOf(openTag);
|
|
41
|
+
if (start === -1) break;
|
|
42
|
+
|
|
43
|
+
const end = resultado.indexOf(closeTag, start);
|
|
44
|
+
if (end === -1) break;
|
|
45
|
+
|
|
46
|
+
resultado = resultado.slice(0, start) + resultado.slice(end + closeTag.length);
|
|
47
|
+
tagsRemovidos++;
|
|
48
|
+
intentos++;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return { textoFiltrado: resultado.trim(), tagsRemovidos };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Verifica si un texto contiene tags de privacidad sin procesar.
|
|
57
|
+
*
|
|
58
|
+
* @param {string} texto
|
|
59
|
+
* @returns {boolean}
|
|
60
|
+
*/
|
|
61
|
+
function contieneTagsPrivados(texto) {
|
|
62
|
+
if (!texto) return false;
|
|
63
|
+
return /<(private|secreto|privado)>/i.test(texto);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Patrones de PII comunes en Mexico y formatos internacionales.
|
|
68
|
+
* Solo cubre PII estructurada con formato verificable; texto libre con
|
|
69
|
+
* direcciones o nombres no se detecta (requiere NER con dependencias
|
|
70
|
+
* pesadas y este hook es zero-deps).
|
|
71
|
+
*
|
|
72
|
+
* Cobertura:
|
|
73
|
+
* - Tarjeta de credito/debito: 13-19 digitos con espacios o guiones opcionales
|
|
74
|
+
* (Visa, MasterCard, Amex, etc.). Validacion formal seria Luhn, pero
|
|
75
|
+
* reportamos por formato porque 99% de falsos positivos en texto libre
|
|
76
|
+
* no tienen 13+ digitos contiguos.
|
|
77
|
+
* - CURP: 18 caracteres, formato oficial mexicano (SAT/RENAPO).
|
|
78
|
+
* - RFC personal: 13 caracteres (persona fisica). RFC moral tiene 12 pero
|
|
79
|
+
* no es PII (es identificador de empresa).
|
|
80
|
+
* - IFE/INE: clave de elector de 18 caracteres alfanumericos.
|
|
81
|
+
* - Numero de Seguro Social (NSS IMSS): 11 digitos.
|
|
82
|
+
* - Telefono MX: 10 digitos con prefijos comunes.
|
|
83
|
+
* - Email: formato RFC5322 simplificado.
|
|
84
|
+
* - IPv4 fuera de rangos privados (posible doxxing).
|
|
85
|
+
*/
|
|
86
|
+
const PATTERNS_PII = [
|
|
87
|
+
{ regex: /\b(?:\d[ -]?){13,19}\b/, tipo: 'tarjeta_credito' },
|
|
88
|
+
{ regex: /\b[A-Z]{4}\d{6}[HMX][A-Z]{5}[A-Z0-9]{2}\b/, tipo: 'curp' },
|
|
89
|
+
{ regex: /\b[A-ZÑ&]{4}\d{6}[A-Z0-9]{3}\b/, tipo: 'rfc_persona_fisica' },
|
|
90
|
+
{ regex: /\b[A-Z]{6}\d{8}[HM]\d{3}\b/, tipo: 'ife_ine' },
|
|
91
|
+
// NSS: 11 digitos aislados, con palabra clave "NSS" cerca para bajar falsos positivos
|
|
92
|
+
{ regex: /\bNSS[:\s]+\d{11}\b/i, tipo: 'nss_imss' },
|
|
93
|
+
// Telefono MX: requiere separador explicito o prefijo +52 para evitar matchear timestamps/hashes
|
|
94
|
+
{ regex: /\+52[\s-]\d{2,3}[\s-]\d{3,4}[\s-]\d{3,4}\b/, tipo: 'telefono_mx' },
|
|
95
|
+
{ regex: /\(\d{2,3}\)[\s-]?\d{3,4}[\s-]?\d{3,4}\b/, tipo: 'telefono_formato_area' },
|
|
96
|
+
{ regex: /\b\d{2,3}[\s-]\d{3,4}[\s-]\d{3,4}\b/, tipo: 'telefono_con_separadores' },
|
|
97
|
+
{ regex: /\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\b/, tipo: 'email' },
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Escanea un texto en busca de PII estructurada (tarjeta, CURP, RFC, NSS,
|
|
102
|
+
* IFE/INE, telefono, email). Devuelve la lista de hallazgos con tipo y
|
|
103
|
+
* un fragmento parcialmente ofuscado para el reporte.
|
|
104
|
+
*
|
|
105
|
+
* No filtra el texto ni lanza excepciones — solo reporta. La decision de
|
|
106
|
+
* bloquear, redactar o advertir es del caller (tipicamente el hook que
|
|
107
|
+
* escribe a memoria).
|
|
108
|
+
*
|
|
109
|
+
* @param {string} texto
|
|
110
|
+
* @returns {Array<{ tipo: string, muestra: string }>}
|
|
111
|
+
*/
|
|
112
|
+
function detectarPII(texto) {
|
|
113
|
+
if (!texto || typeof texto !== 'string') return [];
|
|
114
|
+
const hallazgos = [];
|
|
115
|
+
for (const { regex, tipo } of PATTERNS_PII) {
|
|
116
|
+
const matches = texto.match(new RegExp(regex.source, regex.flags + 'g'));
|
|
117
|
+
if (!matches) continue;
|
|
118
|
+
for (const m of matches.slice(0, 3)) { // max 3 muestras por tipo
|
|
119
|
+
const muestra = m.length > 8
|
|
120
|
+
? m.slice(0, 2) + '***' + m.slice(-2)
|
|
121
|
+
: '***';
|
|
122
|
+
hallazgos.push({ tipo, muestra });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return hallazgos;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
module.exports = { filtrarPrivacidad, contieneTagsPrivados, detectarPII, MAX_TAGS, PATTERNS_PII };
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Prompt Injection Scanner — Detección de inyecciones de prompt y amenazas.
|
|
5
|
+
*
|
|
6
|
+
* Escanea contenido buscando patrones de amenaza conocidos:
|
|
7
|
+
* - Prompt injection (ignore previous instructions, new instructions)
|
|
8
|
+
* - Role hijack (you are now, act as, pretend to be)
|
|
9
|
+
* - Deception (do not tell the user, hide this)
|
|
10
|
+
* - Exfiltración (curl/wget/fetch con secretos)
|
|
11
|
+
* - SSH backdoor (authorized_keys)
|
|
12
|
+
* - Caracteres Unicode invisibles (zero-width, RTL marks)
|
|
13
|
+
*
|
|
14
|
+
* Patrón adoptado de Hermes Agent (memory_tool.py → _MEMORY_THREAT_PATTERNS
|
|
15
|
+
* y prompt_builder.py → _CONTEXT_THREAT_PATTERNS).
|
|
16
|
+
*
|
|
17
|
+
* @module hooks/lib/prompt-injection-scanner
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Patrones de amenaza
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Taxonomía de categorías de amenaza.
|
|
26
|
+
*
|
|
27
|
+
* Clasificación formal inspirada en Google Model Armor y OWASP LLM Top 10.
|
|
28
|
+
* Cada patrón pertenece a una categoría para reportes y métricas agregadas.
|
|
29
|
+
*
|
|
30
|
+
* Categorías:
|
|
31
|
+
* PI — Prompt Injection: manipulación de instrucciones del sistema
|
|
32
|
+
* RAI — Responsible AI: contenido dañino, engaño, manipulación
|
|
33
|
+
* SDP — Sensitive Data Protection: exfiltración de datos, PII, secretos
|
|
34
|
+
* MAL — Malicious Actions: backdoors, destrucción, código malicioso
|
|
35
|
+
*/
|
|
36
|
+
const THREAT_CATEGORIES = {
|
|
37
|
+
PI: { name: 'Prompt Injection', description: 'Manipulación de instrucciones del sistema o jailbreak' },
|
|
38
|
+
RAI: { name: 'Responsible AI', description: 'Engaño, manipulación de comportamiento, ocultamiento' },
|
|
39
|
+
SDP: { name: 'Sensitive Data Protection', description: 'Exfiltración de secretos, PII, credenciales' },
|
|
40
|
+
MAL: { name: 'Malicious Actions', description: 'Backdoors, destrucción de datos, código malicioso' },
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const THREAT_PATTERNS = [
|
|
44
|
+
// --- PI: Prompt Injection ---
|
|
45
|
+
{ regex: /ignore\s+(?:\w+\s+)*(?:previous|all|above|prior)\s+instructions/i, type: 'prompt_injection', category: 'PI', severity: 'critical' },
|
|
46
|
+
{ regex: /disregard\s+(all|any|your)\s+(previous|prior)/i, type: 'prompt_injection', category: 'PI', severity: 'critical' },
|
|
47
|
+
{ regex: /forget\s+(everything|all|your)\s+(instructions|rules|guidelines)/i, type: 'prompt_injection', category: 'PI', severity: 'critical' },
|
|
48
|
+
{ regex: /override\s+(your|all|the)\s+(instructions|rules|guidelines)/i, type: 'prompt_injection', category: 'PI', severity: 'critical' },
|
|
49
|
+
{ regex: /new\s+instructions?\s*:/i, type: 'prompt_injection', category: 'PI', severity: 'high' },
|
|
50
|
+
{ regex: /system\s*:\s*you\s+are/i, type: 'prompt_injection', category: 'PI', severity: 'high' },
|
|
51
|
+
|
|
52
|
+
// --- PI: Role hijack ---
|
|
53
|
+
{ regex: /you\s+are\s+now\s+/i, type: 'role_hijack', category: 'PI', severity: 'critical' },
|
|
54
|
+
{ regex: /act\s+as\s+(?:if\s+you\s+are|a|an)\s+/i, type: 'role_hijack', category: 'PI', severity: 'high' },
|
|
55
|
+
{ regex: /pretend\s+(?:to\s+be|you\s+are|you're)/i, type: 'role_hijack', category: 'PI', severity: 'high' },
|
|
56
|
+
{ regex: /from\s+now\s+on\s+you\s+(?:are|will|must)/i, type: 'role_hijack', category: 'PI', severity: 'high' },
|
|
57
|
+
|
|
58
|
+
// --- RAI: Deception ---
|
|
59
|
+
{ regex: /do\s+not\s+tell\s+the\s+user/i, type: 'deception', category: 'RAI', severity: 'critical' },
|
|
60
|
+
{ regex: /hide\s+this\s+from\s+(?:the\s+)?user/i, type: 'deception', category: 'RAI', severity: 'critical' },
|
|
61
|
+
{ regex: /don'?t\s+mention\s+this\s+(?:to|in)/i, type: 'deception', category: 'RAI', severity: 'medium' },
|
|
62
|
+
{ regex: /never\s+reveal\s+(?:this|that|your)/i, type: 'deception', category: 'RAI', severity: 'high' },
|
|
63
|
+
{ regex: /keep\s+this\s+(?:secret|hidden|private)\s+from/i, type: 'deception', category: 'RAI', severity: 'high' },
|
|
64
|
+
|
|
65
|
+
// --- SDP: Exfiltration ---
|
|
66
|
+
{ regex: /curl\s+[^\n]*\$\{?\w*(?:KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL)/i, type: 'exfil', category: 'SDP', severity: 'critical' },
|
|
67
|
+
{ regex: /curl\s+[^\n]*\s-[dF]\s+@[^\s"']+/i, type: 'exfil_file', category: 'SDP', severity: 'critical' },
|
|
68
|
+
{ regex: /wget\s+[^\n]*\$\{?\w*(?:KEY|TOKEN|SECRET|PASSWORD)/i, type: 'exfil', category: 'SDP', severity: 'critical' },
|
|
69
|
+
{ regex: /wget\s+[^\n]*--post-file[= ][^\s"']+/i, type: 'exfil_file', category: 'SDP', severity: 'critical' },
|
|
70
|
+
{ regex: /fetch\s*\([^\n]*(?:KEY|TOKEN|SECRET|PASSWORD)/i, type: 'exfil', category: 'SDP', severity: 'high' },
|
|
71
|
+
{ regex: /(?:nc|netcat|ncat)\s+[^\n]*(?:\d{1,3}\.){3}\d{1,3}/i, type: 'exfil', category: 'SDP', severity: 'high' },
|
|
72
|
+
|
|
73
|
+
// --- MAL: SSH backdoor ---
|
|
74
|
+
{ regex: /authorized_keys/i, type: 'ssh_backdoor', category: 'MAL', severity: 'high' },
|
|
75
|
+
{ regex: /ssh-(?:rsa|ed25519|ecdsa)\s+[A-Za-z0-9+/]{20,}/i, type: 'ssh_key_injection', category: 'MAL', severity: 'high' },
|
|
76
|
+
|
|
77
|
+
// --- MAL: Destructive (en contexto de prompt, no como comando real) ---
|
|
78
|
+
{ regex: /rm\s+-rf\s+[/~]/i, type: 'destructive_prompt', category: 'MAL', severity: 'high' },
|
|
79
|
+
{ regex: /DROP\s+(?:TABLE|DATABASE|SCHEMA)/i, type: 'destructive_prompt', category: 'MAL', severity: 'high' },
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// Caracteres Unicode invisibles
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Caracteres Unicode que son invisibles pero pueden alterar el comportamiento
|
|
88
|
+
* de parseo de texto. Técnica documentada de inyección de prompts.
|
|
89
|
+
*/
|
|
90
|
+
const INVISIBLE_CHARS = new Set([
|
|
91
|
+
'\u200B', // zero-width space
|
|
92
|
+
'\u200C', // zero-width non-joiner
|
|
93
|
+
'\u200D', // zero-width joiner
|
|
94
|
+
'\u2060', // word joiner
|
|
95
|
+
'\uFEFF', // BOM / zero-width no-break space
|
|
96
|
+
'\u00AD', // soft hyphen
|
|
97
|
+
'\u200E', // left-to-right mark
|
|
98
|
+
'\u200F', // right-to-left mark
|
|
99
|
+
'\u202A', // left-to-right embedding
|
|
100
|
+
'\u202B', // right-to-left embedding
|
|
101
|
+
'\u202C', // pop directional formatting
|
|
102
|
+
'\u202D', // left-to-right override
|
|
103
|
+
'\u202E', // right-to-left override
|
|
104
|
+
'\u2066', // left-to-right isolate
|
|
105
|
+
'\u2067', // right-to-left isolate
|
|
106
|
+
'\u2068', // first strong isolate
|
|
107
|
+
'\u2069', // pop directional isolate
|
|
108
|
+
]);
|
|
109
|
+
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
// API pública
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Escanea contenido buscando amenazas de inyección de prompt.
|
|
116
|
+
*
|
|
117
|
+
* @param {string} content - Contenido a escanear.
|
|
118
|
+
* @param {string} [source='unknown'] - Nombre del origen (para mensajes).
|
|
119
|
+
* @returns {{ safe: boolean, threats: object[], criticalCount: number, highCount: number }}
|
|
120
|
+
*/
|
|
121
|
+
function scan(content, source = 'unknown') {
|
|
122
|
+
if (!content || typeof content !== 'string') {
|
|
123
|
+
return { safe: true, threats: [], criticalCount: 0, highCount: 0 };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const threats = [];
|
|
127
|
+
|
|
128
|
+
// 1. Detectar caracteres Unicode invisibles
|
|
129
|
+
let invisibleCount = 0;
|
|
130
|
+
for (const ch of content) {
|
|
131
|
+
if (INVISIBLE_CHARS.has(ch)) invisibleCount++;
|
|
132
|
+
}
|
|
133
|
+
if (invisibleCount > 0) {
|
|
134
|
+
threats.push({
|
|
135
|
+
type: 'invisible_chars',
|
|
136
|
+
category: 'PI',
|
|
137
|
+
severity: invisibleCount > 5 ? 'critical' : 'high',
|
|
138
|
+
count: invisibleCount,
|
|
139
|
+
message: `${invisibleCount} carácter(es) Unicode invisible(s) en ${source}`,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// 2. Detectar patrones de amenaza
|
|
144
|
+
for (const pattern of THREAT_PATTERNS) {
|
|
145
|
+
const match = content.match(pattern.regex);
|
|
146
|
+
if (match) {
|
|
147
|
+
threats.push({
|
|
148
|
+
type: pattern.type,
|
|
149
|
+
category: pattern.category,
|
|
150
|
+
severity: pattern.severity,
|
|
151
|
+
match: match[0].substring(0, 80),
|
|
152
|
+
message: `Patrón ${pattern.type} en ${source}: "${match[0].substring(0, 50)}"`,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// 3. Agrupar por categoría de amenaza
|
|
158
|
+
const porCategoria = {};
|
|
159
|
+
for (const t of threats) {
|
|
160
|
+
const cat = t.category || 'UNKNOWN';
|
|
161
|
+
porCategoria[cat] = (porCategoria[cat] || 0) + 1;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
safe: threats.length === 0,
|
|
166
|
+
threats,
|
|
167
|
+
criticalCount: threats.filter(t => t.severity === 'critical').length,
|
|
168
|
+
highCount: threats.filter(t => t.severity === 'high').length,
|
|
169
|
+
categorias: porCategoria,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Escanea y produce contenido sanitizado.
|
|
175
|
+
*
|
|
176
|
+
* - Si hay amenazas críticas: bloquea completamente (reemplaza con placeholder).
|
|
177
|
+
* - Si hay amenazas no-críticas: inyecta con advertencia.
|
|
178
|
+
* - Si no hay amenazas: retorna tal cual.
|
|
179
|
+
*
|
|
180
|
+
* @param {string} content - Contenido a sanitizar.
|
|
181
|
+
* @param {string} [source='unknown'] - Nombre del origen.
|
|
182
|
+
* @returns {{ content: string, blocked: boolean, threats: object[] }}
|
|
183
|
+
*/
|
|
184
|
+
function sanitize(content, source = 'unknown') {
|
|
185
|
+
const result = scan(content, source);
|
|
186
|
+
|
|
187
|
+
if (result.safe) {
|
|
188
|
+
return { content, blocked: false, threats: [] };
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (result.criticalCount > 0) {
|
|
192
|
+
const tipos = [...new Set(result.threats.filter(t => t.severity === 'critical').map(t => t.type))];
|
|
193
|
+
return {
|
|
194
|
+
content: `[BLOQUEADO: ${source} contiene ${result.criticalCount} amenaza(s) crítica(s) (${tipos.join(', ')}). Contenido no inyectado.]`,
|
|
195
|
+
blocked: true,
|
|
196
|
+
threats: result.threats,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Amenazas no-críticas: inyectar con advertencia
|
|
201
|
+
const tipos = [...new Set(result.threats.map(t => t.type))];
|
|
202
|
+
return {
|
|
203
|
+
content: `[ADVERTENCIA: ${result.threats.length} patrón(es) sospechoso(s) en ${source} (${tipos.join(', ')})]\n${content}`,
|
|
204
|
+
blocked: false,
|
|
205
|
+
threats: result.threats,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
module.exports = { scan, sanitize, THREAT_PATTERNS, THREAT_CATEGORIES, INVISIBLE_CHARS };
|