@mks2508/better-logger 4.0.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/CHANGELOG.json +23 -1
  2. package/dist/Logger.d.ts +117 -4
  3. package/dist/Logger.d.ts.map +1 -1
  4. package/dist/ScopedLogger.d.ts +17 -0
  5. package/dist/ScopedLogger.d.ts.map +1 -1
  6. package/dist/chunks/{Logger-D-gmmgR2.js → Logger-BZ7B7OXE.js} +228 -175
  7. package/dist/chunks/Logger-BZ7B7OXE.js.map +1 -0
  8. package/dist/chunks/Logger-Cbi1f10o.js +2 -0
  9. package/dist/chunks/Logger-Cbi1f10o.js.map +1 -0
  10. package/dist/chunks/cli-module-CadqgZ1Z.js +2 -0
  11. package/dist/chunks/cli-module-CadqgZ1Z.js.map +1 -0
  12. package/dist/chunks/cli-module-ClIJmaT8.js +383 -0
  13. package/dist/chunks/cli-module-ClIJmaT8.js.map +1 -0
  14. package/dist/chunks/color-converter-CCSQRztd.js +2 -0
  15. package/dist/chunks/color-converter-CCSQRztd.js.map +1 -0
  16. package/dist/chunks/color-converter-_Xdmsy7E.js +462 -0
  17. package/dist/chunks/color-converter-_Xdmsy7E.js.map +1 -0
  18. package/dist/chunks/{environment-COWvu6Wz.js → environment-C1xxvc8l.js} +26 -476
  19. package/dist/chunks/environment-C1xxvc8l.js.map +1 -0
  20. package/dist/chunks/environment-Cprkw3g9.js +4 -0
  21. package/dist/chunks/environment-Cprkw3g9.js.map +1 -0
  22. package/dist/chunks/{formatting-CYjT9yhO.js → formatting-DMJxYq9o.js} +18 -18
  23. package/dist/chunks/{formatting-CYjT9yhO.js.map → formatting-DMJxYq9o.js.map} +1 -1
  24. package/dist/chunks/{formatting-Cg5YhB9Y.js → formatting-DpKxCsXq.js} +2 -2
  25. package/dist/chunks/{formatting-Cg5YhB9Y.js.map → formatting-DpKxCsXq.js.map} +1 -1
  26. package/dist/cli-module.d.ts +15 -0
  27. package/dist/cli-module.d.ts.map +1 -0
  28. package/dist/cli-primitives/box.d.ts +11 -0
  29. package/dist/cli-primitives/box.d.ts.map +1 -0
  30. package/dist/cli-primitives/cli-table.d.ts +11 -0
  31. package/dist/cli-primitives/cli-table.d.ts.map +1 -0
  32. package/dist/cli-primitives/divider.d.ts +11 -0
  33. package/dist/cli-primitives/divider.d.ts.map +1 -0
  34. package/dist/cli-primitives/header.d.ts +12 -0
  35. package/dist/cli-primitives/header.d.ts.map +1 -0
  36. package/dist/cli-primitives/index.d.ts +13 -0
  37. package/dist/cli-primitives/index.d.ts.map +1 -0
  38. package/dist/cli-primitives/server-fallback.d.ts +25 -0
  39. package/dist/cli-primitives/server-fallback.d.ts.map +1 -0
  40. package/dist/cli-primitives/spinner.d.ts +47 -0
  41. package/dist/cli-primitives/spinner.d.ts.map +1 -0
  42. package/dist/cli-primitives/step.d.ts +11 -0
  43. package/dist/cli-primitives/step.d.ts.map +1 -0
  44. package/dist/cli.cjs +2 -0
  45. package/dist/cli.cjs.map +1 -0
  46. package/dist/cli.js +12 -0
  47. package/dist/cli.js.map +1 -0
  48. package/dist/constants.d.ts +9 -1
  49. package/dist/constants.d.ts.map +1 -1
  50. package/dist/core.cjs +1 -1
  51. package/dist/core.js +2 -2
  52. package/dist/exports-module.d.ts +1 -1
  53. package/dist/exports-module.d.ts.map +1 -1
  54. package/dist/exports.cjs +1 -1
  55. package/dist/exports.js +2 -2
  56. package/dist/index.cjs +1 -1
  57. package/dist/index.cjs.map +1 -1
  58. package/dist/index.d.ts +11 -3
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +71 -53
  61. package/dist/index.js.map +1 -1
  62. package/dist/styling-module.d.ts +1 -1
  63. package/dist/styling-module.d.ts.map +1 -1
  64. package/dist/styling.cjs +1 -1
  65. package/dist/styling.js +3 -3
  66. package/dist/types/core.d.ts +47 -0
  67. package/dist/types/core.d.ts.map +1 -1
  68. package/dist/types/index.d.ts +1 -1
  69. package/dist/types/index.d.ts.map +1 -1
  70. package/package.json +28 -3
  71. package/packages/core/package.json +1 -1
  72. package/playground/demo-all.ts +95 -0
  73. package/playground/demo-box.ts +85 -0
  74. package/playground/demo-levels.ts +56 -0
  75. package/playground/demo-real-world.ts +98 -0
  76. package/playground/demo-spinner.ts +77 -0
  77. package/playground/demo-steps.ts +72 -0
  78. package/playground/demo-table.ts +83 -0
  79. package/src/Logger.ts +213 -8
  80. package/src/ScopedLogger.ts +43 -1
  81. package/src/cli-module.ts +21 -0
  82. package/src/cli-primitives/box.ts +86 -0
  83. package/src/cli-primitives/cli-table.ts +62 -0
  84. package/src/cli-primitives/divider.ts +17 -0
  85. package/src/cli-primitives/header.ts +18 -0
  86. package/src/cli-primitives/index.ts +13 -0
  87. package/src/cli-primitives/server-fallback.ts +54 -0
  88. package/src/cli-primitives/spinner.ts +133 -0
  89. package/src/cli-primitives/step.ts +22 -0
  90. package/src/constants.ts +14 -2
  91. package/src/index.ts +18 -1
  92. package/src/types/core.ts +53 -0
  93. package/src/types/index.ts +4 -0
  94. package/vite.config.ts +33 -0
  95. package/dist/chunks/Logger-D-gmmgR2.js.map +0 -1
  96. package/dist/chunks/Logger-D7cfaz15.js +0 -2
  97. package/dist/chunks/Logger-D7cfaz15.js.map +0 -1
  98. package/dist/chunks/environment-COWvu6Wz.js.map +0 -1
  99. package/dist/chunks/environment-C_8J-zQ_.js +0 -4
  100. package/dist/chunks/environment-C_8J-zQ_.js.map +0 -1
@@ -1,4 +1,6 @@
1
- import { C as getAdaptiveColor, F as ADAPTIVE_COLORS, b as StyleBuilder, j as getANSIForeground, A as ANSI, u as getTerminalWidth, G as BUFFER_LIMITS, H as generateLogId, I as parseTimeInput, J as formatDisplayTime, K as safeStringify, M as escapeHtml, N as EXPORT_FORMATS, D as DEFAULT_CONFIG$1, O as setupThemeChangeListener, o as getEnvironment, p as parseStackTrace, f as formatTimestamp$1, y as createStyledOutput, t as getColorCapability, S as StylePresets } from "./environment-COWvu6Wz.js";
1
+ import { h as getAdaptiveColor, A as ADAPTIVE_COLORS, b as StyleBuilder, j as BUFFER_LIMITS, k as generateLogId, l as parseTimeInput, m as formatDisplayTime, n as safeStringify, o as escapeHtml, q as EXPORT_FORMATS, D as DEFAULT_CONFIG$1, r as setupThemeChangeListener, p as parseStackTrace, f as formatTimestamp, c as createStyledOutput, S as StylePresets, C as CLI_LEVEL_MAP } from "./environment-C1xxvc8l.js";
2
+ import { i as getEnvironment, k as getColorCapability, j as isRunningInTerminal } from "./color-converter-_Xdmsy7E.js";
3
+ import { c as formatBadge, k as renderStep, l as renderDivider, m as renderBox, n as renderTable, N as NoopSpinner, S as SpinnerManager, o as ServerFallback, q as renderHeader } from "./cli-module-ClIJmaT8.js";
2
4
  const DEFAULT_CONFIG = {
3
5
  maxDepth: 5,
4
6
  circular: "placeholder",
@@ -1570,157 +1572,6 @@ function getAvailablePresets() {
1570
1572
  function hasPreset(name) {
1571
1573
  return name in SMART_PRESETS;
1572
1574
  }
1573
- function stripAnsi(str) {
1574
- return str.replace(/\x1b\[[0-9;]*m/g, "");
1575
- }
1576
- function getVisibleLength(str) {
1577
- return stripAnsi(str).length;
1578
- }
1579
- function padToWidth(str, width, align = "left") {
1580
- const visibleLen = getVisibleLength(str);
1581
- if (visibleLen >= width) return str;
1582
- const padding = width - visibleLen;
1583
- switch (align) {
1584
- case "right":
1585
- return " ".repeat(padding) + str;
1586
- case "center":
1587
- const leftPad = Math.floor(padding / 2);
1588
- const rightPad = padding - leftPad;
1589
- return " ".repeat(leftPad) + str + " ".repeat(rightPad);
1590
- case "left":
1591
- default:
1592
- return str + " ".repeat(padding);
1593
- }
1594
- }
1595
- function formatWithRightAlign(leftContent, rightContent, maxWidth) {
1596
- const width = maxWidth ?? getTerminalWidth();
1597
- const leftLen = getVisibleLength(leftContent);
1598
- const rightLen = getVisibleLength(rightContent);
1599
- const gap = width - leftLen - rightLen;
1600
- if (gap <= 1) {
1601
- return `${leftContent} ${rightContent}`;
1602
- }
1603
- return `${leftContent}${" ".repeat(gap)}${rightContent}`;
1604
- }
1605
- function formatColumns(columns, maxWidth, colorCapability = "full") {
1606
- const width = maxWidth ?? getTerminalWidth();
1607
- columns.length;
1608
- const columnsWithWidths = columns.map((col, idx) => {
1609
- if (col.width) return { ...col, calculatedWidth: col.width };
1610
- const remainingWidth = width - columns.filter((c, i) => i !== idx && c.width).reduce((sum, c) => sum + (c.width ?? 0), 0);
1611
- const autoColumns = columns.filter((c) => !c.width).length;
1612
- const calculatedWidth = Math.floor(remainingWidth / autoColumns);
1613
- return { ...col, calculatedWidth };
1614
- });
1615
- return columnsWithWidths.map((col) => {
1616
- let content = col.content;
1617
- if (col.color && colorCapability !== "none") {
1618
- const colorCode = getANSIForeground(col.color, colorCapability);
1619
- content = `${colorCode}${content}${ANSI.reset}`;
1620
- }
1621
- return padToWidth(content, col.calculatedWidth, col.align);
1622
- }).join("");
1623
- }
1624
- function formatKeyValue(obj, colorCapability = "full", options = {}) {
1625
- const {
1626
- separator = " ",
1627
- keyColor = "#888888",
1628
- valueColor = "#00ffff"
1629
- } = options;
1630
- const entries = Object.entries(obj);
1631
- if (entries.length === 0) return "";
1632
- const keyColorCode = colorCapability !== "none" ? getANSIForeground(keyColor, colorCapability) : "";
1633
- const valueColorCode = colorCapability !== "none" ? getANSIForeground(valueColor, colorCapability) : "";
1634
- const reset = colorCapability !== "none" ? ANSI.reset : "";
1635
- return entries.map(([key, value]) => {
1636
- const valueStr = typeof value === "object" ? JSON.stringify(value) : String(value);
1637
- return `${keyColorCode}${key}:${reset} ${valueColorCode}${valueStr}${reset}`;
1638
- }).join(separator);
1639
- }
1640
- function isKeyValueObject(obj) {
1641
- if (typeof obj !== "object" || obj === null) return false;
1642
- if (Array.isArray(obj)) return false;
1643
- const proto = Object.getPrototypeOf(obj);
1644
- if (proto !== Object.prototype && proto !== null) return false;
1645
- const values = Object.values(obj);
1646
- return values.every(
1647
- (v) => typeof v === "string" || typeof v === "number" || typeof v === "boolean" || v === null
1648
- );
1649
- }
1650
- function formatBadge(badge, style = "brackets", colorCapability = "full", color) {
1651
- const colorCode = color && colorCapability !== "none" ? getANSIForeground(color, colorCapability) : "";
1652
- const reset = colorCapability !== "none" ? ANSI.reset : "";
1653
- const bgBlack = colorCapability !== "none" ? ANSI.bg.black : "";
1654
- const text = badge.toUpperCase();
1655
- switch (style) {
1656
- case "rounded":
1657
- return `${bgBlack}${colorCode}⟨${text}⟩${reset}`;
1658
- case "plain":
1659
- return `${colorCode}${text}${reset}`;
1660
- case "unicode":
1661
- return `${bgBlack}${colorCode}╭${text}╮${reset}`;
1662
- case "pill":
1663
- return `${bgBlack}${colorCode}⦗${text}⦘${reset}`;
1664
- case "brackets":
1665
- default:
1666
- return `${bgBlack}${colorCode}[${text}]${reset}`;
1667
- }
1668
- }
1669
- function formatTimestamp(date = /* @__PURE__ */ new Date(), format = "time") {
1670
- switch (format) {
1671
- case "iso":
1672
- return date.toISOString();
1673
- case "date":
1674
- return date.toISOString().split("T")[0] ?? "";
1675
- case "time":
1676
- return date.toTimeString().slice(0, 8);
1677
- case "timeMs":
1678
- return date.toTimeString().slice(0, 8) + "." + String(date.getMilliseconds()).padStart(3, "0");
1679
- case "relative":
1680
- return formatRelativeTime(date);
1681
- case "elapsed":
1682
- return formatElapsedTime(date);
1683
- case "custom":
1684
- default:
1685
- return date.toLocaleTimeString();
1686
- }
1687
- }
1688
- let startTime = null;
1689
- function formatRelativeTime(date) {
1690
- if (startTime === null) {
1691
- startTime = Date.now();
1692
- }
1693
- const diff = date.getTime() - startTime;
1694
- if (diff < 1e3) {
1695
- return `+${diff}ms`;
1696
- } else if (diff < 6e4) {
1697
- return `+${(diff / 1e3).toFixed(1)}s`;
1698
- } else {
1699
- const mins = Math.floor(diff / 6e4);
1700
- const secs = Math.floor(diff % 6e4 / 1e3);
1701
- return `+${mins}m${secs}s`;
1702
- }
1703
- }
1704
- function formatElapsedTime(date) {
1705
- if (startTime === null) {
1706
- startTime = Date.now();
1707
- }
1708
- const diff = date.getTime() - startTime;
1709
- const hours = Math.floor(diff / 36e5);
1710
- const mins = Math.floor(diff % 36e5 / 6e4);
1711
- const secs = Math.floor(diff % 6e4 / 1e3);
1712
- return `${String(hours).padStart(2, "0")}:${String(mins).padStart(2, "0")}:${String(secs).padStart(2, "0")}`;
1713
- }
1714
- function resetStartTime() {
1715
- startTime = Date.now();
1716
- }
1717
- function applyLogOptions(message, options, colorCapability = "full") {
1718
- let result = message;
1719
- if (options.rightAlign) {
1720
- result = formatWithRightAlign(message, options.rightAlign);
1721
- }
1722
- return result;
1723
- }
1724
1575
  class ScopedLogger {
1725
1576
  parent;
1726
1577
  scopeName;
@@ -1806,6 +1657,39 @@ class ScopedLogger {
1806
1657
  this.parent.logWithBindings(this.getBindings(), "debug", ...args);
1807
1658
  console.trace(`[${this.scopeName}]`);
1808
1659
  }
1660
+ // ===== CLI PRIMITIVES (v5.0 delegation) =====
1661
+ /** @see Logger.step */
1662
+ step(current, total, message) {
1663
+ this.parent.step(current, total, message);
1664
+ }
1665
+ /** @see Logger.header */
1666
+ header(title, subtitle) {
1667
+ this.parent.header(title, subtitle);
1668
+ }
1669
+ /** @see Logger.divider */
1670
+ divider() {
1671
+ this.parent.divider();
1672
+ }
1673
+ /** @see Logger.blank */
1674
+ blank() {
1675
+ this.parent.blank();
1676
+ }
1677
+ /** @see Logger.box */
1678
+ box(content, options) {
1679
+ this.parent.box(content, options);
1680
+ }
1681
+ /** @see Logger.cliTable */
1682
+ cliTable(rows, options) {
1683
+ this.parent.cliTable(rows, options);
1684
+ }
1685
+ /** @see Logger.spinner */
1686
+ spinner(message) {
1687
+ return this.parent.spinner(message);
1688
+ }
1689
+ /** @see Logger.setCLILevel */
1690
+ setCLILevel(level) {
1691
+ this.parent.setCLILevel(level);
1692
+ }
1809
1693
  _pushContext(context) {
1810
1694
  this.contextStack.push(context);
1811
1695
  }
@@ -3204,6 +3088,10 @@ class Logger {
3204
3088
  serializerRegistry;
3205
3089
  hookManager;
3206
3090
  transportManager;
3091
+ /** Whether CLI primitives (step, box, header, etc.) should be shown @since 5.0.0 */
3092
+ _showPrimitives = true;
3093
+ /** Server-mode fallback for non-TTY environments @since 5.0.0 */
3094
+ _serverFallback;
3207
3095
  /**
3208
3096
  * Crea una nueva instancia del Logger
3209
3097
  *
@@ -3882,7 +3770,7 @@ class Logger {
3882
3770
  if (!this.shouldLog(level)) return;
3883
3771
  const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;
3884
3772
  const prefix = this.getEffectivePrefix();
3885
- const timestamp = formatTimestamp$1();
3773
+ const timestamp = formatTimestamp();
3886
3774
  const serializedArgs = args.map((arg) => this.serializerRegistry.serialize(arg));
3887
3775
  let message = serializedArgs.length > 0 ? String(serializedArgs[0]) : "";
3888
3776
  if (this.badgeList.length > 0 && this.displaySettings.showBadges) {
@@ -4069,7 +3957,7 @@ class Logger {
4069
3957
  console.log(finalFormat, ...styles2);
4070
3958
  }
4071
3959
  const metadata = {
4072
- timestamp: formatTimestamp$1(),
3960
+ timestamp: formatTimestamp(),
4073
3961
  level: "info",
4074
3962
  prefix,
4075
3963
  stackInfo: stackInfo ? stackInfo : void 0
@@ -4214,26 +4102,28 @@ class Logger {
4214
4102
  }
4215
4103
  /**
4216
4104
  * Finaliza un temporizador y muestra el tiempo transcurrido
4217
- *
4105
+ *
4218
4106
  * @param {string} label - Etiqueta del temporizador a finalizar
4219
- *
4107
+ * @returns {number} Elapsed milliseconds, or -1 if timer not found
4108
+ *
4220
4109
  * @example
4221
4110
  * logger.time('consulta-db');
4222
4111
  * await consultarBaseDatos();
4223
- * logger.timeEnd('consulta-db'); // ⏱️ Timer ended: consulta-db - 234.56ms
4224
- *
4112
+ * const elapsed = logger.timeEnd('consulta-db'); // ⏱️ Timer ended: consulta-db - 234.56ms
4113
+ *
4225
4114
  * @since 0.3.0
4226
4115
  */
4227
4116
  timeEnd(label) {
4228
4117
  const timer = this.timers.get(label);
4229
4118
  if (!timer) {
4230
4119
  this.warn(`Timer '${label}' does not exist`);
4231
- return;
4120
+ return -1;
4232
4121
  }
4233
4122
  const elapsed = performance.now() - timer.startTime;
4234
4123
  this.timers.delete(label);
4235
4124
  const timerStyle = StylePresets.success().build();
4236
4125
  console.log(`%c⏱️ Timer ended: ${label} - ${elapsed.toFixed(2)}ms`, timerStyle);
4126
+ return elapsed;
4237
4127
  }
4238
4128
  // ===== ADVANCED VISUAL FEATURES =====
4239
4129
  /**
@@ -4352,6 +4242,182 @@ class Logger {
4352
4242
  this.info("Grouped data:", items);
4353
4243
  }
4354
4244
  }
4245
+ // ===== CLI PRIMITIVES (v5.0) =====
4246
+ /**
4247
+ * Displays a step progress indicator in the terminal
4248
+ *
4249
+ * @param {number} current - Current step number
4250
+ * @param {number} total - Total number of steps
4251
+ * @param {string} message - Step description
4252
+ *
4253
+ * @example
4254
+ * logger.step(1, 5, 'Analyzing repository...');
4255
+ * logger.step(2, 5, 'Generating commit message...');
4256
+ *
4257
+ * @since 5.0.0
4258
+ */
4259
+ step(current, total, message) {
4260
+ if (!this._showPrimitives) return;
4261
+ if (!isRunningInTerminal()) {
4262
+ this.getServerFallback().step(current, total, message);
4263
+ return;
4264
+ }
4265
+ const colorCap = getColorCapability();
4266
+ const output = renderStep(current, total, message, colorCap);
4267
+ process.stderr.write(output + "\n");
4268
+ }
4269
+ /**
4270
+ * Displays a styled header with optional subtitle
4271
+ *
4272
+ * @param {string} title - Main title text
4273
+ * @param {string} subtitle - Optional subtitle (rendered dimmed)
4274
+ *
4275
+ * @example
4276
+ * logger.header('Commit Wizard', 'v2.0.0');
4277
+ *
4278
+ * @since 5.0.0
4279
+ */
4280
+ header(title, subtitle) {
4281
+ if (!this._showPrimitives) return;
4282
+ if (!isRunningInTerminal()) {
4283
+ this.getServerFallback().header(title, subtitle);
4284
+ return;
4285
+ }
4286
+ const output = renderHeader(title, subtitle);
4287
+ process.stderr.write(output + "\n");
4288
+ }
4289
+ /**
4290
+ * Displays a horizontal divider line
4291
+ *
4292
+ * @example
4293
+ * logger.divider();
4294
+ *
4295
+ * @since 5.0.0
4296
+ */
4297
+ divider() {
4298
+ if (!this._showPrimitives) return;
4299
+ if (!isRunningInTerminal()) {
4300
+ this.getServerFallback().divider();
4301
+ return;
4302
+ }
4303
+ const output = renderDivider();
4304
+ process.stderr.write(output + "\n");
4305
+ }
4306
+ /**
4307
+ * Outputs a blank line
4308
+ *
4309
+ * @example
4310
+ * logger.blank();
4311
+ *
4312
+ * @since 5.0.0
4313
+ */
4314
+ blank() {
4315
+ if (!this._showPrimitives) return;
4316
+ if (!isRunningInTerminal()) {
4317
+ this.getServerFallback().blank();
4318
+ return;
4319
+ }
4320
+ process.stderr.write("\n");
4321
+ }
4322
+ /**
4323
+ * Renders content inside a bordered box
4324
+ *
4325
+ * @param {string} content - Content string (may contain newlines)
4326
+ * @param {IBoxOptions} options - Box rendering options
4327
+ *
4328
+ * @example
4329
+ * logger.box('3 commits generated\nProvider: Groq', { title: 'Done', borderColor: '#00ff00' });
4330
+ *
4331
+ * @since 5.0.0
4332
+ */
4333
+ box(content, options) {
4334
+ if (!this._showPrimitives) return;
4335
+ if (!isRunningInTerminal()) {
4336
+ this.getServerFallback().box(content, options);
4337
+ return;
4338
+ }
4339
+ const colorCap = getColorCapability();
4340
+ const output = renderBox(content, options, colorCap);
4341
+ process.stderr.write(output + "\n");
4342
+ }
4343
+ /**
4344
+ * Renders an array of objects as a formatted ASCII table.
4345
+ * Note: This is distinct from the existing table() method which uses console.table.
4346
+ *
4347
+ * @param {Record<string, unknown>[]} rows - Array of row objects
4348
+ * @param {ITableOptions} options - Table rendering options
4349
+ *
4350
+ * @example
4351
+ * logger.cliTable([
4352
+ * { provider: 'Groq', status: 'Available', model: 'llama-3.3-70b' },
4353
+ * { provider: 'Gemini', status: 'Configured', model: 'gemini-2.5-flash' },
4354
+ * ]);
4355
+ *
4356
+ * @since 5.0.0
4357
+ */
4358
+ cliTable(rows, options) {
4359
+ if (!this._showPrimitives) return;
4360
+ if (!isRunningInTerminal()) {
4361
+ this.getServerFallback().cliTable(rows, options);
4362
+ return;
4363
+ }
4364
+ const colorCap = getColorCapability();
4365
+ const output = renderTable(rows, options, colorCap);
4366
+ process.stderr.write(output + "\n");
4367
+ }
4368
+ /**
4369
+ * Creates a spinner handle for showing progress during async operations.
4370
+ * Returns a NoopSpinner in non-TTY environments.
4371
+ *
4372
+ * @param {string} message - Initial spinner text
4373
+ * @returns {ISpinnerHandle} Spinner controller
4374
+ *
4375
+ * @example
4376
+ * const s = logger.spinner('Analyzing repository...');
4377
+ * s.start();
4378
+ * await analyzeRepo();
4379
+ * s.succeed('Analysis complete (1.2s)');
4380
+ *
4381
+ * @since 5.0.0
4382
+ */
4383
+ spinner(message) {
4384
+ if (!isRunningInTerminal() || this.config.outputMode === "silent") {
4385
+ return new NoopSpinner(message, this);
4386
+ }
4387
+ return new SpinnerManager(message, this.config, this);
4388
+ }
4389
+ /**
4390
+ * Sets the CLI verbosity level, controlling both log verbosity and primitive visibility
4391
+ *
4392
+ * @param {CLILogLevel} level - CLI log level
4393
+ *
4394
+ * @example
4395
+ * logger.setCLILevel('quiet'); // Only errors, no CLI primitives
4396
+ * logger.setCLILevel('verbose'); // Debug logs + all CLI primitives
4397
+ *
4398
+ * @since 5.0.0
4399
+ */
4400
+ setCLILevel(level) {
4401
+ const mapping = CLI_LEVEL_MAP[level];
4402
+ this.setVerbosity(mapping.verbosity);
4403
+ this._showPrimitives = mapping.showPrimitives;
4404
+ this.config.cliLevel = level;
4405
+ }
4406
+ /**
4407
+ * Returns the current CLI log level
4408
+ * @returns {CLILogLevel} Current CLI log level
4409
+ * @since 5.0.0
4410
+ */
4411
+ get cliLevel() {
4412
+ return this.config.cliLevel ?? "normal";
4413
+ }
4414
+ /** Lazily creates the server fallback instance @private */
4415
+ getServerFallback() {
4416
+ if (!this._serverFallback) {
4417
+ this._serverFallback = new ServerFallback(this);
4418
+ }
4419
+ return this._serverFallback;
4420
+ }
4355
4421
  // ===== OUTPUT WRITER SYSTEM =====
4356
4422
  /**
4357
4423
  * Writes formatted output to the configured destination.
@@ -4439,20 +4505,7 @@ export {
4439
4505
  THEME_BANNERS as a,
4440
4506
  TransportManager as b,
4441
4507
  ScopedLogger as c,
4442
- ContextLogger as d,
4443
- formatColumns as e,
4444
- formatWithRightAlign as f,
4445
- formatKeyValue as g,
4446
- formatBadge as h,
4447
- formatTimestamp as i,
4448
- formatRelativeTime as j,
4449
- formatElapsedTime as k,
4450
- isKeyValueObject as l,
4451
- getVisibleLength as m,
4452
- applyLogOptions as n,
4453
- displayInitBanner as o,
4454
- padToWidth as p,
4455
- resetStartTime as r,
4456
- stripAnsi as s
4508
+ displayInitBanner as d,
4509
+ ContextLogger as e
4457
4510
  };
4458
- //# sourceMappingURL=Logger-D-gmmgR2.js.map
4511
+ //# sourceMappingURL=Logger-BZ7B7OXE.js.map