@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,407 @@
1
+ ---
2
+ name: manejo-errores
3
+ description: >
4
+ Patrones de manejo de errores en Python y TypeScript. Jerarquía de excepciones,
5
+ excepciones personalizadas, códigos de error, logging estructurado, error boundaries,
6
+ degradación elegante, patrones de reintento y circuit breakers.
7
+ version: "1.1.0"
8
+ evolved: true
9
+ evolved-from: "1.0.2"
10
+ evolved-at: "2026-04-24"
11
+ evolved-by: "aprender"
12
+ evolved-note: "Sección nueva: except Exception: pass en cleanup es válido, pero con logger.debug para trazabilidad"
13
+ herramientasPermitidas: [Read]
14
+ exclusiones:
15
+ - "No cargar para monitoreo y alertas en producción (Prometheus, Grafana, PagerDuty) — para observabilidad cargar `monitoring-alertas` o `sre-patrones`."
16
+ - "No cargar para manejo de errores específico de frameworks (FastAPI exception handlers, Angular Error Interceptor) — los ejemplos aquí son patrones base; para frameworks específicos cargar el skill correspondiente."
17
+ - "No cargar para errores de compilación o build (TypeScript, Rust, Java) — para diagnóstico de errores de compilación cargar `typescript-diagnosticos` o el skill de build errors correspondiente."
18
+ - "No cargar para logging de auditoría o compliance (GDPR, SOC2 log requirements) — este skill cubre logging operacional de errores, no logging de compliance."
19
+ evolvable: true # default para skill estandar
20
+ ---
21
+ # Manejo de Errores — Patrones de Producción
22
+
23
+ ## Cuándo NO cargar
24
+
25
+ - La tarea es monitoreo y alertas en producción: Prometheus, Grafana, SLOs, PagerDuty — cargar `monitoring-alertas` o `sre-patrones`.
26
+ - El manejo de errores es específico de un framework: FastAPI exception handlers, Angular HTTP Interceptor — cargar el skill del framework; los patrones aquí son base.
27
+ - Los errores son de compilación o build: TypeScript errors, Rust borrow checker, Java compile errors — cargar `typescript-diagnosticos` o el skill de build errors del lenguaje.
28
+ - El logging es de auditoría o compliance (GDPR, SOC2) — este skill cubre logging operacional de errores en runtime, no logging de compliance.
29
+
30
+ ## Principios Fundamentales
31
+
32
+ El manejo de errores no es una ocurrencia tardía: es parte del diseño de la interfaz.
33
+ Un módulo que no especifica su contrato de errores es un módulo incompleto.
34
+
35
+ **Reglas de oro:**
36
+ 1. Nunca silencies una excepción sin loguear o re-lanzar.
37
+ 2. Transforma excepciones de bajo nivel en errores de dominio en la frontera de tu módulo.
38
+ 3. El mensaje de error debe responder: ¿qué pasó?, ¿dónde?, ¿qué hace el sistema ahora?
39
+ 4. Los errores recuperables se manejan; los no recuperables se propagan.
40
+
41
+ ---
42
+
43
+ ## Python — Jerarquía de Excepciones
44
+
45
+ ```python
46
+ # BIEN - jerarquía clara con códigos de error
47
+ class ErrorAplicacion(Exception):
48
+ """Base de todos los errores de la aplicación."""
49
+ codigo: str = "APP_ERROR"
50
+
51
+ def __init__(self, mensaje: str, detalle: dict | None = None) -> None:
52
+ super().__init__(mensaje)
53
+ self.mensaje = mensaje
54
+ self.detalle = detalle or {}
55
+
56
+ def to_dict(self) -> dict:
57
+ return {
58
+ "codigo": self.codigo,
59
+ "mensaje": self.mensaje,
60
+ "detalle": self.detalle,
61
+ }
62
+
63
+ class ErrorValidacion(ErrorAplicacion):
64
+ codigo = "VALIDATION_ERROR"
65
+
66
+ class ErrorNoEncontrado(ErrorAplicacion):
67
+ codigo = "NOT_FOUND"
68
+
69
+ class ErrorConflicto(ErrorAplicacion):
70
+ codigo = "CONFLICT"
71
+
72
+ class ErrorExterno(ErrorAplicacion):
73
+ """Para fallos en servicios de terceros."""
74
+ codigo = "EXTERNAL_SERVICE_ERROR"
75
+ ```
76
+
77
+ ---
78
+
79
+ ## Python — Encadenamiento de Excepciones
80
+
81
+ SIEMPRE usar `raise ... from exc` para preservar la cadena de errores:
82
+
83
+ ```python
84
+ def cargar_config(ruta: str) -> Config:
85
+ try:
86
+ with open(ruta) as f:
87
+ datos = json.load(f)
88
+ except FileNotFoundError as exc:
89
+ raise ErrorNoEncontrado(
90
+ f"Archivo de configuración no encontrado: {ruta}",
91
+ ) from exc
92
+ except json.JSONDecodeError as exc:
93
+ raise ErrorValidacion(
94
+ f"JSON malformado en {ruta}: línea {exc.lineno}",
95
+ ) from exc
96
+ ```
97
+
98
+ ---
99
+
100
+ ## Python — Logging Estructurado
101
+
102
+ NUNCA usar `print()` o `logging.error("Algo salió mal")` sin contexto.
103
+
104
+ ```python
105
+ import structlog
106
+
107
+ logger = structlog.get_logger(__name__)
108
+
109
+ def procesar_pedido(pedido_id: str, usuario_id: str) -> Resultado:
110
+ log = logger.bind(pedido_id=pedido_id, usuario_id=usuario_id)
111
+ log.info("iniciando_procesamiento_pedido")
112
+
113
+ try:
114
+ pedido = repositorio.obtener(pedido_id)
115
+ resultado = servicio_pago.cobrar(pedido)
116
+ log.info("pedido_procesado_exitosamente", monto=pedido.total)
117
+ return resultado
118
+ except ErrorExterno as exc:
119
+ log.error(
120
+ "fallo_servicio_externo",
121
+ servicio=exc.detalle.get("servicio"),
122
+ exc_info=True,
123
+ )
124
+ raise
125
+ except Exception as exc:
126
+ log.critical(
127
+ "error_inesperado_procesando_pedido",
128
+ tipo_excepcion=type(exc).__name__,
129
+ exc_info=True,
130
+ )
131
+ raise ErrorAplicacion("Error interno al procesar el pedido") from exc
132
+ ```
133
+
134
+ ---
135
+
136
+ ## Python — Patrón Retry con Backoff Exponencial
137
+
138
+ NUNCA hacer retry infinito sin backoff ni logging.
139
+
140
+ ```python
141
+ from tenacity import (
142
+ retry, stop_after_attempt, wait_exponential,
143
+ retry_if_exception_type, before_sleep_log,
144
+ )
145
+
146
+ @retry(
147
+ stop=stop_after_attempt(3),
148
+ wait=wait_exponential(multiplier=1, min=1, max=10),
149
+ retry=retry_if_exception_type(ErrorExterno),
150
+ before_sleep=before_sleep_log(logger_tenacity, logging.WARNING),
151
+ )
152
+ def llamar_api_con_retry(endpoint: str, payload: dict) -> dict:
153
+ respuesta = httpx.post(endpoint, json=payload, timeout=10.0)
154
+ if respuesta.status_code == 429:
155
+ raise ErrorExterno("Rate limit alcanzado", {"servicio": endpoint, "codigo_http": 429})
156
+ if respuesta.status_code >= 500:
157
+ raise ErrorExterno("Error del servidor externo", {"servicio": endpoint})
158
+ respuesta.raise_for_status()
159
+ return respuesta.json()
160
+ ```
161
+
162
+ ---
163
+
164
+ ## Gotcha: Backoff en Workers y Reconexión de Servicios
165
+
166
+ En workers, colas de mensajes y conexiones a bases de datos, el retry debe usar
167
+ backoff exponencial con techo (cap). Sin techo, los reintentos se espacian tanto
168
+ que el worker parece muerto. Sin backoff, los reintentos saturan el servicio caído.
169
+
170
+ ```python
171
+ # Patrón de reconexión con backoff exponencial y cap
172
+ import time
173
+ import random
174
+
175
+ def conectar_con_backoff(crear_conexion, max_intentos=10, base=1.0, cap=30.0):
176
+ """Reconecta con backoff exponencial: 1s → 2s → 4s → 8s → ... → 30s max."""
177
+ for intento in range(max_intentos):
178
+ try:
179
+ return crear_conexion()
180
+ except Exception as exc:
181
+ if intento == max_intentos - 1:
182
+ raise
183
+ delay = min(base * (2 ** intento), cap)
184
+ # Jitter para evitar thundering herd
185
+ delay *= 0.5 + random.random() * 0.5
186
+ logger.warning(
187
+ "reconexion_fallida",
188
+ intento=intento + 1,
189
+ proximo_reintento_seg=round(delay, 1),
190
+ error=str(exc),
191
+ )
192
+ time.sleep(delay)
193
+ ```
194
+
195
+ ### Reglas de backoff para workers
196
+
197
+ - **Base**: 1 segundo. Nunca 0 — un retry inmediato multiplica la carga.
198
+ - **Cap**: 30 segundos para servicios internos, 60 segundos para APIs externas.
199
+ - **Jitter obligatorio**: sin jitter, N workers reintentan al mismo instante (thundering herd).
200
+ - **Max intentos finito**: siempre. Un worker que reintenta infinitamente consume
201
+ recursos sin producir valor. Tras agotar intentos: enviar a dead letter queue.
202
+ - **Loguear cada reintento**: intento N de M, próximo reintento en X segundos.
203
+ Sin logs, un worker silenciosamente atascado es invisible.
204
+
205
+ ---
206
+
207
+ ## Patrones Avanzados
208
+
209
+ Para implementaciones completas de Circuit Breaker, TypeScript Result types,
210
+ Angular Error Boundaries, Angular HTTP Interceptor y Graceful Degradation,
211
+ ver [recursos/implementaciones-completas.md](recursos/implementaciones-completas.md).
212
+
213
+ ---
214
+
215
+ ## Gotchas / Errores comunes no obvios
216
+
217
+ **`raise ErrorDominio() from exc` con `exc` siendo `None` (Python) causa `TypeError` en el traceback**: si se hace `raise MiError("msg") from None` es válido (suprime el contexto), pero `raise MiError("msg") from variable_que_puede_ser_none` lanza `TypeError: exception causes must derive from BaseException` cuando la variable es `None`. Causa: Python valida que el cause sea una excepción o `None` literal, no una variable que puede ser `None`. Fix: usar `raise MiError("msg") from exc` solo cuando `exc` se capturó en un `except` — fuera de un bloque except usar simplemente `raise MiError("msg")`.
218
+
219
+ **`structlog` configurado con `JSONRenderer` en producción pero `ConsoleRenderer` en tests puede causar que los tests pasen con logs que explotan en producción**: la configuración de structlog se setea globalmente con `structlog.configure()` — si los tests usan una configuración diferente al código de producción, los procesadores que funcionan en tests pueden fallar en prod. Causa: structlog es un singleton de configuración global. Fix: no mezclar configuraciones — usar un mismo renderer en tests y en producción, o verificar que los procesadores configurados son compatibles con ambos entornos.
220
+
221
+ **`tenacity` con `retry_if_exception_type(ErrorExterno)` no reintenta si la excepción está envuelta en otra**: si el código lanza `ErrorServicio("msg") from exc` donde `ErrorServicio` hereda de `ErrorAplicacion` (no de `ErrorExterno`), el retry no se activa aunque el error subyacente sea externo. Causa: `retry_if_exception_type` verifica el tipo exacto de la excepción lanzada, no la causa. Fix: asegurarse de lanzar exactamente la excepción que coincide con `retry_if_exception_type`, o usar `retry_if_exception(lambda e: isinstance(e, (ErrorExterno, httpx.HTTPError)))` con una función predicado más amplia.
222
+
223
+ **El patrón de backoff con `random.random()` no es criptográficamente seguro pero eso no importa — lo que importa es usar `random.seed()` en tests**: si los tests verifican el comportamiento del backoff con un mock de `time.sleep`, los tests pueden ser no-deterministas si `random.random()` devuelve valores diferentes en cada ejecución. Causa: jitter aleatorio hace los tests flakys. Fix: en tests de backoff, mockear `random.random` para que retorne un valor fijo (`mocker.patch('random.random', return_value=0.5)`), o usar `secrets.randbelow` solo en contextos donde el timing de seguridad importa.
224
+
225
+ **Cachear "resultado nulo por fallo transitorio" con el mismo TTL que un resultado exitoso silencia alertas legítimas**: un hook/script verifica algo cada 24h (ej: consultar npm por una nueva versión); si la consulta falla (timeout, red caída, dependencia fuera de línea), cachear el fallo con TTL completo de 24h hace que el siguiente check no reintente hasta el día siguiente — el usuario queda sin aviso durante una ventana completa pese a que la infraestructura ya se recuperó minutos después. Causa: usar un solo TTL nominal sin distinguir éxito de fallo transitorio; el estado "no pude verificar" se trata como "verifiqué y todo OK". Fix: implementar **throttle adaptativo** con dos constantes distintas — `SUCCESS_TTL` largo (24h) y `FAILURE_TTL` corto (1h, 5min según el costo del check); al leer el cache, elegir el intervalo según si el resultado anterior fue exitoso o nulo. Patrón:
226
+
227
+ ```js
228
+ function debeVerificar() {
229
+ try {
230
+ const data = JSON.parse(fs.readFileSync(flagPath(), 'utf8'));
231
+ const intervalo = data.resultado ? SUCCESS_TTL : FAILURE_TTL;
232
+ return (Date.now() - data.timestamp) > intervalo;
233
+ } catch {
234
+ return true;
235
+ }
236
+ }
237
+ ```
238
+
239
+ Aplica a: health checks periódicos, verificación de nuevas versiones, consultas de cuota/rate-limit de APIs externas, chequeos de certificados, polling de colas. La línea divisoria es "¿el resultado anterior fue información real o fue ausencia de información?".
240
+
241
+ ## Gotcha — Retry con cliente HTTP interno: propagar el timeout
242
+
243
+ ### NUNCA: wrapper de retry que promete N segundos sobre cliente HTTP con timeout M << N
244
+
245
+ **Problema**: abstracciones de retry (cadenas de fallback, reintentos con backoff) suelen envolver el intento con `asyncio.wait_for(timeout=N)` pero llaman a un cliente HTTP que tiene su propio `read_timeout = M` fijo y más corto. Si el servidor tarda entre M y N segundos, el cliente HTTP aborta con `ReadTimeout` y el wrapper interpreta "fallo" → degrada a otro modelo o vía, aunque el wrapper prometía esperar N segundos.
246
+
247
+ Caso real observado: wrapper `llm_fallback` prometía 300s al primer modelo, pero `OllamaClient` tenía `httpx.Timeout(read=30.0)` fijo. Ollama necesita 60-120s para cargar un modelo grande en VRAM → aborta a los 30s, 3 reintentos fallan, wrapper degrada al siguiente modelo. Síntoma: log con mensajes de error vacíos (`fallo (intento 1/3): .`), porque `ReadTimeout` sin mensaje se convierte en `"."` vía `str(exc)`.
248
+
249
+ ```python
250
+ # MAL — timeouts desalineados: el wrapper promete 300s, el cliente corta a 30s
251
+ class Client:
252
+ timeout = 30.0
253
+ def _crear(self): return httpx.AsyncClient(timeout=httpx.Timeout(read=self.timeout))
254
+ async def generate(self, model, prompt):
255
+ async with self._crear() as c: return await c.post("/generate", json=...)
256
+
257
+ async def fallback_chain(client, cadena):
258
+ for modelo, timeout_s in cadena:
259
+ try:
260
+ # timeout_s=300, pero client.generate aborta internamente a los 30s
261
+ return await asyncio.wait_for(
262
+ client.generate(modelo, prompt), timeout=timeout_s,
263
+ )
264
+ except (asyncio.TimeoutError, ReadTimeout):
265
+ continue # degrada al siguiente modelo innecesariamente
266
+ ```
267
+
268
+ ```python
269
+ # BIEN — cliente acepta override de timeout; wrapper lo propaga
270
+ class Client:
271
+ timeout = 30.0 # default para llamadas cortas
272
+ def _crear(self, read_timeout_override=None):
273
+ t = read_timeout_override if read_timeout_override is not None else self.timeout
274
+ return httpx.AsyncClient(timeout=httpx.Timeout(read=t))
275
+ async def generate(self, model, prompt, timeout=None):
276
+ async with self._crear(read_timeout_override=timeout) as c:
277
+ return await c.post("/generate", json=...)
278
+
279
+ async def fallback_chain(client, cadena):
280
+ for modelo, timeout_s in cadena:
281
+ try:
282
+ # Ahora el cliente tiene el mismo timeout que el wrapper
283
+ try:
284
+ call = client.generate(modelo, prompt, timeout=timeout_s)
285
+ except TypeError:
286
+ # Cliente hermano sin soporte de `timeout` kwarg
287
+ call = client.generate(modelo, prompt)
288
+ return await asyncio.wait_for(call, timeout=timeout_s)
289
+ except (asyncio.TimeoutError, ConnectionError):
290
+ continue
291
+ ```
292
+
293
+ **Regla general**: en cualquier pila `wrapper_con_retry → cliente_HTTP`, el timeout del cliente HTTP debe ser ≥ al timeout que el wrapper comunica al usuario. Si el cliente tiene default corto (típico: 30s), aceptar un kwarg `timeout` y que el wrapper lo propague en cada intento.
294
+
295
+ **Aplicabilidad**: Celery + requests, nginx + backend, httpx + retry libraries, cualquier abstracción que prometa tiempos más largos que el default del transporte subyacente. Añadir verificación en code review cada vez que se implemente una capa de retry sobre HTTP.
296
+
297
+ ## Checklist de Revisión — Manejo de Errores
298
+
299
+ - [ ] Toda excepción capturada tiene log o re-lanzamiento con contexto.
300
+ - [ ] Las excepciones de infraestructura se transforman en errores de dominio en la frontera del módulo.
301
+ - [ ] Los mensajes de error son accionables para quien los recibe.
302
+ - [ ] Los servicios externos tienen timeout + retry + circuit breaker.
303
+ - [ ] El logging incluye contexto suficiente para reproducir el error.
304
+ - [ ] Los errores HTTP tienen código de estado correcto (4xx vs 5xx).
305
+ - [ ] El tipo de error en TypeScript es explícito, no `any` ni `unknown` sin narrowing.
306
+ - [ ] Los errores de validación devuelven todos los campos inválidos de una vez (no uno por uno).
307
+
308
+ ---
309
+
310
+ ## `except Exception: pass` en cleanup es válido PERO con `logger.debug`
311
+
312
+ ### Regla
313
+
314
+ El patrón `try: ... except Exception: pass` en código de **cleanup** (liberación
315
+ de recursos, eliminación de archivos temporales, cierre de conexiones al salir)
316
+ suele marcarse como anti-patrón automáticamente por linters y revisores. En
317
+ ese contexto específico es **válido**, pero debe acompañarse de `logger.debug`
318
+ para preservar trazabilidad.
319
+
320
+ ### Por qué
321
+
322
+ El cleanup no debe bloquear el flujo principal ni escalar errores secundarios
323
+ sobre el error principal. Ejemplos:
324
+
325
+ - Eliminar un archivo `.tmp` cuya ruta ya no existe porque otro proceso lo borró.
326
+ - Cerrar un socket que el otro extremo cerró antes.
327
+ - Desregistrar un callback cuyo registro nunca se completó por error temprano.
328
+
329
+ En estos casos el error del cleanup es **irrelevante** para la lógica del
330
+ usuario — reintento no ayuda, propagación oculta el error real. Pero "no
331
+ hacer nada" a secas deja al operador ciego cuando un patrón de cleanup
332
+ sistemáticamente falla por bug real (ej: ruta mal construida, permisos).
333
+
334
+ ### Patrón canónico
335
+
336
+ ```python
337
+ import logging
338
+ logger = logging.getLogger(__name__)
339
+
340
+
341
+ def cerrar_recursos(recurso) -> None:
342
+ """Cleanup: no retry, no raise, pero sí debug log."""
343
+ try:
344
+ recurso.close()
345
+ except Exception as exc:
346
+ # Nivel DEBUG: visible solo al investigar, silencioso en prod
347
+ logger.debug("fallo_silenciado_en_cleanup", extra={
348
+ "recurso": repr(recurso),
349
+ "tipo_excepcion": type(exc).__name__,
350
+ "mensaje": str(exc),
351
+ })
352
+
353
+
354
+ def limpiar_temporal(ruta: Path) -> None:
355
+ try:
356
+ ruta.unlink(missing_ok=True)
357
+ except Exception as exc:
358
+ logger.debug(f"no se pudo eliminar {ruta}: {exc}")
359
+ ```
360
+
361
+ ### Reglas
362
+
363
+ - **Solo en cleanup / teardown / finally**: no en flujo principal, no en
364
+ manejo de input de usuario, no en llamadas a APIs externas. Para esos
365
+ casos el manejo es específico de la excepción esperada.
366
+ - **Nivel `debug`, NO `warning`**: los logs de warning de cleanup saturan
367
+ la observabilidad y pierden señal. Debug queda invisible en producción
368
+ normal pero accesible cuando se investiga.
369
+ - **Incluir contexto mínimo**: tipo de excepción y mensaje, más el recurso
370
+ que se intentaba liberar. Sin eso el debug es tan inútil como el `pass`.
371
+ - **`except Exception`, no `except:` desnudo**: `except:` captura también
372
+ `KeyboardInterrupt` y `SystemExit`, convirtiendo Ctrl-C en un "cleanup
373
+ silencioso" que confunde al operador.
374
+
375
+ ### Anti-patrones relacionados
376
+
377
+ ```python
378
+ # MAL — pass desnudo sin trazabilidad
379
+ try:
380
+ socket.close()
381
+ except:
382
+ pass
383
+
384
+
385
+ # MAL — warning satura logs cuando el cleanup falla legítimamente
386
+ try:
387
+ archivo_tmp.unlink()
388
+ except OSError as exc:
389
+ logger.warning(f"fallo cleanup: {exc}") # satura observabilidad
390
+
391
+
392
+ # MAL — cleanup que lanza oculta el error principal
393
+ try:
394
+ operacion_principal()
395
+ finally:
396
+ recurso.close() # si esto lanza, el error original se pierde
397
+ ```
398
+
399
+ ### Aplicabilidad
400
+
401
+ Típico en:
402
+
403
+ - Métodos `__exit__` de context managers custom
404
+ - Bloques `finally` tras operaciones de red
405
+ - Lifecycle hooks de shutdown (atexit, signal handlers)
406
+ - Cleanup de recursos heredados (archivos, file handles, DB cursors, sockets)
407
+ - Garbage collection de objetos con `__del__`
@@ -0,0 +1,248 @@
1
+ # Manejo de Errores — Implementaciones Completas
2
+
3
+ ## Python — Circuit Breaker
4
+
5
+ ```python
6
+ # Circuit breaker manual para servicios externos críticos
7
+ import time
8
+ from enum import Enum
9
+ from threading import Lock
10
+ from dataclasses import dataclass, field
11
+
12
+
13
+ class EstadoCircuito(Enum):
14
+ CERRADO = "CERRADO" # Normal: deja pasar llamadas
15
+ ABIERTO = "ABIERTO" # Fallo: bloquea llamadas
16
+ SEMI_ABIERTO = "SEMI_ABIERTO" # Prueba: permite una llamada
17
+
18
+
19
+ @dataclass
20
+ class CircuitBreaker:
21
+ nombre: str
22
+ umbral_fallos: int = 5
23
+ ventana_segundos: float = 60.0
24
+ tiempo_recuperacion: float = 30.0
25
+
26
+ _estado: EstadoCircuito = field(default=EstadoCircuito.CERRADO, init=False)
27
+ _conteo_fallos: int = field(default=0, init=False)
28
+ _ultimo_fallo: float = field(default=0.0, init=False)
29
+ _lock: Lock = field(default_factory=Lock, init=False)
30
+
31
+ def __call__(self, func):
32
+ def wrapper(*args, **kwargs):
33
+ with self._lock:
34
+ if self._estado == EstadoCircuito.ABIERTO:
35
+ if time.time() - self._ultimo_fallo > self.tiempo_recuperacion:
36
+ self._estado = EstadoCircuito.SEMI_ABIERTO
37
+ else:
38
+ raise ErrorExterno(
39
+ f"Circuito {self.nombre!r} abierto — servicio no disponible",
40
+ {"circuito": self.nombre, "estado": self._estado.value},
41
+ )
42
+
43
+ try:
44
+ resultado = func(*args, **kwargs)
45
+ with self._lock:
46
+ self._conteo_fallos = 0
47
+ self._estado = EstadoCircuito.CERRADO
48
+ return resultado
49
+
50
+ except ErrorExterno:
51
+ with self._lock:
52
+ self._conteo_fallos += 1
53
+ self._ultimo_fallo = time.time()
54
+ if self._conteo_fallos >= self.umbral_fallos:
55
+ self._estado = EstadoCircuito.ABIERTO
56
+ logger.warning(
57
+ "circuito_abierto",
58
+ nombre=self.nombre,
59
+ fallos=self._conteo_fallos,
60
+ )
61
+ raise
62
+
63
+ return wrapper
64
+
65
+
66
+ circuito_pago = CircuitBreaker(nombre="servicio-pago", umbral_fallos=3)
67
+
68
+
69
+ @circuito_pago
70
+ def cobrar_tarjeta(monto: float, token: str) -> dict:
71
+ return cliente_pago.post("/cobrar", json={"monto": monto, "token": token})
72
+ ```
73
+
74
+ ---
75
+
76
+ ## TypeScript — Discriminated Unions para Resultados
77
+
78
+ ```typescript
79
+ // Result type explícito — errores tipados, sin try/catch en el caller
80
+ type Resultado<T, E = ErrorAplicacion> =
81
+ | { ok: true; valor: T }
82
+ | { ok: false; error: E };
83
+
84
+ function exito<T>(valor: T): Resultado<T> {
85
+ return { ok: true, valor };
86
+ }
87
+
88
+ function fallo<E extends ErrorAplicacion>(error: E): Resultado<never, E> {
89
+ return { ok: false, error };
90
+ }
91
+
92
+ interface ErrorAplicacion {
93
+ codigo: string;
94
+ mensaje: string;
95
+ detalle?: Record<string, unknown>;
96
+ }
97
+
98
+ async function obtenerUsuario(
99
+ id: string
100
+ ): Promise<Resultado<Usuario, ErrorAplicacion>> {
101
+ const usuario = await db.findById(id);
102
+ if (!usuario) {
103
+ return fallo({ codigo: "NOT_FOUND", mensaje: `Usuario ${id} no encontrado` });
104
+ }
105
+ return exito(usuario);
106
+ }
107
+
108
+ // Uso
109
+ const resultado = await obtenerUsuario("abc");
110
+ if (!resultado.ok) {
111
+ // TypeScript sabe que resultado.error es ErrorAplicacion
112
+ console.error(resultado.error.codigo);
113
+ return;
114
+ }
115
+ // TypeScript sabe que resultado.valor es Usuario
116
+ console.log(resultado.valor.nombre);
117
+ ```
118
+
119
+ ---
120
+
121
+ ## Angular — Error Boundaries con Componentes de Error
122
+
123
+ ```typescript
124
+ // error-boundary.component.ts
125
+ import { Component, ErrorHandler, Injectable, signal } from '@angular/core';
126
+
127
+ @Injectable()
128
+ export class ManejadorErroresGlobal implements ErrorHandler {
129
+ readonly ultimoError = signal<Error | null>(null);
130
+
131
+ handleError(error: Error): void {
132
+ console.error('[ERROR GLOBAL]', error);
133
+ this.ultimoError.set(error);
134
+ // Enviar a Sentry/DataDog aquí
135
+ }
136
+ }
137
+
138
+ // Uso en componente
139
+ @Component({
140
+ standalone: true,
141
+ template: `
142
+ @if (manejador.ultimoError()) {
143
+ <div class="error-boundary bg-red-50 border border-red-200 rounded p-4">
144
+ <p class="font-semibold text-red-700">Algo salió mal</p>
145
+ <p class="text-red-600 text-sm">{{ manejador.ultimoError()?.message }}</p>
146
+ <button (click)="reintentar()" class="mt-2 px-3 py-1 bg-red-600 text-white rounded text-sm">
147
+ Reintentar
148
+ </button>
149
+ </div>
150
+ } @else {
151
+ <ng-content />
152
+ }
153
+ `,
154
+ })
155
+ export class ErrorBoundaryComponent {
156
+ constructor(protected manejador: ManejadorErroresGlobal) {}
157
+
158
+ reintentar(): void {
159
+ this.manejador.ultimoError.set(null);
160
+ }
161
+ }
162
+ ```
163
+
164
+ ---
165
+
166
+ ## Angular — Interceptor HTTP con Manejo Centralizado
167
+
168
+ ```typescript
169
+ // error.interceptor.ts
170
+ import { HttpInterceptorFn, HttpErrorResponse } from '@angular/common/http';
171
+ import { inject } from '@angular/core';
172
+ import { catchError, throwError } from 'rxjs';
173
+ import { Router } from '@angular/router';
174
+ import { NotificacionService } from './notificacion.service';
175
+
176
+ export const errorInterceptor: HttpInterceptorFn = (req, next) => {
177
+ const router = inject(Router);
178
+ const notificaciones = inject(NotificacionService);
179
+
180
+ return next(req).pipe(
181
+ catchError((error: HttpErrorResponse) => {
182
+ switch (error.status) {
183
+ case 401:
184
+ router.navigate(['/login']);
185
+ break;
186
+ case 403:
187
+ notificaciones.error('Sin permisos para realizar esta acción');
188
+ break;
189
+ case 404:
190
+ notificaciones.advertencia('Recurso no encontrado');
191
+ break;
192
+ case 422:
193
+ // Errores de validación — el componente los maneja directamente
194
+ break;
195
+ case 429:
196
+ notificaciones.advertencia('Demasiadas solicitudes. Espere un momento.');
197
+ break;
198
+ case 0:
199
+ notificaciones.error('Sin conexión a la red');
200
+ break;
201
+ default:
202
+ if (error.status >= 500) {
203
+ notificaciones.error('Error interno del servidor. Intente más tarde.');
204
+ }
205
+ }
206
+ return throwError(() => error);
207
+ })
208
+ );
209
+ };
210
+ ```
211
+
212
+ ---
213
+
214
+ ## Python — Degradación Elegante (Graceful Degradation)
215
+
216
+ ```python
217
+ # Función con fallback explícito
218
+ from functools import wraps
219
+ from typing import TypeVar, Callable, Any
220
+
221
+ T = TypeVar("T")
222
+
223
+
224
+ def con_fallback(valor_default: T, *, loguear: bool = True):
225
+ """Decorador que devuelve un valor por defecto ante cualquier excepción."""
226
+ def decorador(func: Callable[..., T]) -> Callable[..., T]:
227
+ @wraps(func)
228
+ def wrapper(*args, **kwargs) -> T:
229
+ try:
230
+ return func(*args, **kwargs)
231
+ except Exception as exc:
232
+ if loguear:
233
+ logger.warning(
234
+ "usando_fallback",
235
+ funcion=func.__name__,
236
+ excepcion=type(exc).__name__,
237
+ mensaje=str(exc),
238
+ )
239
+ return valor_default
240
+ return wrapper
241
+ return decorador
242
+
243
+
244
+ @con_fallback(valor_default=[], loguear=True)
245
+ def obtener_recomendaciones(usuario_id: str) -> list[Producto]:
246
+ """Si falla el motor de recomendaciones, devuelve lista vacía."""
247
+ return motor_recomendaciones.calcular(usuario_id)
248
+ ```