@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,272 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Hook: degradacion-instintos.js
6
+ * Tipo: PostToolUse (aplica a: Bash, Write, Edit)
7
+ *
8
+ * Detecta cuando un aprendizaje registrado en APRENDIZAJES.md es contradecido
9
+ * por la actividad actual del agente. Busca patrones donde:
10
+ *
11
+ * 1. Un anti-patron registrado fue usado exitosamente (falso positivo)
12
+ * 2. Un patron registrado como "siempre usar X" fue ignorado con exito
13
+ * 3. Un error se repite a pesar de que existe un aprendizaje que lo cubre
14
+ *
15
+ * Si detecta contradiccion:
16
+ * - Agrega marca [CONTRADICHO: YYYY-MM-DD] a la entrada en APRENDIZAJES.md
17
+ * - Tras 3 contradicciones en la misma entrada, la marca como [DEGRADADO]
18
+ *
19
+ * El hook nunca bloquea (siempre exit 0).
20
+ */
21
+
22
+ const fs = require('fs');
23
+ const path = require('path');
24
+
25
+ const { atomicWriteSync } = require('./lib/atomic-write');
26
+
27
+ // ---------------------------------------------------------------------------
28
+ // Constantes
29
+ // ---------------------------------------------------------------------------
30
+
31
+ const RUTA_APRENDIZAJES = path.join(process.cwd(), '.planning', 'APRENDIZAJES.md');
32
+ const MAX_CONTRADICCIONES = 3;
33
+
34
+ // Palabras clave que indican exito en el output del agente
35
+ const KEYWORDS_EXITO = [
36
+ 'exitosamente', 'successfully', 'completado', 'completed',
37
+ 'passed', 'aprobado', 'correcto', 'funciona', 'works',
38
+ 'test passed', 'tests passed', 'all tests pass', 'build succeeded',
39
+ ];
40
+
41
+ // Palabras clave de anti-patrones en aprendizajes existentes
42
+ const KEYWORDS_ANTIPATRON = [
43
+ 'nunca', 'never', 'no usar', 'evitar', 'prohibido',
44
+ 'anti-patrón', 'antipatron', 'no hacer', 'bad practice',
45
+ ];
46
+
47
+ // Palabras clave de patrones obligatorios en aprendizajes existentes
48
+ const KEYWORDS_PATRON = [
49
+ 'siempre', 'always', 'obligatorio', 'required',
50
+ 'siempre usar', 'must use', 'nunca omitir',
51
+ ];
52
+
53
+ // ---------------------------------------------------------------------------
54
+ // Funciones de analisis
55
+ // ---------------------------------------------------------------------------
56
+
57
+ /**
58
+ * Lee y parsea las entradas de APRENDIZAJES.md.
59
+ * @returns {Array<{indice: number, linea: string, descripcion: string, contradicciones: number}>}
60
+ */
61
+ function leerEntradas() {
62
+ try {
63
+ const contenido = fs.readFileSync(RUTA_APRENDIZAJES, 'utf8');
64
+ const lineas = contenido.split('\n');
65
+ const entradas = [];
66
+
67
+ for (let i = 0; i < lineas.length; i++) {
68
+ if (!lineas[i].startsWith('## ')) continue;
69
+
70
+ const descripcion = lineas[i]
71
+ .replace(/^##\s+\[\d{4}-\d{2}-\d{2}\]\s+\w+[-\w]*\s+—\s+/, '')
72
+ .trim()
73
+ .toLowerCase();
74
+
75
+ // Contar contradicciones existentes buscando marcas en lineas siguientes
76
+ let contradicciones = 0;
77
+ for (let j = i + 1; j < Math.min(i + 15, lineas.length); j++) {
78
+ if (lineas[j].startsWith('## ')) break;
79
+ const matchesContra = lineas[j].match(/\[CONTRADICHO:/g);
80
+ if (matchesContra) contradicciones += matchesContra.length;
81
+ }
82
+
83
+ entradas.push({
84
+ indice: i,
85
+ linea: lineas[i],
86
+ descripcion,
87
+ contradicciones,
88
+ });
89
+ }
90
+
91
+ return entradas;
92
+ } catch (_) {
93
+ return [];
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Extrae texto relevante del payload del hook.
99
+ * @param {object} data
100
+ * @returns {string}
101
+ */
102
+ function extraerTexto(data) {
103
+ const toolResult = data.tool_result || data.tool?.result || {};
104
+ const fragmentos = [];
105
+
106
+ if (typeof toolResult === 'string') {
107
+ fragmentos.push(toolResult);
108
+ }
109
+
110
+ if (toolResult && typeof toolResult === 'object') {
111
+ for (const campo of ['output', 'content', 'stdout', 'text', 'result']) {
112
+ if (typeof toolResult[campo] === 'string') {
113
+ fragmentos.push(toolResult[campo]);
114
+ }
115
+ }
116
+ }
117
+
118
+ return fragmentos.join('\n').slice(0, 30000).toLowerCase();
119
+ }
120
+
121
+ /**
122
+ * Detecta si el output actual contradice algun aprendizaje existente.
123
+ *
124
+ * Contradiccion = el output muestra exito + contiene terminos de un
125
+ * anti-patron registrado, o ignora un patron obligatorio con exito.
126
+ *
127
+ * @param {string} texto - Output del agente (lowercase)
128
+ * @param {Array} entradas - Entradas parseadas de APRENDIZAJES.md
129
+ * @returns {Array<{indice: number, motivo: string}>}
130
+ */
131
+ function detectarContradicciones(texto, entradas) {
132
+ // Verificar si el output indica exito
133
+ const hayExito = KEYWORDS_EXITO.some(kw => texto.includes(kw));
134
+ if (!hayExito) return [];
135
+
136
+ const contradicciones = [];
137
+
138
+ for (const entrada of entradas) {
139
+ // Ya esta degradada — no procesar mas
140
+ if (entrada.contradicciones >= MAX_CONTRADICCIONES) continue;
141
+
142
+ const desc = entrada.descripcion;
143
+
144
+ // Caso 1: Anti-patron registrado pero el agente hizo lo contrario con exito
145
+ const esAntiPatron = KEYWORDS_ANTIPATRON.some(kw => desc.includes(kw));
146
+ if (esAntiPatron) {
147
+ // Extraer la accion prohibida del anti-patron
148
+ const accionProhibida = desc
149
+ .replace(/nunca|never|no usar|evitar|prohibido|anti-patrón|antipatron|no hacer|bad practice/gi, '')
150
+ .trim()
151
+ .split(/\s+/)
152
+ .filter(p => p.length > 3)
153
+ .slice(0, 3)
154
+ .join(' ');
155
+
156
+ if (accionProhibida && texto.includes(accionProhibida)) {
157
+ contradicciones.push({
158
+ indice: entrada.indice,
159
+ motivo: `Accion prohibida "${accionProhibida}" usada con exito`,
160
+ });
161
+ }
162
+ }
163
+
164
+ // Caso 2: Error repetido a pesar de aprendizaje existente
165
+ if (desc.includes('error') || desc.includes('bug') || desc.includes('fallo')) {
166
+ const terminos = desc
167
+ .split(/\s+/)
168
+ .filter(p => p.length > 4 && !['error', 'corregido', 'solucion', 'resuelto'].includes(p))
169
+ .slice(0, 3);
170
+
171
+ const terminosEnOutput = terminos.filter(t => texto.includes(t));
172
+ if (terminosEnOutput.length >= 2 && texto.includes('error')) {
173
+ contradicciones.push({
174
+ indice: entrada.indice,
175
+ motivo: `Error similar recurrente a pesar del aprendizaje`,
176
+ });
177
+ }
178
+ }
179
+ }
180
+
181
+ return contradicciones;
182
+ }
183
+
184
+ /**
185
+ * Aplica las marcas de contradiccion al archivo APRENDIZAJES.md.
186
+ * @param {Array<{indice: number, motivo: string}>} contradicciones
187
+ */
188
+ function aplicarDegradaciones(contradicciones) {
189
+ if (contradicciones.length === 0) return;
190
+
191
+ try {
192
+ const contenido = fs.readFileSync(RUTA_APRENDIZAJES, 'utf8');
193
+ const lineas = contenido.split('\n');
194
+ const fecha = new Date().toISOString().slice(0, 10);
195
+
196
+ for (const { indice, motivo } of contradicciones) {
197
+ if (indice >= lineas.length) continue;
198
+
199
+ // Buscar donde insertar la marca (despues de la linea de Contexto)
200
+ let insertIdx = indice + 1;
201
+ for (let j = indice + 1; j < Math.min(indice + 15, lineas.length); j++) {
202
+ if (lineas[j].startsWith('---') || lineas[j].startsWith('## ')) {
203
+ insertIdx = j;
204
+ break;
205
+ }
206
+ insertIdx = j + 1;
207
+ }
208
+
209
+ // Contar contradicciones existentes para esta entrada
210
+ let contadorContra = 0;
211
+ for (let j = indice; j < insertIdx; j++) {
212
+ const matches = lineas[j].match(/\[CONTRADICHO:/g);
213
+ if (matches) contadorContra += matches.length;
214
+ }
215
+
216
+ if (contadorContra + 1 >= MAX_CONTRADICCIONES) {
217
+ // Marcar como degradado
218
+ lineas.splice(insertIdx, 0, `**[DEGRADADO: ${fecha}]** Contradicho ${MAX_CONTRADICCIONES}+ veces. Este aprendizaje ya no es confiable.`);
219
+ } else {
220
+ // Agregar marca de contradiccion
221
+ lineas.splice(insertIdx, 0, `**[CONTRADICHO: ${fecha}]** ${motivo}`);
222
+ }
223
+ }
224
+
225
+ atomicWriteSync(RUTA_APRENDIZAJES, lineas.join('\n'));
226
+ } catch (err) {
227
+ // Error al escribir — ignorar silenciosamente
228
+ }
229
+ }
230
+
231
+ // ---------------------------------------------------------------------------
232
+ // Entrypoint
233
+ // ---------------------------------------------------------------------------
234
+
235
+ let inputRaw = '';
236
+
237
+ process.stdin.on('data', chunk => {
238
+ inputRaw += chunk;
239
+ });
240
+
241
+ process.stdin.on('end', () => {
242
+ try {
243
+ const data = JSON.parse(inputRaw);
244
+ const toolName = String(data.tool_name || data.tool?.name || '');
245
+
246
+ // Solo analizar herramientas que producen resultados de accion
247
+ if (!['Bash', 'Write', 'Edit'].includes(toolName)) {
248
+ return;
249
+ }
250
+
251
+ // Verificar que existe el archivo de aprendizajes
252
+ if (!fs.existsSync(RUTA_APRENDIZAJES)) {
253
+ return;
254
+ }
255
+
256
+ const texto = extraerTexto(data);
257
+ if (!texto || texto.length < 20) {
258
+ return;
259
+ }
260
+
261
+ const entradas = leerEntradas();
262
+ if (entradas.length === 0) {
263
+ return;
264
+ }
265
+
266
+ const contradicciones = detectarContradicciones(texto, entradas);
267
+ aplicarDegradaciones(contradicciones);
268
+
269
+ } catch (err) {
270
+ // No escribir a stderr — Claude Code lo reporta como hook error
271
+ }
272
+ });
@@ -0,0 +1,389 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Hook: escaneo-secretos.js
6
+ * Tipo: PreToolUse (aplica a: Write, Edit)
7
+ *
8
+ * Escanea el contenido que Claude Code está a punto de escribir en disco
9
+ * buscando patrones conocidos de secretos y credenciales sensibles:
10
+ *
11
+ * - API keys de Anthropic / OpenAI (sk-ant-*, sk-proj-*, sk-live-*, sk-test-*)
12
+ * - Tokens de AWS (AKIA*, ASIA*)
13
+ * - Tokens de GitHub (ghp_*, gho_*, ghu_*, ghs_*, ghr_*)
14
+ * - Tokens de GitLab (glpat-*)
15
+ * - Claves privadas PEM / SSH
16
+ * - Passwords hardcodeados en asignaciones de variable comunes
17
+ * - Tokens JWT (tres segmentos base64 separados por puntos)
18
+ * - Connection strings con credenciales embebidas (usuario:contraseña@host)
19
+ * - Variables de entorno sensibles hardcodeadas en código
20
+ *
21
+ * Resultado:
22
+ * - Secreto detectado → razón en stdout + exit code 2 (block)
23
+ * - Sin secreto → sin output, proceso termina naturalmente
24
+ * - Error interno → sin output (nunca bloquear por fallo del hook)
25
+ *
26
+ * NOTA: Este hook es una primera línea de defensa heurística, no un escáner
27
+ * de seguridad exhaustivo. Complementar con herramientas como trufflehog,
28
+ * gitleaks o detect-secrets en el pipeline CI.
29
+ */
30
+
31
+ const { normalizeForDetection } = require('./lib/normalize-input');
32
+ const { normalizar, formatear } = require('./lib/normalize-error');
33
+
34
+ // Importar taxonomía de issue codes con guard de robustez.
35
+ let issueCodes = null;
36
+ try {
37
+ issueCodes = require('./lib/agent-issue-codes');
38
+ } catch (_) {
39
+ // Módulo no disponible — continuar sin códigos estandarizados
40
+ }
41
+
42
+ // ---------------------------------------------------------------------------
43
+ // Patrones de detección
44
+ // ---------------------------------------------------------------------------
45
+
46
+ /**
47
+ * Cada entrada describe un tipo de secreto con:
48
+ * - nombre: Etiqueta para el mensaje de error.
49
+ * - patron: Expresión regular para detectarlo.
50
+ * - ejemplos: Comentario ilustrativo (no se usa en código).
51
+ */
52
+ const PATRONES_SECRETOS = [
53
+ {
54
+ nombre: 'Anthropic API Key (sk-ant-*)',
55
+ // sk-ant-api03-xxxxxxxx...
56
+ patron: /\bsk-ant-[A-Za-z0-9\-_]{20,}\b/,
57
+ },
58
+ {
59
+ nombre: 'OpenAI API Key (sk-proj-* / sk-live-* / sk-test-* / sk-[a-z0-9]{48})',
60
+ // sk-proj-..., sk-live-..., sk-test-..., sk-<48 chars alfanum>
61
+ patron: /\bsk-(?:proj|live|test)-[A-Za-z0-9\-_]{20,}\b|\bsk-[A-Za-z0-9]{48,}\b/,
62
+ },
63
+ {
64
+ nombre: 'AWS Access Key ID (AKIA* / ASIA*)',
65
+ // AKIAIOSFODNN7EXAMPLE o ASIAXXX...
66
+ patron: /\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/,
67
+ },
68
+ {
69
+ nombre: 'GitHub Personal Access Token (ghp_* / gho_* / ghu_* / ghs_* / ghr_*)',
70
+ patron: /\bgh[pousr]_[A-Za-z0-9]{36,}\b/,
71
+ },
72
+ {
73
+ nombre: 'GitLab Personal Access Token (glpat-*)',
74
+ patron: /\bglpat-[A-Za-z0-9\-_]{20,}\b/,
75
+ },
76
+ {
77
+ nombre: 'Clave privada PEM (RSA / EC / OpenSSH)',
78
+ // -----BEGIN RSA PRIVATE KEY----- o -----BEGIN OPENSSH PRIVATE KEY-----
79
+ patron: /-----BEGIN (?:RSA |EC |DSA |OPENSSH |)PRIVATE KEY-----/,
80
+ },
81
+ {
82
+ nombre: 'Password hardcodeado en variable',
83
+ // password = "valor", passwd='valor', pwd="valor" (no vacío, no placeholder)
84
+ // Se ignoran valores que claramente son placeholders: "xxx", "your_", "<", "ENV", os.environ
85
+ patron: /(?:password|passwd|pwd|secret|secret_key|api_secret)\s*[:=]\s*["'](?!(?:your_|<|xxx|ENV|os\.environ|\$\{|%\w+%))[^"'\s]{6,}["']/i,
86
+ },
87
+ {
88
+ nombre: 'Token JWT (tres segmentos base64url)',
89
+ // eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c3IifQ.xxxx
90
+ // Solo se marca si el header decodifica como JSON con "alg" (heurística fuerte)
91
+ patron: /\beyJ[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+\b/,
92
+ },
93
+ {
94
+ nombre: 'Connection string con credenciales (usuario:contraseña@host)',
95
+ // postgresql://user:pass@host, mysql://user:pass@host, mongodb://user:pass@host
96
+ patron: /(?:postgresql|mysql|mongodb|redis|amqp|mssql|jdbc):\/\/[^:@\s]+:[^@\s]+@[^\s"']+/i,
97
+ },
98
+ {
99
+ nombre: 'Stripe Secret Key (sk_live_* / sk_test_*)',
100
+ patron: /\bsk_(?:live|test)_[A-Za-z0-9]{24,}\b/,
101
+ },
102
+ {
103
+ nombre: 'Slack Bot / App Token (xoxb-* / xoxa-* / xoxe-*)',
104
+ patron: /\bxox[bpae]-[A-Za-z0-9\-]{20,}\b/,
105
+ },
106
+ {
107
+ nombre: 'Twilio Account SID / Auth Token',
108
+ // AC seguido de 32 hex chars
109
+ patron: /\bAC[0-9a-fA-F]{32}\b/,
110
+ },
111
+ {
112
+ nombre: 'Google API Key (AIzaSy*)',
113
+ patron: /\bAIzaSy[A-Za-z0-9\-_]{33}\b/,
114
+ },
115
+ {
116
+ nombre: 'Secreto en variable de entorno hardcodeado',
117
+ // SECRET_KEY="valor_largo_no_placeholder" fuera de archivos .env.example
118
+ patron: /(?:SECRET_KEY|AUTH_TOKEN|ACCESS_TOKEN|PRIVATE_KEY|CLIENT_SECRET)\s*=\s*["'][^"'\s]{10,}["']/,
119
+ },
120
+ ];
121
+
122
+ // ---------------------------------------------------------------------------
123
+ // Mapping de patrones a códigos de issue estandarizados
124
+ // ---------------------------------------------------------------------------
125
+
126
+ /**
127
+ * Relaciona el nombre de cada patrón de secreto con su código de issue
128
+ * correspondiente en la taxonomía agent-scan (agent-issue-codes.js).
129
+ *
130
+ * Reglas de mapeo:
131
+ * - Secreto hardcodeado (API key, token, password) → W008
132
+ * - Manejo inseguro de credenciales (connection string con user:pass) → W007
133
+ * - Token con permisos amplios (sin contexto de acotamiento) → W009 si financiero, W008 en general
134
+ *
135
+ * @type {Object.<string, string>}
136
+ */
137
+ const PATRON_A_CODIGO_ISSUE = {
138
+ 'Anthropic API Key (sk-ant-*)': 'W008',
139
+ 'OpenAI API Key (sk-proj-* / sk-live-* / sk-test-* / sk-[a-z0-9]{48})': 'W008',
140
+ 'AWS Access Key ID (AKIA* / ASIA*)': 'W008',
141
+ 'GitHub Personal Access Token (ghp_* / gho_* / ghu_* / ghs_* / ghr_*)': 'W008',
142
+ 'GitLab Personal Access Token (glpat-*)': 'W008',
143
+ 'Clave privada PEM (RSA / EC / OpenSSH)': 'W008',
144
+ 'Password hardcodeado en variable': 'W007',
145
+ 'Token JWT (tres segmentos base64url)': 'W007',
146
+ 'Connection string con credenciales (usuario:contraseña@host)': 'W007',
147
+ 'Stripe Secret Key (sk_live_* / sk_test_*)': 'W008',
148
+ 'Slack Bot / App Token (xoxb-* / xoxa-* / xoxe-*)': 'W008',
149
+ 'Twilio Account SID / Auth Token': 'W008',
150
+ 'Google API Key (AIzaSy*)': 'W008',
151
+ 'Secreto en variable de entorno hardcodeado': 'W008',
152
+ };
153
+
154
+ /**
155
+ * Obtiene el código de issue para un patrón detectado.
156
+ * Retorna el objeto completo si el módulo agent-issue-codes está disponible,
157
+ * o solo el código como string si no lo está.
158
+ *
159
+ * @param {string} nombrePatron - Nombre del patrón detectado.
160
+ * @returns {{ codigo: string, severidad: string }|null}
161
+ */
162
+ function obtenerIssueDePatron(nombrePatron) {
163
+ const codigo = PATRON_A_CODIGO_ISSUE[nombrePatron];
164
+ if (!codigo) return null;
165
+
166
+ if (issueCodes) {
167
+ const issue = issueCodes.obtenerCodigo(codigo);
168
+ if (issue) return { codigo: issue.codigo, severidad: issue.severidad };
169
+ }
170
+
171
+ // Fallback si el módulo no está cargado: inferir severidad del prefijo
172
+ const severidad = codigo.startsWith('E') ? 'error' : 'warning';
173
+ return { codigo, severidad };
174
+ }
175
+
176
+ // ---------------------------------------------------------------------------
177
+ // Lógica de exclusión (falsos positivos comunes)
178
+ // ---------------------------------------------------------------------------
179
+
180
+ /**
181
+ * Patrones que indican que el contenido es un archivo de ejemplo, test o
182
+ * documentación donde los secretos son ficticios.
183
+ * Si el file_path o el contenido coincide con alguno, se omite el bloqueo.
184
+ */
185
+ const PATRONES_EXCLUSION_RUTA = [
186
+ /\.example$/i,
187
+ /\.sample$/i,
188
+ /\.test\.[jt]s$/i,
189
+ /\.spec\.[jt]s$/i,
190
+ /test[s]?[/\\]/i,
191
+ /__tests__[/\\]/i,
192
+ /fixtures?[/\\]/i,
193
+ /mocks?[/\\]/i,
194
+ /README/i,
195
+ /CHANGELOG/i,
196
+ /\.md$/i,
197
+ ];
198
+
199
+ /**
200
+ * Cadenas que indican un valor ficticio o placeholder dentro del contenido.
201
+ * Si la línea que contiene el patrón también contiene alguna de estas cadenas,
202
+ * se considera falso positivo.
203
+ */
204
+ const MARCADORES_PLACEHOLDER = [
205
+ 'YOUR_',
206
+ 'your_',
207
+ '<YOUR',
208
+ 'PLACEHOLDER',
209
+ 'placeholder',
210
+ 'example.com',
211
+ 'example_',
212
+ 'fake_',
213
+ 'dummy_',
214
+ 'test_token',
215
+ 'test_key',
216
+ 'xxxxxxxx',
217
+ '# noqa',
218
+ '// nosec',
219
+ 'pragma: allowlist secret',
220
+ ];
221
+
222
+ // ---------------------------------------------------------------------------
223
+ // Funciones auxiliares
224
+ // ---------------------------------------------------------------------------
225
+
226
+ /**
227
+ * Verifica si la ruta del archivo indica que el contenido es un ejemplo/test.
228
+ * @param {string} filePath
229
+ * @returns {boolean}
230
+ */
231
+ function esArchivoExcluido(filePath) {
232
+ return PATRONES_EXCLUSION_RUTA.some(p => p.test(filePath));
233
+ }
234
+
235
+ /**
236
+ * Verifica si la línea que contiene el match parece ser un placeholder.
237
+ * @param {string} linea
238
+ * @returns {boolean}
239
+ */
240
+ function esPlaceholder(linea) {
241
+ return MARCADORES_PLACEHOLDER.some(m => linea.includes(m));
242
+ }
243
+
244
+ /**
245
+ * Extrae el contenido textual a escanear desde el payload del hook.
246
+ * Para Write: campo "content".
247
+ * Para Edit: campos "new_string" y "content".
248
+ *
249
+ * @param {string} toolName - Nombre de la herramienta ("Write" | "Edit").
250
+ * @param {object} toolInput - Parámetros de la herramienta.
251
+ * @returns {string} Contenido concatenado a escanear.
252
+ */
253
+ function extraerContenido(toolName, toolInput) {
254
+ const partes = [];
255
+
256
+ if (toolName === 'Write') {
257
+ if (typeof toolInput.content === 'string') partes.push(toolInput.content);
258
+ } else if (toolName === 'Edit') {
259
+ // Solo escanear lo que se está insertando, no el texto que se reemplaza
260
+ if (typeof toolInput.new_string === 'string') partes.push(toolInput.new_string);
261
+ // Algunos editores pasan "content" como campo alternativo
262
+ if (typeof toolInput.content === 'string') partes.push(toolInput.content);
263
+ }
264
+
265
+ return partes.join('\n');
266
+ }
267
+
268
+ /**
269
+ * Escanea el contenido contra todos los patrones de secretos.
270
+ * Retorna la primera coincidencia encontrada, o null si el contenido es seguro.
271
+ *
272
+ * @param {string} contenido
273
+ * @param {string} filePath - Ruta del archivo destino (para contexto en mensajes).
274
+ * @returns {{ nombrePatron: string, linea: string, numeroLinea: number }|null}
275
+ */
276
+ function escanear(contenido, filePath) {
277
+ if (!contenido) return null;
278
+
279
+ // Normalizar para prevenir bypass con fullwidth, ANSI escapes o null bytes
280
+ const contenidoNorm = normalizeForDetection(contenido);
281
+ const lineas = contenidoNorm.split('\n');
282
+
283
+ for (let i = 0; i < lineas.length; i++) {
284
+ const linea = lineas[i];
285
+
286
+ // Saltar líneas comentadas con marcadores de exclusión explícitos
287
+ if (esPlaceholder(linea)) continue;
288
+
289
+ for (const { nombre, patron } of PATRONES_SECRETOS) {
290
+ if (patron.test(linea)) {
291
+ const issueInfo = obtenerIssueDePatron(nombre);
292
+ return {
293
+ nombrePatron: nombre,
294
+ // Ofuscar el valor real en el mensaje de error para no exponerlo en logs
295
+ linea: linea.replace(patron, (match) => {
296
+ const visible = match.slice(0, 8);
297
+ return `${visible}${'*'.repeat(Math.max(0, match.length - 8))}`;
298
+ }),
299
+ numeroLinea: i + 1,
300
+ filePath,
301
+ // Campos enriquecidos con la taxonomía estandarizada (nuevos — no rompen contrato)
302
+ codigo_issue: issueInfo ? issueInfo.codigo : null,
303
+ severidad: issueInfo ? issueInfo.severidad : 'warning',
304
+ };
305
+ }
306
+ }
307
+ }
308
+
309
+ return null;
310
+ }
311
+
312
+ // ---------------------------------------------------------------------------
313
+ // Entrypoint principal
314
+ // ---------------------------------------------------------------------------
315
+
316
+ let inputRaw = '';
317
+
318
+ process.stdin.on('data', chunk => {
319
+ inputRaw += chunk;
320
+ });
321
+
322
+ process.stdin.on('end', () => {
323
+ try {
324
+ const data = JSON.parse(inputRaw);
325
+
326
+ const toolName = String(data.tool_name || data.tool?.name || '');
327
+ const toolInput = data.tool_input || data.tool?.input || {};
328
+ const filePath = String(toolInput.file_path || toolInput.path || '');
329
+ const sessionId = String(data.session_id || 'default');
330
+
331
+ // Este hook solo aplica a Write y Edit
332
+ if (!['Write', 'Edit'].includes(toolName)) {
333
+ return;
334
+ }
335
+
336
+ // Si la ruta indica archivo de ejemplo/test, saltar escaneo
337
+ if (filePath && esArchivoExcluido(filePath)) {
338
+ return;
339
+ }
340
+
341
+ // Extraer y escanear el contenido
342
+ const contenido = extraerContenido(toolName, toolInput);
343
+ const coincidencia = escanear(contenido, filePath);
344
+
345
+ // Registrar activación en métricas de guardrail (siempre que se analice el contenido)
346
+ try {
347
+ const { recordActivation } = require('./lib/guardrail-metrics');
348
+ if (coincidencia) {
349
+ recordActivation('escaneo-secretos.js', sessionId, true); // bloqueó
350
+ } else {
351
+ recordActivation('escaneo-secretos.js', sessionId, false); // pasó
352
+ }
353
+ } catch (_) { /* métricas opcionales — nunca bloquear */ }
354
+
355
+ if (coincidencia) {
356
+ // BLOQUEAR: exit code 2 = block en Claude Code hooks API
357
+ // Incluir código de issue estandarizado si está disponible
358
+ const lineaIssue = coincidencia.codigo_issue
359
+ ? `Código: ${coincidencia.codigo_issue} [${coincidencia.severidad}]`
360
+ : null;
361
+
362
+ const razon = [
363
+ `Secreto detectado antes de escribir en disco.`,
364
+ ``,
365
+ `Tipo: ${coincidencia.nombrePatron}`,
366
+ lineaIssue,
367
+ `Archivo: ${coincidencia.filePath || '(desconocido)'}`,
368
+ `Línea: ${coincidencia.numeroLinea}`,
369
+ `Contexto: ${coincidencia.linea.trim().slice(0, 120)}`,
370
+ ``,
371
+ `Acciones recomendadas:`,
372
+ ` 1. Mover el secreto a una variable de entorno (.env, no commiteado).`,
373
+ ` 2. Usar un gestor de secretos (Vault, AWS Secrets Manager, etc.).`,
374
+ ` 3. Si es un valor ficticio, agregar un marcador como YOUR_TOKEN,`,
375
+ ` o una línea: # pragma: allowlist secret`,
376
+ ].filter(l => l !== null).join('\n');
377
+
378
+ process.stderr.write(razon);
379
+ process.exit(2);
380
+ }
381
+
382
+ // Sin secretos detectados — permitir la escritura
383
+
384
+ } catch (err) {
385
+ // El hook nunca bloquea por errores internos propios
386
+ const errNorm = normalizar(err, { fuente: 'escaneo-secretos' });
387
+ process.stderr.write(`[escaneo-secretos] ${formatear(errNorm)}\n`);
388
+ }
389
+ });