@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.
Files changed (702) hide show
  1. package/CLAUDE.md +238 -0
  2. package/README.md +560 -0
  3. package/_userland/agentes/.gitkeep +0 -0
  4. package/_userland/habilidades/.gitkeep +0 -0
  5. package/agentes/.evolved.json +9 -0
  6. package/agentes/accesibilidad-wcag-swl.md +692 -0
  7. package/agentes/arquitecto-swl.md +238 -0
  8. package/agentes/auto-evolucion-swl.md +854 -0
  9. package/agentes/backend-api-swl.md +470 -0
  10. package/agentes/backend-csharp-swl.md +418 -0
  11. package/agentes/backend-go-swl.md +388 -0
  12. package/agentes/backend-java-swl.md +279 -0
  13. package/agentes/backend-node-swl.md +477 -0
  14. package/agentes/backend-python-swl.md +608 -0
  15. package/agentes/backend-rust-swl.md +362 -0
  16. package/agentes/backend-workers-swl.md +480 -0
  17. package/agentes/cloud-infra-swl.md +485 -0
  18. package/agentes/consolidador-swl.md +539 -0
  19. package/agentes/datos-swl.md +584 -0
  20. package/agentes/depurador-swl.md +349 -0
  21. package/agentes/devops-ci-swl.md +374 -0
  22. package/agentes/disenador-ui-swl.md +558 -0
  23. package/agentes/documentador-swl.md +343 -0
  24. package/agentes/evals/arquitecto-swl.evals.json +56 -0
  25. package/agentes/evals/auto-evolucion-swl.evals.json +68 -0
  26. package/agentes/evals/implementador-swl.evals.json +56 -0
  27. package/agentes/evals/orquestador-swl.evals.json +60 -0
  28. package/agentes/evals/perfilador-usuario-swl.evals.json +60 -0
  29. package/agentes/evals/red-team-swl.evals.json +59 -0
  30. package/agentes/evals/revisor-codigo-swl.evals.json +59 -0
  31. package/agentes/frontend-angular-swl.md +627 -0
  32. package/agentes/frontend-css-swl.md +720 -0
  33. package/agentes/frontend-react-swl.md +696 -0
  34. package/agentes/frontend-swl.md +500 -0
  35. package/agentes/frontend-tailwind-swl.md +830 -0
  36. package/agentes/implementador-swl.md +328 -0
  37. package/agentes/investigador-swl.md +430 -0
  38. package/agentes/investigador-ux-swl.md +500 -0
  39. package/agentes/llm-apps-swl.md +276 -0
  40. package/agentes/migrador-swl.md +417 -0
  41. package/agentes/mobile-android-swl.md +509 -0
  42. package/agentes/mobile-cross-swl.md +539 -0
  43. package/agentes/mobile-ios-swl.md +500 -0
  44. package/agentes/mobile-testing-swl.md +300 -0
  45. package/agentes/notificador-swl.md +916 -0
  46. package/agentes/observabilidad-swl.md +436 -0
  47. package/agentes/orquestador-swl.md +884 -0
  48. package/agentes/pagos-swl.md +283 -0
  49. package/agentes/perfilador-usuario-swl.md +306 -0
  50. package/agentes/planificador-swl.md +402 -0
  51. package/agentes/producto-prd-swl.md +587 -0
  52. package/agentes/red-team-swl.md +216 -0
  53. package/agentes/release-manager-swl.md +568 -0
  54. package/agentes/rendimiento-swl.md +714 -0
  55. package/agentes/resolutor-build-swl.md +243 -0
  56. package/agentes/revisor-angular-swl.md +276 -0
  57. package/agentes/revisor-codigo-swl.md +348 -0
  58. package/agentes/revisor-csharp-swl.md +262 -0
  59. package/agentes/revisor-go-swl.md +257 -0
  60. package/agentes/revisor-java-swl.md +255 -0
  61. package/agentes/revisor-kotlin-swl.md +271 -0
  62. package/agentes/revisor-nextjs-swl.md +279 -0
  63. package/agentes/revisor-php-swl.md +269 -0
  64. package/agentes/revisor-react-swl.md +276 -0
  65. package/agentes/revisor-rust-swl.md +344 -0
  66. package/agentes/revisor-seguridad-swl.md +390 -0
  67. package/agentes/revisor-swift-swl.md +266 -0
  68. package/agentes/revisor-typescript-swl.md +344 -0
  69. package/agentes/sre-swl.md +265 -0
  70. package/agentes/tdd-qa-swl.md +354 -0
  71. package/agentes/ux-disenador-swl.md +501 -0
  72. package/bin/lib/bot-comandos.js +1030 -0
  73. package/bin/lib/bot-discovery.js +182 -0
  74. package/bin/lib/bot-git.js +142 -0
  75. package/bin/swl-ses.js +325 -0
  76. package/bin/swl-telegram-bot.js +442 -0
  77. package/bin/swl-telegram-bot.plist +21 -0
  78. package/bin/swl-telegram-bot.service +14 -0
  79. package/comandos/swl/.evolved.json +23 -0
  80. package/comandos/swl/actualizar.md +174 -0
  81. package/comandos/swl/adoptar-proyecto.md +207 -0
  82. package/comandos/swl/aprender.md +701 -0
  83. package/comandos/swl/auditar-deps.md +134 -0
  84. package/comandos/swl/autoresearch.md +170 -0
  85. package/comandos/swl/ayuda.md +224 -0
  86. package/comandos/swl/brainstorm.md +50 -0
  87. package/comandos/swl/checkpoint.md +330 -0
  88. package/comandos/swl/compactar.md +283 -0
  89. package/comandos/swl/configurar-ci.md +227 -0
  90. package/comandos/swl/contexto.md +112 -0
  91. package/comandos/swl/contribuir.md +233 -0
  92. package/comandos/swl/crear-skill.md +292 -0
  93. package/comandos/swl/cron.md +196 -0
  94. package/comandos/swl/dashboard.md +146 -0
  95. package/comandos/swl/discutir-fase.md +230 -0
  96. package/comandos/swl/ejecutar-fase.md +135 -0
  97. package/comandos/swl/evaluar-skill.md +487 -0
  98. package/comandos/swl/evolucion-estado.md +142 -0
  99. package/comandos/swl/evolucionar.md +259 -0
  100. package/comandos/swl/exportar-vault.md +189 -0
  101. package/comandos/swl/gateway.md +158 -0
  102. package/comandos/swl/inbox.md +116 -0
  103. package/comandos/swl/instalar.md +220 -0
  104. package/comandos/swl/instintos.md +86 -0
  105. package/comandos/swl/mapear-codebase.md +312 -0
  106. package/comandos/swl/mcp-status.md +175 -0
  107. package/comandos/swl/metricas.md +270 -0
  108. package/comandos/swl/modelo.md +102 -0
  109. package/comandos/swl/notificaciones.md +396 -0
  110. package/comandos/swl/nuevo-proyecto.md +154 -0
  111. package/comandos/swl/planear-fase.md +221 -0
  112. package/comandos/swl/plugins.md +256 -0
  113. package/comandos/swl/reflect-skills.md +125 -0
  114. package/comandos/swl/release.md +217 -0
  115. package/comandos/swl/revisar-impacto.md +206 -0
  116. package/comandos/swl/revisar.md +330 -0
  117. package/comandos/swl/salud.md +363 -0
  118. package/comandos/swl/sesiones.md +200 -0
  119. package/comandos/swl/skill-search.md +113 -0
  120. package/comandos/swl/verificar.md +585 -0
  121. package/comandos/swl/wiki.md +620 -0
  122. package/contextos/dev.md +32 -0
  123. package/contextos/research.md +30 -0
  124. package/contextos/review.md +31 -0
  125. package/habilidades/accesibilidad-a11y/SKILL.md +201 -0
  126. package/habilidades/accesibilidad-a11y/evals/evals.json +56 -0
  127. package/habilidades/accesibilidad-a11y/recursos/ejemplos-y-checklist-completo.md +441 -0
  128. package/habilidades/agent-browser/SKILL.md +218 -0
  129. package/habilidades/agentes-como-servicio/SKILL.md +218 -0
  130. package/habilidades/ai-runtime-security/SKILL.md +273 -0
  131. package/habilidades/angular-avanzado/SKILL.md +164 -0
  132. package/habilidades/angular-avanzado/recursos/ejemplos-avanzados.md +219 -0
  133. package/habilidades/angular-moderno/SKILL.md +186 -0
  134. package/habilidades/angular-moderno/evals/evals.json +45 -0
  135. package/habilidades/angular-moderno/recursos/ejemplos-avanzados.md +106 -0
  136. package/habilidades/api-rest-diseno/SKILL.md +191 -0
  137. package/habilidades/api-rest-diseno/recursos/openapi-template.yaml +506 -0
  138. package/habilidades/api-rest-diseno/recursos/referencia-api.md +140 -0
  139. package/habilidades/aprendizaje-continuo/SKILL.md +151 -0
  140. package/habilidades/aprendizaje-continuo/evals/evals.json +53 -0
  141. package/habilidades/aprendizaje-continuo/recursos/referencia-instintos.md +290 -0
  142. package/habilidades/async-python/SKILL.md +149 -0
  143. package/habilidades/async-python/evals/evals.json +47 -0
  144. package/habilidades/async-python/recursos/patrones-y-ejemplos-completos.md +292 -0
  145. package/habilidades/auth-patrones/.evolved.json +9 -0
  146. package/habilidades/auth-patrones/SKILL.md +413 -0
  147. package/habilidades/auth-patrones/recursos/implementaciones-completas.md +229 -0
  148. package/habilidades/auto-evolucion-protocolo/SKILL.md +276 -0
  149. package/habilidades/auto-evolucion-protocolo/evals/evals.json +55 -0
  150. package/habilidades/auto-evolucion-protocolo/recursos/referencia-completa.md +145 -0
  151. package/habilidades/autoresearch/SKILL.md +268 -0
  152. package/habilidades/autoresearch/evals/evals.json +41 -0
  153. package/habilidades/autoresearch/recursos/checklist-template.md +191 -0
  154. package/habilidades/autoresearch/scripts/calcular-score.js +88 -0
  155. package/habilidades/azure-cloud/SKILL.md +308 -0
  156. package/habilidades/azure-cloud/recursos/aks.md +327 -0
  157. package/habilidades/backend-mcp-servidor/SKILL.md +270 -0
  158. package/habilidades/backend-production-resilience/SKILL.md +288 -0
  159. package/habilidades/brainstorming/SKILL.md +295 -0
  160. package/habilidades/brainstorming/recursos/componentes-html.md +247 -0
  161. package/habilidades/build-errors-cpp/SKILL.md +270 -0
  162. package/habilidades/build-errors-csharp/SKILL.md +265 -0
  163. package/habilidades/build-errors-go/SKILL.md +306 -0
  164. package/habilidades/build-errors-java/SKILL.md +278 -0
  165. package/habilidades/build-errors-kotlin/SKILL.md +303 -0
  166. package/habilidades/build-errors-nextjs/SKILL.md +312 -0
  167. package/habilidades/build-errors-php/SKILL.md +270 -0
  168. package/habilidades/build-errors-python/SKILL.md +292 -0
  169. package/habilidades/build-errors-rust/SKILL.md +284 -0
  170. package/habilidades/build-errors-swift/SKILL.md +272 -0
  171. package/habilidades/build-errors-typescript/SKILL.md +369 -0
  172. package/habilidades/checklist-calidad/SKILL.md +271 -0
  173. package/habilidades/checklist-calidad/recursos/quality-report-template.md +148 -0
  174. package/habilidades/checklist-seguridad/SKILL.md +285 -0
  175. package/habilidades/checkpoints-verificacion/SKILL.md +298 -0
  176. package/habilidades/checkpoints-verificacion/recursos/checkpoint-templates.md +360 -0
  177. package/habilidades/ci-cd-pipelines/SKILL.md +157 -0
  178. package/habilidades/ci-cd-pipelines/recursos/github-actions-template.yaml +403 -0
  179. package/habilidades/ci-cd-pipelines/recursos/pipelines-completos.md +487 -0
  180. package/habilidades/cloud-aws/SKILL.md +142 -0
  181. package/habilidades/cloud-aws/recursos/servicios-aws-referencia.md +321 -0
  182. package/habilidades/compactacion-contexto/SKILL.md +247 -0
  183. package/habilidades/contenedores-docker/SKILL.md +137 -0
  184. package/habilidades/contenedores-docker/recursos/dockerfile-template.dockerfile +160 -0
  185. package/habilidades/contenedores-docker/recursos/ejemplos-y-configuraciones.md +327 -0
  186. package/habilidades/context-builder/SKILL.md +170 -0
  187. package/habilidades/control-profundidad/SKILL.md +128 -0
  188. package/habilidades/csharp-experto/SKILL.md +322 -0
  189. package/habilidades/csharp-patrones/SKILL.md +316 -0
  190. package/habilidades/csharp-testing/SKILL.md +286 -0
  191. package/habilidades/css-moderno/SKILL.md +166 -0
  192. package/habilidades/css-moderno/evals/evals.json +43 -0
  193. package/habilidades/css-moderno/recursos/ejemplos-y-patrones-completos.md +337 -0
  194. package/habilidades/datos-etl/SKILL.md +129 -0
  195. package/habilidades/datos-etl/recursos/implementaciones-completas.md +322 -0
  196. package/habilidades/dbml-experto/SKILL.md +339 -0
  197. package/habilidades/dbml-experto/evals/evals.json +56 -0
  198. package/habilidades/dependencias-auditoria/SKILL.md +320 -0
  199. package/habilidades/deprecacion-migracion/SKILL.md +169 -0
  200. package/habilidades/deprecacion-migracion/recursos/implementaciones-completas.md +220 -0
  201. package/habilidades/design-tokens/SKILL.md +158 -0
  202. package/habilidades/design-tokens/recursos/tokens-y-configuracion.md +363 -0
  203. package/habilidades/devsecops-pipeline-security/SKILL.md +309 -0
  204. package/habilidades/diagrama-arquitectura/SKILL.md +165 -0
  205. package/habilidades/diagrama-arquitectura/assets/template.html +276 -0
  206. package/habilidades/discutir-fase/SKILL.md +188 -0
  207. package/habilidades/diseno-herramientas-agente/SKILL.md +199 -0
  208. package/habilidades/diseno-responsivo/SKILL.md +186 -0
  209. package/habilidades/diseno-responsivo/recursos/ejemplos-layouts.md +156 -0
  210. package/habilidades/django-experto/SKILL.md +205 -0
  211. package/habilidades/django-experto/recursos/async-django.md +390 -0
  212. package/habilidades/django-experto/recursos/drf-patrones.md +438 -0
  213. package/habilidades/django-experto/recursos/orm-avanzado.md +382 -0
  214. package/habilidades/django-experto/recursos/referencia-completa.md +188 -0
  215. package/habilidades/django-experto/recursos/testing-django.md +415 -0
  216. package/habilidades/doc-sync/SKILL.md +280 -0
  217. package/habilidades/drift-detection/SKILL.md +179 -0
  218. package/habilidades/ejecutar-fase/SKILL.md +468 -0
  219. package/habilidades/estilo-sin-ai-isms/SKILL.md +775 -0
  220. package/habilidades/estilo-sin-ai-isms/evals/evals.json +63 -0
  221. package/habilidades/estilo-sin-ai-isms/scripts/detectar_aiisms.py +500 -0
  222. package/habilidades/estructura-proyecto-claude/SKILL.md +215 -0
  223. package/habilidades/estructura-proyecto-claude/recursos/claude-md-template.md +261 -0
  224. package/habilidades/estructura-proyecto-claude/recursos/configuracion-y-extensiones.md +176 -0
  225. package/habilidades/estructura-proyecto-claude/recursos/frontmatter-y-hooks-referencia.md +289 -0
  226. package/habilidades/estructura-proyecto-claude/recursos/mcp-json-template.json +77 -0
  227. package/habilidades/estructura-proyecto-claude/recursos/variantes-por-stack.md +177 -0
  228. package/habilidades/evaluacion-agentes/SKILL.md +314 -0
  229. package/habilidades/event-driven/SKILL.md +153 -0
  230. package/habilidades/event-driven/recursos/implementaciones-completas.md +423 -0
  231. package/habilidades/extraccion-documentos/SKILL.md +221 -0
  232. package/habilidades/extractor-de-aprendizajes/.evolved.json +9 -0
  233. package/habilidades/extractor-de-aprendizajes/SKILL.md +311 -0
  234. package/habilidades/extractor-de-aprendizajes/evals/evals.json +55 -0
  235. package/habilidades/fastapi-experto/SKILL.md +221 -0
  236. package/habilidades/fastapi-experto/recursos/async-patterns.md +438 -0
  237. package/habilidades/fastapi-experto/recursos/dependency-injection.md +330 -0
  238. package/habilidades/fastapi-experto/recursos/referencia-completa.md +79 -0
  239. package/habilidades/fastapi-experto/recursos/testing-httpx.md +420 -0
  240. package/habilidades/filament-admin/SKILL.md +290 -0
  241. package/habilidades/frontend-avanzado/SKILL.md +257 -0
  242. package/habilidades/frontend-avanzado/recursos/apis-nativas-ejemplos.md +341 -0
  243. package/habilidades/gcp-cloud/SKILL.md +260 -0
  244. package/habilidades/gcp-cloud/recursos/gke.md +234 -0
  245. package/habilidades/gcp-cloud/recursos/terraform-gcp.md +307 -0
  246. package/habilidades/generacion-mermaid/SKILL.md +229 -0
  247. package/habilidades/git-worktrees-paralelo/SKILL.md +270 -0
  248. package/habilidades/go-experto/SKILL.md +305 -0
  249. package/habilidades/go-patrones/SKILL.md +299 -0
  250. package/habilidades/go-testing/SKILL.md +291 -0
  251. package/habilidades/graphql-experto/SKILL.md +323 -0
  252. package/habilidades/guardrail-semantico/SKILL.md +282 -0
  253. package/habilidades/harness-claude-code/SKILL.md +299 -0
  254. package/habilidades/iam-secretos/SKILL.md +265 -0
  255. package/habilidades/iam-secretos/recursos/implementaciones-completas.md +356 -0
  256. package/habilidades/infra-github-actions/SKILL.md +166 -0
  257. package/habilidades/instalar-sistema/.evolved.json +9 -0
  258. package/habilidades/instalar-sistema/SKILL.md +221 -0
  259. package/habilidades/java-experto/SKILL.md +290 -0
  260. package/habilidades/java-patrones/SKILL.md +275 -0
  261. package/habilidades/java-testing/SKILL.md +288 -0
  262. package/habilidades/kotlin-compose/SKILL.md +278 -0
  263. package/habilidades/kotlin-compose/recursos/animaciones-performance.md +93 -0
  264. package/habilidades/kotlin-experto/SKILL.md +318 -0
  265. package/habilidades/kotlin-testing/SKILL.md +267 -0
  266. package/habilidades/kotlin-testing/recursos/testing-avanzado.md +74 -0
  267. package/habilidades/kubernetes-orquestacion/SKILL.md +152 -0
  268. package/habilidades/kubernetes-orquestacion/recursos/manifiestos-completos.md +452 -0
  269. package/habilidades/langchain-langraph/SKILL.md +386 -0
  270. package/habilidades/langchain-langraph/recursos/evaluacion-rag.md +321 -0
  271. package/habilidades/langchain-langraph/recursos/rag-maturity-model.md +225 -0
  272. package/habilidades/langchain-langraph/recursos/vectorstores.md +306 -0
  273. package/habilidades/legacy-code-rescue/SKILL.md +267 -0
  274. package/habilidades/likec4-experto/SKILL.md +412 -0
  275. package/habilidades/likec4-experto/evals/evals.json +69 -0
  276. package/habilidades/manejo-errores/.evolved.json +9 -0
  277. package/habilidades/manejo-errores/SKILL.md +407 -0
  278. package/habilidades/manejo-errores/recursos/implementaciones-completas.md +248 -0
  279. package/habilidades/mapear-codebase/SKILL.md +275 -0
  280. package/habilidades/memoria-busqueda/SKILL.md +194 -0
  281. package/habilidades/memoria-busqueda/evals/evals.json +44 -0
  282. package/habilidades/meta-skills-estandar/SKILL.md +298 -0
  283. package/habilidades/meta-skills-estandar/recursos/anti-patrones-y-leyes.md +205 -0
  284. package/habilidades/meta-skills-estandar/recursos/frameworks-seguridad.md +107 -0
  285. package/habilidades/meta-skills-estandar/recursos/idiomas-framework.md +60 -0
  286. package/habilidades/meta-skills-estandar/recursos/skills-as-agents.md +163 -0
  287. package/habilidades/microservicios/SKILL.md +155 -0
  288. package/habilidades/microservicios/recursos/patrones-y-ejemplos-completos.md +325 -0
  289. package/habilidades/mobile-flutter/SKILL.md +199 -0
  290. package/habilidades/mobile-flutter/recursos/ejemplos-completos.md +319 -0
  291. package/habilidades/mobile-react-native/SKILL.md +176 -0
  292. package/habilidades/mobile-react-native/recursos/ejemplos-completos.md +216 -0
  293. package/habilidades/mongodb-experto/SKILL.md +302 -0
  294. package/habilidades/monitoring-alertas/SKILL.md +201 -0
  295. package/habilidades/monitoring-alertas/recursos/instrumentacion-y-alertas.md +301 -0
  296. package/habilidades/nestjs-experto/SKILL.md +307 -0
  297. package/habilidades/nestjs-experto/recursos/guards-interceptors.md +339 -0
  298. package/habilidades/nestjs-experto/recursos/modulos-di.md +287 -0
  299. package/habilidades/nestjs-experto/recursos/testing-nestjs.md +354 -0
  300. package/habilidades/nextjs-experto/SKILL.md +335 -0
  301. package/habilidades/nextjs-patrones/SKILL.md +303 -0
  302. package/habilidades/nextjs-testing/SKILL.md +331 -0
  303. package/habilidades/node-experto/.evolved.json +9 -0
  304. package/habilidades/node-experto/SKILL.md +266 -0
  305. package/habilidades/node-experto/recursos/patrones-completos.md +283 -0
  306. package/habilidades/notificaciones-multicanal/SKILL.md +159 -0
  307. package/habilidades/notificaciones-multicanal/recursos/config-template.json +115 -0
  308. package/habilidades/notificaciones-multicanal/recursos/configuracion-y-templates.md +303 -0
  309. package/habilidades/nuevo-proyecto/SKILL.md +204 -0
  310. package/habilidades/orquestacion-async/SKILL.md +303 -0
  311. package/habilidades/paid-media-tracking/SKILL.md +269 -0
  312. package/habilidades/paid-media-tracking/recursos/auditoria-tracking.md +220 -0
  313. package/habilidades/paid-media-tracking/recursos/google-ads-api.md +215 -0
  314. package/habilidades/patrones-python/SKILL.md +228 -0
  315. package/habilidades/patrones-python/evals/evals.json +56 -0
  316. package/habilidades/patrones-python/recursos/patrones-avanzados.md +469 -0
  317. package/habilidades/patrones-python/recursos/referencia-completa.md +202 -0
  318. package/habilidades/perfil-usuario/SKILL.md +200 -0
  319. package/habilidades/perfil-usuario/evals/evals.json +55 -0
  320. package/habilidades/performance-baseline/SKILL.md +297 -0
  321. package/habilidades/php-experto/SKILL.md +291 -0
  322. package/habilidades/php-patrones/SKILL.md +306 -0
  323. package/habilidades/php-testing/SKILL.md +280 -0
  324. package/habilidades/planear-fase/SKILL.md +269 -0
  325. package/habilidades/postgresql-experto/SKILL.md +151 -0
  326. package/habilidades/postgresql-experto/evals/evals.json +53 -0
  327. package/habilidades/postgresql-experto/recursos/referencia-completa.md +215 -0
  328. package/habilidades/prevencion-racionalizacion/SKILL.md +175 -0
  329. package/habilidades/prevencion-sobreingenieria/SKILL.md +323 -0
  330. package/habilidades/privacy-memoria/SKILL.md +141 -0
  331. package/habilidades/privacy-memoria/evals/evals.json +43 -0
  332. package/habilidades/prompt-engineering/SKILL.md +518 -0
  333. package/habilidades/prompt-engineering/recursos/patrones-avanzados.md +467 -0
  334. package/habilidades/rag-arquitectura/SKILL.md +338 -0
  335. package/habilidades/rails-experto/SKILL.md +237 -0
  336. package/habilidades/rails-experto/recursos/active-record.md +260 -0
  337. package/habilidades/rails-experto/recursos/hotwire-turbo.md +293 -0
  338. package/habilidades/rails-experto/recursos/testing-rspec.md +362 -0
  339. package/habilidades/react-experto/SKILL.md +209 -0
  340. package/habilidades/react-experto/evals/evals.json +55 -0
  341. package/habilidades/react-experto/recursos/patrones-y-ejemplos-completos.md +240 -0
  342. package/habilidades/react-optimizacion/SKILL.md +174 -0
  343. package/habilidades/react-optimizacion/recursos/patrones-avanzados.md +138 -0
  344. package/habilidades/redis-experto/SKILL.md +305 -0
  345. package/habilidades/release-semver/.evolved.json +9 -0
  346. package/habilidades/release-semver/SKILL.md +248 -0
  347. package/habilidades/release-semver/scripts/generar-changelog.sh +238 -0
  348. package/habilidades/rust-experto/SKILL.md +400 -0
  349. package/habilidades/rust-patrones/SKILL.md +296 -0
  350. package/habilidades/rust-testing/SKILL.md +311 -0
  351. package/habilidades/seguridad-skills-ia/SKILL.md +262 -0
  352. package/habilidades/sql-optimizacion/SKILL.md +200 -0
  353. package/habilidades/sql-optimizacion/evals/evals.json +54 -0
  354. package/habilidades/sql-optimizacion/recursos/patrones-sql-avanzados.md +131 -0
  355. package/habilidades/sre-patrones/SKILL.md +333 -0
  356. package/habilidades/sre-patrones/recursos/chaos-engineering.md +241 -0
  357. package/habilidades/sre-patrones/recursos/oncall-design.md +236 -0
  358. package/habilidades/stripe-pagos/SKILL.md +550 -0
  359. package/habilidades/stripe-pagos/recursos/errores-reintentos.md +390 -0
  360. package/habilidades/stripe-pagos/recursos/stripe-connect.md +290 -0
  361. package/habilidades/structured-outputs/SKILL.md +343 -0
  362. package/habilidades/swift-experto/SKILL.md +320 -0
  363. package/habilidades/swift-experto/recursos/keychain-y-wrappers.md +110 -0
  364. package/habilidades/swift-patrones/SKILL.md +313 -0
  365. package/habilidades/swift-patrones/recursos/tca-ejemplo-completo.md +113 -0
  366. package/habilidades/swift-testing/SKILL.md +254 -0
  367. package/habilidades/swift-testing/recursos/xcuitest-planes.md +143 -0
  368. package/habilidades/swl-dashboard/SKILL.md +370 -0
  369. package/habilidades/swl-markitdown/SKILL.md +285 -0
  370. package/habilidades/swl-markitdown/evals/evals.json +52 -0
  371. package/habilidades/swl-revisar-impacto/SKILL.md +233 -0
  372. package/habilidades/tailwind-experto/SKILL.md +240 -0
  373. package/habilidades/tailwind-experto/recursos/referencia-completa.md +184 -0
  374. package/habilidades/tdd-workflow/SKILL.md +293 -0
  375. package/habilidades/terraform-experto/SKILL.md +321 -0
  376. package/habilidades/testing-python/SKILL.md +340 -0
  377. package/habilidades/testing-python/recursos/ejemplos-completos.md +167 -0
  378. package/habilidades/threat-model-lite/SKILL.md +246 -0
  379. package/habilidades/tracing-processor/SKILL.md +212 -0
  380. package/habilidades/tracking-measurement/SKILL.md +239 -0
  381. package/habilidades/tracking-measurement/recursos/consent-mode.md +231 -0
  382. package/habilidades/tracking-measurement/recursos/gtm-datalayer.md +216 -0
  383. package/habilidades/tracking-measurement/recursos/meta-capi.md +262 -0
  384. package/habilidades/typescript-avanzado/SKILL.md +144 -0
  385. package/habilidades/typescript-avanzado/evals/evals.json +55 -0
  386. package/habilidades/typescript-avanzado/recursos/patrones-y-ejemplos-completos.md +298 -0
  387. package/habilidades/typescript-diagnosticos/SKILL.md +513 -0
  388. package/habilidades/ux-diseno/SKILL.md +116 -0
  389. package/habilidades/ux-diseno/evals/evals.json +43 -0
  390. package/habilidades/ux-diseno/recursos/patrones-ux-referencia.md +214 -0
  391. package/habilidades/validacion-ci-sistema/SKILL.md +136 -0
  392. package/habilidades/validacion-ci-sistema/recursos/validadores-completos.md +369 -0
  393. package/habilidades/validacion-ci-sistema/scripts/validar-sistema.sh +286 -0
  394. package/habilidades/verificacion-evidencia/SKILL.md +160 -0
  395. package/habilidades/verificar-trabajo/SKILL.md +303 -0
  396. package/habilidades/verificar-trabajo/recursos/plantilla-verificacion.md +60 -0
  397. package/habilidades/wiki-conocimiento/SKILL.md +276 -0
  398. package/habilidades/wireframes-flujos/SKILL.md +212 -0
  399. package/habilidades/wireframes-flujos/recursos/referencia-completa.md +192 -0
  400. package/habilidades/workflow-claude-code/SKILL.md +260 -0
  401. package/habilidades/workflow-claude-code/recursos/referencia-completa.md +109 -0
  402. package/hooks/_run-hook.sh +57 -0
  403. package/hooks/actualizar-perfil-usuario.js +364 -0
  404. package/hooks/agente-lifecycle.js +71 -0
  405. package/hooks/aiisms-detector.js +173 -0
  406. package/hooks/audit-trail.js +204 -0
  407. package/hooks/auto-background.js +97 -0
  408. package/hooks/auto-consolidacion.js +178 -0
  409. package/hooks/auto-evolucion.js +666 -0
  410. package/hooks/auto-restaurar-settings.js +360 -0
  411. package/hooks/calidad-pre-commit.js +929 -0
  412. package/hooks/calidad-typescript.js +511 -0
  413. package/hooks/captura-feedback-usuario.js +148 -0
  414. package/hooks/check-update.js +211 -0
  415. package/hooks/clasificador-mensajes.js +271 -0
  416. package/hooks/degradacion-instintos.js +272 -0
  417. package/hooks/escaneo-secretos.js +389 -0
  418. package/hooks/extraccion-aprendizajes.js +763 -0
  419. package/hooks/grafo-contexto.js +129 -0
  420. package/hooks/graph-update.js +67 -0
  421. package/hooks/guardrail-modelo.js +247 -0
  422. package/hooks/inbox-aviso.js +75 -0
  423. package/hooks/inyeccion-contexto.js +246 -0
  424. package/hooks/lib/abort-registry.js +214 -0
  425. package/hooks/lib/agent-backend.js +210 -0
  426. package/hooks/lib/agent-comms.js +263 -0
  427. package/hooks/lib/agent-issue-codes.js +284 -0
  428. package/hooks/lib/agent-matcher.js +189 -0
  429. package/hooks/lib/async-hook-registry.js +252 -0
  430. package/hooks/lib/atomic-write.js +130 -0
  431. package/hooks/lib/auto-consolidator.js +335 -0
  432. package/hooks/lib/canary-skills.js +187 -0
  433. package/hooks/lib/consolidation-lock.js +291 -0
  434. package/hooks/lib/context-builder.js +430 -0
  435. package/hooks/lib/context-compressor.js +657 -0
  436. package/hooks/lib/convergence-detector.js +105 -0
  437. package/hooks/lib/delegation-tracker.js +198 -0
  438. package/hooks/lib/detectar-package-manager.js +423 -0
  439. package/hooks/lib/edit-accumulator.js +171 -0
  440. package/hooks/lib/error-classifier.js +308 -0
  441. package/hooks/lib/event-bus.js +112 -0
  442. package/hooks/lib/evolution-tracker.js +442 -0
  443. package/hooks/lib/execution-state.js +316 -0
  444. package/hooks/lib/fingerprint-id.js +135 -0
  445. package/hooks/lib/gateway-notify.js +116 -0
  446. package/hooks/lib/graph-security.js +75 -0
  447. package/hooks/lib/guardrail-metrics.js +202 -0
  448. package/hooks/lib/hook-circuit-breaker.js +206 -0
  449. package/hooks/lib/loop-detector.js +267 -0
  450. package/hooks/lib/mcp-health.js +184 -0
  451. package/hooks/lib/mcp-pool.js +436 -0
  452. package/hooks/lib/memory-search.js +506 -0
  453. package/hooks/lib/merkle-audit.js +96 -0
  454. package/hooks/lib/model-router.js +222 -0
  455. package/hooks/lib/normalize-error.js +324 -0
  456. package/hooks/lib/normalize-input.js +65 -0
  457. package/hooks/lib/nudge-tracker.js +306 -0
  458. package/hooks/lib/otlp-exporter.js +365 -0
  459. package/hooks/lib/performance-marks.js +239 -0
  460. package/hooks/lib/privacy-filter.js +128 -0
  461. package/hooks/lib/prompt-injection-scanner.js +209 -0
  462. package/hooks/lib/provenance-tracker.js +183 -0
  463. package/hooks/lib/rate-limit-tracker.js +253 -0
  464. package/hooks/lib/reflect-classifier.js +164 -0
  465. package/hooks/lib/resource-quota.js +122 -0
  466. package/hooks/lib/retry-jitter.js +165 -0
  467. package/hooks/lib/risk-engine.js +368 -0
  468. package/hooks/lib/run-log.js +408 -0
  469. package/hooks/lib/session-fts.js +379 -0
  470. package/hooks/lib/session-store.js +293 -0
  471. package/hooks/lib/singleton-guard.js +159 -0
  472. package/hooks/lib/skill-auditor.js +588 -0
  473. package/hooks/lib/sync-status.js +228 -0
  474. package/hooks/lib/taint-tracker.js +107 -0
  475. package/hooks/lib/task-service.js +295 -0
  476. package/hooks/lib/tech-skills-map.js +146 -0
  477. package/hooks/lib/telegram-cliente.js +159 -0
  478. package/hooks/lib/telegram-config.js +170 -0
  479. package/hooks/lib/token-budget.js +156 -0
  480. package/hooks/lib/token-estimator.js +420 -0
  481. package/hooks/lib/toon-compressor.js +245 -0
  482. package/hooks/lib/usage-model.js +183 -0
  483. package/hooks/lib/variable-resolver.js +230 -0
  484. package/hooks/linea-estado.js +324 -0
  485. package/hooks/metricas-evolucion.js +209 -0
  486. package/hooks/monitor-contexto.js +325 -0
  487. package/hooks/notificacion-sesion-stop.js +198 -0
  488. package/hooks/notificacion-telegram-notification.js +4 -0
  489. package/hooks/notificacion-telegram-subagent.js +4 -0
  490. package/hooks/notificacion-telegram.js +267 -0
  491. package/hooks/preservar-estado-pre-compact.js +150 -0
  492. package/hooks/proteccion-rutas.js +366 -0
  493. package/hooks/registro-turnos.js +209 -0
  494. package/hooks/resumen-sesion.js +249 -0
  495. package/hooks/risk-scoring.js +323 -0
  496. package/hooks/rotar-audit-auto.js +122 -0
  497. package/hooks/sugerir-regenerar-inventario.js +170 -0
  498. package/hooks/telemetria-agentes.js +167 -0
  499. package/hooks/tracking-costos.js +688 -0
  500. package/instintos/global.yaml +8 -0
  501. package/instintos/perfil-usuario.yaml +53 -0
  502. package/instintos/prompt-appendices.yaml +57 -0
  503. package/instintos/proyecto.yaml +372 -0
  504. package/manifiestos/gateway-config.json +77 -0
  505. package/manifiestos/handoff-context.json +223 -0
  506. package/manifiestos/hook-profiles.json +44 -0
  507. package/manifiestos/hooks-config.json +360 -0
  508. package/manifiestos/modulos.json +1173 -0
  509. package/manifiestos/perfiles.json +404 -0
  510. package/package.json +86 -0
  511. package/plantillas/ESTADO.md +109 -0
  512. package/plantillas/HOJA-RUTA.md +143 -0
  513. package/plantillas/PROYECTO.md +122 -0
  514. package/plantillas/REQUISITOS.md +132 -0
  515. package/plantillas/auditor-veto-template.md +105 -0
  516. package/plantillas/github-workflows/README.md +47 -0
  517. package/plantillas/github-workflows/release-please.yml +44 -0
  518. package/plantillas/github-workflows/swl-ci.yml +107 -0
  519. package/plantillas/github-workflows/swl-security.yml +51 -0
  520. package/plantillas/mcp-mineru.json +13 -0
  521. package/plantillas/research/ARQUITECTURA.md +220 -0
  522. package/plantillas/research/FUNCIONALIDADES.md +175 -0
  523. package/plantillas/research/RESUMEN.md +165 -0
  524. package/plantillas/research/STACK.md +233 -0
  525. package/plantillas/research/TRAMPAS.md +299 -0
  526. package/plantillas/skill-evals-template.json +44 -0
  527. package/plugin.json +343 -0
  528. package/reglas/accesibilidad.md +269 -0
  529. package/reglas/api-diseno.md +400 -0
  530. package/reglas/arquitectura.md +352 -0
  531. package/reglas/brevedad-output.md +124 -0
  532. package/reglas/cloud-infra.md +247 -0
  533. package/reglas/docs.md +245 -0
  534. package/reglas/estilo-codigo.md +201 -0
  535. package/reglas/git-workflow.md +245 -0
  536. package/reglas/gobernanza.md +271 -0
  537. package/reglas/harness-claude-code.md +213 -0
  538. package/reglas/hooks.md +186 -0
  539. package/reglas/lenguajes/csharp/estilo-codigo.md +231 -0
  540. package/reglas/lenguajes/csharp/hooks.md +281 -0
  541. package/reglas/lenguajes/csharp/patrones.md +226 -0
  542. package/reglas/lenguajes/csharp/seguridad.md +258 -0
  543. package/reglas/lenguajes/csharp/testing.md +176 -0
  544. package/reglas/lenguajes/go/estilo-codigo.md +195 -0
  545. package/reglas/lenguajes/go/hooks.md +249 -0
  546. package/reglas/lenguajes/go/patrones.md +249 -0
  547. package/reglas/lenguajes/go/seguridad.md +225 -0
  548. package/reglas/lenguajes/go/testing.md +272 -0
  549. package/reglas/lenguajes/java/estilo-codigo.md +217 -0
  550. package/reglas/lenguajes/java/hooks.md +251 -0
  551. package/reglas/lenguajes/java/patrones.md +226 -0
  552. package/reglas/lenguajes/java/seguridad.md +233 -0
  553. package/reglas/lenguajes/java/testing.md +238 -0
  554. package/reglas/lenguajes/kotlin/estilo-codigo.md +208 -0
  555. package/reglas/lenguajes/kotlin/hooks.md +245 -0
  556. package/reglas/lenguajes/kotlin/patrones.md +201 -0
  557. package/reglas/lenguajes/kotlin/seguridad.md +202 -0
  558. package/reglas/lenguajes/kotlin/testing.md +236 -0
  559. package/reglas/lenguajes/nextjs/estilo-codigo.md +175 -0
  560. package/reglas/lenguajes/nextjs/hooks.md +186 -0
  561. package/reglas/lenguajes/nextjs/patrones.md +225 -0
  562. package/reglas/lenguajes/nextjs/seguridad.md +216 -0
  563. package/reglas/lenguajes/nextjs/testing.md +193 -0
  564. package/reglas/lenguajes/php/estilo-codigo.md +228 -0
  565. package/reglas/lenguajes/php/hooks.md +165 -0
  566. package/reglas/lenguajes/php/patrones.md +233 -0
  567. package/reglas/lenguajes/php/seguridad.md +186 -0
  568. package/reglas/lenguajes/php/testing.md +205 -0
  569. package/reglas/lenguajes/rust/estilo-codigo.md +207 -0
  570. package/reglas/lenguajes/rust/hooks.md +240 -0
  571. package/reglas/lenguajes/rust/patrones.md +250 -0
  572. package/reglas/lenguajes/rust/seguridad.md +221 -0
  573. package/reglas/lenguajes/rust/testing.md +194 -0
  574. package/reglas/lenguajes/swift/estilo-codigo.md +238 -0
  575. package/reglas/lenguajes/swift/hooks.md +257 -0
  576. package/reglas/lenguajes/swift/patrones.md +235 -0
  577. package/reglas/lenguajes/swift/seguridad.md +248 -0
  578. package/reglas/lenguajes/swift/testing.md +242 -0
  579. package/reglas/markitdown.md +60 -0
  580. package/reglas/memoria-consolidada.md +209 -0
  581. package/reglas/patrones.md +225 -0
  582. package/reglas/performance.md +195 -0
  583. package/reglas/pruebas.md +159 -0
  584. package/reglas/seguridad-agentes.md +351 -0
  585. package/reglas/seguridad.md +151 -0
  586. package/reglas/skills-estandar.md +373 -0
  587. package/reglas/testing.md +193 -0
  588. package/schemas/agent-contract.json +176 -0
  589. package/schemas/agent-frontmatter.schema.json +149 -0
  590. package/schemas/agent-message.schema.json +53 -0
  591. package/schemas/agent-output-implementacion.schema.json +85 -0
  592. package/schemas/agent-output-planificacion.schema.json +113 -0
  593. package/schemas/agent-output-review.schema.json +78 -0
  594. package/schemas/diary-entry.schema.json +80 -0
  595. package/schemas/hook-profiles.schema.json +39 -0
  596. package/schemas/hooks-config.schema.json +74 -0
  597. package/schemas/instinct.schema.json +115 -0
  598. package/schemas/modulos.schema.json +29 -0
  599. package/schemas/perfiles.schema.json +28 -0
  600. package/schemas/plugin.schema.json +64 -0
  601. package/schemas/skill-evals.schema.json +95 -0
  602. package/schemas/skill-frontmatter.schema.json +170 -0
  603. package/scripts/actualizar.js +145 -0
  604. package/scripts/audit-skills.sh +78 -0
  605. package/scripts/auditar-agentes-gaps.js +149 -0
  606. package/scripts/auditar-cobertura-frameworks.js +241 -0
  607. package/scripts/auditar-skills-gaps.js +206 -0
  608. package/scripts/bootstrap-instintos.js +259 -0
  609. package/scripts/check-update.js +109 -0
  610. package/scripts/comandos/agents.js +105 -0
  611. package/scripts/comandos/info.js +108 -0
  612. package/scripts/comandos/install-asistido.js +186 -0
  613. package/scripts/comandos/skills.js +211 -0
  614. package/scripts/configurar-branch-protection.js +418 -0
  615. package/scripts/daemon-swl.py +388 -0
  616. package/scripts/desinstalar.js +130 -0
  617. package/scripts/doctor.js +559 -0
  618. package/scripts/field-report.js +199 -0
  619. package/scripts/generar-inventario.js +317 -0
  620. package/scripts/inbox-tmux-inject.js +161 -0
  621. package/scripts/inferir-herramientas-permitidas.js +586 -0
  622. package/scripts/inicializar.js +133 -0
  623. package/scripts/instalador.js +1031 -0
  624. package/scripts/instalar-git-hook.js +122 -0
  625. package/scripts/lib/agp-frontmatter.js +222 -0
  626. package/scripts/lib/append-con-marcadores.js +199 -0
  627. package/scripts/lib/artefactos-python.js +43 -0
  628. package/scripts/lib/audit-query.js +221 -0
  629. package/scripts/lib/autostart-linux.js +347 -0
  630. package/scripts/lib/autostart-macos.js +360 -0
  631. package/scripts/lib/autostart-windows.js +307 -0
  632. package/scripts/lib/budget-enforcer.js +252 -0
  633. package/scripts/lib/claude-sessions.js +285 -0
  634. package/scripts/lib/configurar-ci.js +380 -0
  635. package/scripts/lib/console-span-exporter.js +92 -0
  636. package/scripts/lib/contadores-inventario.js +217 -0
  637. package/scripts/lib/dashboard-widgets.js +290 -0
  638. package/scripts/lib/detectar-runtime.js +279 -0
  639. package/scripts/lib/detectar-stack.js +187 -0
  640. package/scripts/lib/diary-entry.js +234 -0
  641. package/scripts/lib/drift-detector.js +545 -0
  642. package/scripts/lib/estado.js +124 -0
  643. package/scripts/lib/gestor-componentes.js +243 -0
  644. package/scripts/lib/gitignore-manifest.js +305 -0
  645. package/scripts/lib/graph-analyze.py +556 -0
  646. package/scripts/lib/graph-builder.py +485 -0
  647. package/scripts/lib/graph-cluster.py +259 -0
  648. package/scripts/lib/health-row.js +168 -0
  649. package/scripts/lib/hooks-settings.js +789 -0
  650. package/scripts/lib/manifiestos.js +138 -0
  651. package/scripts/lib/mc-client.js +137 -0
  652. package/scripts/lib/notificaciones-telegram.js +1107 -0
  653. package/scripts/lib/npm-version.js +261 -0
  654. package/scripts/lib/paquetes-conocidos.js +50 -0
  655. package/scripts/lib/preservar-usuario.js +586 -0
  656. package/scripts/lib/prompt-builder.js +264 -0
  657. package/scripts/lib/resolver-externo.js +332 -0
  658. package/scripts/lib/schedule-parser.js +305 -0
  659. package/scripts/lib/scoring-instintos.js +240 -0
  660. package/scripts/lib/seguridad.js +160 -0
  661. package/scripts/lib/selector-interactivo.js +152 -0
  662. package/scripts/lib/semantic-search.js +242 -0
  663. package/scripts/lib/skill-discovery.js +234 -0
  664. package/scripts/lib/skill-metrics.js +246 -0
  665. package/scripts/lib/skill-normalizer.js +112 -0
  666. package/scripts/lib/skills-hub.js +340 -0
  667. package/scripts/lib/span-schema.js +134 -0
  668. package/scripts/lib/tool-cost-analyzer.js +255 -0
  669. package/scripts/lib/tracing-processor-interface.js +286 -0
  670. package/scripts/lib/transformadores/base.js +80 -0
  671. package/scripts/lib/transformadores/claude.js +124 -0
  672. package/scripts/lib/transformadores/codex.js +115 -0
  673. package/scripts/lib/transformadores/copilot.js +106 -0
  674. package/scripts/lib/transformadores/gemini.js +74 -0
  675. package/scripts/lib/transformadores/index.js +35 -0
  676. package/scripts/lib/transformadores/opencode.js +75 -0
  677. package/scripts/lib/ui.js +259 -0
  678. package/scripts/limpiar-artefactos-python.js +131 -0
  679. package/scripts/mcp-orchestrator.py +386 -0
  680. package/scripts/mcp-pool-manager.py +352 -0
  681. package/scripts/mcp-telemetry.py +378 -0
  682. package/scripts/poblar-evolvable.js +226 -0
  683. package/scripts/publicar.js +287 -0
  684. package/scripts/reflect-skills.js +403 -0
  685. package/scripts/rotar-audit-logs.js +185 -0
  686. package/scripts/run-skill-evals.js +242 -0
  687. package/scripts/smoke-test.js +374 -0
  688. package/scripts/token-analysis.py +471 -0
  689. package/scripts/validar-manifest.js +195 -0
  690. package/scripts/validar-memoria.js +321 -0
  691. package/scripts/validar-tests-aislamiento.js +184 -0
  692. package/scripts/validar-tokens-test.js +208 -0
  693. package/scripts/validar.js +147 -0
  694. package/scripts/validate-markdown.py +339 -0
  695. package/scripts/validate-skills.py +385 -0
  696. package/scripts/vendor/claude-usage/README.md +116 -0
  697. package/scripts/vendor/claude-usage/cli.py +334 -0
  698. package/scripts/vendor/claude-usage/dashboard.py +795 -0
  699. package/scripts/vendor/claude-usage/scanner.py +467 -0
  700. package/scripts/vendor/markitdown/cli.py +194 -0
  701. package/scripts/verificar-evolucion.js +289 -0
  702. 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 };