@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,146 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Tech Skills Map — Conecta tecnologías detectadas con skills SWL recomendados.
5
+ *
6
+ * Usa el resultado de detectarTecnologias() para generar una lista priorizada
7
+ * de skills que deberian cargarse automaticamente al inicio de sesion.
8
+ *
9
+ * Integración:
10
+ * - inyeccion-contexto.js puede usar sugerirSkills() para recomendar skills
11
+ * - agent-matcher.js puede usar obtenerAgentesPorStack() para routing
12
+ * - orquestador-swl puede consultar al asignar agentes a tareas
13
+ *
14
+ * @module hooks/lib/tech-skills-map
15
+ */
16
+
17
+ const { detectarTecnologias } = require('./detectar-package-manager');
18
+
19
+ // ---------------------------------------------------------------------------
20
+ // API pública
21
+ // ---------------------------------------------------------------------------
22
+
23
+ /**
24
+ * Genera lista de skills recomendados basandose en las tecnologias detectadas.
25
+ * Los skills se deduplican y se ordenan por frecuencia (mas tecnologias lo referencian = mas arriba).
26
+ *
27
+ * @param {string} dir - Directorio raiz del proyecto.
28
+ * @returns {{ skills: Array<{name: string, sources: string[], priority: number}>, agentes: Array<{name: string, source: string}>, combos: Array<{id: string, skills: string[], pipeline: string}> }}
29
+ */
30
+ function sugerirSkills(dir) {
31
+ const { tecnologias, combos } = detectarTecnologias(dir);
32
+
33
+ // Agrupar skills con sus fuentes
34
+ const skillMap = new Map(); // skillName → { sources: Set, priority: number }
35
+
36
+ for (const tech of tecnologias) {
37
+ for (const skill of tech.skills) {
38
+ if (!skillMap.has(skill)) {
39
+ skillMap.set(skill, { sources: new Set(), priority: 0 });
40
+ }
41
+ const entry = skillMap.get(skill);
42
+ entry.sources.add(tech.name);
43
+ entry.priority++;
44
+ }
45
+ }
46
+
47
+ // Agregar skills de combos con prioridad bonus
48
+ for (const combo of combos) {
49
+ for (const skill of combo.skills) {
50
+ if (!skillMap.has(skill)) {
51
+ skillMap.set(skill, { sources: new Set(), priority: 0 });
52
+ }
53
+ const entry = skillMap.get(skill);
54
+ entry.sources.add(`combo:${combo.id}`);
55
+ entry.priority += 2; // bonus por ser combo
56
+ }
57
+ }
58
+
59
+ // Convertir a array y ordenar por prioridad descendente
60
+ const skills = Array.from(skillMap.entries())
61
+ .map(([name, { sources, priority }]) => ({
62
+ name,
63
+ sources: Array.from(sources),
64
+ priority,
65
+ }))
66
+ .sort((a, b) => b.priority - a.priority);
67
+
68
+ // Agentes recomendados (deduplicados)
69
+ const agenteSet = new Map();
70
+ for (const tech of tecnologias) {
71
+ if (tech.agente && !agenteSet.has(tech.agente)) {
72
+ agenteSet.set(tech.agente, tech.name);
73
+ }
74
+ }
75
+ const agentes = Array.from(agenteSet.entries())
76
+ .map(([name, source]) => ({ name, source }));
77
+
78
+ return { skills, agentes, combos };
79
+ }
80
+
81
+ /**
82
+ * Obtiene los agentes recomendados para el stack del proyecto.
83
+ *
84
+ * @param {string} dir
85
+ * @returns {Array<{agente: string, tecnologia: string, skills: string[]}>}
86
+ */
87
+ function obtenerAgentesPorStack(dir) {
88
+ const { tecnologias } = detectarTecnologias(dir);
89
+ const agenteMap = new Map(); // agenteName → { tecnologias: [], skills: Set }
90
+
91
+ for (const tech of tecnologias) {
92
+ if (!tech.agente) continue;
93
+ if (!agenteMap.has(tech.agente)) {
94
+ agenteMap.set(tech.agente, { tecnologias: [], skills: new Set() });
95
+ }
96
+ const entry = agenteMap.get(tech.agente);
97
+ entry.tecnologias.push(tech.name);
98
+ tech.skills.forEach(s => entry.skills.add(s));
99
+ }
100
+
101
+ return Array.from(agenteMap.entries())
102
+ .map(([agente, { tecnologias: techs, skills }]) => ({
103
+ agente,
104
+ tecnologia: techs.join(', '),
105
+ skills: Array.from(skills),
106
+ }));
107
+ }
108
+
109
+ /**
110
+ * Genera un resumen compacto del stack para inyectar en contexto.
111
+ * Formato: una linea por tecnologia con skills recomendados.
112
+ *
113
+ * @param {string} dir
114
+ * @returns {string} Resumen en texto plano, vacio si no detecta nada.
115
+ */
116
+ function generarResumenStack(dir) {
117
+ const { skills, agentes, combos } = sugerirSkills(dir);
118
+ if (skills.length === 0) return '';
119
+
120
+ const lines = ['## Stack detectado'];
121
+
122
+ if (agentes.length > 0) {
123
+ lines.push('Agentes recomendados: ' + agentes.map(a => a.name).join(', '));
124
+ }
125
+
126
+ if (skills.length > 0) {
127
+ const top = skills.slice(0, 10).map(s => s.name);
128
+ lines.push('Skills sugeridos: ' + top.join(', '));
129
+ }
130
+
131
+ if (combos.length > 0) {
132
+ lines.push('Combos: ' + combos.map(c => c.id + ' (' + c.pipeline + ')').join(', '));
133
+ }
134
+
135
+ return lines.join('\n');
136
+ }
137
+
138
+ // ---------------------------------------------------------------------------
139
+ // Exports
140
+ // ---------------------------------------------------------------------------
141
+
142
+ module.exports = {
143
+ sugerirSkills,
144
+ obtenerAgentesPorStack,
145
+ generarResumenStack,
146
+ };
@@ -0,0 +1,159 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Cliente HTTP Telegram — zero-deps.
5
+ *
6
+ * Provee `enviarMensaje(token, chatId, texto, opts)` con:
7
+ * - Escape HTML automático
8
+ * - Truncado a 3500 chars con sufijo "… [truncado]"
9
+ * - Reintentos con backoff exponencial (100/200/400ms) para respuestas 5xx
10
+ * - Sin reintento para respuestas 4xx
11
+ * - Timeout de 8 segundos
12
+ *
13
+ * Dependencias: solo módulos node: (https, fs, path, os).
14
+ *
15
+ * @module hooks/lib/telegram-cliente
16
+ */
17
+
18
+ const https = require('node:https');
19
+
20
+ // Límite de Telegram es 4096 chars; usamos 3500 para dar margen al wrapper HTML.
21
+ const LIMITE_CHARS = 3500;
22
+ const SUFIJO_TRUNCADO = '\n… [truncado]';
23
+ const TIMEOUT_MS = 8000;
24
+ const REINTENTOS_MAX = 3;
25
+ const BACKOFF_BASE_MS = 100;
26
+
27
+ /**
28
+ * Escapa caracteres HTML especiales para parse_mode HTML de Telegram.
29
+ *
30
+ * @param {string} texto - Texto a escapar.
31
+ * @returns {string} Texto con &, < y > escapados.
32
+ */
33
+ function escaparHtml(texto) {
34
+ return String(texto)
35
+ .replace(/&/g, '&amp;')
36
+ .replace(/</g, '&lt;')
37
+ .replace(/>/g, '&gt;');
38
+ }
39
+
40
+ /**
41
+ * Trunca el texto si supera el límite, agregando el sufijo de truncado.
42
+ *
43
+ * @param {string} texto - Texto a truncar.
44
+ * @param {number} limite - Límite máximo de caracteres.
45
+ * @returns {string} Texto truncado o el original si cabe.
46
+ */
47
+ function truncar(texto, limite) {
48
+ const s = String(texto);
49
+ if (s.length <= limite) return s;
50
+ const corte = limite - SUFIJO_TRUNCADO.length;
51
+ return s.slice(0, corte).trimEnd() + SUFIJO_TRUNCADO;
52
+ }
53
+
54
+ /**
55
+ * Realiza un intento de envío HTTP hacia la API de Telegram.
56
+ *
57
+ * @param {string} token - Token del bot de Telegram.
58
+ * @param {string} chatId - ID del chat destinatario.
59
+ * @param {string} texto - Texto del mensaje (ya preparado para enviar).
60
+ * @param {object} opts - Opciones adicionales del mensaje.
61
+ * @returns {Promise<{ok: boolean, statusCode: number, cuerpo: string}>}
62
+ */
63
+ function _intentarEnvio(token, chatId, texto, opts) {
64
+ const payload = JSON.stringify({
65
+ chat_id: chatId,
66
+ text: texto,
67
+ parse_mode: 'HTML',
68
+ disable_web_page_preview: true,
69
+ ...opts,
70
+ });
71
+
72
+ return new Promise((resolve) => {
73
+ const req = https.request(
74
+ {
75
+ method: 'POST',
76
+ hostname: 'api.telegram.org',
77
+ path: `/bot${token}/sendMessage`,
78
+ headers: {
79
+ 'Content-Type': 'application/json',
80
+ 'Content-Length': Buffer.byteLength(payload),
81
+ },
82
+ timeout: TIMEOUT_MS,
83
+ },
84
+ (res) => {
85
+ let cuerpo = '';
86
+ res.on('data', (chunk) => { cuerpo += chunk; });
87
+ res.on('end', () => {
88
+ resolve({ ok: res.statusCode >= 200 && res.statusCode < 300, statusCode: res.statusCode, cuerpo });
89
+ });
90
+ }
91
+ );
92
+
93
+ req.on('timeout', () => {
94
+ req.destroy();
95
+ resolve({ ok: false, statusCode: 0, cuerpo: 'timeout' });
96
+ });
97
+
98
+ req.on('error', (err) => {
99
+ resolve({ ok: false, statusCode: 0, cuerpo: err.message });
100
+ });
101
+
102
+ req.write(payload);
103
+ req.end();
104
+ });
105
+ }
106
+
107
+ /**
108
+ * Pausa durante `ms` milisegundos.
109
+ *
110
+ * @param {number} ms - Milisegundos a esperar.
111
+ * @returns {Promise<void>}
112
+ */
113
+ function _esperar(ms) {
114
+ return new Promise((resolve) => setTimeout(resolve, ms));
115
+ }
116
+
117
+ /**
118
+ * Envía un mensaje de Telegram con escape HTML, truncado y reintentos.
119
+ *
120
+ * Solo reintenta en errores 5xx (falla de servidor). Los errores 4xx
121
+ * (credenciales inválidas, chat no encontrado) no se reintentan porque
122
+ * volver a intentar no resolvería el problema.
123
+ *
124
+ * @param {string} token - Token del bot (`123:ABC...`).
125
+ * @param {string} chatId - ID numérico del chat destino.
126
+ * @param {string} texto - Texto del mensaje. Se escapa y trunca automáticamente.
127
+ * @param {object} [opts] - Campos adicionales para el body de sendMessage.
128
+ * @returns {Promise<{ok: boolean, statusCode: number, error?: string}>}
129
+ */
130
+ async function enviarMensaje(token, chatId, texto, opts = {}) {
131
+ const textoPrepado = truncar(escaparHtml(texto), LIMITE_CHARS);
132
+
133
+ for (let intento = 0; intento < REINTENTOS_MAX; intento++) {
134
+ const resultado = await _intentarEnvio(token, chatId, textoPrepado, opts);
135
+
136
+ if (resultado.cuerpo === 'timeout') {
137
+ return { ok: false, statusCode: 0, error: 'timeout' };
138
+ }
139
+
140
+ if (resultado.ok) {
141
+ return { ok: true, statusCode: resultado.statusCode };
142
+ }
143
+
144
+ // Errores 4xx: no reintentar (credenciales inválidas, chat inexistente, etc.)
145
+ if (resultado.statusCode >= 400 && resultado.statusCode < 500) {
146
+ const etiqueta = resultado.statusCode === 401 ? 'unauthorized' : `http-${resultado.statusCode}`;
147
+ return { ok: false, statusCode: resultado.statusCode, error: etiqueta };
148
+ }
149
+
150
+ // Error de red (statusCode 0) o 5xx: reintento con backoff exponencial
151
+ if (intento < REINTENTOS_MAX - 1) {
152
+ await _esperar(BACKOFF_BASE_MS * Math.pow(2, intento));
153
+ }
154
+ }
155
+
156
+ return { ok: false, statusCode: 0, error: 'max-retries-exceeded' };
157
+ }
158
+
159
+ module.exports = { enviarMensaje, escaparHtml, truncar };
@@ -0,0 +1,170 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Configuración de notificaciones Telegram — zero-deps.
5
+ *
6
+ * Lee credenciales desde `~/.claude/notifications/.env`, valida campos
7
+ * requeridos y gestiona la lista de proyectos silenciados (`muted.json`).
8
+ *
9
+ * Convenciones del parser .env:
10
+ * - Líneas que comienzan con # son comentarios y se ignoran.
11
+ * - El separador es el PRIMER `=` de la línea; el valor puede contener `=`.
12
+ * - Las comillas simples y dobles se eliminan solo si envuelven el valor completo.
13
+ * - Los espacios alrededor de nombre y valor se recortan.
14
+ *
15
+ * @module hooks/lib/telegram-config
16
+ */
17
+
18
+ const fs = require('node:fs');
19
+ const path = require('node:path');
20
+ const os = require('node:os');
21
+
22
+ const { atomicWriteJSON } = require('./atomic-write');
23
+
24
+ // Directorio donde viven las credenciales y estado
25
+ const DIR_NOTIFICACIONES = path.join(os.homedir(), '.claude', 'notifications');
26
+ const RUTA_ENV = path.join(DIR_NOTIFICACIONES, '.env');
27
+ const RUTA_MUTED = path.join(DIR_NOTIFICACIONES, 'muted.json');
28
+
29
+ // Campos que deben estar presentes para que las notificaciones funcionen
30
+ const CAMPOS_REQUERIDOS = ['TELEGRAM_BOT_TOKEN', 'TELEGRAM_CHAT_ID'];
31
+
32
+ /**
33
+ * Parsea el contenido de un archivo .env.
34
+ *
35
+ * Respeta el primer `=` como separador, de modo que valores como
36
+ * `TOKEN=abc=def` producen `{ TOKEN: "abc=def" }`.
37
+ *
38
+ * @param {string} contenido - Texto completo del archivo .env.
39
+ * @returns {Record<string, string>} Mapa de variables.
40
+ */
41
+ function _parsearEnv(contenido) {
42
+ const resultado = {};
43
+
44
+ for (const linea of contenido.split(/\r?\n/)) {
45
+ const recortada = linea.trim();
46
+
47
+ // Ignorar líneas vacías y comentarios
48
+ if (!recortada || recortada.startsWith('#')) continue;
49
+
50
+ // El nombre es todo hasta el primer `=`
51
+ const posIgual = recortada.indexOf('=');
52
+ if (posIgual === -1) continue;
53
+
54
+ const nombre = recortada.slice(0, posIgual).trim();
55
+ let valor = recortada.slice(posIgual + 1).trim();
56
+
57
+ // Eliminar comillas envolventes (simples o dobles)
58
+ if (
59
+ (valor.startsWith('"') && valor.endsWith('"')) ||
60
+ (valor.startsWith("'") && valor.endsWith("'"))
61
+ ) {
62
+ valor = valor.slice(1, -1);
63
+ }
64
+
65
+ // Solo guardar si el nombre es un identificador de variable válido
66
+ if (/^[A-Z_][A-Z0-9_]*$/.test(nombre)) {
67
+ resultado[nombre] = valor;
68
+ }
69
+ }
70
+
71
+ return resultado;
72
+ }
73
+
74
+ /**
75
+ * Carga la configuración de notificaciones desde `~/.claude/notifications/.env`.
76
+ *
77
+ * Las variables del proceso (`process.env`) tienen precedencia sobre el archivo
78
+ * para permitir inyección en entornos CI o de prueba.
79
+ *
80
+ * @returns {{ config: Record<string, string>, valido: boolean, errores: string[] }}
81
+ */
82
+ function cargarConfig() {
83
+ let configArchivo = {};
84
+
85
+ if (fs.existsSync(RUTA_ENV)) {
86
+ try {
87
+ const contenido = fs.readFileSync(RUTA_ENV, 'utf8');
88
+ configArchivo = _parsearEnv(contenido);
89
+ } catch (_) {
90
+ // Si el archivo no se puede leer, continuar con vacío
91
+ }
92
+ }
93
+
94
+ // Las variables de entorno del proceso tienen precedencia
95
+ const config = { ...configArchivo };
96
+ for (const campo of CAMPOS_REQUERIDOS) {
97
+ if (process.env[campo]) config[campo] = process.env[campo];
98
+ }
99
+
100
+ const errores = CAMPOS_REQUERIDOS.filter((c) => !config[c] || !config[c].trim());
101
+ return { config, valido: errores.length === 0, errores };
102
+ }
103
+
104
+ /**
105
+ * Lee la lista actual de proyectos silenciados.
106
+ *
107
+ * @returns {string[]} Lista de nombres de proyecto silenciados.
108
+ */
109
+ function _leerMuted() {
110
+ try {
111
+ if (!fs.existsSync(RUTA_MUTED)) return [];
112
+ const contenido = fs.readFileSync(RUTA_MUTED, 'utf8');
113
+ const datos = JSON.parse(contenido);
114
+ return Array.isArray(datos) ? datos : [];
115
+ } catch (_) {
116
+ return [];
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Agrega un proyecto a la lista de silenciados.
122
+ *
123
+ * Idempotente: si el proyecto ya estaba silenciado, no lo duplica.
124
+ *
125
+ * @param {string} proyecto - Nombre del proyecto a silenciar.
126
+ */
127
+ function agregarMute(proyecto) {
128
+ const actuales = _leerMuted();
129
+ if (!actuales.includes(proyecto)) {
130
+ actuales.push(proyecto);
131
+ atomicWriteJSON(RUTA_MUTED, actuales);
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Elimina un proyecto de la lista de silenciados.
137
+ *
138
+ * Idempotente: si el proyecto no estaba silenciado, no hace nada.
139
+ *
140
+ * @param {string} proyecto - Nombre del proyecto a des-silenciar.
141
+ */
142
+ function eliminarMute(proyecto) {
143
+ const actuales = _leerMuted();
144
+ const nuevos = actuales.filter((p) => p !== proyecto);
145
+ // Solo escribir si cambió algo
146
+ if (nuevos.length !== actuales.length) {
147
+ atomicWriteJSON(RUTA_MUTED, nuevos);
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Verifica si un proyecto está actualmente silenciado.
153
+ *
154
+ * @param {string} proyecto - Nombre del proyecto a verificar.
155
+ * @returns {boolean} `true` si el proyecto está en la lista de silenciados.
156
+ */
157
+ function estaMuted(proyecto) {
158
+ return _leerMuted().includes(proyecto);
159
+ }
160
+
161
+ module.exports = {
162
+ cargarConfig,
163
+ agregarMute,
164
+ eliminarMute,
165
+ estaMuted,
166
+ // Exportar rutas para facilitar pruebas
167
+ RUTA_ENV,
168
+ RUTA_MUTED,
169
+ DIR_NOTIFICACIONES,
170
+ };
@@ -0,0 +1,156 @@
1
+ /**
2
+ * token-budget.js — Calculador de presupuesto de tokens para inyección de contexto
3
+ *
4
+ * Estima tokens y distribuye un presupuesto limitado entre bloques de contexto
5
+ * priorizados por recencia e importancia. Inspirado en el sistema de token
6
+ * budget de agentmemory.
7
+ * Zero dependencias externas — aritmética pura de Node.js.
8
+ *
9
+ * Uso:
10
+ * const { estimateTokens, allocateBudget } = require('./token-budget');
11
+ * const tokens = estimateTokens('texto de ejemplo');
12
+ * const bloques = allocateBudget(candidatos, 2000);
13
+ */
14
+
15
+ 'use strict';
16
+
17
+ /**
18
+ * Estima el número de tokens en un texto.
19
+ * Heurística: ~4 caracteres por token en inglés/español, ~3 para código.
20
+ * No es exacta pero es suficiente para presupuestación sin dependencias externas.
21
+ *
22
+ * @param {string} text - Texto a estimar
23
+ * @param {'prose'|'code'|'mixed'} [type='mixed'] - Tipo de contenido
24
+ * @returns {number} Estimación de tokens
25
+ */
26
+ function estimateTokens(text, type) {
27
+ if (!text || typeof text !== 'string') return 0;
28
+
29
+ const len = text.length;
30
+ switch (type) {
31
+ case 'prose': return Math.ceil(len / 4.2);
32
+ case 'code': return Math.ceil(len / 3.0);
33
+ case 'mixed':
34
+ default: return Math.ceil(len / 3.5);
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Bloque de contexto candidato para inyección.
40
+ * @typedef {Object} ContextBlock
41
+ * @property {string} type - Tipo: 'summary'|'observation'|'memory'|'rule'|'skill'
42
+ * @property {string} content - Contenido del bloque
43
+ * @property {number} [tokens] - Tokens pre-calculados (se estima si no se da)
44
+ * @property {number} [recency] - Timestamp Unix de última relevancia (más reciente = mayor prioridad)
45
+ * @property {number} [importance] - Importancia 0.0-1.0 (default 0.5)
46
+ */
47
+
48
+ /**
49
+ * Calcula el score de prioridad de un bloque.
50
+ * Combina recencia (60%) e importancia (40%) para ordenar candidatos.
51
+ *
52
+ * @param {ContextBlock} block - Bloque a evaluar
53
+ * @param {number} now - Timestamp actual en ms
54
+ * @returns {number} Score normalizado 0.0-1.0
55
+ */
56
+ function scoreBlock(block, now) {
57
+ const importance = typeof block.importance === 'number'
58
+ ? Math.max(0, Math.min(1, block.importance))
59
+ : 0.5;
60
+
61
+ let recencyScore = 0.5;
62
+ if (typeof block.recency === 'number' && block.recency > 0) {
63
+ const ageMs = now - block.recency;
64
+ const ageHours = ageMs / (1000 * 60 * 60);
65
+ // Decaimiento exponencial: pierde 50% de recencia cada 24 horas
66
+ recencyScore = Math.exp(-0.693 * ageHours / 24);
67
+ }
68
+
69
+ return recencyScore * 0.6 + importance * 0.4;
70
+ }
71
+
72
+ /**
73
+ * Distribuye un presupuesto de tokens entre bloques candidatos.
74
+ * Prioriza por score (recencia + importancia). Incluye bloques completos
75
+ * hasta agotar el presupuesto — no corta bloques a la mitad.
76
+ *
77
+ * @param {ContextBlock[]} candidates - Bloques candidatos
78
+ * @param {number} budget - Presupuesto total de tokens
79
+ * @param {Object} [options] - Opciones de configuración
80
+ * @param {number} [options.reserveTokens=200] - Tokens reservados para overhead del prompt
81
+ * @param {number} [options.maxBlocks=20] - Máximo de bloques a incluir
82
+ * @returns {{ selected: ContextBlock[], totalTokens: number, rejected: number }}
83
+ */
84
+ function allocateBudget(candidates, budget, options) {
85
+ const opts = options || {};
86
+ const reserve = typeof opts.reserveTokens === 'number' ? opts.reserveTokens : 200;
87
+ const maxBlocks = typeof opts.maxBlocks === 'number' ? opts.maxBlocks : 20;
88
+ const effectiveBudget = Math.max(0, budget - reserve);
89
+ const now = Date.now();
90
+
91
+ if (!Array.isArray(candidates) || candidates.length === 0) {
92
+ return { selected: [], totalTokens: 0, rejected: 0 };
93
+ }
94
+
95
+ // Estimar tokens si no están pre-calculados
96
+ const scored = candidates.map(block => {
97
+ const tokens = typeof block.tokens === 'number'
98
+ ? block.tokens
99
+ : estimateTokens(block.content);
100
+ return {
101
+ ...block,
102
+ tokens,
103
+ _score: scoreBlock(block, now)
104
+ };
105
+ });
106
+
107
+ // Ordenar por score descendente
108
+ scored.sort((a, b) => b._score - a._score);
109
+
110
+ const selected = [];
111
+ let totalTokens = 0;
112
+
113
+ for (const block of scored) {
114
+ if (selected.length >= maxBlocks) break;
115
+ if (totalTokens + block.tokens > effectiveBudget) continue;
116
+
117
+ selected.push({
118
+ type: block.type,
119
+ content: block.content,
120
+ tokens: block.tokens,
121
+ recency: block.recency,
122
+ importance: block.importance
123
+ });
124
+ totalTokens += block.tokens;
125
+ }
126
+
127
+ return {
128
+ selected,
129
+ totalTokens,
130
+ rejected: candidates.length - selected.length
131
+ };
132
+ }
133
+
134
+ /**
135
+ * Calcula estadísticas de uso de tokens para un conjunto de contenidos.
136
+ * Útil para reportes de eficiencia y diagnóstico.
137
+ *
138
+ * @param {Object.<string, string>} namedContents - Mapa nombre→contenido
139
+ * @returns {Object.<string, number>} Mapa nombre→tokens estimados
140
+ */
141
+ function tokenBreakdown(namedContents) {
142
+ const result = {};
143
+ if (!namedContents || typeof namedContents !== 'object') return result;
144
+
145
+ for (const [name, content] of Object.entries(namedContents)) {
146
+ result[name] = estimateTokens(content);
147
+ }
148
+ return result;
149
+ }
150
+
151
+ module.exports = {
152
+ estimateTokens,
153
+ scoreBlock,
154
+ allocateBudget,
155
+ tokenBreakdown
156
+ };