@mks2508/better-logger 0.18.2-alpha.1 → 0.18.3

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 (207) hide show
  1. package/README.md +38 -336
  2. package/dist/Logger.d.ts +356 -157
  3. package/dist/Logger.d.ts.map +1 -1
  4. package/dist/ScopedLogger.d.ts +549 -9
  5. package/dist/ScopedLogger.d.ts.map +1 -1
  6. package/dist/chunks/HookBridge-C-AvXmPD.cjs +504 -0
  7. package/dist/chunks/HookBridge-C-AvXmPD.cjs.map +1 -0
  8. package/dist/chunks/HookBridge-CI2PH79S.js +487 -0
  9. package/dist/chunks/HookBridge-CI2PH79S.js.map +1 -0
  10. package/dist/chunks/{LogContext-L7HzynFw.cjs → LogContext-BaMXleWj.cjs} +19 -4
  11. package/dist/chunks/LogContext-BaMXleWj.cjs.map +1 -0
  12. package/dist/chunks/LogContext-DZasm_P5.cjs +141 -0
  13. package/dist/chunks/LogContext-DZasm_P5.cjs.map +1 -0
  14. package/dist/chunks/{LogContext-Cwn-1Zzb.js → LogContext-DjlITOzZ.js} +19 -4
  15. package/dist/chunks/LogContext-DjlITOzZ.js.map +1 -0
  16. package/dist/chunks/LogContext-Dyzs61XG.js +136 -0
  17. package/dist/chunks/LogContext-Dyzs61XG.js.map +1 -0
  18. package/dist/chunks/SerializerBridge-Ba43Mk7j.js +393 -0
  19. package/dist/chunks/SerializerBridge-Ba43Mk7j.js.map +1 -0
  20. package/dist/chunks/SerializerBridge-C4a9Z37F.cjs +410 -0
  21. package/dist/chunks/SerializerBridge-C4a9Z37F.cjs.map +1 -0
  22. package/dist/chunks/{StyleManager-CIpd6wbO.cjs → StyleManager-DQ6UNRB-.cjs} +37 -11
  23. package/dist/chunks/StyleManager-DQ6UNRB-.cjs.map +1 -0
  24. package/dist/chunks/StyleManager-DjwAYbxE.js +113 -0
  25. package/dist/chunks/StyleManager-DjwAYbxE.js.map +1 -0
  26. package/dist/chunks/{core-PoT7RrTK.js → core-Blfi2klP.js} +1 -4
  27. package/dist/chunks/core-Blfi2klP.js.map +1 -0
  28. package/dist/chunks/{core-Dzz7agGa.cjs → core-CqS_UBzJ.cjs} +1 -4
  29. package/dist/chunks/core-CqS_UBzJ.cjs.map +1 -0
  30. package/dist/chunks/{environment-detector-CI3TrWK_.js → environment-detector-7NvnYUfr.js} +11 -11
  31. package/dist/chunks/environment-detector-7NvnYUfr.js.map +1 -0
  32. package/dist/chunks/{environment-detector-Cnn6wr6O.cjs → environment-detector-D-tHkKWA.cjs} +11 -11
  33. package/dist/chunks/environment-detector-D-tHkKWA.cjs.map +1 -0
  34. package/dist/chunks/server-fallback-CaCPjWby.cjs +119 -0
  35. package/dist/chunks/server-fallback-CaCPjWby.cjs.map +1 -0
  36. package/dist/chunks/server-fallback-jj0T6XaK.js +114 -0
  37. package/dist/chunks/server-fallback-jj0T6XaK.js.map +1 -0
  38. package/dist/chunks/{spinner-DNvxbM9a.cjs → spinner-BHyYEXsM.cjs} +319 -37
  39. package/dist/chunks/spinner-BHyYEXsM.cjs.map +1 -0
  40. package/dist/chunks/{spinner-D3FsF78o.js → spinner-BtkwpzYv.js} +319 -37
  41. package/dist/chunks/spinner-BtkwpzYv.js.map +1 -0
  42. package/dist/chunks/styling-CRw3KQW4.js +1592 -0
  43. package/dist/chunks/styling-CRw3KQW4.js.map +1 -0
  44. package/dist/chunks/styling-Cel2wPRy.cjs +1645 -0
  45. package/dist/chunks/styling-Cel2wPRy.cjs.map +1 -0
  46. package/dist/chunks/transports-BGfwwakw.js +1237 -0
  47. package/dist/chunks/transports-BGfwwakw.js.map +1 -0
  48. package/dist/chunks/transports-BZ-Mc2IT.cjs +1450 -0
  49. package/dist/chunks/transports-BZ-Mc2IT.cjs.map +1 -0
  50. package/dist/chunks/transports-DvaLAeGJ.js +1403 -0
  51. package/dist/chunks/transports-DvaLAeGJ.js.map +1 -0
  52. package/dist/chunks/transports-yK6CL0Ml.cjs +1278 -0
  53. package/dist/chunks/transports-yK6CL0Ml.cjs.map +1 -0
  54. package/dist/chunks/{utils-BqlFYocD.cjs → utils-W_cxqriN.cjs} +44 -37
  55. package/dist/chunks/utils-W_cxqriN.cjs.map +1 -0
  56. package/dist/chunks/{utils-VETbVpkR.js → utils-tKfBAWUM.js} +44 -37
  57. package/dist/chunks/utils-tKfBAWUM.js.map +1 -0
  58. package/dist/cli/CommandProcessor.d.ts +166 -19
  59. package/dist/cli/CommandProcessor.d.ts.map +1 -1
  60. package/dist/cli/commands/ConfigCommand.d.ts +36 -1
  61. package/dist/cli/commands/ConfigCommand.d.ts.map +1 -1
  62. package/dist/cli/commands/ExportCommand.d.ts +49 -3
  63. package/dist/cli/commands/ExportCommand.d.ts.map +1 -1
  64. package/dist/cli/commands/ThemeCommand.d.ts +62 -3
  65. package/dist/cli/commands/ThemeCommand.d.ts.map +1 -1
  66. package/dist/cli/help.d.ts +30 -2
  67. package/dist/cli/help.d.ts.map +1 -1
  68. package/dist/cli/index.d.ts +29 -2
  69. package/dist/cli/index.d.ts.map +1 -1
  70. package/dist/cli.cjs +2 -2
  71. package/dist/cli.js +2 -2
  72. package/dist/context/LogContext.d.ts +167 -70
  73. package/dist/context/LogContext.d.ts.map +1 -1
  74. package/dist/context.cjs +1 -1
  75. package/dist/context.js +1 -1
  76. package/dist/core.cjs +52 -29
  77. package/dist/core.cjs.map +1 -1
  78. package/dist/core.d.ts +50 -27
  79. package/dist/core.d.ts.map +1 -1
  80. package/dist/core.js +52 -29
  81. package/dist/core.js.map +1 -1
  82. package/dist/hooks/HookBridge.d.ts +15 -9
  83. package/dist/hooks/HookBridge.d.ts.map +1 -1
  84. package/dist/hooks/HookManager.d.ts +295 -2
  85. package/dist/hooks/HookManager.d.ts.map +1 -1
  86. package/dist/hooks.cjs +1 -1
  87. package/dist/hooks.js +1 -1
  88. package/dist/index.cjs +1415 -214
  89. package/dist/index.cjs.map +1 -1
  90. package/dist/index.d.ts +5 -1
  91. package/dist/index.d.ts.map +1 -1
  92. package/dist/index.js +1413 -215
  93. package/dist/index.js.map +1 -1
  94. package/dist/playground/TerminalBridge.d.ts +23 -16
  95. package/dist/playground/TerminalBridge.d.ts.map +1 -1
  96. package/dist/playground/box.d.ts +36 -5
  97. package/dist/playground/box.d.ts.map +1 -1
  98. package/dist/playground/cli-table.d.ts +41 -5
  99. package/dist/playground/cli-table.d.ts.map +1 -1
  100. package/dist/playground/divider.d.ts +22 -3
  101. package/dist/playground/divider.d.ts.map +1 -1
  102. package/dist/playground/header.d.ts +21 -4
  103. package/dist/playground/header.d.ts.map +1 -1
  104. package/dist/playground/server-fallback.d.ts +96 -9
  105. package/dist/playground/server-fallback.d.ts.map +1 -1
  106. package/dist/playground/spinner.d.ts +159 -10
  107. package/dist/playground/spinner.d.ts.map +1 -1
  108. package/dist/playground/step.d.ts +25 -6
  109. package/dist/playground/step.d.ts.map +1 -1
  110. package/dist/playground.cjs +1 -1
  111. package/dist/playground.js +1 -1
  112. package/dist/serializers/SerializerBridge.d.ts +13 -6
  113. package/dist/serializers/SerializerBridge.d.ts.map +1 -1
  114. package/dist/serializers/SerializerRegistry.d.ts +236 -0
  115. package/dist/serializers/SerializerRegistry.d.ts.map +1 -1
  116. package/dist/serializers.cjs +1 -1
  117. package/dist/serializers.js +1 -1
  118. package/dist/styles/StyleManager.d.ts +138 -31
  119. package/dist/styles/StyleManager.d.ts.map +1 -1
  120. package/dist/styles.cjs +2 -2
  121. package/dist/styles.js +2 -2
  122. package/dist/styling/SmartPresets.d.ts +100 -6
  123. package/dist/styling/SmartPresets.d.ts.map +1 -1
  124. package/dist/styling/StyleBuilder.d.ts +453 -32
  125. package/dist/styling/StyleBuilder.d.ts.map +1 -1
  126. package/dist/styling/banners.d.ts +83 -7
  127. package/dist/styling/banners.d.ts.map +1 -1
  128. package/dist/styling/themes.d.ts +41 -2
  129. package/dist/styling/themes.d.ts.map +1 -1
  130. package/dist/transports/ConsoleTransport.d.ts +95 -0
  131. package/dist/transports/ConsoleTransport.d.ts.map +1 -1
  132. package/dist/transports/FileTransport.d.ts +99 -18
  133. package/dist/transports/FileTransport.d.ts.map +1 -1
  134. package/dist/transports/HttpTransport.d.ts +135 -22
  135. package/dist/transports/HttpTransport.d.ts.map +1 -1
  136. package/dist/transports/OtlpTraceTransport.d.ts +118 -0
  137. package/dist/transports/OtlpTraceTransport.d.ts.map +1 -0
  138. package/dist/transports/OtlpTransport.d.ts +80 -37
  139. package/dist/transports/OtlpTransport.d.ts.map +1 -1
  140. package/dist/transports/SpanRuntime.d.ts +73 -0
  141. package/dist/transports/SpanRuntime.d.ts.map +1 -0
  142. package/dist/transports/TransportBridge.d.ts +19 -13
  143. package/dist/transports/TransportBridge.d.ts.map +1 -1
  144. package/dist/transports/TransportManager.d.ts +232 -10
  145. package/dist/transports/TransportManager.d.ts.map +1 -1
  146. package/dist/transports/index.d.ts +1 -0
  147. package/dist/transports/index.d.ts.map +1 -1
  148. package/dist/transports-module.d.ts +3 -1
  149. package/dist/transports-module.d.ts.map +1 -1
  150. package/dist/transports.cjs +2 -1
  151. package/dist/transports.js +2 -2
  152. package/dist/types/core.d.ts +155 -59
  153. package/dist/types/core.d.ts.map +1 -1
  154. package/dist/types/hooks.d.ts +92 -14
  155. package/dist/types/hooks.d.ts.map +1 -1
  156. package/dist/types/index.d.ts +1 -1
  157. package/dist/types/index.d.ts.map +1 -1
  158. package/dist/types/serializers.d.ts +72 -0
  159. package/dist/types/serializers.d.ts.map +1 -1
  160. package/dist/types/transports.d.ts +163 -39
  161. package/dist/types/transports.d.ts.map +1 -1
  162. package/dist/utils/ansi-colors.d.ts +15 -15
  163. package/dist/utils/asyncLocalStorage.d.ts +33 -0
  164. package/dist/utils/asyncLocalStorage.d.ts.map +1 -0
  165. package/dist/utils/environment-detector.d.ts +11 -11
  166. package/dist/utils/formatting.d.ts +8 -8
  167. package/dist/utils/output.d.ts +9 -9
  168. package/dist/utils/output.d.ts.map +1 -1
  169. package/dist/utils/stackTrace.d.ts +2 -2
  170. package/package.json +24 -25
  171. package/dist/chunks/HookBridge-CiRfR67f.cjs +0 -190
  172. package/dist/chunks/HookBridge-CiRfR67f.cjs.map +0 -1
  173. package/dist/chunks/HookBridge-SgMmbXZB.js +0 -173
  174. package/dist/chunks/HookBridge-SgMmbXZB.js.map +0 -1
  175. package/dist/chunks/LogContext-Cwn-1Zzb.js.map +0 -1
  176. package/dist/chunks/LogContext-L7HzynFw.cjs.map +0 -1
  177. package/dist/chunks/SerializerBridge-BaOQOb8q.cjs +0 -166
  178. package/dist/chunks/SerializerBridge-BaOQOb8q.cjs.map +0 -1
  179. package/dist/chunks/SerializerBridge-BkpQu5c9.js +0 -149
  180. package/dist/chunks/SerializerBridge-BkpQu5c9.js.map +0 -1
  181. package/dist/chunks/StyleManager-CIpd6wbO.cjs.map +0 -1
  182. package/dist/chunks/StyleManager-LCvVlVdx.js +0 -87
  183. package/dist/chunks/StyleManager-LCvVlVdx.js.map +0 -1
  184. package/dist/chunks/core-Dzz7agGa.cjs.map +0 -1
  185. package/dist/chunks/core-PoT7RrTK.js.map +0 -1
  186. package/dist/chunks/environment-detector-CI3TrWK_.js.map +0 -1
  187. package/dist/chunks/environment-detector-Cnn6wr6O.cjs.map +0 -1
  188. package/dist/chunks/server-fallback-BUKjdLS7.cjs +0 -42
  189. package/dist/chunks/server-fallback-BUKjdLS7.cjs.map +0 -1
  190. package/dist/chunks/server-fallback-BsuWH1Dk.js +0 -37
  191. package/dist/chunks/server-fallback-BsuWH1Dk.js.map +0 -1
  192. package/dist/chunks/spinner-D3FsF78o.js.map +0 -1
  193. package/dist/chunks/spinner-DNvxbM9a.cjs.map +0 -1
  194. package/dist/chunks/styling-84N8T97t.js +0 -941
  195. package/dist/chunks/styling-84N8T97t.js.map +0 -1
  196. package/dist/chunks/styling-Cg5saQ46.cjs +0 -994
  197. package/dist/chunks/styling-Cg5saQ46.cjs.map +0 -1
  198. package/dist/chunks/transports-BiDk345e.js +0 -715
  199. package/dist/chunks/transports-BiDk345e.js.map +0 -1
  200. package/dist/chunks/transports-COPWmlF1.cjs +0 -756
  201. package/dist/chunks/transports-COPWmlF1.cjs.map +0 -1
  202. package/dist/chunks/utils-BqlFYocD.cjs.map +0 -1
  203. package/dist/chunks/utils-VETbVpkR.js.map +0 -1
  204. package/dist/example.d.ts +0 -18
  205. package/dist/example.d.ts.map +0 -1
  206. package/dist/main.d.ts +0 -2
  207. package/dist/main.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -1,21 +1,61 @@
1
- import { t as LOG_LEVELS } from "./chunks/core-PoT7RrTK.js";
2
- import { o as LOG_LEVEL_TO_SEVERITY_NUMBER, s as LOG_LEVEL_TO_SEVERITY_TEXT, t as TransportManager } from "./chunks/transports-BiDk345e.js";
3
- import { _ as DEFAULT_CONFIG, a as safeSerialize, b as parseStackTrace, c as ansiBackground, d as ansiDim, f as ansiStyle, g as CLI_LEVEL_MAP, h as formatSuccessANSI, i as getConsoleMethod, l as ansiBold, m as formatLogLevelANSI, o as createStyledOutput, p as ansiUnderline, r as formatTablePlain, s as setupThemeChangeListener, t as createLogEntry, u as ansiColor, y as formatTimestamp } from "./chunks/utils-VETbVpkR.js";
4
- import { a as THEME_BANNERS, c as StyleBuilder, i as BANNER_VARIANTS, l as StylePresets, n as getSmartPreset, o as displayInitBanner, r as hasPreset, s as THEME_PRESETS, t as getAvailablePresets } from "./chunks/styling-84N8T97t.js";
5
- import { a as getTerminalWidth, c as isRunningInTerminal, i as getTerminalHeight, l as supportsANSI, n as getEnvironment, r as getEnvironmentInfo, t as getColorCapability } from "./chunks/environment-detector-CI3TrWK_.js";
6
- import { a as renderDivider, c as formatBadge, i as renderBox, n as SpinnerManager, o as renderHeader, r as renderTable, s as renderStep, t as NoopSpinner } from "./chunks/spinner-D3FsF78o.js";
7
- import { t as createLogContext } from "./chunks/LogContext-Cwn-1Zzb.js";
8
- import { t as createHookBridge } from "./chunks/HookBridge-SgMmbXZB.js";
9
- import { t as createSerializerBridge } from "./chunks/SerializerBridge-BkpQu5c9.js";
10
- import { t as ServerFallback } from "./chunks/server-fallback-BsuWH1Dk.js";
11
- import { t as createStyleManager } from "./chunks/StyleManager-LCvVlVdx.js";
1
+ import { n as resolveAsyncLocalStorage, t as createLogContext } from "./chunks/LogContext-Dyzs61XG.js";
2
+ import { t as LOG_LEVELS } from "./chunks/core-Blfi2klP.js";
3
+ import { c as LOG_LEVEL_TO_SEVERITY_TEXT, s as LOG_LEVEL_TO_SEVERITY_NUMBER, t as TransportManager } from "./chunks/transports-DvaLAeGJ.js";
4
+ import { _ as DEFAULT_CONFIG, a as safeSerialize, b as parseStackTrace, c as ansiBackground, d as ansiDim, f as ansiStyle, g as CLI_LEVEL_MAP, h as formatSuccessANSI, i as getConsoleMethod, l as ansiBold, m as formatLogLevelANSI, o as createStyledOutput, p as ansiUnderline, r as formatTablePlain, s as setupThemeChangeListener, t as createLogEntry, u as ansiColor, y as formatTimestamp } from "./chunks/utils-tKfBAWUM.js";
5
+ import { a as THEME_BANNERS, c as StyleBuilder, i as BANNER_VARIANTS, l as StylePresets, n as getSmartPreset, o as displayInitBanner, r as hasPreset, s as THEME_PRESETS, t as getAvailablePresets } from "./chunks/styling-CRw3KQW4.js";
6
+ import { a as getTerminalWidth, c as isRunningInTerminal, i as getTerminalHeight, l as supportsANSI, n as getEnvironment, r as getEnvironmentInfo, t as getColorCapability } from "./chunks/environment-detector-7NvnYUfr.js";
7
+ import { a as renderDivider, c as formatBadge, i as renderBox, n as SpinnerManager, o as renderHeader, r as renderTable, s as renderStep, t as NoopSpinner } from "./chunks/spinner-BtkwpzYv.js";
8
+ import { t as createHookBridge } from "./chunks/HookBridge-CI2PH79S.js";
9
+ import { t as createSerializerBridge } from "./chunks/SerializerBridge-Ba43Mk7j.js";
10
+ import { t as ServerFallback } from "./chunks/server-fallback-jj0T6XaK.js";
11
+ import { t as createStyleManager } from "./chunks/StyleManager-DjwAYbxE.js";
12
12
  //#region src/ScopedLogger.ts
13
+ /**
14
+ * Logger prefijado por un scope nominal. Mantiene su propio stack de badges
15
+ * y contextos y delega el envío de mensajes al {@link Logger} padre a través
16
+ * de bindings (`{ scope, badges }`).
17
+ *
18
+ * Es la base de la jerarquía temática: {@link APILogger} y
19
+ * {@link ComponentLogger} extienden de ella, y {@link ContextLogger} la
20
+ * consume para apilar/subdesapilar sub-prefijos en el scope.
21
+ *
22
+ * No se construye directamente: se obtiene con `logger.scope('name')`.
23
+ *
24
+ * @example
25
+ * // El factory method del Logger raíz devuelve un ScopedLogger
26
+ * import logger from '@mks2508/better-logger';
27
+ *
28
+ * const http = logger.scope('HTTP');
29
+ * http.badge('OUTBOUND').info('Request enviada');
30
+ * // salida: [HTTP] [OUTBOUND] Request enviada
31
+ *
32
+ * @example
33
+ * // Anidar contextos dentro de un scope (el prefijo se compone con ':')
34
+ * const retry = http.context('retry');
35
+ * retry.run(() => http.warn('Reintentando petición'));
36
+ * // salida: [HTTP:retry] Reintentando petición
37
+ *
38
+ * @see {@link Logger.scope}
39
+ * @see {@link APILogger}
40
+ * @see {@link ComponentLogger}
41
+ * @see {@link ContextLogger}
42
+ */
13
43
  var ScopedLogger = class {
14
44
  parent;
15
45
  scopeName;
16
46
  badgeList = [];
17
47
  contextStack = [];
18
48
  _timers;
49
+ /**
50
+ * Construye un ScopedLogger vinculado a un {@link Logger} padre.
51
+ *
52
+ * Los clientes no deben llamar a este constructor directamente: usen
53
+ * `logger.scope(name)`, que configura correctamente la instancia.
54
+ *
55
+ * @param {Logger} parent - Logger raíz al que se delegan los mensajes.
56
+ * @param {string} scopeName - Etiqueta del scope; se renderiza como
57
+ * prefijo `[scopeName]` en cada línea.
58
+ */
19
59
  constructor(parent, scopeName) {
20
60
  this.parent = parent;
21
61
  this.scopeName = scopeName;
@@ -34,31 +74,125 @@ var ScopedLogger = class {
34
74
  if (this.contextStack.length === 0) return this.scopeName;
35
75
  return [this.scopeName, ...this.contextStack].join(":");
36
76
  }
77
+ /**
78
+ * Reemplaza la lista actual de badges por la pasada y la aplica a todos
79
+ * los mensajes posteriores de este scope.
80
+ *
81
+ * @param {string[]} badges - Etiquetas a mostrar como badges adyacentes
82
+ * al prefijo (p. ej. `['OUTBOUND', 'CACHED']`).
83
+ * @returns {this} La misma instancia, para encadenar llamadas.
84
+ *
85
+ * @example
86
+ * logger.scope('HTTP').badges(['OUTBOUND', 'CACHED']).info('Cache hit');
87
+ * // salida: [HTTP] [OUTBOUND] [CACHED] Cache hit
88
+ *
89
+ * @see {@link badge} para añadir sin reemplazar los existentes.
90
+ * @see {@link clearBadges} para vaciar la lista.
91
+ */
37
92
  badges(badges) {
38
93
  this.badgeList = [...badges];
39
94
  return this;
40
95
  }
96
+ /**
97
+ * Añade un badge al scope de forma idempotente (no lo duplica si ya existe).
98
+ *
99
+ * @param {string} badge - Etiqueta a añadir a la lista de badges.
100
+ * @returns {this} La misma instancia, para encadenar llamadas.
101
+ *
102
+ * @example
103
+ * logger.scope('API')
104
+ * .badge('OUTBOUND')
105
+ * .badge('RETRY')
106
+ * .warn('Reintentando');
107
+ * // salida: [API] [OUTBOUND] [RETRY] Reintentando
108
+ */
41
109
  badge(badge) {
42
110
  if (!this.badgeList.includes(badge)) this.badgeList.push(badge);
43
111
  return this;
44
112
  }
113
+ /**
114
+ * Vacía la lista de badges del scope.
115
+ *
116
+ * @returns {this} La misma instancia, para encadenar llamadas.
117
+ *
118
+ * @example
119
+ * const http = logger.scope('HTTP');
120
+ * http.badge('OUTBOUND').info('uno');
121
+ * http.clearBadges().info('dos');
122
+ * // [HTTP] [OUTBOUND] uno / [HTTP] dos
123
+ */
45
124
  clearBadges() {
46
125
  this.badgeList = [];
47
126
  return this;
48
127
  }
128
+ /**
129
+ * Aplica un theme preset al logger padre. El preset afecta a toda la
130
+ * instancia raíz (no solo a este scope) porque el style es compartido.
131
+ *
132
+ * @param {string} presetName - Nombre del preset registrado en el StyleManager.
133
+ * @returns {this} La misma instancia, para encadenar llamadas.
134
+ *
135
+ * @example
136
+ * logger.scope('UI').style('cyberpunk').info('neon');
137
+ * @see {@link Logger.setTheme}
138
+ */
49
139
  style(presetName) {
50
140
  this.parent.setTheme(presetName);
51
141
  return this;
52
142
  }
143
+ /**
144
+ * Crea un {@link ContextLogger} vinculado a este scope. Los contextos se
145
+ * apilan en el prefijo separados por `:`, permitiendo agrupar bloques de
146
+ * logs relacionados (reintentos, sub-etapas, etc.) sin `console.group`.
147
+ *
148
+ * @param {string} contextName - Nombre del contexto a apilar.
149
+ * @returns {ContextLogger} Handler con `run`, `runAsync`, `start`/`end`.
150
+ *
151
+ * @example
152
+ * const retry = logger.scope('HTTP').context('retry');
153
+ * retry.run(() => logger.warn('Reintentando'));
154
+ * // salida: [HTTP:retry] Reintentando
155
+ * @see {@link ContextLogger}
156
+ */
53
157
  context(contextName) {
54
158
  return new ContextLogger(this, contextName);
55
159
  }
160
+ /**
161
+ * Inicia un timer etiquetado bajo el namespace `<scopeName>:<label>`.
162
+ * El label es local a este scope, así que dos scopes pueden reutilizar el
163
+ * mismo nombre sin colisión.
164
+ *
165
+ * @param {string} label - Identificador del timer.
166
+ *
167
+ * @example
168
+ * const http = logger.scope('HTTP');
169
+ * http.time('request');
170
+ * // ... trabajo ...
171
+ * http.timeEnd('request'); // imprime "Timer: request - 12.34ms"
172
+ * @see {@link timeEnd}
173
+ */
56
174
  time(label) {
57
175
  this.timers.set(label, {
58
176
  label: `${this.scopeName}:${label}`,
59
177
  startTime: performance.now()
60
178
  });
61
179
  }
180
+ /**
181
+ * Detiene un timer previamente iniciado con {@link time} y registra la
182
+ * duración con nivel `success`. Si el label no existe, emite un `warn`
183
+ * y devuelve `undefined`.
184
+ *
185
+ * @param {string} label - Mismo label pasado a {@link time}.
186
+ * @returns {number | undefined} Milisegundos transcurridos, o `undefined`
187
+ * si el timer no estaba registrado.
188
+ *
189
+ * @example
190
+ * const http = logger.scope('HTTP');
191
+ * http.time('fetch');
192
+ * await fetch(url);
193
+ * const ms = http.timeEnd('fetch');
194
+ * if (ms && ms > 1000) http.warn('Latencia alta');
195
+ */
62
196
  timeEnd(label) {
63
197
  const timer = this.timers.get(label);
64
198
  if (!timer) {
@@ -70,118 +204,447 @@ var ScopedLogger = class {
70
204
  this.success(`Timer: ${label} - ${elapsed.toFixed(2)}ms`);
71
205
  return elapsed;
72
206
  }
207
+ /**
208
+ * Emite un mensaje a nivel `debug` con los bindings actuales del scope.
209
+ *
210
+ * @param {...unknown[]} args - Mensaje y argumentos adicionales (objetos,
211
+ * errores, etc.) serializados igual que en el logger raíz.
212
+ *
213
+ * @example
214
+ * logger.scope('DB').debug('query', { sql, params });
215
+ */
73
216
  debug(...args) {
74
217
  this.parent.logWithBindings(this.getBindings(), "debug", ...args);
75
218
  }
219
+ /**
220
+ * Emite un mensaje a nivel `info` con los bindings actuales del scope.
221
+ *
222
+ * @param {...unknown[]} args - Mensaje y argumentos adicionales.
223
+ *
224
+ * @example
225
+ * logger.scope('AUTH').info('Login exitoso', { userId });
226
+ */
76
227
  info(...args) {
77
228
  this.parent.logWithBindings(this.getBindings(), "info", ...args);
78
229
  }
230
+ /**
231
+ * Emite un mensaje a nivel `warn` con los bindings actuales del scope.
232
+ *
233
+ * @param {...unknown[]} args - Mensaje y argumentos adicionales.
234
+ *
235
+ * @example
236
+ * logger.scope('CACHE').warn('Cache miss', { key });
237
+ */
79
238
  warn(...args) {
80
239
  this.parent.logWithBindings(this.getBindings(), "warn", ...args);
81
240
  }
241
+ /**
242
+ * Emite un mensaje a nivel `error` con los bindings actuales del scope.
243
+ *
244
+ * @param {...unknown[]} args - Mensaje y argumentos adicionales (típicamente
245
+ * un `Error` o contexto del fallo).
246
+ *
247
+ * @example
248
+ * logger.scope('DB').error('Conexión rechazada', err);
249
+ */
82
250
  error(...args) {
83
251
  this.parent.logWithBindings(this.getBindings(), "error", ...args);
84
252
  }
253
+ /**
254
+ * Emite un mensaje con badge visual `SUCCESS` a nivel `info`. Úselo para
255
+ * hitos positivos dentro del scope (conexión establecida, sync completo,
256
+ * commit aplicado).
257
+ *
258
+ * @param {...unknown[]} args - Mensaje y argumentos adicionales.
259
+ *
260
+ * @example
261
+ * logger.scope('SYNC').success('Sincronización completa', { count: 42 });
262
+ */
85
263
  success(...args) {
86
264
  const bindings = this.getBindings();
87
265
  this.parent.logWithBindingsAndTag(bindings, "info", "success", ...args);
88
266
  }
267
+ /**
268
+ * Emite un mensaje a nivel `critical` con los bindings actuales del scope.
269
+ * Reservado para fallos que detienen el flujo de la aplicación.
270
+ *
271
+ * @param {...unknown[]} args - Mensaje y argumentos adicionales.
272
+ *
273
+ * @example
274
+ * logger.scope('PAY').critical('Pasarela inaccesible', err);
275
+ */
89
276
  critical(...args) {
90
277
  this.parent.logWithBindings(this.getBindings(), "critical", ...args);
91
278
  }
279
+ /**
280
+ * Emite un mensaje a nivel `trace` (verbosidad máxima) con los bindings
281
+ * actuales del scope. Solo aparece si la verbosity global lo permite.
282
+ *
283
+ * @param {...unknown[]} args - Mensaje y argumentos adicionales.
284
+ *
285
+ * @example
286
+ * logger.scope('NET').trace('packet', { bytes });
287
+ */
92
288
  trace(...args) {
93
289
  this.parent.logWithBindings(this.getBindings(), "trace", ...args);
94
290
  }
95
- /** @see Logger.step */
291
+ /**
292
+ * Emite un point-span con el scope de este logger como
293
+ * `SpanRecord.scope`. Ver {@link Logger.event}.
294
+ *
295
+ * @param {string} name - Nombre del evento.
296
+ * @param {SpanAttributes} [attributes] - Attributes del span.
297
+ *
298
+ * @example
299
+ * logger.scope('BUILD').event('step.done', { step: 'compile' });
300
+ */
301
+ event(name, attributes) {
302
+ this.parent._emitSpanEvent(name, attributes, this.getScopePrefix());
303
+ }
304
+ span(name, fnOrAttributes, maybeFn) {
305
+ const { attributes, fn } = resolveSpanArgs(fnOrAttributes, maybeFn);
306
+ return this.parent._runSpan(name, attributes, this.getScopePrefix(), fn);
307
+ }
308
+ /**
309
+ * Inicia un span externally-ended etiquetado con el scope de este
310
+ * logger. Ver {@link Logger.startSpan}.
311
+ *
312
+ * @param {string} name - Nombre de la operación.
313
+ * @param {SpanAttributes} [attributes] - Attributes iniciales.
314
+ * @returns {Span} Handle con `set`/`end`/`fail`.
315
+ */
316
+ startSpan(name, attributes) {
317
+ return this.parent._startSpan(name, attributes, this.getScopePrefix());
318
+ }
319
+ /**
320
+ * Delegación a {@link Logger.step}: dibuja una barra de progreso discreta
321
+ * `current/total` para este scope.
322
+ *
323
+ * @param {number} current - Paso actual (1-indexed).
324
+ * @param {number} total - Total de pasos.
325
+ * @param {string} message - Texto mostrado junto al contador.
326
+ * @see {@link Logger.step}
327
+ */
96
328
  step(current, total, message) {
97
329
  this.parent.step(current, total, message);
98
330
  }
99
- /** @see Logger.header */
331
+ /**
332
+ * Delegación a {@link Logger.header}: imprime un título con separadores visuales.
333
+ *
334
+ * @param {string} title - Texto del título.
335
+ * @param {string} [subtitle] - Subtítulo opcional bajo el título.
336
+ * @see {@link Logger.header}
337
+ */
100
338
  header(title, subtitle) {
101
339
  this.parent.header(title, subtitle);
102
340
  }
103
- /** @see Logger.divider */
341
+ /**
342
+ * Delegación a {@link Logger.divider}: imprime una línea separadora horizontal.
343
+ * @see {@link Logger.divider}
344
+ */
104
345
  divider() {
105
346
  this.parent.divider();
106
347
  }
107
- /** @see Logger.blank */
348
+ /**
349
+ * Delegación a {@link Logger.blank}: inserta una línea en blanco.
350
+ * @see {@link Logger.blank}
351
+ */
108
352
  blank() {
109
353
  this.parent.blank();
110
354
  }
111
- /** @see Logger.box */
355
+ /**
356
+ * Delegación a {@link Logger.box}: dibuja un recuadro ANSI alrededor de `content`.
357
+ *
358
+ * @param {string} content - Texto a enmarcar.
359
+ * @param {IBoxOptions} [options] - Opciones de estilo del box.
360
+ * @see {@link Logger.box}
361
+ */
112
362
  box(content, options) {
113
363
  this.parent.box(content, options);
114
364
  }
115
- /** @see Logger.cliTable */
365
+ /**
366
+ * Delegación a {@link Logger.cliTable}: renderiza `rows` como tabla ASCII.
367
+ *
368
+ * @param {Record<string, unknown>[]} rows - Filas a mostrar.
369
+ * @param {ITableOptions} [options] - Opciones de columnas y estilo.
370
+ * @see {@link Logger.cliTable}
371
+ */
116
372
  cliTable(rows, options) {
117
373
  this.parent.cliTable(rows, options);
118
374
  }
119
- /** @see Logger.spinner */
375
+ /**
376
+ * Delegación a {@link Logger.spinner}: arranca un spinner con `message`.
377
+ *
378
+ * @param {string} message - Texto a mostrar al lado del spinner.
379
+ * @returns {ISpinnerHandle} Handle para detener/actualizar el spinner.
380
+ * @see {@link Logger.spinner}
381
+ */
120
382
  spinner(message) {
121
383
  return this.parent.spinner(message);
122
384
  }
123
- /** @see Logger.setCLILevel */
385
+ /**
386
+ * Delegación a {@link Logger.setCLILevel}: ajusta el nivel mínimo de las
387
+ * primitivas CLI visibles.
388
+ *
389
+ * @param {CLILogLevel} level - Nivel CLI (`silent` … `verbose`).
390
+ * @see {@link Logger.setCLILevel}
391
+ */
124
392
  setCLILevel(level) {
125
393
  this.parent.setCLILevel(level);
126
394
  }
395
+ /**
396
+ * Apila un contexto en el prefijo del scope. Invocado por
397
+ * {@link ContextLogger}; los clientes no deben llamarlo directamente.
398
+ *
399
+ * @param {string} context - Nombre del contexto a apilar.
400
+ * @internal
401
+ */
127
402
  _pushContext(context) {
128
403
  this.contextStack.push(context);
129
404
  }
405
+ /**
406
+ * Desapila el último contexto del prefijo del scope. Invocado por
407
+ * {@link ContextLogger}; los clientes no deben llamarlo directamente.
408
+ *
409
+ * @internal
410
+ */
130
411
  _popContext() {
131
412
  this.contextStack.pop();
132
413
  }
133
414
  };
415
+ /**
416
+ * Logger especializado para llamadas a APIs y servicios externos.
417
+ *
418
+ * Extiende {@link ScopedLogger} pre-seteando el badge `API` y exponiendo
419
+ * atajos para eventos típicos de integración: llamadas lentas ({@link slow}),
420
+ * rate limiting ({@link rateLimit}), fallos de autenticación ({@link auth}) y
421
+ * APIs deprecadas ({@link deprecated}).
422
+ *
423
+ * Se obtiene con `logger.api(name)` y no se construye directamente.
424
+ *
425
+ * @example
426
+ * import logger from '@mks2508/better-logger';
427
+ *
428
+ * const stripe = logger.api('Stripe');
429
+ * stripe.info('Consultando customer', { id });
430
+ * // salida: [API:Stripe] [API] Consultando customer
431
+ *
432
+ * stripe.slow('customer.retrieve', 1250);
433
+ * // salida: [API:Stripe] [API] [SLOW] customer.retrieve (1250ms)
434
+ *
435
+ * @see {@link Logger.api}
436
+ * @see {@link ScopedLogger}
437
+ */
134
438
  var APILogger = class extends ScopedLogger {
439
+ /**
440
+ * Construye un APILogger con scope `API:<apiName>` y badge `API` ya aplicado.
441
+ *
442
+ * Los clientes deben usar `logger.api(name)`.
443
+ *
444
+ * @param {Logger} parent - Logger raíz al que se delegan los mensajes.
445
+ * @param {string} apiName - Nombre del servicio/API (se prefija con `API:`).
446
+ */
135
447
  constructor(parent, apiName) {
136
448
  super(parent, `API:${apiName}`);
137
449
  this.badge("API");
138
450
  }
451
+ /**
452
+ * Registra una llamada lenta con badge `SLOW` a nivel `warn`.
453
+ *
454
+ * @param {string} message - Descripción de la operación lenta.
455
+ * @param {number} [duration] - Duración medida en ms; si se pasa, se
456
+ * anexa al mensaje como `(Nms)`.
457
+ *
458
+ * @example
459
+ * const t0 = performance.now();
460
+ * await stripe.customers.retrieve(id);
461
+ * logger.api('Stripe').slow('retrieve', performance.now() - t0);
462
+ */
139
463
  slow(message, duration) {
140
464
  this.badge("SLOW");
141
465
  const msg = duration ? `${message} (${duration}ms)` : message;
142
466
  this.warn(msg);
143
467
  }
468
+ /**
469
+ * Registra un evento de rate limiting (HTTP 429) con badge `RATE_LIMIT`.
470
+ *
471
+ * @param {string} message - Detalle del límite golpeado.
472
+ *
473
+ * @example
474
+ * logger.api('GitHub').rateLimit('Secondary rate limit on /search');
475
+ */
144
476
  rateLimit(message) {
145
477
  this.badge("RATE_LIMIT");
146
478
  this.warn(message);
147
479
  }
480
+ /**
481
+ * Registra un fallo de autenticación (401/403) con badge `AUTH` a nivel
482
+ * `error`.
483
+ *
484
+ * @param {string} message - Detalle del fallo de credenciales/token.
485
+ *
486
+ * @example
487
+ * logger.api('OAuth').auth('Token expirado');
488
+ */
148
489
  auth(message) {
149
490
  this.badge("AUTH");
150
491
  this.error(message);
151
492
  }
493
+ /**
494
+ * Marca una API como deprecada con badge `DEPRECATED` a nivel `warn`.
495
+ *
496
+ * @param {string} message - Mensaje guiando a la migración (endpoint
497
+ * alternativo, versión retirada, etc.).
498
+ *
499
+ * @example
500
+ * logger.api('Legacy').deprecated('Usar v3; v2 se retira en Q4');
501
+ */
152
502
  deprecated(message) {
153
503
  this.badge("DEPRECATED");
154
504
  this.warn(message);
155
505
  }
156
506
  };
507
+ /**
508
+ * Logger para componentes UI, módulos o cualquier unidad con ciclo de vida.
509
+ *
510
+ * Extiende {@link ScopedLogger} pre-seteando el badge `COMPONENT` y exponiendo
511
+ * atajos para eventos típicos: {@link lifecycle}, {@link stateChange} y
512
+ * {@link propsChange}.
513
+ *
514
+ * Se obtiene con `logger.component(name)` y no se construye directamente.
515
+ *
516
+ * @example
517
+ * import logger from '@mks2508/better-logger';
518
+ *
519
+ * const cart = logger.component('Cart');
520
+ * cart.lifecycle('mount');
521
+ * // salida: [Cart] [COMPONENT] [LIFECYCLE] mount
522
+ *
523
+ * cart.stateChange('empty', 'has-items', { count: 3 });
524
+ * // salida: [Cart] [COMPONENT] [STATE] empty → has-items { count: 3 }
525
+ *
526
+ * @see {@link Logger.component}
527
+ * @see {@link ScopedLogger}
528
+ */
157
529
  var ComponentLogger = class extends ScopedLogger {
530
+ /**
531
+ * Construye un ComponentLogger con badge `COMPONENT` ya aplicado.
532
+ *
533
+ * Los clientes deben usar `logger.component(name)`.
534
+ *
535
+ * @param {Logger} parent - Logger raíz al que se delegan los mensajes.
536
+ * @param {string} componentName - Nombre del componente (scope label).
537
+ */
158
538
  constructor(parent, componentName) {
159
539
  super(parent, componentName);
160
540
  this.badge("COMPONENT");
161
541
  }
542
+ /**
543
+ * Registra un evento de ciclo de vida con badge `LIFECYCLE` a nivel `info`.
544
+ *
545
+ * @param {string} event - Nombre del evento (`mount`, `unmount`,
546
+ * `update`, ...).
547
+ * @param {string} [message] - Detalle opcional; si se omite, solo se
548
+ * registra el nombre del evento.
549
+ *
550
+ * @example
551
+ * logger.component('Cart').lifecycle('mount', 'Modal abierto');
552
+ */
162
553
  lifecycle(event, message) {
163
554
  this.badge("LIFECYCLE");
164
555
  const msg = message ? `${event}: ${message}` : event;
165
556
  this.info(msg);
166
557
  }
558
+ /**
559
+ * Registra una transición de estado con badge `STATE` a nivel `info`.
560
+ *
561
+ * @param {string} from - Estado previo.
562
+ * @param {string} to - Estado nuevo.
563
+ * @param {unknown} [data] - Payload opcional asociado a la transición.
564
+ *
565
+ * @example
566
+ * const fsm = logger.component('FSM');
567
+ * fsm.stateChange('idle', 'loading');
568
+ * fsm.stateChange('loading', 'success', { items: 3 });
569
+ */
167
570
  stateChange(from, to, data) {
168
571
  this.badge("STATE");
169
572
  const msg = `${from} → ${to}`;
170
573
  if (data) this.info(msg, data);
171
574
  else this.info(msg);
172
575
  }
576
+ /**
577
+ * Registra cambios de props/debug del componente con badge `PROPS` a nivel
578
+ * `debug`.
579
+ *
580
+ * @param {Record<string, unknown>} changes - Mapa prop → valor (típicamente
581
+ * el diff de props entre renders).
582
+ *
583
+ * @example
584
+ * logger.component('Cart').propsChange({ itemCount: 5, currency: 'EUR' });
585
+ */
173
586
  propsChange(changes) {
174
587
  this.badge("PROPS");
175
588
  this.debug("Props changed:", changes);
176
589
  }
177
590
  };
591
+ /**
592
+ * Handler de contexto apilable sobre un {@link ScopedLogger}.
593
+ *
594
+ * Permite agrupar bloques de logs bajo un sub-prefijo separado por `:`,
595
+ * manteniendo la correlación visual sin necesidad de `console.group`. El
596
+ * prefijo compuesto se forma como `<scopeName>:<contextName>`.
597
+ *
598
+ * Se crea con `scopedLogger.context(name)`. El patrón idiomático es
599
+ * {@link run}/{@link runAsync} (auto push/pop con try/finally); {@link start}
600
+ * y {@link end} permiten control manual cuando el bloque no cierra
601
+ * léxicamente (event handlers distribuidos, promesas de larga duración).
602
+ *
603
+ * @example
604
+ * import logger from '@mks2508/better-logger';
605
+ *
606
+ * const http = logger.scope('HTTP');
607
+ *
608
+ * // Bloque síncrono auto-cerrado
609
+ * http.context('retry').run(() => {
610
+ * http.warn('Reintentando petición');
611
+ * });
612
+ * // salida: [HTTP:retry] Reintentando petición
613
+ *
614
+ * // Bloque async auto-cerrado
615
+ * await http.context('refresh').runAsync(async () => {
616
+ * await refreshToken();
617
+ * http.info('Token refrescado');
618
+ * });
619
+ *
620
+ * @see {@link ScopedLogger.context}
621
+ */
178
622
  var ContextLogger = class {
179
623
  parentLogger;
180
624
  contextName;
625
+ /**
626
+ * @param {ScopedLogger} parentLogger - Scope sobre el que se apila el contexto.
627
+ * @param {string} contextName - Sub-prefijo a apilar en el scope padre.
628
+ */
181
629
  constructor(parentLogger, contextName) {
182
630
  this.parentLogger = parentLogger;
183
631
  this.contextName = contextName;
184
632
  }
633
+ /**
634
+ * Ejecuta `fn` síncrona dentro del contexto, garantizando el pop del
635
+ * prefijo incluso si `fn` lanza. El contexto solo está activo durante la
636
+ * ejecución de `fn`.
637
+ *
638
+ * @typeParam T - Tipo de retorno de `fn`.
639
+ * @param {() => T} fn - Función a ejecutar bajo el contexto.
640
+ * @returns {T} Lo que devuelva `fn`.
641
+ * @throws {unknown} Relanza cualquier excepción de `fn` tras desapilar.
642
+ *
643
+ * @example
644
+ * logger.scope('HTTP').context('warmup').run(() => {
645
+ * logger.info('Pre-cargando caché');
646
+ * });
647
+ */
185
648
  run(fn) {
186
649
  this.parentLogger._pushContext(this.contextName);
187
650
  try {
@@ -190,6 +653,21 @@ var ContextLogger = class {
190
653
  this.parentLogger._popContext();
191
654
  }
192
655
  }
656
+ /**
657
+ * Variante async de {@link run}: mantiene el contexto activo mientras se
658
+ * awaiting la promesa de `fn`, incluyendo awaits internos.
659
+ *
660
+ * @typeParam T - Tipo resuelto por la promesa de `fn`.
661
+ * @param {() => Promise<T>} fn - Función async a ejecutar bajo el contexto.
662
+ * @returns {Promise<T>} Promesa que resuelve al valor de `fn`.
663
+ * @throws {unknown} Relanza cualquier rechazo de `fn` tras desapilar.
664
+ *
665
+ * @example
666
+ * await logger.scope('HTTP').context('fetch').runAsync(async () => {
667
+ * const r = await fetch(url);
668
+ * logger.info('Recibido', { status: r.status });
669
+ * });
670
+ */
193
671
  async runAsync(fn) {
194
672
  this.parentLogger._pushContext(this.contextName);
195
673
  try {
@@ -198,27 +676,80 @@ var ContextLogger = class {
198
676
  this.parentLogger._popContext();
199
677
  }
200
678
  }
679
+ /**
680
+ * Apila el contexto manualmente. Útil cuando el bloque que lo consume no
681
+ * cierra léxicamente (event handlers, timeouts, streams). Debe emparejarse
682
+ * con un {@link end} posterior; olvidarlo deja el prefijo contaminado para
683
+ * los logs siguientes del scope.
684
+ *
685
+ * @example
686
+ * const ctx = logger.scope('WS').context('subscribe');
687
+ * socket.onopen = () => { ctx.start(); ctx.info('connected'); };
688
+ * socket.onclose = () => { ctx.info('disconnected'); ctx.end(); };
689
+ * @see {@link end}
690
+ */
201
691
  start() {
202
692
  this.parentLogger._pushContext(this.contextName);
203
693
  }
694
+ /**
695
+ * Desapila el último contexto abierto con {@link start}.
696
+ *
697
+ * @see {@link start}
698
+ */
204
699
  end() {
205
700
  this.parentLogger._popContext();
206
701
  }
702
+ /**
703
+ * Atajo a `scopedLogger.debug(...)`. El contexto se aplica al prefijo del
704
+ * scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.
705
+ *
706
+ * @param {...unknown[]} args - Mensaje y argumentos adicionales.
707
+ */
207
708
  debug(...args) {
208
709
  this.parentLogger.debug(...args);
209
710
  }
711
+ /**
712
+ * Atajo a `scopedLogger.info(...)`. El contexto se aplica al prefijo del
713
+ * scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.
714
+ *
715
+ * @param {...unknown[]} args - Mensaje y argumentos adicionales.
716
+ */
210
717
  info(...args) {
211
718
  this.parentLogger.info(...args);
212
719
  }
720
+ /**
721
+ * Atajo a `scopedLogger.warn(...)`. El contexto se aplica al prefijo del
722
+ * scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.
723
+ *
724
+ * @param {...unknown[]} args - Mensaje y argumentos adicionales.
725
+ */
213
726
  warn(...args) {
214
727
  this.parentLogger.warn(...args);
215
728
  }
729
+ /**
730
+ * Atajo a `scopedLogger.error(...)`. El contexto se aplica al prefijo del
731
+ * scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.
732
+ *
733
+ * @param {...unknown[]} args - Mensaje y argumentos adicionales.
734
+ */
216
735
  error(...args) {
217
736
  this.parentLogger.error(...args);
218
737
  }
738
+ /**
739
+ * Atajo a `scopedLogger.success(...)`. El contexto se aplica al prefijo del
740
+ * scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.
741
+ *
742
+ * @param {...unknown[]} args - Mensaje y argumentos adicionales.
743
+ */
219
744
  success(...args) {
220
745
  this.parentLogger.success(...args);
221
746
  }
747
+ /**
748
+ * Atajo a `scopedLogger.critical(...)`. El contexto se aplica al prefijo
749
+ * del scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.
750
+ *
751
+ * @param {...unknown[]} args - Mensaje y argumentos adicionales.
752
+ */
222
753
  critical(...args) {
223
754
  this.parentLogger.critical(...args);
224
755
  }
@@ -226,7 +757,34 @@ var ContextLogger = class {
226
757
  //#endregion
227
758
  //#region src/cli/CommandProcessor.ts
228
759
  /**
229
- * CLI command processor
760
+ * Procesador central del CLI del logger. Resuelve nombres de comando (con
761
+ * aliases), despacha ejecución, mantiene historial acotado (max 100 entradas)
762
+ * y soporta un sistema de plugins para extensión de terceros.
763
+ *
764
+ * No es un binario standalone: se invoca desde la consola del navegador vía
765
+ * `window.cli("<command>")` (modo interactivo habilitado por
766
+ * {@link enterInteractiveMode}) o desde código vía `logger.cli()`. El
767
+ * constructor no registra ningún comando por defecto — usar
768
+ * {@link createDefaultCLI} para obtener una instancia con los 8 comandos
769
+ * estándar ya cargados.
770
+ *
771
+ * @example
772
+ * ```ts
773
+ * const cli = createDefaultCLI();
774
+ * await cli.processCommand('/themes', logger);
775
+ * await cli.processCommand('/config theme=neon', logger);
776
+ * ```
777
+ *
778
+ * @example
779
+ * ```ts
780
+ * // Modo interactivo: expone `window.cli` en el navegador
781
+ * cli.enterInteractiveMode(logger);
782
+ * // Desde la devtools: cli('help') → procesa '/help'
783
+ * ```
784
+ *
785
+ * @see {@link createDefaultCLI}
786
+ * @see {@link ICommand}
787
+ * @see {@link ICLIPlugin}
230
788
  */
231
789
  var CommandProcessor = class {
232
790
  commands = /* @__PURE__ */ new Map();
@@ -236,14 +794,26 @@ var CommandProcessor = class {
236
794
  maxHistorySize = 100;
237
795
  isInteractiveMode = false;
238
796
  /**
239
- * Register a command
797
+ * Registra un comando. Si el comando declara `aliases`, también se indexan
798
+ * para resolución. Un comando con el mismo `name` sobreescribe al previo.
799
+ *
800
+ * @param {ICommand} command - Comando a registrar.
801
+ * @see {@link ICommand}
240
802
  */
241
803
  registerCommand(command) {
242
804
  this.commands.set(command.name, command);
243
805
  if (command.aliases) for (const alias of command.aliases) this.aliases.set(alias, command.name);
244
806
  }
245
807
  /**
246
- * Register a plugin
808
+ * Registra un plugin: indexa todos sus commands y, si el plugin define
809
+ * `initialize`, lo invoca con el processor y el logger. Los comandos del
810
+ * plugin se registran vía {@link registerCommand} y sus aliases quedan
811
+ * resolvibles igual que los directos.
812
+ *
813
+ * @param {ICLIPlugin} plugin - Plugin a registrar.
814
+ * @param {Logger} [logger] - Logger activo; requerido solo si el plugin define `initialize`.
815
+ * @throws {Error} Si ya existe un plugin registrado con el mismo `name`.
816
+ * @see {@link unregisterPlugin}
247
817
  */
248
818
  registerPlugin(plugin, logger) {
249
819
  if (this.plugins.has(plugin.name)) throw new Error(`Plugin ${plugin.name} is already registered`);
@@ -252,7 +822,12 @@ var CommandProcessor = class {
252
822
  if (plugin.initialize && logger) plugin.initialize(this, logger);
253
823
  }
254
824
  /**
255
- * Unregister a plugin
825
+ * Desregistra un plugin por nombre: elimina todos sus commands (y los
826
+ * aliases que aportasen), invoca su hook `cleanup` si existe y lo quita
827
+ * del registry. No-op si el nombre no existe.
828
+ *
829
+ * @param {string} pluginName - Nombre del plugin a desregistrar.
830
+ * @see {@link registerPlugin}
256
831
  */
257
832
  unregisterPlugin(pluginName) {
258
833
  const plugin = this.plugins.get(pluginName);
@@ -265,13 +840,20 @@ var CommandProcessor = class {
265
840
  this.plugins.delete(pluginName);
266
841
  }
267
842
  /**
268
- * Get all registered commands
843
+ * Lista todos los commands registrados (directamente o vía plugins).
844
+ * No incluye aliases.
845
+ *
846
+ * @returns {ICommand[]} Snapshot array de los commands registrados.
269
847
  */
270
848
  getCommands() {
271
849
  return Array.from(this.commands.values());
272
850
  }
273
851
  /**
274
- * Get a specific command
852
+ * Resuelve un comando por nombre canónico o alias. Devuelve `undefined`
853
+ * si no existe ninguno que matchee.
854
+ *
855
+ * @param {string} name - Nombre canónico o alias del comando.
856
+ * @returns {ICommand | undefined} El comando resuelto, o `undefined`.
275
857
  */
276
858
  getCommand(name) {
277
859
  let command = this.commands.get(name);
@@ -280,25 +862,38 @@ var CommandProcessor = class {
280
862
  if (aliasTarget) return this.commands.get(aliasTarget);
281
863
  }
282
864
  /**
283
- * Get command history
865
+ * Devuelve una copia del historial de comandos ejecutados (más recientes
866
+ * primero). Acotado a 100 entradas por {@link maxHistorySize}; las más
867
+ * viejas se descartan al insertar nuevas.
868
+ *
869
+ * @returns {HistoryEntry[]} Snapshot del historial; mutar el array devuelto
870
+ * no afecta al estado interno del processor.
284
871
  */
285
872
  getHistory() {
286
873
  return [...this.history];
287
874
  }
288
875
  /**
289
- * Clear command history
876
+ * Vacía el historial de comandos en memoria.
290
877
  */
291
878
  clearHistory() {
292
879
  this.history = [];
293
880
  }
294
881
  /**
295
- * Get registered plugins
882
+ * Lista los plugins actualmente registrados.
883
+ *
884
+ * @returns {ICLIPlugin[]} Snapshot array de plugins activos.
296
885
  */
297
886
  getPlugins() {
298
887
  return Array.from(this.plugins.values());
299
888
  }
300
889
  /**
301
- * Enter interactive mode
890
+ * Activa el modo interactivo. Marca el flag interno y, si se ejecuta en
891
+ * navegador, expone `window.cli(command)` para invocar comandos desde la
892
+ * devtools sin prefijo `/` (se añade automáticamente al input).
893
+ *
894
+ * @param {Logger} logger - Logger activo (emite el mensaje de bienvenida
895
+ * con hint sobre `cli(...)` en browser).
896
+ * @see {@link exitInteractiveMode}
302
897
  */
303
898
  enterInteractiveMode(logger) {
304
899
  this.isInteractiveMode = true;
@@ -306,13 +901,22 @@ var CommandProcessor = class {
306
901
  if (typeof window !== "undefined") this.setupBrowserInteractiveMode(logger);
307
902
  }
308
903
  /**
309
- * Exit interactive mode
904
+ * Desactiva el flag de modo interactivo. Nota: no elimina el `window.cli`
905
+ * que {@link enterInteractiveMode} haya expuesto en el navegador — el
906
+ * handler global sigue vivo hasta reload.
907
+ *
908
+ * @see {@link enterInteractiveMode}
310
909
  */
311
910
  exitInteractiveMode() {
312
911
  this.isInteractiveMode = false;
313
912
  }
314
913
  /**
315
- * Setup browser interactive mode
914
+ * Instala `window.cli(command)` como wrapper delgado alrededor de
915
+ * {@link processCommand}, prefijando `/` automáticamente. Solo se invoca
916
+ * desde {@link enterInteractiveMode} cuando `window` está disponible.
917
+ *
918
+ * @internal
919
+ * @param logger - Logger activo, reenviado a cada invocación.
316
920
  */
317
921
  setupBrowserInteractiveMode(logger) {
318
922
  window.cli = (commandString) => {
@@ -321,7 +925,20 @@ var CommandProcessor = class {
321
925
  logger.info("💡 Use cli(\"command\") to execute CLI commands in browser console.");
322
926
  }
323
927
  /**
324
- * Process a CLI command
928
+ * Parsea y ejecuta un comando. El formato esperado es `/name args...`:
929
+ * split por espacios, primer token = nombre del comando, resto = args
930
+ * (re-joined con espacios). Si el comando no existe, loguea el error y
931
+ * sugiere similares vía {@link getSuggestions} ("Did you mean: ...?").
932
+ *
933
+ * Toda invocación (válida o no) se registra en el historial con flag de
934
+ * éxito/fallo según si `execute` resolvió o throweó.
935
+ *
936
+ * @param {string} commandString - Comando completo, debe empezar con `/`.
937
+ * @param {Logger} logger - Logger activo para output y errores.
938
+ * @returns {Promise<void>} Resuelve cuando el comando termina (sync o async).
939
+ * Nunca rechaza: los errores de `execute` se capturan y se loguean.
940
+ * @see {@link ICommand.execute}
941
+ * @see {@link getSuggestions}
325
942
  */
326
943
  async processCommand(commandString, logger) {
327
944
  if (!commandString.startsWith("/")) {
@@ -349,7 +966,12 @@ var CommandProcessor = class {
349
966
  }
350
967
  }
351
968
  /**
352
- * Add command to history
969
+ * Inserta una entrada al frente del historial y trunca a
970
+ * {@link maxHistorySize} (100) si hace falta.
971
+ *
972
+ * @internal
973
+ * @param command - String crudo del comando ejecutado.
974
+ * @param success - Si la ejecución tuvo éxito.
353
975
  */
354
976
  addToHistory(command, success) {
355
977
  this.history.unshift({
@@ -360,7 +982,12 @@ var CommandProcessor = class {
360
982
  if (this.history.length > this.maxHistorySize) this.history = this.history.slice(0, this.maxHistorySize);
361
983
  }
362
984
  /**
363
- * Get command suggestions for partial matches
985
+ * Devuelve nombres de comando que empiezan con el prefijo dado. Alimente
986
+ * el hint "Did you mean" de {@link processCommand} cuando un comando no
987
+ * se encuentra. Match por `startsWith` (no fuzzy).
988
+ *
989
+ * @param {string} partial - Prefijo parcial tipeado por el usuario.
990
+ * @returns {string[]} Nombres canónicos que matchean; aliases excluidos.
364
991
  */
365
992
  getSuggestions(partial) {
366
993
  return Array.from(this.commands.keys()).filter((name) => name.startsWith(partial));
@@ -369,12 +996,47 @@ var CommandProcessor = class {
369
996
  //#endregion
370
997
  //#region src/cli/commands/ConfigCommand.ts
371
998
  /**
372
- * Configuration command handler
999
+ * Comando `/config` del CLI runtime del {@link Logger}. Inspecciona o muta
1000
+ * la configuración del logger en vivo desde la DevTools console.
1001
+ *
1002
+ * Acepta tres modos de invocación:
1003
+ * - Sin argumentos: vuelca el estado actual como tabla agrupada.
1004
+ * - JSON completo (empieza con `{`): aplica un objeto de configuración parcial.
1005
+ * - Pares `key=value` separados por coma: atajo para mutaciones puntuales.
1006
+ *
1007
+ * Solo se aplican las keys de la whitelist interna (`theme`, `verbosity`,
1008
+ * `enableColors`, `enableTimestamps`, `enableStackTrace`, `globalPrefix`,
1009
+ * `bannerType`); cualquier otra key se rechaza con un `warn` y se ignora.
1010
+ *
1011
+ * @example
1012
+ * // Sin argumentos: ver estado actual
1013
+ * // > /config
1014
+ *
1015
+ * @example
1016
+ * // Objeto JSON completo
1017
+ * // > /config {"theme":"neon","verbosity":"debug"}
1018
+ *
1019
+ * @example
1020
+ * // Atajo key=value (múltiples pares separados por coma)
1021
+ * // > /config theme=neon,verbosity=debug,globalPrefix=MiApp
1022
+ *
1023
+ * @see {@link ICommand} para el contrato que implementa este comando.
1024
+ * @see {@link Logger.setTheme}, {@link Logger.setVerbosity},
1025
+ * {@link Logger.setBannerType}, {@link Logger.setGlobalPrefix}
1026
+ * para los setters subyacentes.
373
1027
  */
374
1028
  var ConfigCommand = class {
375
1029
  name = "config";
376
1030
  description = "Show or update logger configuration";
377
1031
  usage = "/config [json|key=value,...]";
1032
+ /**
1033
+ * Ejecuta el comando `/config` contra el logger dado.
1034
+ *
1035
+ * @param args - Argumentos crudos del usuario. Vacío = status; con `{`
1036
+ * inicial = parse JSON; resto = pares `key=value` separados
1037
+ * por coma.
1038
+ * @param logger - Instancia destino cuyos setters se invocan.
1039
+ */
378
1040
  execute(args, logger) {
379
1041
  if (!args) {
380
1042
  this.showStatus(logger);
@@ -448,12 +1110,30 @@ var ConfigCommand = class {
448
1110
  //#endregion
449
1111
  //#region src/cli/commands/ThemeCommand.ts
450
1112
  /**
451
- * Themes command - show available themes
1113
+ * Comando `/themes` del CLI runtime del {@link Logger}. Lista los presets
1114
+ * temáticos disponibles en {@link THEME_PRESETS}, renderizando una preview
1115
+ * con los colores reales de cada tema (background, foreground, border).
1116
+ *
1117
+ * Es de solo lectura: no muta el logger. Útil para descubrir qué tema
1118
+ * aplicar antes de correr `/config theme=<name>`.
1119
+ *
1120
+ * @example
1121
+ * // Listar todos los temas con preview coloreada
1122
+ * // > /themes
1123
+ *
1124
+ * @see {@link THEME_PRESETS} para el catálogo completo de temas.
1125
+ * @see {@link ConfigCommand} para aplicar un tema vía `/config theme=...`.
452
1126
  */
453
1127
  var ThemesCommand = class {
454
1128
  name = "themes";
455
1129
  description = "Show available theme presets";
456
1130
  usage = "/themes";
1131
+ /**
1132
+ * Ejecuta el comando `/themes` contra el logger dado.
1133
+ *
1134
+ * @param _args - Ignorado (comando sin parámetros).
1135
+ * @param logger - Instancia usada para abrir/cerrar el `group` de salida.
1136
+ */
457
1137
  execute(_args, logger) {
458
1138
  logger.group("🎨 Available Themes");
459
1139
  Object.keys(THEME_PRESETS).forEach((themeName) => {
@@ -465,12 +1145,30 @@ var ThemesCommand = class {
465
1145
  }
466
1146
  };
467
1147
  /**
468
- * Banners command - show available banner types
1148
+ * Comando `/banners` del CLI runtime del {@link Logger}. Enumera los tipos
1149
+ * de banner disponibles en {@link BANNER_VARIANTS} (`simple`, `ascii`,
1150
+ * `unicode`, ...) con una mini-preview de cada uno para inspección visual.
1151
+ *
1152
+ * Es de solo lectura: no muta el logger. Para cambiar el banner activo
1153
+ * usar {@link BannerCommand}.
1154
+ *
1155
+ * @example
1156
+ * // Listar todas las variantes de banner con preview
1157
+ * // > /banners
1158
+ *
1159
+ * @see {@link BANNER_VARIANTS} para el catálogo completo de variantes.
1160
+ * @see {@link BannerCommand} para aplicar un tipo concreto.
469
1161
  */
470
1162
  var BannersCommand = class {
471
1163
  name = "banners";
472
1164
  description = "Show available banner types";
473
1165
  usage = "/banners";
1166
+ /**
1167
+ * Ejecuta el comando `/banners` contra el logger dado.
1168
+ *
1169
+ * @param _args - Ignorado (comando sin parámetros).
1170
+ * @param logger - Instancia usada para abrir/cerrar el `group` de salida.
1171
+ */
474
1172
  execute(_args, logger) {
475
1173
  logger.group("🖼️ Available Banner Types");
476
1174
  Object.keys(BANNER_VARIANTS).forEach((bannerName) => {
@@ -486,12 +1184,35 @@ var BannersCommand = class {
486
1184
  }
487
1185
  };
488
1186
  /**
489
- * Banner command - change/show banner type
1187
+ * Comando `/banner [type]` del CLI runtime del {@link Logger}.
1188
+ *
1189
+ * - Sin argumentos: re-renderiza el banner actualmente activo.
1190
+ * - Con un tipo válido: lo aplica vía {@link Logger.setBannerType} y lo
1191
+ * muestra inmediatamente.
1192
+ * - Con un tipo inválido: loguea un `error` listando las opciones válidas.
1193
+ *
1194
+ * @example
1195
+ * // Mostrar el banner actual
1196
+ * // > /banner
1197
+ *
1198
+ * @example
1199
+ * // Cambiar a un tipo concreto
1200
+ * // > /banner ascii
1201
+ *
1202
+ * @see {@link BANNER_VARIANTS} para los tipos aceptados.
1203
+ * @see {@link Logger.setBannerType} y {@link Logger.showBanner} para los
1204
+ * métodos subyacentes.
490
1205
  */
491
1206
  var BannerCommand = class {
492
1207
  name = "banner";
493
1208
  description = "Change or show current banner type";
494
1209
  usage = "/banner [type]";
1210
+ /**
1211
+ * Ejecuta el comando `/banner` contra el logger dado.
1212
+ *
1213
+ * @param args - Tipo de banner solicitado. Vacío = mostrar banner actual.
1214
+ * @param logger - Instancia destino cuyo banner se actualiza/muestra.
1215
+ */
495
1216
  execute(args, logger) {
496
1217
  if (!args) {
497
1218
  logger.showBanner();
@@ -506,12 +1227,27 @@ var BannerCommand = class {
506
1227
  //#endregion
507
1228
  //#region src/cli/commands/ExportCommand.ts
508
1229
  /**
509
- * Status command - show logger configuration and statistics
1230
+ * Comando `/status` del CLI runtime del {@link Logger}. Vuelca la
1231
+ * configuración vigente y algunas estadísticas (theme, verbosity, flags
1232
+ * de features, handler count, bufferSize) en una tabla agrupada dentro
1233
+ * de la consola. Es de solo lectura: no muta el logger.
1234
+ *
1235
+ * @example
1236
+ * // Inspeccionar el estado actual del logger
1237
+ * // > /status
1238
+ *
1239
+ * @see {@link Logger.getConfig} fuente de los datos mostrados.
510
1240
  */
511
1241
  var StatusCommand = class {
512
1242
  name = "status";
513
1243
  description = "Show current logger status and configuration";
514
1244
  usage = "/status";
1245
+ /**
1246
+ * Ejecuta el comando `/status` contra el logger dado.
1247
+ *
1248
+ * @param _args - Ignorado (comando sin parámetros).
1249
+ * @param logger - Instancia de la que se lee la configuración.
1250
+ */
515
1251
  execute(_args, logger) {
516
1252
  const config = logger.getConfig();
517
1253
  const statusData = {
@@ -531,23 +1267,54 @@ var StatusCommand = class {
531
1267
  }
532
1268
  };
533
1269
  /**
534
- * Reset command - reset logger to defaults
1270
+ * Comando `/reset` del CLI runtime del {@link Logger}. Restaura la
1271
+ * configuración a sus defaults de fábrica vía {@link Logger.resetConfig}.
1272
+ * No resetea handlers ni transports registrados — solo config.
1273
+ *
1274
+ * @example
1275
+ * // Volver a la configuración por defecto
1276
+ * // > /reset
1277
+ *
1278
+ * @see {@link Logger.resetConfig} para el método subyacente.
535
1279
  */
536
1280
  var ResetCommand = class {
537
1281
  name = "reset";
538
1282
  description = "Reset logger configuration to defaults";
539
1283
  usage = "/reset";
1284
+ /**
1285
+ * Ejecuta el comando `/reset` contra el logger dado.
1286
+ *
1287
+ * @param _args - Ignorado (comando sin parámetros).
1288
+ * @param logger - Instancia cuya configuración se resetea.
1289
+ */
540
1290
  execute(_args, logger) {
541
1291
  logger.resetConfig();
542
1292
  }
543
1293
  };
544
1294
  /**
545
- * Demo command - show logger feature demonstration
1295
+ * Comando `/demo` del CLI runtime del {@link Logger}. Ejecuta una
1296
+ * demostración integral de las capacidades del logger: todos los niveles
1297
+ * de log (debug → critical), tablas, timers (`time`/`timeEnd`), SVG inline
1298
+ * y mensajes animados. Útil para validar que el styling funciona en un
1299
+ * entorno nuevo o tras un cambio de tema.
1300
+ *
1301
+ * @example
1302
+ * // Lanzar la demo completa
1303
+ * // > /demo
1304
+ *
1305
+ * @see {@link Logger} para cada feature individual (`table`, `time`,
1306
+ * `logWithSVG`, `logAnimated`, ...).
546
1307
  */
547
1308
  var DemoCommand = class {
548
1309
  name = "demo";
549
1310
  description = "Show comprehensive feature demonstration";
550
1311
  usage = "/demo";
1312
+ /**
1313
+ * Ejecuta el comando `/demo` contra el logger dado.
1314
+ *
1315
+ * @param _args - Ignorado (comando sin parámetros).
1316
+ * @param logger - Instancia sobre la que se ejecutan los ejemplos.
1317
+ */
551
1318
  execute(_args, logger) {
552
1319
  logger.group("🎪 Advanced Logger Demo");
553
1320
  logger.debug("Debug message with detailed information");
@@ -593,12 +1360,38 @@ var DemoCommand = class {
593
1360
  //#endregion
594
1361
  //#region src/cli/help.ts
595
1362
  /**
596
- * Help command - show comprehensive CLI help
1363
+ * Comando `/help`: renderiza en consola el panel de ayuda del CLI con todos
1364
+ * los comandos disponibles, opciones de configuración, filtros de export y
1365
+ * ejemplos. El panel usa un gradient claro con {@link StyleBuilder} y los
1366
+ * quick tips se agrupan vía `logger.group`.
1367
+ *
1368
+ * Registrado por defecto por {@link createDefaultCLI}.
1369
+ *
1370
+ * @example
1371
+ * ```ts
1372
+ * const cli = createDefaultCLI();
1373
+ * await cli.processCommand('/help', logger);
1374
+ * // Imprime el panel ASCII con gradient + grupo "Quick Tips".
1375
+ * ```
1376
+ *
1377
+ * @see {@link ICommand}
1378
+ * @see {@link createDefaultCLI}
597
1379
  */
598
1380
  var HelpCommand = class {
599
1381
  name = "help";
600
1382
  description = "Show CLI help and available commands";
601
1383
  usage = "/help [command]";
1384
+ /**
1385
+ * Renderiza el panel de ayuda completo. Actualmente ignora `_args`: el
1386
+ * `usage` declara `/help [command]` (sub-comando opcional) pero la
1387
+ * implementación siempre muestra el panel global.
1388
+ *
1389
+ * @param {string} _args - Argumentos opcionales (reservado para ayuda por
1390
+ * sub-comando; sin uso actual).
1391
+ * @param {Logger} logger - Logger activo; se usa solo para `group`/`info`
1392
+ * de los quick tips.
1393
+ * @returns {void}
1394
+ */
602
1395
  execute(_args, logger) {
603
1396
  const helpStyle = new StyleBuilder().bg("linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%)").color("#495057").padding("15px 20px").rounded("8px").border("1px solid #dee2e6").font("Monaco, Consolas, monospace").size("13px").build();
604
1397
  console.log(`%c
@@ -698,7 +1491,30 @@ var HelpCommand = class {
698
1491
  //#endregion
699
1492
  //#region src/cli/index.ts
700
1493
  /**
701
- * Create and configure default CLI processor
1494
+ * Crea un {@link CommandProcessor} con los 8 comandos estándar ya registrados:
1495
+ * `help`, `config`, `themes`, `banners`, `banner`, `status`, `reset` y
1496
+ * `demo`. Es el factory canónico — los consumidores normalmente no construyen
1497
+ * un `CommandProcessor` vacío a mano, ya que este no trae comandos cargados.
1498
+ *
1499
+ * @returns {CommandProcessor} Processor listo para usar, sin modo interactivo activo.
1500
+ *
1501
+ * @example
1502
+ * ```ts
1503
+ * const cli = createDefaultCLI();
1504
+ * await cli.processCommand('/help', logger);
1505
+ * await cli.processCommand('/config theme=neon', logger);
1506
+ * ```
1507
+ *
1508
+ * @example
1509
+ * ```ts
1510
+ * // Modo interactivo en el navegador: expone `window.cli`
1511
+ * const cli = createDefaultCLI();
1512
+ * cli.enterInteractiveMode(logger);
1513
+ * // desde devtools: cli('themes') → procesa '/themes'
1514
+ * ```
1515
+ *
1516
+ * @see {@link CommandProcessor}
1517
+ * @see {@link HelpCommand}
702
1518
  */
703
1519
  function createDefaultCLI() {
704
1520
  const processor = new CommandProcessor();
@@ -715,7 +1531,9 @@ function createDefaultCLI() {
715
1531
  //#endregion
716
1532
  //#region src/transports/TransportBridge.ts
717
1533
  /**
718
- * Creates a TransportBridge instance.
1534
+ * Crea una instancia de {@link TransportBridge}.
1535
+ *
1536
+ * @internal
719
1537
  */
720
1538
  function createTransportBridge() {
721
1539
  let transportManager;
@@ -743,9 +1561,170 @@ function createTransportBridge() {
743
1561
  };
744
1562
  }
745
1563
  //#endregion
1564
+ //#region src/transports/SpanRuntime.ts
1565
+ /** ALS singleton del módulo — compartido por todas las instancias de Logger.
1566
+ *
1567
+ * Resolución por capas (global → `process.getBuiltinModule` → `require`,
1568
+ * undefined en browser) delegada al helper compartido
1569
+ * {@link resolveAsyncLocalStorage} — ver su doc para el detalle de capas.
1570
+ * `context/LogContext.ts` usa el mismo helper para su ALS de MDC. */
1571
+ const activeSpanStore = resolveAsyncLocalStorage();
1572
+ /**
1573
+ * Span activo en el call stack corriente (dentro de `span(fn)`), si lo hay.
1574
+ * Lo consumen la correlación log→span (`TransportRecord.traceId/spanId`) y la
1575
+ * resolución de `parentSpanId` en spans hijos.
1576
+ */
1577
+ function getActiveSpan() {
1578
+ return activeSpanStore?.getStore();
1579
+ }
1580
+ /**
1581
+ * Ejecuta `fn` con `record` como span activo. Sin ALS disponible (browser),
1582
+ * ejecuta `fn` directamente — sin correlación pero funcional.
1583
+ */
1584
+ function runWithActiveSpan(record, fn) {
1585
+ return activeSpanStore ? activeSpanStore.run(record, fn) : fn();
1586
+ }
1587
+ /** Nanosegundos Unix actuales como string decimal (formato OTLP). */
1588
+ function nowUnixNano() {
1589
+ return String(BigInt(Date.now()) * 1000000n);
1590
+ }
1591
+ /**
1592
+ * Hex aleatorio de `bytes` bytes. Usa `crypto.getRandomValues`; sin
1593
+ * `crypto` (runtimes exóticos) degrada a `Math.random` — suficiente para ids
1594
+ * de correlación, no para secrets.
1595
+ */
1596
+ function randomHex(bytes) {
1597
+ const cryptoObj = globalThis.crypto;
1598
+ if (cryptoObj?.getRandomValues) {
1599
+ const buf = new Uint8Array(bytes);
1600
+ cryptoObj.getRandomValues(buf);
1601
+ let out = "";
1602
+ for (const b of buf) out += b.toString(16).padStart(2, "0");
1603
+ return out;
1604
+ }
1605
+ let out = "";
1606
+ for (let i = 0; i < bytes * 2; i++) out += Math.floor(Math.random() * 16).toString(16);
1607
+ return out;
1608
+ }
1609
+ /** Trace id W3C: 16 bytes → 32 chars hex. */
1610
+ function generateTraceId() {
1611
+ return randomHex(16);
1612
+ }
1613
+ /** Span id W3C: 8 bytes → 16 chars hex. */
1614
+ function generateSpanId() {
1615
+ return randomHex(8);
1616
+ }
1617
+ /**
1618
+ * Registry de spans abiertos (leak-safety). Cubre tanto los de `startSpan()`
1619
+ * (externally-ended, el caso del handoff) como los de `span(fn)` en curso:
1620
+ * si un flush llega mid-flight, es mejor exportar el span incompleto que
1621
+ * tirarlo. El doble-`end()` es no-op, así que el cierre natural posterior no
1622
+ * duplica el export.
1623
+ */
1624
+ const openSpans = /* @__PURE__ */ new Map();
1625
+ /**
1626
+ * Crea el record de span y su {@link Span} handle. El handle registra el
1627
+ * span en el registry de abiertos; `onEnd` se invoca una única vez, con el
1628
+ * record final (duración real o `incomplete: true`), para su export al
1629
+ * pipeline de transports.
1630
+ *
1631
+ * `end()` solo fija `endTimeUnixNano` si no se fijó antes — así los
1632
+ * point-spans (`event()`) pueden fijar `end = start` exacto.
1633
+ *
1634
+ * @param name - Nombre de la operación.
1635
+ * @param attributes - Attributes iniciales (copia propia del record).
1636
+ * @param scope - Scope del logger emisor.
1637
+ * @param onEnd - Callback de export; recibe el record cerrado.
1638
+ * @returns El record (para el ALS store) y el handle del span.
1639
+ */
1640
+ function createSpan(name, attributes, scope, onEnd) {
1641
+ const parent = getActiveSpan();
1642
+ const record = {
1643
+ kind: "span",
1644
+ traceId: parent?.traceId ?? generateTraceId(),
1645
+ spanId: generateSpanId(),
1646
+ parentSpanId: parent?.spanId,
1647
+ name,
1648
+ spanKind: 1,
1649
+ startTimeUnixNano: nowUnixNano(),
1650
+ endTimeUnixNano: "0",
1651
+ attributes: { ...attributes ?? {} },
1652
+ scope
1653
+ };
1654
+ let ended = false;
1655
+ const finish = () => {
1656
+ if (ended) return;
1657
+ ended = true;
1658
+ openSpans.delete(record);
1659
+ onEnd(record);
1660
+ };
1661
+ openSpans.set(record, {
1662
+ record,
1663
+ end: finish,
1664
+ forceEnd: () => {
1665
+ if (ended) return;
1666
+ record.incomplete = true;
1667
+ if (record.endTimeUnixNano === "0") record.endTimeUnixNano = nowUnixNano();
1668
+ finish();
1669
+ }
1670
+ });
1671
+ const handle = {
1672
+ traceId: record.traceId,
1673
+ spanId: record.spanId,
1674
+ set(key, value) {
1675
+ record.attributes[key] = value;
1676
+ return handle;
1677
+ },
1678
+ end(attributes) {
1679
+ if (attributes) Object.assign(record.attributes, attributes);
1680
+ if (ended) return;
1681
+ if (record.endTimeUnixNano === "0") record.endTimeUnixNano = nowUnixNano();
1682
+ finish();
1683
+ },
1684
+ fail(err) {
1685
+ if (ended) return;
1686
+ record.status = {
1687
+ code: 2,
1688
+ message: err instanceof Error ? err.message : String(err)
1689
+ };
1690
+ this.end();
1691
+ }
1692
+ };
1693
+ return {
1694
+ record,
1695
+ span: handle
1696
+ };
1697
+ }
1698
+ /**
1699
+ * Emite un point-span (`event()`): start = end exactamente, sin registro en
1700
+ * abiertos tras el cierre — no hay leak posible. El `parentSpanId` se resuelve
1701
+ * contra el span activo si existe, pero NO fija contexto ALS.
1702
+ */
1703
+ function emitEventSpan(name, attributes, scope, onEnd) {
1704
+ const { record, span } = createSpan(name, attributes, scope, onEnd);
1705
+ record.endTimeUnixNano = record.startTimeUnixNano;
1706
+ span.end();
1707
+ }
1708
+ /**
1709
+ * Fuerza el cierre de todos los spans abiertos (`incomplete: true`) y los
1710
+ * exporta vía el `onEnd` de cada uno. Lo invocan `flushTransports()` /
1711
+ * `closeTransports()` / `cleanup()` ANTES del flush real — un span abierto
1712
+ * nunca se tira en shutdown.
1713
+ *
1714
+ * @returns Los records forzados a cerrar (para diagnóstico/tests).
1715
+ */
1716
+ function forceCloseOpenSpans() {
1717
+ const snapshot = [...openSpans.values()];
1718
+ for (const entry of snapshot) entry.forceEnd();
1719
+ return snapshot.map((entry) => entry.record);
1720
+ }
1721
+ //#endregion
746
1722
  //#region src/playground/TerminalBridge.ts
747
1723
  /**
748
- * Creates a TerminalBridge using a getter to avoid circular reference at construction.
1724
+ * Crea un {@link TerminalBridge} usando un getter para evitar referencias
1725
+ * circulares en la construcción.
1726
+ *
1727
+ * @internal
749
1728
  */
750
1729
  function createTerminalBridge(options) {
751
1730
  let _showPrimitives = true;
@@ -870,37 +1849,38 @@ var Logger = class Logger {
870
1849
  hookBridge;
871
1850
  logContext;
872
1851
  transportBridge;
873
- /** Set during success() so log() skips its own dispatch (N2 fix). */
1852
+ /** Fijado por `success()` para que `log()` salte su propio dispatch. */
874
1853
  _successTagDispatched = false;
875
1854
  styleManager;
876
- /** Whether CLI primitives (step, box, header, etc.) should be shown*/
1855
+ /** Controla si las CLI primitives (step, box, header, ...) deben renderizarse. */
877
1856
  _showPrimitives = true;
878
1857
  terminalBridge;
879
1858
  /**
880
- * Active smart-preset reference (set by `preset()`). Typed as `unknown`
881
- * to keep the public surface clean; consumed by `createStyledOutput`.
1859
+ * Referencia activa al smart-preset (fijada por `preset()`). Tipada como
1860
+ * `unknown` para mantener limpia la surface pública; la consume
1861
+ * `createStyledOutput`.
882
1862
  */
883
1863
  _activePreset;
884
1864
  /**
885
- * Name of the active smart-preset. Stored separately so theme-change
886
- * detection can re-render without re-running the preset body.
1865
+ * Nombre del smart-preset activo. Se guarda aparte para que la detección
1866
+ * de cambio de tema pueda re-renderizar sin re-ejecutar el body del preset.
887
1867
  */
888
1868
  _activePresetName;
889
1869
  /**
890
- * Last-applied `customize()` overrides. Stored for later read by
891
- * `createStyledOutput`.
1870
+ * Overrides aplicados por el último `customize()`. Se conservan para que
1871
+ * `createStyledOutput` los lea después.
892
1872
  */
893
1873
  _customization;
894
1874
  /**
895
- * This logger's own context bindings (from child() calls).
896
- * Single source of truth for this logger's contribution to the context chain.
1875
+ * Bindings propios de este logger (provenientes de llamadas a `child()`).
1876
+ * Source of truth única de la contribución de este logger a la cadena de contexto.
897
1877
  * @private
898
1878
  */
899
1879
  _bindings = {};
900
1880
  /**
901
- * Reference to the parent's merged context record at the time this logger
902
- * was created. Together with _bindings, forms the context chain.
903
- * Undefined for the root logger.
1881
+ * Referencia al record de contexto mergueado del parent en el momento en
1882
+ * que se creó este logger. Junto con `_bindings`, forma la cadena de
1883
+ * contexto. `undefined` para el logger raíz.
904
1884
  * @private
905
1885
  */
906
1886
  _parentContextRecord;
@@ -1068,65 +2048,66 @@ var Logger = class Logger {
1068
2048
  this.success(`Banner type changed to: ${bannerType}`);
1069
2049
  }
1070
2050
  /**
1071
- * Runs `fn` within an AsyncLocalStorage scope where `bindings` are
1072
- * merged into the context for all log calls inside `fn`.
2051
+ * Ejecuta `fn` dentro de un scope AsyncLocalStorage donde `bindings` se
2052
+ * merguean al contexto para todas las llamadas de log dentro de `fn`.
1073
2053
  *
1074
- * Without `fn` (the old setter shape): no-op for backwards compatibility.
1075
- * Prefer `child()` for persistent bindings or `withContextAsync()` for
1076
- * async callbacks.
2054
+ * Sin `fn` (el shape legacy de setter): no-op por backwards compatibility.
2055
+ * Preferir `child()` para bindings persistentes o `withContextAsync()`
2056
+ * para callbacks async.
1077
2057
  *
1078
- * @param bindings - Key-value pairs to attach for the duration of `fn`
1079
- * @param fn - Optional synchronous function to run with scoped bindings
1080
- * @returns The return value of `fn`, or undefined if no fn provided
2058
+ * @param bindings - Pares key-value a adjuntar durante la ejecución de `fn`
2059
+ * @param fn - Función sincrónica opcional a ejecutar con los bindings en scope
2060
+ * @returns El valor de retorno de `fn`, o `undefined` si no se pasa `fn`
1081
2061
  *
1082
2062
  * @example
1083
- * // Scoped synchronous callback
2063
+ * // Callback sincrónico scoped
1084
2064
  * logger.withContext({ requestId: 'r-42' }, () => {
1085
- * doWork(); // logs inside see requestId in attributes
2065
+ * doWork(); // los logs de aquí ven requestId en attributes
1086
2066
  * });
1087
2067
  *
1088
2068
  * @example
1089
- * // Persistent binding: use child()
2069
+ * // Binding persistente: usar child()
1090
2070
  * const reqLog = logger.child({ requestId: 'r-42' });
1091
- * reqLog.info('handling request'); // attributes include requestId
2071
+ * reqLog.info('handling request'); // attributes incluye requestId
1092
2072
  *
1093
- * @see {@link child} for an immutable copy with the merged context
1094
- * @see {@link withContextAsync} for async callback variant
2073
+ * @see {@link child} para una copia inmutable con el contexto mergueado
2074
+ * @see {@link withContextAsync} para la variante con callback async
1095
2075
  */
1096
2076
  withContext(bindings, fn) {
1097
2077
  return this.logContext.withContext(bindings, fn);
1098
2078
  }
1099
2079
  /**
1100
- * Async variant of `withContext`. Runs `fn` within an AsyncLocalStorage
1101
- * scope so bindings are available to all async log calls inside `fn`.
2080
+ * Variante async de `withContext`. Ejecuta `fn` dentro de un scope
2081
+ * AsyncLocalStorage para que los bindings estén disponibles a todas las
2082
+ * llamadas de log async dentro de `fn`.
1102
2083
  *
1103
- * @param bindings - Key-value pairs to attach for the duration of `fn`
1104
- * @param fn - Async function to run with the scoped bindings
1105
- * @returns The return value of `fn`
2084
+ * @param bindings - Pares key-value a adjuntar durante la ejecución de `fn`
2085
+ * @param fn - Función async a ejecutar con los bindings en scope
2086
+ * @returns El valor de retorno de `fn`
1106
2087
  *
1107
2088
  * @example
1108
2089
  * await logger.withContextAsync({ requestId: 'r-42' }, async () => {
1109
- * await fetchData(); // logs inside see requestId in attributes
2090
+ * await fetchData(); // los logs de aquí ven requestId en attributes
1110
2091
  * });
1111
2092
  *
1112
- * @see {@link child} for a persistent child logger
1113
- * @see {@link withContext} for synchronous callback variant
2093
+ * @see {@link child} para un child logger persistente
2094
+ * @see {@link withContext} para la variante con callback sincrónico
1114
2095
  */
1115
2096
  withContextAsync(bindings, fn) {
1116
2097
  return this.logContext.withContextAsync(bindings, fn);
1117
2098
  }
1118
2099
  /**
1119
- * Returns an immutable copy of this logger with the extra context bound.
1120
- * Future calls on the child emit with the merged context, without
1121
- * mutating the parent — the canonical MDC pattern.
2100
+ * Devuelve una copia inmutable de este logger con el contexto extra bound.
2101
+ * Las llamadas futuras sobre el child emiten con el contexto mergueado,
2102
+ * sin mutar al parent — el patrón canónico de MDC.
1122
2103
  *
1123
- * @param extra - Key-value pairs to attach (requestId, userId, ...)
1124
- * @returns A new Logger with merged context
2104
+ * @param extra - Pares key-value a adjuntar (requestId, userId, ...)
2105
+ * @returns Un nuevo Logger con el contexto mergueado
1125
2106
  *
1126
2107
  * @example
1127
2108
  * const reqLog = logger.child({ requestId: req.id });
1128
- * reqLog.info('start'); // emits attributes: { requestId }
1129
- * logger.info('unrelated'); // NOT affected — parent's context untouched
2109
+ * reqLog.info('start'); // emite attributes: { requestId }
2110
+ * logger.info('unrelated'); // NO afectado — el contexto del parent queda intacto
1130
2111
  *
1131
2112
  */
1132
2113
  child(extra) {
@@ -1136,21 +2117,21 @@ var Logger = class Logger {
1136
2117
  return childLogger;
1137
2118
  }
1138
2119
  /**
1139
- * Drops every key from the bound context. After this call, emitted
1140
- * records no longer carry `attributes` until {@link withContext} or
1141
- * {@link child} re-establish one.
2120
+ * Descarta todas las keys del contexto bound. Tras esta llamada, los
2121
+ * records emitidos dejan de llevar `attributes` hasta que
2122
+ * {@link withContext} o {@link child} restablezcan uno.
1142
2123
  *
1143
- * @returns The same logger instance, now context-free
2124
+ * @returns La misma instancia del logger, ahora sin contexto
1144
2125
  */
1145
2126
  clearContext() {
1146
2127
  this.logContext.clearContext();
1147
2128
  return this;
1148
2129
  }
1149
2130
  /**
1150
- * Snapshot of the bound context. Returned object is a shallow copy:
1151
- * mutating it does NOT affect what subsequent log calls emit.
2131
+ * Snapshot del contexto bound. El objeto devuelto es una shallow copy:
2132
+ * mutarlo NO afecta lo que emiten las llamadas de log posteriores.
1152
2133
  *
1153
- * @returns A read-only snapshot of the current context
2134
+ * @returns Un snapshot read-only del contexto actual
1154
2135
  */
1155
2136
  getContext() {
1156
2137
  let merged = this._parentContextRecord ?? {};
@@ -1161,12 +2142,12 @@ var Logger = class Logger {
1161
2142
  return merged;
1162
2143
  }
1163
2144
  /**
1164
- * Updates the default OTel resource (service.name, version, env).
1165
- * Persisted into every emitted record's `resource` field unless the
1166
- * record itself overrides it.
2145
+ * Actualiza el resource OTel por defecto (service.name, version, env).
2146
+ * Se persiste en el campo `resource` de cada record emitido, salvo que
2147
+ * el propio record lo override.
1167
2148
  *
1168
- * @param resource - Partial OTel resource to merge into the current one
1169
- * @returns The same logger instance, for chaining
2149
+ * @param resource - Resource OTel parcial a merguear con el actual
2150
+ * @returns La misma instancia del logger, para chaining
1170
2151
  *
1171
2152
  * @example
1172
2153
  * logger.setResource({ 'service.name': 'api', 'service.version': '1.2.3' });
@@ -1195,20 +2176,15 @@ var Logger = class Logger {
1195
2176
  this.success("Logger configuration reset to defaults");
1196
2177
  }
1197
2178
  /**
1198
- * Método de limpieza para eliminar listeners y liberar recursos
1199
- *
1200
- * @example
1201
- * // Antes de cerrar la aplicación
1202
- * logger.cleanup();
1203
- *
1204
- */
1205
- /**
1206
- * Tears down every resource held by this Logger. Safe to call multiple
1207
- * times. Fixed in 5.1.0 to fully drain transports + clear timers +
1208
- * drop the legacy handler list + reset group depth + clear context.
2179
+ * Método de limpieza para eliminar listeners y liberar recursos.
2180
+ *
2181
+ * Vacía los transports (drain), limpia timers, suelta la lista de
2182
+ * handlers legacy, resetea el group depth y limpia el context.
2183
+ * Seguro de invocar múltiples veces.
1209
2184
  *
1210
2185
  * @example
1211
- * await logger.cleanup(); // before process exit / hot reload
2186
+ * // Antes de cerrar la aplicación
2187
+ * await logger.cleanup();
1212
2188
  *
1213
2189
  */
1214
2190
  async cleanup() {
@@ -1218,6 +2194,7 @@ var Logger = class Logger {
1218
2194
  } catch {}
1219
2195
  this.themeChangeListener = null;
1220
2196
  }
2197
+ forceCloseOpenSpans();
1221
2198
  await this.transportBridge.closeTransports();
1222
2199
  this.handlers.length = 0;
1223
2200
  this.timers.clear();
@@ -1237,7 +2214,7 @@ var Logger = class Logger {
1237
2214
  * logger.preset('glassmorphism'); // Efectos de blur modernos
1238
2215
  * logger.preset('minimal'); // Minimalista y elegante
1239
2216
  * logger.preset('debug'); // Modo desarrollo detallado
1240
- * logger.preset('production'); // Optimizado para producción
2217
+ * logger.preset('production'); // Enfocado en producción
1241
2218
  *
1242
2219
  */
1243
2220
  preset(name) {
@@ -1383,12 +2360,63 @@ var Logger = class Logger {
1383
2360
  this.badgeList = [];
1384
2361
  return this;
1385
2362
  }
2363
+ /**
2364
+ * Crea un logger scoped para un componente o módulo del dominio.
2365
+ *
2366
+ * El `ComponentLogger` resultante prepends un badge `[name]` a cada
2367
+ * mensaje y comparte configuración, transports y hooks con el logger
2368
+ * padre. Útil para trazar el origen de los logs en apps con muchos
2369
+ * módulos (Auth, DB, Cache, ...).
2370
+ *
2371
+ * @param {string} name - Nombre del componente que aparecerá como badge
2372
+ * @returns {ComponentLogger} Logger scoped para el componente
2373
+ *
2374
+ * @example
2375
+ * const auth = logger.component('Auth');
2376
+ * auth.info('Validando token'); // [Auth] Validando token
2377
+ * auth.success('Token válido');
2378
+ *
2379
+ * @see {@link api} para loggers de endpoints REST/GraphQL
2380
+ * @see {@link scope} para un scope genérico sin badge de componente
2381
+ */
1386
2382
  component(name) {
1387
2383
  return new ComponentLogger(this, name);
1388
2384
  }
2385
+ /**
2386
+ * Crea un logger scoped para un endpoint o surface de API.
2387
+ *
2388
+ * Como `component()` pero con styling orientado a APIs (badge `[API]`
2389
+ * por defecto más el nombre del sub-scope). Útil para distinguir
2390
+ * tráfico REST vs GraphQL vs WebSocket en los logs.
2391
+ *
2392
+ * @param {string} name - Nombre de la API o surface (p.ej. `'REST'`, `'GraphQL'`)
2393
+ * @returns {APILogger} Logger scoped para la API
2394
+ *
2395
+ * @example
2396
+ * const rest = logger.api('REST');
2397
+ * rest.info('GET /users/42'); // [API] [REST] GET /users/42
2398
+ *
2399
+ * @see {@link component} para loggers de componentes de dominio
2400
+ */
1389
2401
  api(name) {
1390
2402
  return new APILogger(this, name);
1391
2403
  }
2404
+ /**
2405
+ * Crea un logger scoped genérico con un prefijo.
2406
+ *
2407
+ * Variante minimal de `component()` / `api()`: solo aplica un prefijo
2408
+ * de scope sin badges ni styling especial. Útil para sub-módulos que
2409
+ * no encajan en las categorías de `component`/`api`.
2410
+ *
2411
+ * @param {string} name - Texto del prefijo de scope
2412
+ * @returns {ScopedLogger} Logger con el scope aplicado
2413
+ *
2414
+ * @example
2415
+ * const db = logger.scope('db');
2416
+ * db.info('Pool conectado'); // [db] Pool conectado
2417
+ *
2418
+ * @see {@link component} y {@link api} para variantes con badges
2419
+ */
1392
2420
  scope(name) {
1393
2421
  return new ScopedLogger(this, name);
1394
2422
  }
@@ -1589,21 +2617,27 @@ var Logger = class Logger {
1589
2617
  return this.transportBridge.removeTransport(id);
1590
2618
  }
1591
2619
  /**
1592
- * Fuerza el flush de todos los transports
2620
+ * Fuerza el flush de todos los transports. Antes de flushear, cierra los
2621
+ * spans aún abiertos (`incomplete: true`) y los encola para export — un
2622
+ * span abierto nunca se tira en un flush.
1593
2623
  *
1594
2624
  * @returns Promise que resuelve cuando todos los buffers están vaciados
1595
2625
  *
1596
2626
  */
1597
2627
  async flushTransports() {
2628
+ forceCloseOpenSpans();
1598
2629
  await this.transportBridge.flushTransports();
1599
2630
  }
1600
2631
  /**
1601
- * Cierra todos los transports
2632
+ * Cierra todos los transports. Como en {@link flushTransports}, primero
2633
+ * fuerza el cierre de los spans abiertos para que viajen en el flush
2634
+ * final del close.
1602
2635
  *
1603
2636
  * @returns Promise que resuelve cuando todos están cerrados
1604
2637
  *
1605
2638
  */
1606
2639
  async closeTransports() {
2640
+ forceCloseOpenSpans();
1607
2641
  await this.transportBridge.closeTransports();
1608
2642
  }
1609
2643
  /**
@@ -1625,33 +2659,29 @@ var Logger = class Logger {
1625
2659
  return LOG_LEVELS[level] >= LOG_LEVELS[this.config.verbosity];
1626
2660
  }
1627
2661
  /**
1628
- * Builds and dispatches a `TransportRecord` to the {@link TransportManager}
1629
- * (no-op if no transports are registered). Shared by every log path —
1630
- * `log()`, `success()`, and visual methods like `table()` / `group()` /
1631
- * `time()` — so all emissions hit the same transport pipeline.
2662
+ * Tag pendiente de inyectar en el siguiente `TransportRecord` emitido
2663
+ * por `log()`. Lo fijan `success()` y `logWithBindingsAndTag()` antes
2664
+ * de delegar; `log()` lo consume y lo resetea a `undefined`.
1632
2665
  *
1633
- * @param level - The canonical log level (trace/debug/info/warn/error/critical)
1634
- * @param message - Final, post-hook message text
1635
- * @param prefix - Effective prefix (global + scope)
1636
- * @param stackInfo - Optional caller location
1637
- * @param extra - Optional fields to merge into the record (e.g. `{ tag: 'success' }`)
2666
+ * @internal
1638
2667
  */
1639
2668
  _dispatchTag;
1640
2669
  /**
1641
- * Computes the fully-merged context for this logger.
2670
+ * Computa el contexto completamente mergueado para este logger.
1642
2671
  *
1643
- * The context chain is built at child-creation time: each child stores
1644
- * its parent's fully-merged context (at that moment) as _parentContextRecord.
1645
- * This means _parentContextRecord already contains all ancestors' bindings
1646
- * in the correct precedence order (root first, nearest child last).
2672
+ * La cadena de contexto se construye en el momento de crear el child:
2673
+ * cada child almacena el contexto fully-merged de su parent (en ese
2674
+ * instante) como `_parentContextRecord`. Esto implica que
2675
+ * `_parentContextRecord` ya contiene los bindings de todos los ancestros
2676
+ * en el orden de precedencia correcto (root primero, child más cercano al final).
1647
2677
  *
1648
- * Merge order (later wins):
1649
- * 1. _parentContextRecord — parent's merged context snapshot at creation time
1650
- * 2. _bindings — this logger's own bindings (child() calls)
1651
- * 3. ALS store — withContext/withContextAsync scope (highest priority)
2678
+ * Orden de merge (gana el último):
2679
+ * 1. _parentContextRecord — snapshot del contexto mergueado del parent en la creación
2680
+ * 2. _bindings — bindings propios de este logger (llamadas a `child()`)
2681
+ * 3. ALS store — scope de `withContext`/`withContextAsync` (prioridad máxima)
1652
2682
  *
1653
2683
  * @internal
1654
- * @returns The merged context record
2684
+ * @returns El record de contexto mergueado
1655
2685
  */
1656
2686
  _getMergedContext() {
1657
2687
  let merged = this._parentContextRecord ?? {};
@@ -1666,7 +2696,7 @@ var Logger = class Logger {
1666
2696
  };
1667
2697
  return merged;
1668
2698
  }
1669
- /** @internal Exposes base merged context (no ALS) to LogContext child factory closure. */
2699
+ /** @internal Expone el contexto base mergueado (sin ALS) a la closure de la child factory de LogContext. */
1670
2700
  _captureMergedContext() {
1671
2701
  let merged = this._parentContextRecord ?? {};
1672
2702
  if (this._bindings && Object.keys(this._bindings).length > 0) merged = {
@@ -1675,6 +2705,21 @@ var Logger = class Logger {
1675
2705
  };
1676
2706
  return merged;
1677
2707
  }
2708
+ /**
2709
+ * Construye y despacha un `TransportRecord` al {@link TransportManager}
2710
+ * (no-op si no hay transports registrados). Lo comparten todos los
2711
+ * caminos de log — `log()`, `success()` y los métodos visuales como
2712
+ * `table()` / `group()` / `time()` — para que toda emisión atraviese
2713
+ * el mismo pipeline de transports.
2714
+ *
2715
+ * @protected
2716
+ * @param {LogLevel} level - Nivel canónico (trace/debug/info/warn/error/critical)
2717
+ * @param {string} message - Mensaje final, post-hook
2718
+ * @param {string | undefined} prefix - Prefijo efectivo (global + scope)
2719
+ * @param {StackInfo | null} stackInfo - Ubicación del caller, opcional
2720
+ * @param {Partial<TransportRecord>} [extra] - Campos extra a mergear en el record
2721
+ * (p.ej. `{ tag: 'success' }` o `attributes` adicionales)
2722
+ */
1678
2723
  dispatchToTransports(level, message, prefix, stackInfo, extra) {
1679
2724
  const record = {
1680
2725
  level,
@@ -1694,6 +2739,11 @@ var Logger = class Logger {
1694
2739
  resource: this.logContext._getResource() ? { ...this.logContext._getResource() } : void 0,
1695
2740
  ...extra
1696
2741
  };
2742
+ const activeSpan = getActiveSpan();
2743
+ if (activeSpan && !record.traceId) {
2744
+ record.traceId = activeSpan.traceId;
2745
+ record.spanId = activeSpan.spanId;
2746
+ }
1697
2747
  this.transportBridge.writeRecord(record);
1698
2748
  }
1699
2749
  /**
@@ -1706,37 +2756,23 @@ var Logger = class Logger {
1706
2756
  return parts.length > 0 ? parts.join(":") : void 0;
1707
2757
  }
1708
2758
  /**
1709
- * Método central de logging. Awaits the `beforeLog` hook pipeline
1710
- * synchronously (so redactions / enrichments are reflected in the
1711
- * emitted message before console + transport dispatch).
1712
- *
1713
- * Fire-and-forget callers (e.g. `logger.info(...)` without `await`)
1714
- * still work — the resulting `Promise<void>` is dropped on the floor.
1715
- * Awaiting is recommended when `beforeLog` hooks mutate `message`
1716
- * (e.g. PII redaction, correlation IDs).
1717
- *
1718
- * @protected
1719
- * @param level - Nivel del log
1720
- * @param args - Argumentos a loggear
1721
- * @returns Promise that resolves once the record has been dispatched
2759
+ * Método central de logging. Espera el hook pipeline `beforeLog`
2760
+ * antes de despachar a consola y transports, para que redacciones
2761
+ * o enriquecimientos (PII, correlation IDs) se reflejen en el
2762
+ * mensaje emitido.
1722
2763
  *
1723
- */
1724
- /**
1725
- * Protected logging method. Awaits the `beforeLog` hook pipeline
1726
- * synchronously (so redactions / enrichments are reflected in the
1727
- * emitted message before console + transport dispatch).
2764
+ * Los callers fire-and-forget (p.ej. `logger.info(...)` sin `await`)
2765
+ * siguen funcionando: el `Promise<void>` resultante se descarta.
2766
+ * Se recomienda `await` cuando los hooks `beforeLog` mutan `message`.
1728
2767
  *
1729
- * Fire-and-forget callers (e.g. `logger.info(...)` without `await`)
1730
- * still work — the resulting `Promise<void>` is dropped on the floor.
1731
- * Awaiting is recommended when `beforeLog` hooks mutate `message`
1732
- * (e.g. PII redaction, correlation IDs).
2768
+ * El tag opcional (`TransportRecord.tag`) NO se pasa como argumento:
2769
+ * se establece vía `_dispatchTag` (ver `success()` y
2770
+ * {@link logWithBindingsAndTag}) antes de invocar este método.
1733
2771
  *
1734
2772
  * @protected
1735
- * @param level - Nivel del log
1736
- * @param args - Argumentos a loggear
1737
- * @param tag - Optional tag forwarded to `dispatchToTransports` as
1738
- * `TransportRecord.tag` (e.g. `'success'` for success records).
1739
- * @returns Promise that resolves once the record has been dispatched
2773
+ * @param {LogLevel} level - Nivel del log
2774
+ * @param {unknown[]} args - Argumentos a loggear (mensaje + datos)
2775
+ * @returns {Promise<void>} Promesa que resuelve al completar el dispatch
1740
2776
  *
1741
2777
  */
1742
2778
  async log(level, ...args) {
@@ -1786,6 +2822,22 @@ var Logger = class Logger {
1786
2822
  else this.dispatchToTransports(level, message, prefix, stackInfo);
1787
2823
  this.hookBridge.getHookManager().emit("afterLog", processed).catch(() => {});
1788
2824
  }
2825
+ /**
2826
+ * Emite un log aplicando bindings (badges, scope) al prefijo del
2827
+ * mensaje antes de delegar en {@link Logger.log}.
2828
+ *
2829
+ * No es API pública de consumo: existe para que `ScopedLogger`
2830
+ * (`component()` / `api()` / `scope()`) pueda reutilizar el pipeline
2831
+ * central de `log()` sin duplicar la lógica de styling/badges.
2832
+ *
2833
+ * @internal
2834
+ * @param {Bindings} bindings - Bindings de scope (badges, scope name, ...)
2835
+ * @param {LogLevel} level - Nivel de log
2836
+ * @param {unknown[]} args - Argumentos a loggear
2837
+ * @returns {Promise<void>} Promesa del dispatch
2838
+ *
2839
+ * @see {@link logWithBindingsAndTag} para la variante con `tag`
2840
+ */
1789
2841
  logWithBindings(bindings, level, ...args) {
1790
2842
  if (!this.shouldLog(level)) return Promise.resolve();
1791
2843
  let prefix = "";
@@ -1796,19 +2848,45 @@ var Logger = class Logger {
1796
2848
  return this.log(level, ...args);
1797
2849
  }
1798
2850
  /**
1799
- * Like `logWithBindings()` but sets _dispatchTag first so that
1800
- * `log()` dispatches with the tag. Used by ScopedLogger.success()
1801
- * to propagate tag:'success' through the normal log() pipeline.
2851
+ * Como {@link logWithBindings} pero fija `_dispatchTag` antes de
2852
+ * delegar, para que `log()` despache el `TransportRecord` con el
2853
+ * tag indicado. Lo usa `ScopedLogger.success()` para propagar
2854
+ * `tag: 'success'` a través del pipeline normal de `log()`.
2855
+ *
2856
+ * @internal
2857
+ * @param {Bindings} bindings - Bindings de scope (badges, scope name, ...)
2858
+ * @param {LogLevel} level - Nivel de log
2859
+ * @param {LogTag} tag - Tag a inyectar en el `TransportRecord`
2860
+ * @param {unknown[]} args - Argumentos a loggear
2861
+ * @returns {Promise<void>} Promesa del dispatch
1802
2862
  */
1803
2863
  logWithBindingsAndTag(bindings, level, tag, ...args) {
1804
2864
  this._dispatchTag = tag;
1805
2865
  return this.logWithBindings(bindings, level, ...args);
1806
2866
  }
2867
+ /**
2868
+ * Registra mensajes de debug (nivel más verboso junto a `trace`).
2869
+ * Pensado para diagnóstico de desarrollo: valores intermedios, flags
2870
+ * de control flow, estado interno. Devuelve `Promise<void>`.
2871
+ *
2872
+ * Filtrado por defecto cuando `verbosity > 'debug'` (ver `setVerbosity`).
2873
+ *
2874
+ * @param {unknown[]} args - Mensaje + datos a inspeccionar
2875
+ * @returns {Promise<void>} Promesa del dispatch
2876
+ *
2877
+ * @example
2878
+ * logger.debug('Estado interno:', { conn, queueSize });
2879
+ * logger.debug('Entrando en branch X');
2880
+ *
2881
+ * @see {@link trace} para diagnósticos aún más granulares
2882
+ * @see {@link setVerbosity} para controlar el nivel mínimo visible
2883
+ */
1807
2884
  debug(...args) {
1808
2885
  return this.log("debug", ...args);
1809
2886
  }
1810
2887
  /**
1811
- * Registra mensajes informativos. Devuelve `Promise<void>` desde 5.1.0.
2888
+ * Registra mensajes informativos. El `await` retorna cuando el hook
2889
+ * `beforeLog` y el dispatch a transports han terminado.
1812
2890
  *
1813
2891
  * @param args - Mensajes y datos informativos
1814
2892
  *
@@ -1821,7 +2899,7 @@ var Logger = class Logger {
1821
2899
  return this.log("info", ...args);
1822
2900
  }
1823
2901
  /**
1824
- * Registra mensajes de advertencia. Devuelve `Promise<void>` desde 5.1.0.
2902
+ * Registra mensajes de advertencia.
1825
2903
  *
1826
2904
  * @param args - Mensajes de advertencia
1827
2905
  *
@@ -1830,7 +2908,7 @@ var Logger = class Logger {
1830
2908
  return this.log("warn", ...args);
1831
2909
  }
1832
2910
  /**
1833
- * Registra mensajes de error. Devuelve `Promise<void>` desde 5.1.0.
2911
+ * Registra mensajes de error.
1834
2912
  *
1835
2913
  * @param args - Mensaje de error y stack traces
1836
2914
  *
@@ -1910,7 +2988,7 @@ var Logger = class Logger {
1910
2988
  this.log("trace", ...args);
1911
2989
  }
1912
2990
  /**
1913
- * Registra errores críticos (prioridad más alta). Devuelve `Promise<void>` desde 5.1.0.
2991
+ * Registra errores críticos (prioridad más alta).
1914
2992
  *
1915
2993
  * @param args - Errores críticos del sistema
1916
2994
  *
@@ -1922,6 +3000,104 @@ var Logger = class Logger {
1922
3000
  return this.log("critical", ...args);
1923
3001
  }
1924
3002
  /**
3003
+ * Emite un **point-span**: un span con `start = end` para completion
3004
+ * signals y eventos puntuales (una operación instantánea, un hito).
3005
+ * No registra contexto activo ni puede leakear — se exporta de inmediato.
3006
+ *
3007
+ * El nombre `event` (y no `trace`) es deliberado: `trace` es un log level
3008
+ * (el -1) y está reservado.
3009
+ *
3010
+ * @param {string} name - Nombre del evento (`job.completed`, `cache.flushed`, ...).
3011
+ * @param {SpanAttributes} [attributes] - Attributes del span.
3012
+ *
3013
+ * @example
3014
+ * logger.event('build.finished', { status: 'ok', durationMs: 4200 });
3015
+ *
3016
+ * @see {@link span} para intervalos con work-block
3017
+ * @see {@link startSpan} para intervalos externally-ended
3018
+ */
3019
+ event(name, attributes) {
3020
+ emitEventSpan(name, attributes, this._spanScopeName(), (record) => {
3021
+ this.transportBridge.writeRecord(record);
3022
+ });
3023
+ }
3024
+ span(name, fnOrAttributes, maybeFn) {
3025
+ const { attributes, fn } = resolveSpanArgs(fnOrAttributes, maybeFn);
3026
+ return this._runSpan(name, attributes, this._spanScopeName(), fn);
3027
+ }
3028
+ /**
3029
+ * Inicia un span de intervalo **externally-ended**: devuelve el handle y
3030
+ * NO fija contexto ALS (el cierre ocurre fuera del bloque léxico — p.ej.
3031
+ * un `cli.spawn` que se cierra desde un poll o callback externo).
3032
+ *
3033
+ * Si el span no se cierra antes de `flushTransports()` / shutdown, el
3034
+ * flush lo fuerza a cerrar con `incomplete: true` y lo exporta — nunca
3035
+ * se tira.
3036
+ *
3037
+ * @param {string} name - Nombre de la operación.
3038
+ * @param {SpanAttributes} [attributes] - Attributes iniciales.
3039
+ * @returns {Span} Handle con `set`/`end`/`fail` y los ids del span.
3040
+ *
3041
+ * @example
3042
+ * const s = logger.startSpan('spawn.build', { cmd: 'make' });
3043
+ * proc.on('exit', code => {
3044
+ * if (code === 0) s.end({ exitCode: code });
3045
+ * else s.fail(new Error(`exit ${code}`));
3046
+ * });
3047
+ *
3048
+ * @see {@link span} para el caso con work-block
3049
+ */
3050
+ startSpan(name, attributes) {
3051
+ return this._startSpan(name, attributes, this._spanScopeName());
3052
+ }
3053
+ /**
3054
+ * Scope por defecto de los spans emitidos por este logger (el
3055
+ * `globalPrefix`, o `'root'`).
3056
+ * @internal
3057
+ */
3058
+ _spanScopeName() {
3059
+ return this.config.globalPrefix || "root";
3060
+ }
3061
+ /**
3062
+ * Emite un point-span con scope explícito. Lo consume
3063
+ * {@link ScopedLogger.event}, que pasa su scope compuesto.
3064
+ * @internal
3065
+ */
3066
+ _emitSpanEvent(name, attributes, scope) {
3067
+ emitEventSpan(name, attributes, scope, (record) => {
3068
+ this.transportBridge.writeRecord(record);
3069
+ });
3070
+ }
3071
+ /**
3072
+ * Crea un span externally-ended con scope explícito. Lo consume
3073
+ * {@link ScopedLogger.startSpan}.
3074
+ * @internal
3075
+ */
3076
+ _startSpan(name, attributes, scope) {
3077
+ const { span } = createSpan(name, attributes, scope, (record) => {
3078
+ this.transportBridge.writeRecord(record);
3079
+ });
3080
+ return span;
3081
+ }
3082
+ /**
3083
+ * Corre `fn` dentro de un span activo en el ALS con scope explícito.
3084
+ * Lo consume {@link ScopedLogger.span}.
3085
+ * @internal
3086
+ */
3087
+ async _runSpan(name, attributes, scope, fn) {
3088
+ const { record, span } = createSpan(name, attributes, scope, (r) => {
3089
+ this.transportBridge.writeRecord(r);
3090
+ });
3091
+ try {
3092
+ const result = await runWithActiveSpan(record, () => fn(span));
3093
+ span.end();
3094
+ return result;
3095
+ } catch (error) {
3096
+ span.fail(error);
3097
+ throw error;
3098
+ }
3099
+ }
3100
+ /**
1925
3101
  * Muestra datos en formato de tabla. Pasa por la pipeline completa
1926
3102
  * (outputMode-respecting writeOutput + transports + hooks).
1927
3103
  *
@@ -2030,7 +3206,7 @@ var Logger = class Logger {
2030
3206
  * Finaliza un temporizador y muestra el tiempo transcurrido
2031
3207
  *
2032
3208
  * @param {string} label - Etiqueta del temporizador a finalizar
2033
- * @returns {number} Elapsed milliseconds, or -1 if timer not found
3209
+ * @returns {number} Milisegundos transcurridos, o `-1` si no se encuentra el timer
2034
3210
  *
2035
3211
  * @example
2036
3212
  * logger.time('consulta-db');
@@ -2152,11 +3328,11 @@ var Logger = class Logger {
2152
3328
  } });
2153
3329
  }
2154
3330
  /**
2155
- * Displays a step progress indicator in the terminal
3331
+ * Muestra un indicador de progreso de pasos en la terminal
2156
3332
  *
2157
- * @param {number} current - Current step number
2158
- * @param {number} total - Total number of steps
2159
- * @param {string} message - Step description
3333
+ * @param {number} current - Número de paso actual
3334
+ * @param {number} total - Número total de pasos
3335
+ * @param {string} message - Descripción del paso
2160
3336
  *
2161
3337
  * @example
2162
3338
  * logger.step(1, 5, 'Analyzing repository...');
@@ -2167,10 +3343,10 @@ var Logger = class Logger {
2167
3343
  this.terminalBridge.step(current, total, message);
2168
3344
  }
2169
3345
  /**
2170
- * Displays a styled header with optional subtitle
3346
+ * Muestra un header con estilo y subtítulo opcional
2171
3347
  *
2172
- * @param {string} title - Main title text
2173
- * @param {string} subtitle - Optional subtitle (rendered dimmed)
3348
+ * @param {string} title - Texto del título principal
3349
+ * @param {string} subtitle - Subtítulo opcional (se renderiza atenuado)
2174
3350
  *
2175
3351
  * @example
2176
3352
  * logger.header('Commit Wizard', 'v2.0.0');
@@ -2180,7 +3356,7 @@ var Logger = class Logger {
2180
3356
  this.terminalBridge.header(title, subtitle);
2181
3357
  }
2182
3358
  /**
2183
- * Displays a horizontal divider line
3359
+ * Muestra una línea divisoria horizontal
2184
3360
  *
2185
3361
  * @example
2186
3362
  * logger.divider();
@@ -2190,7 +3366,7 @@ var Logger = class Logger {
2190
3366
  this.terminalBridge.divider();
2191
3367
  }
2192
3368
  /**
2193
- * Outputs a blank line
3369
+ * Emite una línea en blanco
2194
3370
  *
2195
3371
  * @example
2196
3372
  * logger.blank();
@@ -2200,10 +3376,10 @@ var Logger = class Logger {
2200
3376
  this.terminalBridge.blank();
2201
3377
  }
2202
3378
  /**
2203
- * Renders content inside a bordered box
3379
+ * Renderiza contenido dentro de un box con borde
2204
3380
  *
2205
- * @param {string} content - Content string (may contain newlines)
2206
- * @param {IBoxOptions} options - Box rendering options
3381
+ * @param {string} content - String de contenido (puede contener newlines)
3382
+ * @param {IBoxOptions} options - Opciones de renderizado del box
2207
3383
  *
2208
3384
  * @example
2209
3385
  * logger.box('3 commits generated\nProvider: Groq', { title: 'Done', borderColor: '#00ff00' });
@@ -2213,11 +3389,11 @@ var Logger = class Logger {
2213
3389
  this.terminalBridge.box(content, options);
2214
3390
  }
2215
3391
  /**
2216
- * Renders an array of objects as a formatted ASCII table.
2217
- * Note: This is distinct from the existing table() method which uses console.table.
3392
+ * Renderiza un array de objetos como una tabla ASCII formateada.
3393
+ * Distinto del método `table()` existente, que usa `console.table`.
2218
3394
  *
2219
- * @param {Record<string, unknown>[]} rows - Array of row objects
2220
- * @param {ITableOptions} options - Table rendering options
3395
+ * @param {Record<string, unknown>[]} rows - Array de objetos fila
3396
+ * @param {ITableOptions} options - Opciones de renderizado de la tabla
2221
3397
  *
2222
3398
  * @example
2223
3399
  * logger.cliTable([
@@ -2230,11 +3406,11 @@ var Logger = class Logger {
2230
3406
  this.terminalBridge.cliTable(rows, options);
2231
3407
  }
2232
3408
  /**
2233
- * Creates a spinner handle for showing progress during async operations.
2234
- * Returns a NoopSpinner in non-TTY environments.
3409
+ * Crea un handle de spinner para mostrar progreso durante operaciones async.
3410
+ * Devuelve un `NoopSpinner` en entornos non-TTY.
2235
3411
  *
2236
- * @param {string} message - Initial spinner text
2237
- * @returns {ISpinnerHandle} Spinner controller
3412
+ * @param {string} message - Texto inicial del spinner
3413
+ * @returns {ISpinnerHandle} Controller del spinner
2238
3414
  *
2239
3415
  * @example
2240
3416
  * const s = logger.spinner('Analyzing repository...');
@@ -2247,13 +3423,14 @@ var Logger = class Logger {
2247
3423
  return this.terminalBridge.spinner(message);
2248
3424
  }
2249
3425
  /**
2250
- * Sets the CLI verbosity level, controlling both log verbosity and primitive visibility
3426
+ * Fija el nivel de verbosidad del CLI, controlando a la vez la verbosidad
3427
+ * de logs y la visibilidad de las primitives
2251
3428
  *
2252
- * @param {CLILogLevel} level - CLI log level
3429
+ * @param {CLILogLevel} level - Nivel de log del CLI
2253
3430
  *
2254
3431
  * @example
2255
- * logger.setCLILevel('quiet'); // Only errors, no CLI primitives
2256
- * logger.setCLILevel('verbose'); // Debug logs + all CLI primitives
3432
+ * logger.setCLILevel('quiet'); // Solo errors, sin CLI primitives
3433
+ * logger.setCLILevel('verbose'); // Debug logs + todas las CLI primitives
2257
3434
  *
2258
3435
  */
2259
3436
  setCLILevel(level) {
@@ -2263,21 +3440,21 @@ var Logger = class Logger {
2263
3440
  this.config.cliLevel = level;
2264
3441
  }
2265
3442
  /**
2266
- * Returns the current CLI log level
2267
- * @returns {CLILogLevel} Current CLI log level
3443
+ * Devuelve el nivel de log del CLI actual
3444
+ * @returns {CLILogLevel} Nivel de log del CLI actual
2268
3445
  */
2269
3446
  get cliLevel() {
2270
3447
  return this.config.cliLevel ?? "normal";
2271
3448
  }
2272
3449
  /**
2273
- * Writes formatted output to the configured destination.
2274
- * Respects outputMode configuration for console, silent, or custom output.
3450
+ * Escribe output formateado al destino configurado.
3451
+ * Respeta la configuración `outputMode` para output a consola, silencioso o custom.
2275
3452
  *
2276
3453
  * @private
2277
- * @param {string} message - Formatted log message
2278
- * @param {LogLevel} level - Log level
2279
- * @param {string[]} styles - CSS styles for browser console
2280
- * @param {unknown[]} additionalArgs - Additional arguments to log
3454
+ * @param {string} message - Mensaje de log formateado
3455
+ * @param {LogLevel} level - Nivel de log
3456
+ * @param {string[]} styles - Estilos CSS para la consola del navegador
3457
+ * @param {unknown[]} additionalArgs - Argumentos adicionales a loggear
2281
3458
  */
2282
3459
  writeOutput(message, level, styles, additionalArgs) {
2283
3460
  const mode = this.config.outputMode ?? "console";
@@ -2317,21 +3494,20 @@ var Logger = class Logger {
2317
3494
  }
2318
3495
  };
2319
3496
  /**
2320
- /**
2321
- * Lazy singleton instance — initialised on first call to {@link getDefaultLogger},
2322
- * not on module import. Fixes BUG-N11 (eager side-effect at import time).
3497
+ * Instancia singleton lazy — se inicializa en la primera llamada a
3498
+ * {@link getDefaultLogger}, no al importar el módulo.
2323
3499
  *
2324
3500
  * @private
2325
3501
  */
2326
3502
  let _defaultLogger = null;
2327
3503
  /**
2328
- * Lazily creates the default Logger singleton.
3504
+ * Crea el singleton del Logger por defecto de forma lazy.
2329
3505
  *
2330
- * The singleton is only built on first call, so importing the module
2331
- * never executes `new Logger(...)` or `displayInitBanner()`. This keeps
2332
- * module imports side-effect free.
3506
+ * El singleton se construye solo en la primera llamada, de modo que
3507
+ * importar el módulo nunca ejecuta `new Logger(...)` ni
3508
+ * `displayInitBanner()`. Así los imports del módulo quedan side-effect free.
2333
3509
  *
2334
- * @returns The shared Logger instance
3510
+ * @returns La instancia compartida de Logger
2335
3511
  */
2336
3512
  function getDefaultLogger() {
2337
3513
  if (!_defaultLogger) {
@@ -2354,12 +3530,12 @@ new Proxy({}, { get(_target, prop, receiver) {
2354
3530
  return typeof value === "function" ? value.bind(instance) : value;
2355
3531
  } });
2356
3532
  /**
2357
- * Narrow a free-form `Record<string, unknown>` context into a typed
2358
- * `ILogAttributes` bag. Unknown shapes fall back to JSON-encoded strings,
2359
- * which keeps the OTLP transport happy (every value lands in a typed slot).
3533
+ * Estrecha un contexto free-form `Record<string, unknown>` a un bag tipado
3534
+ * `ILogAttributes`. Los shapes desconocidos caen a strings JSON-encoded,
3535
+ * lo que mantiene conforme al transport OTLP (cada valor cae en un slot tipado).
2360
3536
  *
2361
- * @param input - The user-supplied context (typically `Logger.context`).
2362
- * @returns A new attribute bag matching `ILogAttributes`.
3537
+ * @param input - Contexto suministrado por el usuario (típicamente `Logger.context`).
3538
+ * @returns Un nuevo bag de attributes que satisface `ILogAttributes`.
2363
3539
  */
2364
3540
  function toLogAttributes(input) {
2365
3541
  const out = {};
@@ -2386,6 +3562,23 @@ function toAttributeValue(value) {
2386
3562
  return;
2387
3563
  }
2388
3564
  }
3565
+ /**
3566
+ * Resuelve los argumentos del overload `span(name, fn?)` /
3567
+ * `span(name, attributes, fn)` a `{ attributes, fn }`.
3568
+ *
3569
+ * @internal Compartido con `ScopedLogger.span`; no es API pública.
3570
+ */
3571
+ function resolveSpanArgs(fnOrAttributes, maybeFn) {
3572
+ if (typeof fnOrAttributes === "function") return {
3573
+ attributes: void 0,
3574
+ fn: fnOrAttributes
3575
+ };
3576
+ if (typeof maybeFn === "function") return {
3577
+ attributes: fnOrAttributes,
3578
+ fn: maybeFn
3579
+ };
3580
+ throw new TypeError("span(name, …): se requiere una función fn");
3581
+ }
2389
3582
  //#endregion
2390
3583
  //#region src/index.ts
2391
3584
  /**
@@ -2418,6 +3611,11 @@ const group = (label, collapsed) => getLogger().group(label, collapsed);
2418
3611
  const groupEnd = () => getLogger().groupEnd();
2419
3612
  const time = (label) => getLogger().time(label);
2420
3613
  const timeEnd = (label) => getLogger().timeEnd(label);
3614
+ const event = (name, attributes) => getLogger().event(name, attributes);
3615
+ const startSpan = (name, attributes) => getLogger().startSpan(name, attributes);
3616
+ function span(name, fnOrAttributes, maybeFn) {
3617
+ return getLogger().span(name, fnOrAttributes, maybeFn);
3618
+ }
2421
3619
  const setGlobalPrefix = (prefix) => getLogger().setGlobalPrefix(prefix);
2422
3620
  const scope = (name) => getLogger().scope(name);
2423
3621
  const component = (name) => getLogger().component(name);
@@ -2444,6 +3642,6 @@ const removeTransport = (id) => getLogger().removeTransport(id);
2444
3642
  const flushTransports = () => getLogger().flushTransports();
2445
3643
  const closeTransports = () => getLogger().closeTransports();
2446
3644
  //#endregion
2447
- export { APILogger, BANNER_VARIANTS, ComponentLogger, ContextLogger, DEFAULT_CONFIG, Logger, ScopedLogger, StyleBuilder, StylePresets, THEME_BANNERS, THEME_PRESETS, addHandler, addSerializer, addTransport, ansiBackground, ansiBold, ansiColor, ansiDim, ansiStyle, ansiUnderline, api, badge, badges, clearBadges, cli, closeTransports, component, createLogEntry, critical, debug, src_default as default, error, flushTransports, formatLogLevelANSI, formatSuccessANSI, formatTablePlain, formatTimestamp, getColorCapability, getConsoleMethod, getEnvironment, getEnvironmentInfo, getTerminalHeight, getTerminalWidth, group, groupEnd, info, isRunningInTerminal, logAnimated, logWithSVG, off, on, once, parseStackTrace, removeSerializer, removeTransport, safeSerialize, scope, setBannerType, setGlobalPrefix, setTheme, setVerbosity, showBanner, success, supportsANSI, table, time, timeEnd, trace, use, warn };
3645
+ export { APILogger, BANNER_VARIANTS, ComponentLogger, ContextLogger, DEFAULT_CONFIG, Logger, ScopedLogger, StyleBuilder, StylePresets, THEME_BANNERS, THEME_PRESETS, addHandler, addSerializer, addTransport, ansiBackground, ansiBold, ansiColor, ansiDim, ansiStyle, ansiUnderline, api, badge, badges, clearBadges, cli, closeTransports, component, createLogEntry, critical, debug, src_default as default, error, event, flushTransports, formatLogLevelANSI, formatSuccessANSI, formatTablePlain, formatTimestamp, getColorCapability, getConsoleMethod, getEnvironment, getEnvironmentInfo, getTerminalHeight, getTerminalWidth, group, groupEnd, info, isRunningInTerminal, logAnimated, logWithSVG, off, on, once, parseStackTrace, removeSerializer, removeTransport, safeSerialize, scope, setBannerType, setGlobalPrefix, setTheme, setVerbosity, showBanner, span, startSpan, success, supportsANSI, table, time, timeEnd, trace, use, warn };
2448
3646
 
2449
3647
  //# sourceMappingURL=index.js.map