@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,763 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Hook: extraccion-aprendizajes.js
6
+ * Tipo: PostToolUse (aplica a: Bash, Write, Edit — al finalizar acciones del agente)
7
+ *
8
+ * Lee el output de herramientas del agente buscando patrones que indiquen
9
+ * un aprendizaje significativo: errores resueltos, bugs encontrados, decisiones
10
+ * arquitectónicas, descubrimientos de comportamiento inesperado.
11
+ *
12
+ * Si detecta un aprendizaje potencial:
13
+ * 1. Clasifica el tipo: anti-patrón | patrón | gotcha | decisión | bug-fix
14
+ * 2. Extrae el contexto (±3 líneas alrededor del keyword)
15
+ * 3. Verifica que no sea un duplicado de aprendizajes ya registrados
16
+ * 4. Escribe la entrada en .planning/APRENDIZAJES.md
17
+ *
18
+ * El hook nunca bloquea (siempre exit 0).
19
+ * Los errores internos se reportan en stderr y se ignoran silenciosamente.
20
+ *
21
+ * Formato de entrada en APRENDIZAJES.md:
22
+ * ─────────────────────────────────────────────────────────
23
+ * ## [YYYY-MM-DD] tipo — descripción corta
24
+ * **Agente**: nombre-del-agente
25
+ * **Contexto**: extracto del output que originó el aprendizaje
26
+ * ─────────────────────────────────────────────────────────
27
+ */
28
+
29
+ const fs = require('fs');
30
+ const path = require('path');
31
+ const os = require('os');
32
+
33
+ const { atomicWriteSync } = require('./lib/atomic-write');
34
+
35
+ // ---------------------------------------------------------------------------
36
+ // Constantes de configuración
37
+ // ---------------------------------------------------------------------------
38
+
39
+ /**
40
+ * Ruta del archivo donde se acumulan los aprendizajes.
41
+ * Se resuelve relativa al CWD del proceso (raíz del proyecto).
42
+ */
43
+ const RUTA_APRENDIZAJES = path.join(process.cwd(), '.planning', 'APRENDIZAJES.md');
44
+
45
+ /**
46
+ * Número de líneas de contexto a extraer alrededor del keyword detectado.
47
+ * El extracto será de hasta (LINEAS_CONTEXTO * 2 + 1) líneas.
48
+ */
49
+ const LINEAS_CONTEXTO = 3;
50
+
51
+ /**
52
+ * Longitud máxima del extracto de contexto a guardar (en caracteres).
53
+ * Evita que contextos muy largos inflen el archivo de aprendizajes.
54
+ */
55
+ const MAX_CHARS_CONTEXTO = 500;
56
+
57
+ /**
58
+ * Longitud mínima de la descripción extraída para considerarla significativa.
59
+ * Extractos muy cortos (< N chars) se descartan como ruido.
60
+ */
61
+ const MIN_CHARS_DESCRIPCION = 40;
62
+
63
+ /**
64
+ * Umbral de similitud para deduplicación (Jaccard sobre bigramas de palabras).
65
+ * Valores entre 0 y 1. Un aprendizaje con similitud >= este umbral se considera
66
+ * duplicado y no se escribe.
67
+ */
68
+ const UMBRAL_SIMILITUD = 0.75;
69
+
70
+ // ---------------------------------------------------------------------------
71
+ // Keywords y clasificación de aprendizajes
72
+ // ---------------------------------------------------------------------------
73
+
74
+ /**
75
+ * Keywords que indican un aprendizaje potencial.
76
+ * Cada entrada define:
77
+ * - keywords: términos a buscar (case-insensitive) en el output
78
+ * - tipo: categoría del aprendizaje
79
+ * - peso: prioridad al elegir entre múltiples matches en la misma línea
80
+ */
81
+ const REGLAS_CLASIFICACION = [
82
+ {
83
+ keywords: ['anti-patrón', 'antipatron', 'anti patrón', 'nunca hacer', 'never do', 'bad practice'],
84
+ tipo: 'anti-patrón',
85
+ peso: 5,
86
+ },
87
+ {
88
+ keywords: ['bug fix', 'bugfix', 'corrección', 'corregido', 'fixed', 'se corrigió', 'arreglado'],
89
+ tipo: 'bug-fix',
90
+ peso: 5,
91
+ },
92
+ {
93
+ keywords: ['gotcha', 'trampa', 'cuidado con', 'ojo con', 'footgun', 'pitfall'],
94
+ tipo: 'gotcha',
95
+ peso: 4,
96
+ },
97
+ {
98
+ keywords: ['decisión', 'decision', 'decidimos', 'elegimos', 'optamos por', 'trade-off', 'tradeoff'],
99
+ tipo: 'decisión',
100
+ peso: 3,
101
+ },
102
+ {
103
+ keywords: ['patrón', 'patron', 'best practice', 'buena práctica', 'recomendado', 'siempre usar'],
104
+ tipo: 'patrón',
105
+ peso: 3,
106
+ },
107
+ {
108
+ keywords: ['descubrimiento', 'discovery', 'encontramos', 'hallazgo', 'aprendizaje', 'lección'],
109
+ tipo: 'descubrimiento',
110
+ peso: 2,
111
+ },
112
+ {
113
+ keywords: ['error', 'fallo', 'failure', 'exception', 'traceback'],
114
+ tipo: 'bug-fix',
115
+ peso: 1,
116
+ },
117
+ {
118
+ keywords: ['bug', 'issue', 'problema resuelto'],
119
+ tipo: 'bug-fix',
120
+ peso: 1,
121
+ },
122
+ {
123
+ keywords: ['fix', 'solucion', 'solución', 'resuelto', 'resolved'],
124
+ tipo: 'bug-fix',
125
+ peso: 1,
126
+ },
127
+ ];
128
+
129
+ // ---------------------------------------------------------------------------
130
+ // Utilidades de texto
131
+ // ---------------------------------------------------------------------------
132
+
133
+ /**
134
+ * Trunca un texto respetando bordes naturales: prefiere cortar al final de
135
+ * una oración (`. ! ?`) y si no hay, al final de una palabra (último espacio).
136
+ * Jamás corta a mitad de palabra ni en medio de un caracter multibyte.
137
+ *
138
+ * @param {string} texto
139
+ * @param {number} maxChars Límite duro superior.
140
+ * @param {object} [opts]
141
+ * @param {number} [opts.minRatio=0.6] Proporción mínima de maxChars que debe
142
+ * alcanzar el punto de corte. Si un corte
143
+ * de oración caería antes de este ratio,
144
+ * preferimos cortar en espacio.
145
+ * @returns {string} Texto truncado con '…' si se acortó.
146
+ */
147
+ function truncarElegante(texto, maxChars, opts = {}) {
148
+ const s = String(texto || '');
149
+ if (s.length <= maxChars) return s;
150
+
151
+ const minRatio = typeof opts.minRatio === 'number' ? opts.minRatio : 0.6;
152
+ const minCorte = Math.floor(maxChars * minRatio);
153
+ const ventana = s.slice(0, maxChars);
154
+
155
+ // 1. Intentar corte en fin de oración (`. ! ?` seguido de espacio o fin)
156
+ const reOracion = /[.!?](?=\s|$)/g;
157
+ let ultimaOracion = -1;
158
+ let m;
159
+ while ((m = reOracion.exec(ventana)) !== null) {
160
+ ultimaOracion = m.index + 1; // incluir el signo de puntuación
161
+ }
162
+ if (ultimaOracion >= minCorte) {
163
+ return s.slice(0, ultimaOracion).trimEnd() + ' …';
164
+ }
165
+
166
+ // 2. Intentar corte en `,` o `;` seguido de espacio
167
+ const reClausula = /[,;:](?=\s)/g;
168
+ let ultimaClausula = -1;
169
+ while ((m = reClausula.exec(ventana)) !== null) {
170
+ ultimaClausula = m.index + 1;
171
+ }
172
+ if (ultimaClausula >= minCorte) {
173
+ return s.slice(0, ultimaClausula).trimEnd() + ' …';
174
+ }
175
+
176
+ // 3. Último recurso: último espacio antes del límite
177
+ const ultimoEspacio = ventana.lastIndexOf(' ');
178
+ if (ultimoEspacio >= minCorte) {
179
+ return s.slice(0, ultimoEspacio).trimEnd() + ' …';
180
+ }
181
+
182
+ // 4. Si la "palabra" es enorme (URL, ruta), cortar duro pero no en
183
+ // medio de un code-point (trimEnd no ayuda con surrogates; usar Array.from).
184
+ const chars = Array.from(ventana);
185
+ return chars.slice(0, maxChars).join('').trimEnd() + ' …';
186
+ }
187
+
188
+ /**
189
+ * Construye el conjunto de bigramas de palabras de un texto.
190
+ * Usado para la deduplicación por similitud Jaccard.
191
+ *
192
+ * @param {string} texto
193
+ * @returns {Set<string>}
194
+ */
195
+ function bigramasTexto(texto) {
196
+ const palabras = texto
197
+ .toLowerCase()
198
+ .replace(/[^\w\s]/g, ' ')
199
+ .split(/\s+/)
200
+ .filter(p => p.length > 2); // Ignorar palabras muy cortas
201
+
202
+ const bigramas = new Set();
203
+ for (let i = 0; i < palabras.length - 1; i++) {
204
+ bigramas.add(`${palabras[i]}|${palabras[i + 1]}`);
205
+ }
206
+ return bigramas;
207
+ }
208
+
209
+ /**
210
+ * Calcula la similitud de Jaccard entre dos conjuntos.
211
+ *
212
+ * @param {Set<string>} a
213
+ * @param {Set<string>} b
214
+ * @returns {number} Valor entre 0 (sin similitud) y 1 (idénticos).
215
+ */
216
+ function similitudJaccard(a, b) {
217
+ if (a.size === 0 && b.size === 0) return 1;
218
+ if (a.size === 0 || b.size === 0) return 0;
219
+
220
+ let interseccion = 0;
221
+ for (const elem of a) {
222
+ if (b.has(elem)) interseccion++;
223
+ }
224
+ const union = a.size + b.size - interseccion;
225
+ return interseccion / union;
226
+ }
227
+
228
+ /**
229
+ * Extrae un identificador hash simple de un texto para comparación rápida
230
+ * antes de calcular Jaccard completo (optimización).
231
+ *
232
+ * @param {string} texto
233
+ * @returns {string}
234
+ */
235
+ function hashTexto(texto) {
236
+ let hash = 0;
237
+ for (let i = 0; i < texto.length; i++) {
238
+ hash = ((hash << 5) - hash + texto.charCodeAt(i)) | 0;
239
+ }
240
+ return String(hash >>> 0);
241
+ }
242
+
243
+ // ---------------------------------------------------------------------------
244
+ // Normalización de fechas relativas (patrón autoDream)
245
+ // ---------------------------------------------------------------------------
246
+
247
+ /**
248
+ * Mapa de expresiones relativas en español a funciones de cálculo.
249
+ * Convierte "ayer", "hace 2 días", etc. a fechas absolutas YYYY-MM-DD.
250
+ */
251
+ const PATRONES_FECHA_RELATIVA = [
252
+ { regex: /\bhoy\b/gi, calc: () => 0 },
253
+ { regex: /\bayer\b/gi, calc: () => -1 },
254
+ { regex: /\banteayer\b/gi, calc: () => -2 },
255
+ { regex: /\bhace\s+(\d+)\s+días?\b/gi, calc: (m) => -parseInt(m[1], 10) },
256
+ { regex: /\bhace\s+(\d+)\s+semanas?\b/gi, calc: (m) => -parseInt(m[1], 10) * 7 },
257
+ { regex: /\bla\s+semana\s+pasada\b/gi, calc: () => -7 },
258
+ { regex: /\bhace\s+(\d+)\s+meses?\b/gi, calc: (m) => -parseInt(m[1], 10) * 30 },
259
+ { regex: /\bel\s+mes\s+pasado\b/gi, calc: () => -30 },
260
+ ];
261
+
262
+ /**
263
+ * Reemplaza fechas relativas en un texto por fechas absolutas YYYY-MM-DD.
264
+ * Preserva el texto original si no hay coincidencias.
265
+ *
266
+ * @param {string} texto - Texto con posibles fechas relativas.
267
+ * @param {Date} [ahora] - Fecha de referencia (default: Date.now()).
268
+ * @returns {string} Texto con fechas absolutas.
269
+ */
270
+ function normalizarFechas(texto, ahora = new Date()) {
271
+ let resultado = texto;
272
+
273
+ for (const { regex, calc } of PATRONES_FECHA_RELATIVA) {
274
+ resultado = resultado.replace(regex, (...args) => {
275
+ const diasOffset = calc(args);
276
+ const fecha = new Date(ahora);
277
+ fecha.setDate(fecha.getDate() + diasOffset);
278
+ return fecha.toISOString().slice(0, 10); // YYYY-MM-DD
279
+ });
280
+ }
281
+
282
+ return resultado;
283
+ }
284
+
285
+ // ---------------------------------------------------------------------------
286
+ // Extracción del texto a analizar
287
+ // ---------------------------------------------------------------------------
288
+
289
+ /**
290
+ * Extrae el texto relevante del payload del hook para analizar en busca
291
+ * de aprendizajes. Soporta múltiples estructuras que Claude Code puede enviar.
292
+ *
293
+ * @param {object} data - Payload JSON del hook.
294
+ * @returns {{ texto: string, agente: string }}
295
+ */
296
+ function extraerTextoYAgente(data) {
297
+ const toolName = String(data.tool_name || data.tool?.name || '');
298
+ const toolResult = data.tool_result || data.tool?.result || {};
299
+ const toolInput = data.tool_input || data.tool?.input || {};
300
+
301
+ // Nombre del agente: preferir session_id o model; fallback a tool_name
302
+ const agente = String(
303
+ data.agent_name ||
304
+ data.session_id ||
305
+ data.model ||
306
+ toolName ||
307
+ 'agente-desconocido'
308
+ ).slice(0, 60);
309
+
310
+ // Recolectar fragmentos de texto del resultado de la herramienta
311
+ const fragmentos = [];
312
+
313
+ // Resultado puede ser string directo
314
+ if (typeof toolResult === 'string') {
315
+ fragmentos.push(toolResult);
316
+ }
317
+
318
+ // Resultado puede ser objeto con campo "output", "content", "stdout", etc.
319
+ if (toolResult && typeof toolResult === 'object') {
320
+ const camposResultado = ['output', 'content', 'stdout', 'text', 'result', 'message'];
321
+ for (const campo of camposResultado) {
322
+ if (typeof toolResult[campo] === 'string') {
323
+ fragmentos.push(toolResult[campo]);
324
+ }
325
+ }
326
+ }
327
+
328
+ // Para herramientas Write/Edit, analizar el contenido que se escribió
329
+ if (['Write', 'Edit'].includes(toolName)) {
330
+ const contenido = toolInput.content || toolInput.new_string || '';
331
+ if (typeof contenido === 'string' && contenido.length > 0) {
332
+ // Solo analizar comentarios y docstrings del código, no el código mismo
333
+ const lineasComentario = contenido
334
+ .split('\n')
335
+ .filter(l => /^\s*(#|\/\/|\/\*|\*|"""|''')/.test(l))
336
+ .join('\n');
337
+ if (lineasComentario) fragmentos.push(lineasComentario);
338
+ }
339
+ }
340
+
341
+ // Leer también de stdin si hay datos adicionales (modo pipe directo)
342
+ const texto = fragmentos.join('\n\n').slice(0, 50_000); // Límite de 50KB para análisis
343
+
344
+ return { texto, agente };
345
+ }
346
+
347
+ // ---------------------------------------------------------------------------
348
+ // Detección y clasificación de aprendizajes
349
+ // ---------------------------------------------------------------------------
350
+
351
+ /**
352
+ * Resultado de analizar el texto en busca de aprendizajes.
353
+ * @typedef {{ tipo: string, contexto: string, descripcion: string }} Aprendizaje
354
+ */
355
+
356
+ /**
357
+ * Analiza el texto del output del agente buscando aprendizajes significativos.
358
+ * Retorna el aprendizaje más relevante encontrado, o null si no hay ninguno.
359
+ *
360
+ * Estrategia:
361
+ * 1. Buscar keywords de mayor peso primero.
362
+ * 2. Para cada match, extraer contexto de ±LINEAS_CONTEXTO líneas.
363
+ * 3. Verificar longitud mínima del contexto.
364
+ * 4. Clasificar por el tipo de keyword que disparó la detección.
365
+ *
366
+ * @param {string} texto
367
+ * @returns {Aprendizaje|null}
368
+ */
369
+ function detectarAprendizaje(texto) {
370
+ if (!texto || texto.trim().length < MIN_CHARS_DESCRIPCION) return null;
371
+
372
+ const lineas = texto.split('\n');
373
+
374
+ // Ordenar reglas de mayor a menor peso para priorizar los más significativos
375
+ const reglasPorPeso = [...REGLAS_CLASIFICACION].sort((a, b) => b.peso - a.peso);
376
+
377
+ for (const { keywords, tipo } of reglasPorPeso) {
378
+ for (const keyword of keywords) {
379
+ const patronKeyword = new RegExp(keyword, 'i');
380
+
381
+ for (let i = 0; i < lineas.length; i++) {
382
+ if (!patronKeyword.test(lineas[i])) continue;
383
+
384
+ // Extraer contexto alrededor de la línea con el keyword
385
+ const inicio = Math.max(0, i - LINEAS_CONTEXTO);
386
+ const fin = Math.min(lineas.length, i + LINEAS_CONTEXTO + 1);
387
+ const contexto = lineas.slice(inicio, fin).join('\n').trim();
388
+
389
+ // Verificar longitud mínima significativa
390
+ if (contexto.length < MIN_CHARS_DESCRIPCION) continue;
391
+
392
+ // Truncar el contexto respetando bordes de oración/palabra
393
+ const contextoFinal = truncarElegante(contexto, MAX_CHARS_CONTEXTO);
394
+
395
+ // Descripción: la línea del keyword, limpiada de símbolos de código.
396
+ // Preferir cortar al final de la primera oración si cabe en 120 chars;
397
+ // si no, al último espacio antes del límite.
398
+ const lineaLimpia = lineas[i]
399
+ .trim()
400
+ .replace(/^[#*\/\-–•]+\s*/, '') // Quitar prefijos de comentario/lista
401
+ .replace(/\*\*/g, '') // Quitar marcadores de negrita Markdown
402
+ .replace(/`+/g, ''); // Quitar backticks
403
+
404
+ // Si la línea tiene un punto temprano, usarlo como fin natural
405
+ const matchOracion = lineaLimpia.match(/^[^.!?]*[.!?]/);
406
+ const descripcionBase = matchOracion
407
+ ? matchOracion[0].trim()
408
+ : lineaLimpia;
409
+
410
+ const descripcion = truncarElegante(descripcionBase, 120, { minRatio: 0.4 });
411
+
412
+ if (descripcion.length < 10) continue;
413
+
414
+ return { tipo, contexto: contextoFinal, descripcion };
415
+ }
416
+ }
417
+ }
418
+
419
+ return null;
420
+ }
421
+
422
+ // ---------------------------------------------------------------------------
423
+ // Gestión del archivo APRENDIZAJES.md
424
+ // ---------------------------------------------------------------------------
425
+
426
+ /**
427
+ * Lee las entradas existentes en APRENDIZAJES.md.
428
+ * Retorna el contenido completo y una lista de descripciones para deduplicar.
429
+ *
430
+ * @returns {{ contenidoExistente: string, descripciones: string[] }}
431
+ */
432
+ function leerAprendizajesExistentes() {
433
+ try {
434
+ const contenido = fs.readFileSync(RUTA_APRENDIZAJES, 'utf8');
435
+ // Extraer las líneas de descripción corta (las que empiezan con "##")
436
+ const descripciones = contenido
437
+ .split('\n')
438
+ .filter(l => l.startsWith('## '))
439
+ .map(l => l.replace(/^##\s+\[\d{4}-\d{2}-\d{2}\]\s+\w+[-\w]*\s+—\s+/, '').trim());
440
+
441
+ return { contenidoExistente: contenido, descripciones };
442
+ } catch (_) {
443
+ // El archivo no existe aún — primera ejecución
444
+ return { contenidoExistente: '', descripciones: [] };
445
+ }
446
+ }
447
+
448
+ /**
449
+ * Verifica si un aprendizaje candidato ya existe en el archivo,
450
+ * usando similitud de Jaccard sobre bigramas para detectar duplicados
451
+ * semánticamente similares aunque no idénticos.
452
+ *
453
+ * @param {string} descripcion - Descripción del aprendizaje candidato.
454
+ * @param {string[]} descripciones - Descripciones existentes en el archivo.
455
+ * @returns {boolean} true si el aprendizaje ya existe (o es muy similar).
456
+ */
457
+ function esDuplicado(descripcion, descripciones) {
458
+ if (descripciones.length === 0) return false;
459
+
460
+ const bigramasNuevo = bigramasTexto(descripcion);
461
+
462
+ for (const desc of descripciones) {
463
+ const bigramasExistente = bigramasTexto(desc);
464
+ const similitud = similitudJaccard(bigramasNuevo, bigramasExistente);
465
+ if (similitud >= UMBRAL_SIMILITUD) return true;
466
+ }
467
+
468
+ return false;
469
+ }
470
+
471
+ /**
472
+ * Asegura que el directorio padre de RUTA_APRENDIZAJES existe.
473
+ * Crea el directorio .planning/ si no existe.
474
+ */
475
+ function asegurarDirectorio() {
476
+ const dir = path.dirname(RUTA_APRENDIZAJES);
477
+ if (!fs.existsSync(dir)) {
478
+ fs.mkdirSync(dir, { recursive: true });
479
+ }
480
+ }
481
+
482
+ /**
483
+ * Escribe el encabezado inicial del archivo APRENDIZAJES.md si está vacío.
484
+ *
485
+ * @param {string} contenidoExistente
486
+ * @returns {string} Contenido actualizado con encabezado.
487
+ */
488
+ function asegurarEncabezado(contenidoExistente) {
489
+ if (contenidoExistente.length > 0) return contenidoExistente;
490
+
491
+ return [
492
+ '# Aprendizajes del Sistema',
493
+ '',
494
+ 'Registro automático de aprendizajes extraídos por el hook `extraccion-aprendizajes.js`.',
495
+ 'Cada entrada describe un anti-patrón, patrón, gotcha, bug-fix o decisión detectada',
496
+ 'durante la ejecución de agentes en el proyecto.',
497
+ '',
498
+ '---',
499
+ '',
500
+ ].join('\n');
501
+ }
502
+
503
+ /**
504
+ * Formatea una entrada de aprendizaje para insertar en el archivo.
505
+ *
506
+ * @param {string} fecha - Fecha en formato YYYY-MM-DD.
507
+ * @param {string} tipo - Tipo del aprendizaje.
508
+ * @param {string} descripcion - Descripción corta.
509
+ * @param {string} agente - Nombre/ID del agente que generó el aprendizaje.
510
+ * @param {string} contexto - Extracto del output del agente.
511
+ * @returns {string}
512
+ */
513
+ function formatearEntrada(fecha, tipo, descripcion, agente, contexto) {
514
+ // Indentar el contexto para que se muestre como blockquote en Markdown
515
+ const contextoIndentado = contexto
516
+ .split('\n')
517
+ .map(l => `> ${l}`)
518
+ .join('\n');
519
+
520
+ // Markdown válido requiere líneas en blanco antes de ## y antes/después de ---
521
+ return [
522
+ '',
523
+ `## [${fecha}] ${tipo} — ${descripcion}`,
524
+ '',
525
+ `**Agente**: \`${agente}\``,
526
+ '',
527
+ `**Contexto**:`,
528
+ '',
529
+ contextoIndentado,
530
+ '',
531
+ '---',
532
+ '',
533
+ ].join('\n');
534
+ }
535
+
536
+ /**
537
+ * Escribe un nuevo aprendizaje al final del archivo APRENDIZAJES.md.
538
+ *
539
+ * @param {Aprendizaje} aprendizaje
540
+ * @param {string} agente
541
+ */
542
+ function escribirAprendizaje(aprendizaje, agente) {
543
+ asegurarDirectorio();
544
+
545
+ const { contenidoExistente, descripciones } = leerAprendizajesExistentes();
546
+
547
+ // Verificar duplicado antes de escribir
548
+ if (esDuplicado(aprendizaje.descripcion, descripciones)) {
549
+ // Aprendizaje duplicado — omitido silenciosamente
550
+ return;
551
+ }
552
+
553
+ const fecha = new Date().toISOString().slice(0, 10); // YYYY-MM-DD
554
+ const contenidoBase = asegurarEncabezado(contenidoExistente);
555
+
556
+ // Normalizar fechas relativas a absolutas (patrón autoDream)
557
+ const descripcionNorm = normalizarFechas(aprendizaje.descripcion);
558
+ const contextoNorm = normalizarFechas(aprendizaje.contexto);
559
+
560
+ const entrada = formatearEntrada(
561
+ fecha,
562
+ aprendizaje.tipo,
563
+ descripcionNorm,
564
+ agente,
565
+ contextoNorm
566
+ );
567
+
568
+ atomicWriteSync(RUTA_APRENDIZAJES, contenidoBase + entrada);
569
+
570
+ // Aprendizaje registrado silenciosamente
571
+ }
572
+
573
+ // ---------------------------------------------------------------------------
574
+ // Filtros de señal vs. ruido
575
+ // ---------------------------------------------------------------------------
576
+
577
+ /**
578
+ * Determina si el evento del hook proviene de una herramienta cuyo output
579
+ * vale la pena analizar para extraer aprendizajes.
580
+ *
581
+ * Se excluyen herramientas puramente de lectura y de estado
582
+ * que generan mucho ruido sin información nueva.
583
+ *
584
+ * @param {string} toolName
585
+ * @returns {boolean}
586
+ */
587
+ function esHerramientaRelevante(toolName) {
588
+ const HERRAMIENTAS_EXCLUIDAS = new Set([
589
+ 'Read', // Lectura pura — sin aprendizajes del agente
590
+ 'Glob', // Listado de archivos
591
+ 'Grep', // Búsqueda — output técnico sin narrativa
592
+ ]);
593
+ return !HERRAMIENTAS_EXCLUIDAS.has(toolName);
594
+ }
595
+
596
+ /**
597
+ * Rutas de archivos SWL donde Write/Edit NO debe generar aprendizajes.
598
+ * Editar contenido de skills, reglas, APRENDIZAJES, ADRs, etc. es
599
+ * mantenimiento del sistema SWL, no descubrimiento en tiempo de ejecución.
600
+ * Capturar fragmentos de esos archivos produce ruido auto-referente.
601
+ */
602
+ const PATRONES_ARCHIVO_SWL_EXCLUIDO = [
603
+ /[\\/]habilidades[\\/]/,
604
+ /[\\/]agentes[\\/]/,
605
+ /[\\/]reglas[\\/]/,
606
+ /[\\/]comandos[\\/]swl[\\/]/,
607
+ /[\\/]hooks[\\/]/,
608
+ /[\\/]scripts[\\/]/,
609
+ /[\\/]schemas[\\/]/,
610
+ /[\\/]manifiestos[\\/]/,
611
+ /[\\/]plantillas[\\/]/,
612
+ /[\\/]contextos[\\/]/,
613
+ /[\\/]instintos[\\/]/,
614
+ // Todo .planning/ salvo wiki/ (que puede contener conocimiento del proyecto usuario).
615
+ // En swl-ses .planning/ es meta del sistema; los aprendizajes se gestionan manualmente.
616
+ /[\\/]\.planning[\\/](?!wiki[\\/])/,
617
+ /[\\/]CHANGELOG\.md$/i,
618
+ /[\\/]CLAUDE\.md$/i,
619
+ /[\\/]AGENTS\.md$/i,
620
+ /[\\/]README\.md$/i,
621
+ /[\\/]MANUAL_USO\.md$/i,
622
+ /[\\/]COMANDOS\.md$/i,
623
+ /[\\/]INSTALACION\.md$/i,
624
+ /[\\/]INVENTARIO\.md$/i,
625
+ /[\\/]SALUD\.md$/i,
626
+ /[\\/]package\.json$/,
627
+ /[\\/]plugin\.json$/,
628
+ /[\\/]package-lock\.json$/,
629
+ ];
630
+
631
+ /**
632
+ * Determina si el target de Write/Edit es un archivo del sistema SWL
633
+ * donde la edición es mantenimiento, no descubrimiento. Previene ruido
634
+ * auto-referente (capturar fragmentos de SKILL.md propios como "aprendizajes").
635
+ *
636
+ * @param {string} filePath
637
+ * @returns {boolean}
638
+ */
639
+ function esArchivoSwlExcluido(filePath) {
640
+ if (!filePath || typeof filePath !== 'string') return false;
641
+ return PATRONES_ARCHIVO_SWL_EXCLUIDO.some(rx => rx.test(filePath));
642
+ }
643
+
644
+ /**
645
+ * Detecta si un fragmento parece ser contenido estructurado de skill/regla
646
+ * (frontmatter YAML, encabezados ## NN, tablas markdown grandes) en vez de
647
+ * un aprendizaje narrativo genuino. Filtro final antes de persistir.
648
+ *
649
+ * @param {string} contexto
650
+ * @returns {boolean} true si el fragmento parece estructural (descartar)
651
+ */
652
+ function pareceContenidoEstructuralSwl(contexto) {
653
+ if (!contexto) return false;
654
+ const lineas = contexto.split('\n');
655
+
656
+ // Frontmatter YAML: ---\nname: ...\ndescription: ...\n---
657
+ if (lineas.some(l => /^---\s*$/.test(l)) && lineas.some(l => /^(name|description|version|evolved):/i.test(l))) {
658
+ return true;
659
+ }
660
+
661
+ // Tabla markdown dominante: más del 50% de líneas no vacías son filas de tabla
662
+ const noVacias = lineas.filter(l => l.trim().length > 0);
663
+ const filas = noVacias.filter(l => /^\|.*\|/.test(l));
664
+ if (noVacias.length > 0 && filas.length / noVacias.length > 0.5) {
665
+ return true;
666
+ }
667
+
668
+ // Enumeración de encabezados sin cuerpo sustantivo
669
+ // (3+ líneas tipo "## [fecha] tipo — descripción" juntas)
670
+ const encabezadosFecha = lineas.filter(l => /^##\s+\[\d{4}-\d{2}-\d{2}\]/.test(l));
671
+ if (encabezadosFecha.length >= 2) {
672
+ return true;
673
+ }
674
+
675
+ return false;
676
+ }
677
+
678
+ /**
679
+ * Determina si el texto tiene suficiente contenido narrativo para contener
680
+ * un aprendizaje significativo (vs. output técnico puro como stack traces
681
+ * o listados de archivos).
682
+ *
683
+ * Heurística: el ratio de palabras largas (>4 chars) sobre el total
684
+ * indica prosa vs. código/rutas.
685
+ *
686
+ * @param {string} texto
687
+ * @returns {boolean}
688
+ */
689
+ function tieneContenidoNarrativo(texto) {
690
+ if (texto.length < MIN_CHARS_DESCRIPCION) return false;
691
+
692
+ const palabras = texto.split(/\s+/).filter(p => p.length > 0);
693
+ const palabrasLargas = palabras.filter(p => p.length > 4);
694
+ const ratioNarrativo = palabras.length > 0 ? palabrasLargas.length / palabras.length : 0;
695
+
696
+ // Al menos 30% de palabras largas sugiere prosa con contenido semántico
697
+ return ratioNarrativo >= 0.30 && palabras.length >= 10;
698
+ }
699
+
700
+ // ---------------------------------------------------------------------------
701
+ // Entrypoint principal
702
+ // ---------------------------------------------------------------------------
703
+
704
+ let inputRaw = '';
705
+
706
+ process.stdin.on('data', chunk => {
707
+ inputRaw += chunk;
708
+ });
709
+
710
+ process.stdin.on('end', () => {
711
+ try {
712
+ const data = JSON.parse(inputRaw);
713
+
714
+ const toolName = String(data.tool_name || data.tool?.name || '');
715
+
716
+ // Filtrar herramientas que generan ruido sin aprendizajes
717
+ if (!esHerramientaRelevante(toolName)) {
718
+ return;
719
+ }
720
+
721
+ // Filtrar Write/Edit sobre archivos del sistema SWL (auto-referencia).
722
+ // Editar habilidades/, agentes/, reglas/, CHANGELOG, CLAUDE.md, etc. es
723
+ // mantenimiento del sistema, no descubrimiento en tiempo de ejecución.
724
+ if (toolName === 'Write' || toolName === 'Edit' || toolName === 'MultiEdit') {
725
+ const toolInput = data.tool_input || data.tool?.input || {};
726
+ const filePath = String(toolInput.file_path || toolInput.path || '');
727
+ if (esArchivoSwlExcluido(filePath)) {
728
+ return;
729
+ }
730
+ }
731
+
732
+ // Extraer texto y nombre del agente del payload
733
+ const { texto, agente } = extraerTextoYAgente(data);
734
+
735
+ // Verificar que el texto tiene contenido narrativo suficiente
736
+ if (!tieneContenidoNarrativo(texto)) {
737
+ return;
738
+ }
739
+
740
+ // Detectar aprendizaje en el texto
741
+ const aprendizaje = detectarAprendizaje(texto);
742
+
743
+ if (!aprendizaje) {
744
+ // Sin aprendizaje detectado — salir silenciosamente
745
+ return;
746
+ }
747
+
748
+ // Filtro final: descartar si el contexto parece estructural (frontmatter
749
+ // YAML, tablas markdown, enumeración de encabezados sin cuerpo). Previene
750
+ // que fragmentos de skills/reglas se persistan como aprendizajes.
751
+ if (pareceContenidoEstructuralSwl(aprendizaje.contexto)) {
752
+ return;
753
+ }
754
+
755
+ // Escribir el aprendizaje (incluye deduplicación interna)
756
+ escribirAprendizaje(aprendizaje, agente);
757
+
758
+ // PostToolUse: no escribir a stdout — salida limpia.
759
+
760
+ } catch (err) {
761
+ // No escribir a stderr — Claude Code lo reporta como hook error
762
+ }
763
+ });