@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,249 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Hook: resumen-sesion.js
6
+ * Tipo: Stop
7
+ *
8
+ * Se ejecuta cuando Claude Code termina una respuesta. Imprime un resumen
9
+ * compacto de la sesión: componentes SWL utilizados, tokens, costo y archivos.
10
+ *
11
+ * Solo imprime si la sesión tiene al menos 5 tool calls (evita ruido en
12
+ * interacciones triviales) y si hay componentes SWL registrados.
13
+ *
14
+ * Resultado:
15
+ * - stdout: resumen formateado (visible para Claude como contexto)
16
+ * - stderr: no escribe (nunca bloquea)
17
+ * - exit 0: siempre
18
+ */
19
+
20
+ const fs = require('fs');
21
+ const path = require('path');
22
+ const os = require('os');
23
+ const { execFile } = require('child_process');
24
+
25
+ const bus = require('./lib/event-bus');
26
+ const runLog = require('./lib/run-log');
27
+ const abortRegistry = require('./lib/abort-registry');
28
+
29
+ // Umbral mínimo de tool calls para mostrar resumen cuando NO hay componentes SWL
30
+ // registrados. Si hay componentes, emitimos siempre (gap 3 resuelto en v5.8.1, mantenido en v5.10.0).
31
+ const MIN_TOOL_CALLS_SIN_COMPONENTES = 5;
32
+ const MIN_TOOL_CALLS_CON_COMPONENTES = 1;
33
+
34
+ /**
35
+ * Sincroniza los JSONL de Claude Code → SQLite (claude-usage) en segundo plano.
36
+ * No bloquea ni falla si Python no está disponible.
37
+ */
38
+ function sincronizarUsageDB() {
39
+ const cliPath = path.join(__dirname, '..', 'scripts', 'vendor', 'claude-usage', 'cli.py');
40
+ if (!fs.existsSync(cliPath)) return;
41
+
42
+ const python = process.platform === 'win32' ? 'python' : 'python3';
43
+ execFile(python, [cliPath, 'scan'], { timeout: 30_000 }, () => {
44
+ // Silencioso — nunca bloquea el hook
45
+ });
46
+ }
47
+
48
+ /**
49
+ * Lee el estado del bridge de tracking-costos para la sesión.
50
+ */
51
+ function leerBridge(sessionId) {
52
+ const bridgePath = path.join(os.tmpdir(), `swl-costs-${sessionId}.json`);
53
+ try {
54
+ return JSON.parse(fs.readFileSync(bridgePath, 'utf8'));
55
+ } catch (_) {
56
+ return null;
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Formatea número con separador de miles.
62
+ */
63
+ function fmt(n) {
64
+ return n.toLocaleString('es-MX');
65
+ }
66
+
67
+ /**
68
+ * Genera el resumen de sesión.
69
+ */
70
+ /**
71
+ * Lee los hooks SWL que se dispararon en la sesión actual.
72
+ * Fuente: eventos del event-bus (fallback: run-log).
73
+ * Esto complementa `componentesSWL.hooks` que solo captura registros manuales.
74
+ */
75
+ function hooksDisparados(sessionId) {
76
+ const hooks = new Set();
77
+ try {
78
+ const eventos = (runLog.readEvents && runLog.readEvents(sessionId)) || [];
79
+ for (const e of eventos) {
80
+ if (e && typeof e.hook === 'string' && e.hook) hooks.add(e.hook);
81
+ }
82
+ } catch { /* ignore */ }
83
+
84
+ // Fallback: heurística por archivos JSONL de hooks conocidos en .planning/
85
+ try {
86
+ const planningDir = path.join(process.cwd(), '.planning');
87
+ const jsonlCandidatos = [
88
+ ['evolucion/nudges.jsonl', 'nudge-tracker'],
89
+ ['auto-evolucion/agentes.jsonl', 'auto-evolucion'],
90
+ ['perfil-usuario/dirty.json', 'actualizar-perfil-usuario'],
91
+ ['evolucion/metricas.json', 'metricas-evolucion'],
92
+ ];
93
+ for (const [rel, nombre] of jsonlCandidatos) {
94
+ const p = path.join(planningDir, rel);
95
+ if (fs.existsSync(p)) {
96
+ const stat = fs.statSync(p);
97
+ // Si se modificó en los últimos 10 minutos, probablemente fue de esta sesión
98
+ if (Date.now() - stat.mtimeMs < 10 * 60 * 1000) {
99
+ hooks.add(nombre);
100
+ }
101
+ }
102
+ }
103
+ } catch { /* ignore */ }
104
+
105
+ return Array.from(hooks);
106
+ }
107
+
108
+ function generarResumen(estado, sessionId) {
109
+ const c = estado.componentesSWL || {};
110
+
111
+ // Fusionar hooks registrados con los detectados por JSONL recientes
112
+ const hooksDet = hooksDisparados(sessionId);
113
+ const hooksSet = new Set([...(c.hooks || []), ...hooksDet]);
114
+ const hooks = Array.from(hooksSet);
115
+
116
+ const tieneComponentes =
117
+ (c.agentes || []).length > 0 ||
118
+ (c.skills || []).length > 0 ||
119
+ (c.comandos || []).length > 0 ||
120
+ (c.scripts || []).length > 0 ||
121
+ (c.reglas || []).length > 0 ||
122
+ hooks.length > 0;
123
+
124
+ // Solo suprimir el resumen si NO hay componentes Y la sesión fue trivial.
125
+ const umbral = tieneComponentes
126
+ ? MIN_TOOL_CALLS_CON_COMPONENTES
127
+ : MIN_TOOL_CALLS_SIN_COMPONENTES;
128
+ if (estado.toolCalls < umbral) return null;
129
+ if (!tieneComponentes && estado.toolCalls < MIN_TOOL_CALLS_SIN_COMPONENTES) return null;
130
+
131
+ // Si no hay ningún componente SWL registrado pero sí hubo muchas tool calls,
132
+ // emitir una nota mínima en lugar de nada (gap 3: "no se usó SWL visiblemente").
133
+ if (!tieneComponentes) {
134
+ return [
135
+ '',
136
+ '━━━ Resumen de sesión SWL ━━━',
137
+ ` Herramientas: ${fmt(estado.toolCalls)} llamadas | Tokens: ~${fmt(estado.tokensTotal)} | Costo: ~$${estado.costoTotal.toFixed(2)} USD`,
138
+ ' Componentes SWL usados: ninguno registrado (sesión sin delegación a agentes ni carga explícita de skills).',
139
+ ' Tip: invoca agentes con Agent(subagent_type="...-swl") o skills con Skill("...") para registrarlos.',
140
+ '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
141
+ '',
142
+ ].join('\n');
143
+ }
144
+
145
+ const lineas = [];
146
+ lineas.push('');
147
+ lineas.push('━━━ Resumen de sesión SWL ━━━');
148
+ lineas.push(` Herramientas: ${fmt(estado.toolCalls)} llamadas | Tokens: ~${fmt(estado.tokensTotal)} | Costo: ~$${estado.costoTotal.toFixed(2)} USD`);
149
+
150
+ if ((c.agentes || []).length > 0) {
151
+ lineas.push(` Agentes (${c.agentes.length}): ${c.agentes.join(', ')}`);
152
+ }
153
+ if ((c.skills || []).length > 0) {
154
+ lineas.push(` Skills (${c.skills.length}): ${c.skills.join(', ')}`);
155
+ }
156
+ if ((c.comandos || []).length > 0) {
157
+ lineas.push(` Comandos: ${c.comandos.join(', ')}`);
158
+ }
159
+ if ((c.scripts || []).length > 0) {
160
+ lineas.push(` Scripts: ${c.scripts.join(', ')}`);
161
+ }
162
+ if (hooks.length > 0) {
163
+ lineas.push(` Hooks (${hooks.length}): ${hooks.join(', ')}`);
164
+ }
165
+ if ((c.reglas || []).length > 0) {
166
+ lineas.push(` Reglas: ${c.reglas.join(', ')}`);
167
+ }
168
+
169
+ // Top 5 herramientas más usadas
170
+ const topTools = Object.entries(estado.desglosePorHerramienta || {})
171
+ .sort(([, a], [, b]) => b.llamadas - a.llamadas)
172
+ .slice(0, 5)
173
+ .map(([nombre, datos]) => `${nombre}(${datos.llamadas})`)
174
+ .join(', ');
175
+ if (topTools) {
176
+ lineas.push(` Top herramientas: ${topTools}`);
177
+ }
178
+
179
+ lineas.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
180
+ lineas.push('');
181
+
182
+ return lineas.join('\n');
183
+ }
184
+
185
+ // ---------------------------------------------------------------------------
186
+ // Entrypoint
187
+ // ---------------------------------------------------------------------------
188
+
189
+ let inputRaw = '';
190
+
191
+ process.stdin.on('data', chunk => {
192
+ inputRaw += chunk;
193
+ });
194
+
195
+ process.stdin.on('end', () => {
196
+ try {
197
+ const data = JSON.parse(inputRaw);
198
+ const sessionId = String(data.session_id || 'default');
199
+
200
+ // Registrar sesión activa en abort-registry para manejo de señales
201
+ abortRegistry.registrarSesionActiva(sessionId);
202
+
203
+ // Sincronizar JSONL → SQLite en background (claude-usage)
204
+ sincronizarUsageDB();
205
+
206
+ const estado = leerBridge(sessionId);
207
+
208
+ // Registrar evento session-stop en JSONL de run (trazabilidad)
209
+ if (estado) {
210
+ runLog.sessionStop(sessionId, {
211
+ toolCalls: estado.toolCalls || 0,
212
+ tokensTotal: estado.tokensTotal || 0,
213
+ costoTotal: estado.costoTotal || 0,
214
+ modeloPredominante: estado.modeloPredominante || 'unknown',
215
+ });
216
+ bus.publish({
217
+ type: 'session-stop',
218
+ runId: sessionId,
219
+ toolCalls: estado.toolCalls || 0,
220
+ costoTotal: estado.costoTotal || 0,
221
+ modeloPredominante: estado.modeloPredominante || 'unknown',
222
+ });
223
+ }
224
+
225
+ // Limpiar abort-registry post-sesión
226
+ abortRegistry.cleanup(sessionId);
227
+
228
+ if (!estado) return;
229
+
230
+ const resumen = generarResumen(estado, sessionId);
231
+ if (resumen) {
232
+ // Agregar diagnóstico de guardrails al resumen de sesión si hay activaciones
233
+ let resumenCompleto = resumen;
234
+ try {
235
+ const { getMetrics, diagnosticar } = require('./lib/guardrail-metrics');
236
+ const metricas = getMetrics(sessionId);
237
+ const advertencias = diagnosticar(metricas);
238
+ if (advertencias.length > 0) {
239
+ resumenCompleto += '\n⚠ Diagnóstico de guardrails:\n' +
240
+ advertencias.map(a => ' - ' + a).join('\n') + '\n';
241
+ }
242
+ } catch (_) { /* métricas opcionales */ }
243
+
244
+ process.stdout.write(resumenCompleto);
245
+ }
246
+ } catch (_) {
247
+ // Nunca bloquear
248
+ }
249
+ });
@@ -0,0 +1,323 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Hook: risk-scoring.js
6
+ * Tipo: PreToolUse (aplica a: todas las herramientas — matcher vacío)
7
+ *
8
+ * Evalúa el riesgo de cada operación de Claude Code usando el motor de scoring
9
+ * compuesto definido en lib/risk-engine.js. Toma decisiones en 4 niveles:
10
+ *
11
+ * allow (score < 0.35) — Continúa silenciosamente.
12
+ * review (score < 0.60) — Emite advertencia en stderr y continúa.
13
+ * confirm (score < 0.85) — Bloquea con mensaje que solicita reformulación
14
+ * o aprobación explícita del usuario.
15
+ * block (score ≥ 0.85) — Bloquea con mensaje de operación peligrosa.
16
+ *
17
+ * La fórmula de scoring es:
18
+ * score = min(1.0, baseRisk + fileSensitivity + blastRadius + irreversibility)
19
+ *
20
+ * Resultado:
21
+ * - allow → exit 0, sin output
22
+ * - review → exit 0, warning en stderr
23
+ * - confirm → exit 2, JSON {result:"block", reason:"..."} en stdout
24
+ * - block → exit 2, JSON {result:"block", reason:"..."} en stdout
25
+ * - Error → exit 0 (nunca bloquear por fallo interno del hook)
26
+ */
27
+
28
+ const fs = require('fs');
29
+ const path = require('path');
30
+ const os = require('os');
31
+
32
+ // Cargar el motor de scoring desde lib/ relativo al directorio de este script
33
+ const { calcularRiskScore, UMBRALES_DEFAULT } = require(
34
+ path.join(__dirname, 'lib', 'risk-engine.js')
35
+ );
36
+ const { getDelegationRiskFactor } = require(
37
+ path.join(__dirname, 'lib', 'delegation-tracker.js')
38
+ );
39
+ const { isTripped, recordFailure, recordSuccess } = require(
40
+ path.join(__dirname, 'lib', 'hook-circuit-breaker.js')
41
+ );
42
+ const { normalizar, formatear } = require(
43
+ path.join(__dirname, 'lib', 'normalize-error.js')
44
+ );
45
+ const { tracker: taintTracker } = require(
46
+ path.join(__dirname, 'lib', 'taint-tracker.js')
47
+ );
48
+
49
+ // ---------------------------------------------------------------------------
50
+ // Override tracking — registra cuando el usuario ignora advertencias de riesgo
51
+ // ---------------------------------------------------------------------------
52
+
53
+ const HOOK_NAME = 'risk-scoring';
54
+ const MAX_HIGH_OVERRIDES = 5;
55
+
56
+ /**
57
+ * Ruta del archivo de tracking de overrides por sesión.
58
+ */
59
+ function overrideTrackingPath() {
60
+ const sessionId = process.env.SWL_SESSION_ID || 'default';
61
+ return path.join(os.tmpdir(), `swl-risk-overrides-${sessionId}.json`);
62
+ }
63
+
64
+ /**
65
+ * Lee el estado de overrides.
66
+ */
67
+ function readOverrides() {
68
+ try {
69
+ return JSON.parse(fs.readFileSync(overrideTrackingPath(), 'utf8'));
70
+ } catch {
71
+ return { highOverrides: 0, auditWritten: false, entries: [] };
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Escribe el estado de overrides.
77
+ */
78
+ function writeOverrides(state) {
79
+ try {
80
+ fs.writeFileSync(overrideTrackingPath(), JSON.stringify(state), 'utf8');
81
+ } catch { /* silencioso */ }
82
+ }
83
+
84
+ /**
85
+ * Registra un override de nivel alto y escribe audit si supera el umbral.
86
+ */
87
+ function trackHighOverride(score, factors, toolName) {
88
+ const state = readOverrides();
89
+ state.highOverrides += 1;
90
+ state.entries.push({
91
+ timestamp: new Date().toISOString(),
92
+ score: score.toFixed(2),
93
+ tool: toolName,
94
+ factors: Array.isArray(factors) ? factors : Object.keys(factors),
95
+ });
96
+
97
+ if (state.highOverrides >= MAX_HIGH_OVERRIDES && !state.auditWritten) {
98
+ const auditPath = path.join(process.cwd(), '.planning', 'AUDITORIA.md');
99
+ try {
100
+ const auditEntry = [
101
+ '',
102
+ `## [${new Date().toISOString().slice(0, 16)}] risk-override-threshold`,
103
+ '',
104
+ `**Agente**: sesión activa`,
105
+ '',
106
+ `**Operación**: ${state.highOverrides} operaciones de riesgo alto aceptadas sin mitigación`,
107
+ '',
108
+ `**Justificación**: registro automático — umbral de ${MAX_HIGH_OVERRIDES} overrides superado`,
109
+ '',
110
+ `**Detalle de overrides**:`,
111
+ '',
112
+ ...state.entries.map(e => `- ${e.timestamp.slice(0, 16)} | ${e.tool} | score ${e.score}`),
113
+ '',
114
+ `**Estado**: registrado automáticamente por risk-scoring.js`,
115
+ '',
116
+ '---',
117
+ '',
118
+ ].join('\n');
119
+
120
+ if (fs.existsSync(auditPath)) {
121
+ fs.appendFileSync(auditPath, auditEntry);
122
+ } else {
123
+ const dir = path.dirname(auditPath);
124
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
125
+ fs.writeFileSync(auditPath, `# Registro de Auditoría\n\nRegistro automático de operaciones de alto riesgo generado por \`risk-scoring.js\`.\n${auditEntry}`);
126
+ }
127
+ state.auditWritten = true;
128
+ } catch { /* no bloquear por fallo de audit */ }
129
+ }
130
+
131
+ writeOverrides(state);
132
+ }
133
+
134
+ // ---------------------------------------------------------------------------
135
+ // Construcción de mensajes
136
+ // ---------------------------------------------------------------------------
137
+
138
+ /**
139
+ * Construye el mensaje de bloqueo para niveles 'confirm' y 'block'.
140
+ *
141
+ * El mensaje para 'confirm' usa un tono más suave: solicita reformulación
142
+ * o aprobación explícita en lugar de declarar la operación directamente
143
+ * peligrosa. El mensaje para 'block' usa lenguaje más firme.
144
+ *
145
+ * @param {'confirm'|'block'} level - Nivel de decisión.
146
+ * @param {number} score - Score calculado.
147
+ * @param {string[]} factors - Factores que contribuyeron al score.
148
+ * @param {object} umbrales - Umbrales usados en la evaluación.
149
+ * @returns {string}
150
+ */
151
+ function construirMensajeBloqueo(level, score, factors, umbrales) {
152
+ const factoresTexto = factors.length > 0
153
+ ? factors.map(f => ` - ${f}`).join('\n')
154
+ : ' - (sin factores específicos identificados)';
155
+
156
+ if (level === 'confirm') {
157
+ return [
158
+ `Operación pausada por Risk Scoring (score: ${score.toFixed(2)} / umbral de confirmación: ${umbrales.confirm}).`,
159
+ ``,
160
+ `Esta operación requiere confirmación explícita antes de continuar.`,
161
+ ``,
162
+ `Factores de riesgo detectados:`,
163
+ factoresTexto,
164
+ ``,
165
+ `Para proceder:`,
166
+ ` 1. Solicita aprobación explícita al usuario antes de ejecutar esta operación.`,
167
+ ` 2. O reformula la operación reduciendo su alcance o riesgo.`,
168
+ ` 3. Si el usuario ya aprobó explícitamente, indica "aprobado por el usuario" en tu mensaje.`,
169
+ ].join('\n');
170
+ }
171
+
172
+ // level === 'block'
173
+ return [
174
+ `Operación bloqueada por Risk Scoring (score: ${score.toFixed(2)} / umbral: ${umbrales.confirm}).`,
175
+ ``,
176
+ `Factores de riesgo detectados:`,
177
+ factoresTexto,
178
+ ``,
179
+ `Para proceder, reformula la operación con menor riesgo o solicita aprobación explícita.`,
180
+ ].join('\n');
181
+ }
182
+
183
+ /**
184
+ * Construye el mensaje de advertencia para nivel 'review'.
185
+ *
186
+ * @param {number} score - Score calculado.
187
+ * @param {string[]} factors - Factores que contribuyeron al score.
188
+ * @param {object} umbrales - Umbrales usados en la evaluación.
189
+ * @returns {string}
190
+ */
191
+ function construirMensajeReview(score, factors, umbrales) {
192
+ const factoresTexto = factors.length > 0
193
+ ? factors.map(f => ` - ${f}`).join('\n')
194
+ : ' - (sin factores específicos identificados)';
195
+
196
+ return [
197
+ `[risk-scoring] ADVERTENCIA — score de riesgo: ${score.toFixed(2)} (umbral review: ${umbrales.allow}, confirm: ${umbrales.review})`,
198
+ ` Factores detectados:`,
199
+ factoresTexto,
200
+ ` La operación continúa — verificar que es intencional.`,
201
+ ].join('\n');
202
+ }
203
+
204
+ // ---------------------------------------------------------------------------
205
+ // Entrypoint principal
206
+ // ---------------------------------------------------------------------------
207
+
208
+ let inputRaw = '';
209
+
210
+ process.stdin.on('data', chunk => {
211
+ inputRaw += chunk;
212
+ });
213
+
214
+ process.stdin.on('end', () => {
215
+ try {
216
+ // Circuit breaker: si el hook ha fallado demasiadas veces, degradar
217
+ if (isTripped(HOOK_NAME, { maxConsecutive: 5 })) {
218
+ process.stderr.write('[risk-scoring] Circuit breaker activo — hook degradado a pass-through\n');
219
+ return;
220
+ }
221
+
222
+ const data = JSON.parse(inputRaw);
223
+
224
+ const toolName = String(data.tool_name || data.tool?.name || '');
225
+ const toolInput = data.tool_input || data.tool?.input || {};
226
+ const sessionId = String(data.session_id || 'default');
227
+
228
+ // Sin nombre de herramienta: nada que evaluar
229
+ if (!toolName) {
230
+ recordSuccess(HOOK_NAME);
231
+ return;
232
+ }
233
+
234
+ // Taint tracking: registrar sources y verificar sinks
235
+ const targetPath = toolInput.file_path || toolInput.command || toolInput.url || '';
236
+ if (/^Read$/i.test(toolName) || /^WebFetch$/i.test(toolName)) {
237
+ taintTracker.registrarSource(toolName, targetPath);
238
+ }
239
+ const taintViolation = taintTracker.verificarSink(toolName, targetPath);
240
+ if (taintViolation) {
241
+ const msg = [
242
+ `Operación bloqueada por Taint Tracking (${taintViolation.severity}).`,
243
+ ``,
244
+ `Flujo de información peligroso detectado:`,
245
+ ` ${taintViolation.flujo}`,
246
+ ``,
247
+ `${taintViolation.descripcion}.`,
248
+ `Reformula la operación sin propagar datos sensibles a este destino.`,
249
+ ].join('\n');
250
+ process.stderr.write(msg);
251
+ try { require('./lib/guardrail-metrics').recordActivation('risk-scoring.js', sessionId, true); } catch (_) {}
252
+ recordSuccess(HOOK_NAME);
253
+ process.exit(2);
254
+ }
255
+
256
+ // Calcular el score de riesgo compuesto
257
+ const result = calcularRiskScore(toolName, toolInput, UMBRALES_DEFAULT);
258
+
259
+ // Agregar factor de profundidad de delegación (0.15 por nivel)
260
+ const delegationFactor = getDelegationRiskFactor();
261
+ result.score = Math.min(1.0, result.score + delegationFactor);
262
+ if (delegationFactor > 0) {
263
+ result.factors.delegation = delegationFactor;
264
+ }
265
+
266
+ // Recalcular level después del ajuste por delegación
267
+ const { score, factors } = result;
268
+ const level = score >= UMBRALES_DEFAULT.confirm ? 'block'
269
+ : score >= UMBRALES_DEFAULT.review ? 'confirm'
270
+ : score >= UMBRALES_DEFAULT.allow ? 'review'
271
+ : 'allow';
272
+
273
+ switch (level) {
274
+ case 'allow':
275
+ // Operación segura — exit 0 (allow)
276
+ recordSuccess(HOOK_NAME);
277
+ return;
278
+
279
+ case 'review': {
280
+ // Advertencia visible pero no bloqueante — stdout con info, exit 0 (allow)
281
+ const mensajeReview = construirMensajeReview(score, factors, UMBRALES_DEFAULT);
282
+ process.stderr.write(mensajeReview);
283
+ // Registrar como override si el score era alto (>= confirm threshold)
284
+ if (score >= UMBRALES_DEFAULT.review) {
285
+ trackHighOverride(score, factors, toolName);
286
+ }
287
+ try { require('./lib/guardrail-metrics').recordActivation('risk-scoring.js', sessionId, false); } catch (_) {}
288
+ recordSuccess(HOOK_NAME);
289
+ break;
290
+ }
291
+
292
+ case 'confirm': {
293
+ // Bloqueo suave: solicita confirmación — exit 2 (block)
294
+ // stderr: Claude recibe el mensaje y puede razonar con él.
295
+ const mensajeConfirm = construirMensajeBloqueo('confirm', score, factors, UMBRALES_DEFAULT);
296
+ process.stderr.write(mensajeConfirm);
297
+ try { require('./lib/guardrail-metrics').recordActivation('risk-scoring.js', sessionId, true); } catch (_) {}
298
+ recordSuccess(HOOK_NAME);
299
+ process.exit(2);
300
+ }
301
+
302
+ case 'block': {
303
+ // Bloqueo firme: operación peligrosa — exit 2 (block)
304
+ // stderr: Claude recibe el mensaje y puede razonar con él.
305
+ const mensajeBlock = construirMensajeBloqueo('block', score, factors, UMBRALES_DEFAULT);
306
+ process.stderr.write(mensajeBlock);
307
+ try { require('./lib/guardrail-metrics').recordActivation('risk-scoring.js', sessionId, true); } catch (_) {}
308
+ recordSuccess(HOOK_NAME);
309
+ process.exit(2);
310
+ }
311
+
312
+ default:
313
+ recordSuccess(HOOK_NAME);
314
+ break;
315
+ }
316
+
317
+ } catch (err) {
318
+ // El hook nunca bloquea por errores internos propios
319
+ const errNorm = normalizar(err, { fuente: 'risk-scoring' });
320
+ process.stderr.write(`[risk-scoring] ${formatear(errNorm)}\n`);
321
+ recordFailure(HOOK_NAME);
322
+ }
323
+ });
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Hook: rotar-audit-auto.js
6
+ * Tipo: Stop
7
+ *
8
+ * Se ejecuta al terminar una respuesta. Verifica si los archivos de auditoría
9
+ * (.planning/audit.jsonl y audit-merkle.jsonl) superan el umbral configurable
10
+ * y, de ser así, invoca scripts/rotar-audit-logs.js para archivar entradas
11
+ * antiguas a .planning/archivo/audit/<nombre>-YYYY-MM.jsonl.gz.
12
+ *
13
+ * Política:
14
+ * - Umbral default: 5 MB por archivo (UMBRAL_BYTES). Configurable vía env
15
+ * SWL_AUDIT_ROTATE_UMBRAL_MB (valor en MB, default 5).
16
+ * - Retención default: 30 días (coincide con el default del script).
17
+ * Configurable vía env SWL_AUDIT_ROTATE_DIAS.
18
+ * - Desactivable con SWL_AUDIT_ROTATE_OFF=1 (para CI o escenarios donde
19
+ * la rotación debe ser manual).
20
+ * - Cooldown: no se re-ejecuta si hubo una rotación exitosa en las últimas
21
+ * 6 horas (marca en .planning/archivo/audit/.ultima-rotacion).
22
+ *
23
+ * Resultado:
24
+ * - stdout: 1-2 líneas si se rotó, silencioso si no
25
+ * - stderr: nunca escribe
26
+ * - exit 0: siempre (hook no-bloqueante)
27
+ */
28
+
29
+ const fs = require('fs');
30
+ const path = require('path');
31
+ const { spawnSync } = require('child_process');
32
+
33
+ const RAIZ_PROYECTO = path.resolve(__dirname, '..');
34
+ const DIR_PLANNING = path.join(RAIZ_PROYECTO, '.planning');
35
+ const ARCHIVOS_AUDIT = [
36
+ path.join(DIR_PLANNING, 'audit.jsonl'),
37
+ path.join(DIR_PLANNING, 'audit-merkle.jsonl'),
38
+ ];
39
+ const DIR_ARCHIVO = path.join(DIR_PLANNING, 'archivo', 'audit');
40
+ const MARCA_ULTIMA_ROTACION = path.join(DIR_ARCHIVO, '.ultima-rotacion');
41
+ const SCRIPT_ROTAR = path.join(RAIZ_PROYECTO, 'scripts', 'rotar-audit-logs.js');
42
+
43
+ const COOLDOWN_MS = 6 * 60 * 60 * 1000; // 6 horas
44
+
45
+ function umbralBytes() {
46
+ const mb = parseFloat(process.env.SWL_AUDIT_ROTATE_UMBRAL_MB || '5');
47
+ return isNaN(mb) || mb <= 0 ? 5 * 1024 * 1024 : mb * 1024 * 1024;
48
+ }
49
+
50
+ function diasRetencion() {
51
+ const d = parseInt(process.env.SWL_AUDIT_ROTATE_DIAS || '30', 10);
52
+ return isNaN(d) || d <= 0 ? 30 : d;
53
+ }
54
+
55
+ function algunArchivoSuperaUmbral() {
56
+ const limite = umbralBytes();
57
+ for (const ruta of ARCHIVOS_AUDIT) {
58
+ try {
59
+ const st = fs.statSync(ruta);
60
+ if (st.size > limite) return { excedido: true, ruta, size: st.size, limite };
61
+ } catch (_) {
62
+ // Archivo ausente — ignorar
63
+ }
64
+ }
65
+ return { excedido: false };
66
+ }
67
+
68
+ function enCooldown() {
69
+ try {
70
+ const raw = fs.readFileSync(MARCA_ULTIMA_ROTACION, 'utf8').trim();
71
+ const ultima = parseInt(raw, 10);
72
+ if (isNaN(ultima)) return false;
73
+ return Date.now() - ultima < COOLDOWN_MS;
74
+ } catch (_) {
75
+ return false;
76
+ }
77
+ }
78
+
79
+ function marcarRotacion() {
80
+ try {
81
+ fs.mkdirSync(DIR_ARCHIVO, { recursive: true });
82
+ fs.writeFileSync(MARCA_ULTIMA_ROTACION, String(Date.now()), 'utf8');
83
+ } catch (_) {
84
+ // Silencioso — no crítico
85
+ }
86
+ }
87
+
88
+ function main() {
89
+ if (process.env.SWL_AUDIT_ROTATE_OFF === '1') return;
90
+ if (!fs.existsSync(SCRIPT_ROTAR)) return;
91
+
92
+ const check = algunArchivoSuperaUmbral();
93
+ if (!check.excedido) return;
94
+ if (enCooldown()) return;
95
+
96
+ const dias = diasRetencion();
97
+ const nodeBin = process.execPath;
98
+ const result = spawnSync(
99
+ nodeBin,
100
+ [SCRIPT_ROTAR, `--dias=${dias}`, `--raiz=${DIR_PLANNING}`],
101
+ { encoding: 'utf8', timeout: 30_000, cwd: RAIZ_PROYECTO }
102
+ );
103
+
104
+ if (result.status === 0) {
105
+ marcarRotacion();
106
+ const sizeMb = (check.size / 1024 / 1024).toFixed(1);
107
+ const limiteMb = (check.limite / 1024 / 1024).toFixed(1);
108
+ const nombreArchivo = path.basename(check.ruta);
109
+ const match = (result.stdout || '').match(/(\d+) archivadas/g);
110
+ const archivadas = match ? match.map((m) => m.replace(' archivadas', '')).join('+') : '?';
111
+ process.stdout.write(
112
+ `[rotacion-audit] ${nombreArchivo}=${sizeMb}MB > ${limiteMb}MB → archivadas ${archivadas} entradas (>${dias}d)\n`
113
+ );
114
+ }
115
+ }
116
+
117
+ try {
118
+ main();
119
+ } catch (_) {
120
+ // Nunca bloquear
121
+ }
122
+ process.exit(0);