@mks2508/mks-ui 0.5.7 → 0.5.8

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 (262) hide show
  1. package/dist/react-ui/primitives/waapi/Gooey/Gooey.types.d.ts +2 -0
  2. package/dist/react-ui/primitives/waapi/Gooey/Gooey.types.d.ts.map +1 -1
  3. package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.d.ts +1 -1
  4. package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.d.ts.map +1 -1
  5. package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.js +173 -43
  6. package/dist/react-ui/ui/DynamicToggle/{DynamicToggle-DOR3Ld-k.css → DynamicToggle-DJLwEkHr.css} +12 -19
  7. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.css +12 -20
  8. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.d.ts +1 -0
  9. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.d.ts.map +1 -1
  10. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.js +7 -1
  11. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.types.d.ts +55 -31
  12. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.types.d.ts.map +1 -1
  13. package/dist/react-ui/ui/DynamicToggle/index.d.ts +9 -3
  14. package/dist/react-ui/ui/DynamicToggle/index.d.ts.map +1 -1
  15. package/dist/react-ui/ui/DynamicToggle/index.js +47 -34
  16. package/package.json +52 -13
  17. package/src/assets/react.svg +0 -1
  18. package/src/core/index.ts +0 -7
  19. package/src/core/types.ts +0 -82
  20. package/src/css.d.ts +0 -7
  21. package/src/index.css +0 -129
  22. package/src/index.ts +0 -29
  23. package/src/react-ui/blocks/Terminal/ResttyAdapter.ts +0 -278
  24. package/src/react-ui/blocks/Terminal/Terminal.adapter.ts +0 -97
  25. package/src/react-ui/blocks/Terminal/Terminal.theme.restty.ts +0 -155
  26. package/src/react-ui/blocks/Terminal/Terminal.theme.ts +0 -80
  27. package/src/react-ui/blocks/Terminal/Terminal.types.ts +0 -438
  28. package/src/react-ui/blocks/Terminal/TerminalDisplay.styles.ts +0 -38
  29. package/src/react-ui/blocks/Terminal/TerminalDisplay.tsx +0 -254
  30. package/src/react-ui/blocks/Terminal/TerminalDisplay.types.ts +0 -73
  31. package/src/react-ui/blocks/Terminal/TerminalPanel.tsx +0 -269
  32. package/src/react-ui/blocks/Terminal/TerminalRestty.tsx +0 -326
  33. package/src/react-ui/blocks/Terminal/TerminalXterm.tsx +0 -230
  34. package/src/react-ui/blocks/Terminal/XTermAdapter.ts +0 -163
  35. package/src/react-ui/blocks/Terminal/chrome.ts +0 -25
  36. package/src/react-ui/blocks/Terminal/components/LogLineBadges.tsx +0 -316
  37. package/src/react-ui/blocks/Terminal/components/SpecializedSyntaxHighlighter.tsx +0 -218
  38. package/src/react-ui/blocks/Terminal/components/SyntaxHighlight.tsx +0 -386
  39. package/src/react-ui/blocks/Terminal/components/TerminalLogBadge.tsx +0 -67
  40. package/src/react-ui/blocks/Terminal/components/index.ts +0 -10
  41. package/src/react-ui/blocks/Terminal/display.ts +0 -46
  42. package/src/react-ui/blocks/Terminal/hooks/index.ts +0 -22
  43. package/src/react-ui/blocks/Terminal/hooks/useTerminalSettings.ts +0 -229
  44. package/src/react-ui/blocks/Terminal/hooks/useTerminalWebSocket.ts +0 -292
  45. package/src/react-ui/blocks/Terminal/index.ts +0 -111
  46. package/src/react-ui/blocks/Terminal/panel/LogLinesViewer.tsx +0 -330
  47. package/src/react-ui/blocks/Terminal/panel/TerminalDebugPanel.tsx +0 -242
  48. package/src/react-ui/blocks/Terminal/panel/TerminalFilterDropdown.tsx +0 -202
  49. package/src/react-ui/blocks/Terminal/panel/TerminalFilterTabs.tsx +0 -140
  50. package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanel.tsx +0 -68
  51. package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanel.types.ts +0 -85
  52. package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanelRestty.tsx +0 -383
  53. package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanelXterm.tsx +0 -439
  54. package/src/react-ui/blocks/Terminal/panel/TerminalLogsPanel.tsx +0 -550
  55. package/src/react-ui/blocks/Terminal/panel/TerminalLogsPanel.types.ts +0 -259
  56. package/src/react-ui/blocks/Terminal/panel/TerminalPanelChrome.styles.ts +0 -75
  57. package/src/react-ui/blocks/Terminal/panel/TerminalPanelChrome.tsx +0 -266
  58. package/src/react-ui/blocks/Terminal/panel/TerminalPanelChrome.types.ts +0 -82
  59. package/src/react-ui/blocks/Terminal/panel/TerminalPanelFooter.tsx +0 -112
  60. package/src/react-ui/blocks/Terminal/panel/TerminalPanelHeader.tsx +0 -178
  61. package/src/react-ui/blocks/Terminal/panel/TerminalPanelToolbar.tsx +0 -203
  62. package/src/react-ui/blocks/Terminal/panel/TerminalSessionControl.tsx +0 -252
  63. package/src/react-ui/blocks/Terminal/panel/TerminalSessionTabs.tsx +0 -334
  64. package/src/react-ui/blocks/Terminal/panel/TerminalSettingsPopover.tsx +0 -261
  65. package/src/react-ui/blocks/Terminal/panel/TerminalThemeSelector.tsx +0 -248
  66. package/src/react-ui/blocks/Terminal/panel/index.ts +0 -72
  67. package/src/react-ui/blocks/Terminal/panel/terminal-filter-dropdown.module.css +0 -59
  68. package/src/react-ui/blocks/Terminal/panel/terminal-session-tabs.module.css +0 -59
  69. package/src/react-ui/blocks/Terminal/parsing/BadgeFormatter.ts +0 -180
  70. package/src/react-ui/blocks/Terminal/parsing/HttpLogParser.ts +0 -248
  71. package/src/react-ui/blocks/Terminal/parsing/LogParser.types.ts +0 -283
  72. package/src/react-ui/blocks/Terminal/parsing/LogParserService.ts +0 -686
  73. package/src/react-ui/blocks/Terminal/parsing/MultilineAggregator.ts +0 -466
  74. package/src/react-ui/blocks/Terminal/parsing/PersistentLogBuffer.ts +0 -343
  75. package/src/react-ui/blocks/Terminal/parsing/SyntaxHighlighter.ts +0 -167
  76. package/src/react-ui/blocks/Terminal/parsing/TableParser.ts +0 -348
  77. package/src/react-ui/blocks/Terminal/parsing/ansi/AnsiColorMapper.ts +0 -251
  78. package/src/react-ui/blocks/Terminal/parsing/ansi/AnsiParser.ts +0 -390
  79. package/src/react-ui/blocks/Terminal/parsing/ansi/ansi.constants.ts +0 -320
  80. package/src/react-ui/blocks/Terminal/parsing/ansi/index.ts +0 -20
  81. package/src/react-ui/blocks/Terminal/parsing/index.ts +0 -69
  82. package/src/react-ui/blocks/Terminal/parsing/levels/LogLevel.types.ts +0 -68
  83. package/src/react-ui/blocks/Terminal/parsing/levels/LogLevelDetector.ts +0 -436
  84. package/src/react-ui/blocks/Terminal/parsing/levels/index.ts +0 -14
  85. package/src/react-ui/blocks/index.ts +0 -11
  86. package/src/react-ui/components/MorphingPopover/MorphingPopover.types.ts +0 -49
  87. package/src/react-ui/components/MorphingPopover/index.tsx +0 -186
  88. package/src/react-ui/components/MorphingPopover/morphing-popover.module.css +0 -153
  89. package/src/react-ui/components/index.ts +0 -9
  90. package/src/react-ui/hooks/Animation/UseAutoHeight.tsx +0 -123
  91. package/src/react-ui/hooks/DOM/UseIsInView.tsx +0 -44
  92. package/src/react-ui/hooks/Formatting/UseListFormat.ts +0 -134
  93. package/src/react-ui/hooks/State/UseControlledState.tsx +0 -57
  94. package/src/react-ui/hooks/State/UseDataState.tsx +0 -76
  95. package/src/react-ui/hooks/index.ts +0 -20
  96. package/src/react-ui/icons/index.ts +0 -12
  97. package/src/react-ui/icons/lucide-animated/activity.tsx +0 -109
  98. package/src/react-ui/icons/lucide-animated/arrow-down-to-line.tsx +0 -51
  99. package/src/react-ui/icons/lucide-animated/arrow-up.tsx +0 -50
  100. package/src/react-ui/icons/lucide-animated/bell-electric.tsx +0 -124
  101. package/src/react-ui/icons/lucide-animated/bell.tsx +0 -93
  102. package/src/react-ui/icons/lucide-animated/bot.tsx +0 -122
  103. package/src/react-ui/icons/lucide-animated/box.tsx +0 -117
  104. package/src/react-ui/icons/lucide-animated/check.tsx +0 -21
  105. package/src/react-ui/icons/lucide-animated/circle-check.tsx +0 -107
  106. package/src/react-ui/icons/lucide-animated/delete.tsx +0 -133
  107. package/src/react-ui/icons/lucide-animated/download.tsx +0 -99
  108. package/src/react-ui/icons/lucide-animated/edit-2.tsx +0 -21
  109. package/src/react-ui/icons/lucide-animated/globe.tsx +0 -23
  110. package/src/react-ui/icons/lucide-animated/home.tsx +0 -103
  111. package/src/react-ui/icons/lucide-animated/index.ts +0 -38
  112. package/src/react-ui/icons/lucide-animated/layers.tsx +0 -23
  113. package/src/react-ui/icons/lucide-animated/layout-panel-top.tsx +0 -143
  114. package/src/react-ui/icons/lucide-animated/list.tsx +0 -54
  115. package/src/react-ui/icons/lucide-animated/package.tsx +0 -24
  116. package/src/react-ui/icons/lucide-animated/palette.tsx +0 -25
  117. package/src/react-ui/icons/lucide-animated/plus.tsx +0 -92
  118. package/src/react-ui/icons/lucide-animated/refresh-cw.tsx +0 -24
  119. package/src/react-ui/icons/lucide-animated/rocket.tsx +0 -24
  120. package/src/react-ui/icons/lucide-animated/save.tsx +0 -23
  121. package/src/react-ui/icons/lucide-animated/search.tsx +0 -94
  122. package/src/react-ui/icons/lucide-animated/settings.tsx +0 -92
  123. package/src/react-ui/icons/lucide-animated/terminal.tsx +0 -46
  124. package/src/react-ui/icons/lucide-animated/trash-2.tsx +0 -25
  125. package/src/react-ui/icons/lucide-animated/trending-down.tsx +0 -151
  126. package/src/react-ui/icons/lucide-animated/trending-up.tsx +0 -150
  127. package/src/react-ui/icons/lucide-animated/type.tsx +0 -23
  128. package/src/react-ui/icons/lucide-animated/upload.tsx +0 -23
  129. package/src/react-ui/icons/lucide-animated/x.tsx +0 -102
  130. package/src/react-ui/index.ts +0 -30
  131. package/src/react-ui/lib/get-strict-context.tsx +0 -56
  132. package/src/react-ui/lib/icon-wrapper.tsx +0 -70
  133. package/src/react-ui/lib/index.ts +0 -9
  134. package/src/react-ui/lib/utils.ts +0 -24
  135. package/src/react-ui/primitives/AutoHeight/index.tsx +0 -74
  136. package/src/react-ui/primitives/CountingNumber/index.tsx +0 -147
  137. package/src/react-ui/primitives/Highlight/Highlight.types.ts +0 -136
  138. package/src/react-ui/primitives/Highlight/index.tsx +0 -577
  139. package/src/react-ui/primitives/Slot/index.tsx +0 -128
  140. package/src/react-ui/primitives/index.ts +0 -16
  141. package/src/react-ui/primitives/waapi/Gooey/Gooey.types.ts +0 -141
  142. package/src/react-ui/primitives/waapi/Gooey/GooeyCanvas.tsx +0 -217
  143. package/src/react-ui/primitives/waapi/Gooey/GooeyFilter.tsx +0 -77
  144. package/src/react-ui/primitives/waapi/Gooey/MorphPath.tsx +0 -58
  145. package/src/react-ui/primitives/waapi/Gooey/gooey-utils.ts +0 -253
  146. package/src/react-ui/primitives/waapi/Gooey/index.ts +0 -50
  147. package/src/react-ui/primitives/waapi/Gooey/useMorphPath.ts +0 -48
  148. package/src/react-ui/primitives/waapi/Morph/Morph.types.ts +0 -106
  149. package/src/react-ui/primitives/waapi/Morph/MorphContext.tsx +0 -21
  150. package/src/react-ui/primitives/waapi/Morph/index.tsx +0 -56
  151. package/src/react-ui/primitives/waapi/Morph/techniques/index.ts +0 -12
  152. package/src/react-ui/primitives/waapi/Morph/techniques/useCSSGridMorph.ts +0 -89
  153. package/src/react-ui/primitives/waapi/Morph/techniques/useFLIPClipPath.ts +0 -176
  154. package/src/react-ui/primitives/waapi/Morph/techniques/useViewTransitions.ts +0 -87
  155. package/src/react-ui/primitives/waapi/Morph/useMorph.ts +0 -101
  156. package/src/react-ui/primitives/waapi/Reorder/Reorder.types.ts +0 -177
  157. package/src/react-ui/primitives/waapi/Reorder/index.tsx +0 -260
  158. package/src/react-ui/primitives/waapi/Reorder/useReorder.ts +0 -47
  159. package/src/react-ui/primitives/waapi/Reorder/useReorderPresence.ts +0 -209
  160. package/src/react-ui/primitives/waapi/Reorder/utils/separatorCoordination.ts +0 -104
  161. package/src/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.styles.ts +0 -14
  162. package/src/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.types.ts +0 -84
  163. package/src/react-ui/primitives/waapi/SlidingNumber/index.tsx +0 -474
  164. package/src/react-ui/primitives/waapi/SlidingText/SlidingText.styles.ts +0 -32
  165. package/src/react-ui/primitives/waapi/SlidingText/SlidingText.types.ts +0 -69
  166. package/src/react-ui/primitives/waapi/SlidingText/index.tsx +0 -140
  167. package/src/react-ui/primitives/waapi/core/animationConstants.ts +0 -215
  168. package/src/react-ui/primitives/waapi/core/index.ts +0 -53
  169. package/src/react-ui/primitives/waapi/core/types.ts +0 -200
  170. package/src/react-ui/primitives/waapi/core/useAnimationOrchestrator.ts +0 -430
  171. package/src/react-ui/primitives/waapi/core/useElementRegistry.ts +0 -81
  172. package/src/react-ui/primitives/waapi/core/useFLIPAnimation.ts +0 -138
  173. package/src/react-ui/primitives/waapi/core/usePositionCapture.ts +0 -106
  174. package/src/react-ui/primitives/waapi/index.ts +0 -139
  175. package/src/react-ui/styles/animations.css +0 -369
  176. package/src/react-ui/ui/Accordion/Accordion.styles.ts +0 -72
  177. package/src/react-ui/ui/Accordion/Accordion.types.ts +0 -199
  178. package/src/react-ui/ui/Accordion/index.tsx +0 -362
  179. package/src/react-ui/ui/AlertDialog/AlertDialog.styles.ts +0 -38
  180. package/src/react-ui/ui/AlertDialog/AlertDialog.types.ts +0 -296
  181. package/src/react-ui/ui/AlertDialog/index.tsx +0 -540
  182. package/src/react-ui/ui/Badge/Badge.styles.ts +0 -43
  183. package/src/react-ui/ui/Badge/Badge.types.ts +0 -26
  184. package/src/react-ui/ui/Badge/index.tsx +0 -34
  185. package/src/react-ui/ui/Button/Button.styles.ts +0 -57
  186. package/src/react-ui/ui/Button/Button.types.ts +0 -63
  187. package/src/react-ui/ui/Button/index.tsx +0 -155
  188. package/src/react-ui/ui/Card/Card.styles.ts +0 -32
  189. package/src/react-ui/ui/Card/Card.types.ts +0 -39
  190. package/src/react-ui/ui/Card/index.tsx +0 -130
  191. package/src/react-ui/ui/Checkbox/Checkbox.styles.ts +0 -40
  192. package/src/react-ui/ui/Checkbox/Checkbox.types.ts +0 -98
  193. package/src/react-ui/ui/Checkbox/index.tsx +0 -233
  194. package/src/react-ui/ui/Combobox/Combobox.styles.ts +0 -34
  195. package/src/react-ui/ui/Combobox/Combobox.types.ts +0 -89
  196. package/src/react-ui/ui/Combobox/index.tsx +0 -331
  197. package/src/react-ui/ui/CornerBracket/CornerBracket.styles.ts +0 -38
  198. package/src/react-ui/ui/CornerBracket/CornerBracket.types.ts +0 -15
  199. package/src/react-ui/ui/CornerBracket/index.tsx +0 -49
  200. package/src/react-ui/ui/DataCard/DataCard.styles.ts +0 -94
  201. package/src/react-ui/ui/DataCard/DataCard.types.ts +0 -125
  202. package/src/react-ui/ui/DataCard/index.tsx +0 -340
  203. package/src/react-ui/ui/Dialog/Dialog.styles.ts +0 -59
  204. package/src/react-ui/ui/Dialog/Dialog.types.ts +0 -284
  205. package/src/react-ui/ui/Dialog/index.tsx +0 -452
  206. package/src/react-ui/ui/DropdownMenu/DropdownMenu.styles.ts +0 -35
  207. package/src/react-ui/ui/DropdownMenu/DropdownMenu.types.ts +0 -81
  208. package/src/react-ui/ui/DropdownMenu/index.tsx +0 -300
  209. package/src/react-ui/ui/DynamicToggle/DynamicToggle.css +0 -376
  210. package/src/react-ui/ui/DynamicToggle/DynamicToggle.styles.ts +0 -85
  211. package/src/react-ui/ui/DynamicToggle/DynamicToggle.types.ts +0 -180
  212. package/src/react-ui/ui/DynamicToggle/index.tsx +0 -316
  213. package/src/react-ui/ui/DynamicToggle/prototype-v7-ios.html +0 -413
  214. package/src/react-ui/ui/DynamicToggle/prototype-v7.html +0 -615
  215. package/src/react-ui/ui/DynamicToggle/prototype-v8-gooey-safari.html +0 -560
  216. package/src/react-ui/ui/DynamicToggle/prototype-v8b-react-structure.html +0 -227
  217. package/src/react-ui/ui/DynamicToggle/prototype.html +0 -419
  218. package/src/react-ui/ui/Field/Field.styles.ts +0 -47
  219. package/src/react-ui/ui/Field/Field.types.ts +0 -60
  220. package/src/react-ui/ui/Field/index.tsx +0 -254
  221. package/src/react-ui/ui/Input/Input.styles.ts +0 -11
  222. package/src/react-ui/ui/Input/Input.types.ts +0 -10
  223. package/src/react-ui/ui/Input/index.tsx +0 -32
  224. package/src/react-ui/ui/InputGroup/InputGroup.styles.ts +0 -53
  225. package/src/react-ui/ui/InputGroup/InputGroup.types.ts +0 -44
  226. package/src/react-ui/ui/InputGroup/index.tsx +0 -149
  227. package/src/react-ui/ui/Label/Label.styles.ts +0 -10
  228. package/src/react-ui/ui/Label/Label.types.ts +0 -9
  229. package/src/react-ui/ui/Label/index.tsx +0 -27
  230. package/src/react-ui/ui/Menu/Menu.styles.ts +0 -71
  231. package/src/react-ui/ui/Menu/Menu.types.ts +0 -425
  232. package/src/react-ui/ui/Menu/index.tsx +0 -900
  233. package/src/react-ui/ui/Popover/Popover.styles.ts +0 -55
  234. package/src/react-ui/ui/Popover/Popover.types.ts +0 -261
  235. package/src/react-ui/ui/Popover/index.tsx +0 -422
  236. package/src/react-ui/ui/Progress/Progress.styles.ts +0 -36
  237. package/src/react-ui/ui/Progress/Progress.types.ts +0 -162
  238. package/src/react-ui/ui/Progress/index.tsx +0 -254
  239. package/src/react-ui/ui/Select/Select.styles.ts +0 -30
  240. package/src/react-ui/ui/Select/Select.types.ts +0 -51
  241. package/src/react-ui/ui/Select/index.tsx +0 -225
  242. package/src/react-ui/ui/Separator/Separator.styles.ts +0 -10
  243. package/src/react-ui/ui/Separator/Separator.types.ts +0 -10
  244. package/src/react-ui/ui/Separator/index.tsx +0 -37
  245. package/src/react-ui/ui/Switch/Switch.styles.ts +0 -50
  246. package/src/react-ui/ui/Switch/Switch.types.ts +0 -155
  247. package/src/react-ui/ui/Switch/index.tsx +0 -253
  248. package/src/react-ui/ui/Tabs/Tabs.css +0 -39
  249. package/src/react-ui/ui/Tabs/Tabs.styles.ts +0 -148
  250. package/src/react-ui/ui/Tabs/Tabs.types.ts +0 -255
  251. package/src/react-ui/ui/Tabs/index.tsx +0 -529
  252. package/src/react-ui/ui/TextFlow/TextFlow.styles.ts +0 -36
  253. package/src/react-ui/ui/TextFlow/TextFlow.types.ts +0 -118
  254. package/src/react-ui/ui/TextFlow/index.tsx +0 -276
  255. package/src/react-ui/ui/Textarea/Textarea.styles.ts +0 -10
  256. package/src/react-ui/ui/Textarea/Textarea.types.ts +0 -9
  257. package/src/react-ui/ui/Textarea/index.tsx +0 -27
  258. package/src/react-ui/ui/Tooltip/Tooltip.styles.ts +0 -43
  259. package/src/react-ui/ui/Tooltip/Tooltip.types.ts +0 -253
  260. package/src/react-ui/ui/Tooltip/index.tsx +0 -394
  261. package/src/react-ui/ui/index.ts +0 -41
  262. package/src/types/css-modules.d.ts +0 -18
@@ -1,686 +0,0 @@
1
- /**
2
- * Log parser service for terminal log processing.
3
- *
4
- * Main service that combines ANSI parsing, log level detection,
5
- * timestamp extraction, and structured log handling into a
6
- * unified API for processing log streams.
7
- *
8
- * @module components/devenv/terminal/parsing/service
9
- */
10
-
11
- import { AnsiParser } from './ansi/AnsiParser';
12
- import { LogLevelDetector } from './levels/LogLevelDetector';
13
- import { BadgeFormatter } from './BadgeFormatter';
14
- import { MultilineAggregator } from './MultilineAggregator';
15
- import type {
16
- IParsedLogEntry,
17
- IParserState,
18
- ILogParserOptions,
19
- ILogFilterOptions,
20
- ILogStats,
21
- TLogLevel,
22
- } from './LogParser.types';
23
-
24
- /**
25
- * Timestamp patterns for common log formats.
26
- *
27
- * IMPORTANT: Order matters! More specific patterns must come first.
28
- * The double timestamp pattern MUST be before single timestamp patterns.
29
- */
30
- const TIMESTAMP_PATTERNS = [
31
- // Double timestamp (devenv-agent-backend better-logger): 2026-02-05T22:41:05.372991285Z 22:41:05.372
32
- // This MUST come first as it's more specific
33
- {
34
- regex: /^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z?)\s+(\d{2}:\d{2}:\d{2}(?:\.\d+)?)\s+/,
35
- format: 'double',
36
- extractIndex: 2, // Extract the time portion (index 2) for display
37
- },
38
- // Supervisord format (comma in milliseconds): 2026-02-05 22:22:38,372
39
- {
40
- regex: /^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}),(\d+)\s+/,
41
- format: 'supervisord',
42
- },
43
- // ISO 8601 with microseconds: 2026-02-05T21:35:28.944519682Z
44
- {
45
- regex: /^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z?)\s/,
46
- format: 'iso',
47
- },
48
- // Time with milliseconds: 21:35:28.944
49
- {
50
- regex: /^(\d{2}:\d{2}:\d{2}(?:\.\d+)?)\s/,
51
- format: 'time',
52
- },
53
- // Unix timestamp in milliseconds: [1770328479225]
54
- {
55
- regex: /^\[(\d{13,})\]\s/,
56
- format: 'unix',
57
- },
58
- // Date/time: [2026-02-05 21:35:28]
59
- {
60
- regex: /^\[(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})\]\s/,
61
- format: 'datetime',
62
- },
63
- // Syslog format: Feb 5 21:35:28
64
- {
65
- regex: /^([A-Z][a-z]{2}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2})\s/,
66
- format: 'syslog',
67
- },
68
- ];
69
-
70
- /**
71
- * Tag extraction pattern.
72
- * Matches: ⦗COMPONENT⦘ ⦗ROUTES⦘ etc.
73
- */
74
- const TAG_PATTERN = /⦗([^⦘]+)⦘/g;
75
-
76
- /**
77
- * Log parser service class.
78
- *
79
- * Provides unified API for parsing log text with ANSI colorization,
80
- * log level detection, timestamp extraction, and structured data handling.
81
- *
82
- * @example
83
- * ```ts
84
- * const parser = new LogParserService();
85
- * const entry = parser.parseLine('2026-02-05T21:35:28.944Z INFO ⦗API⦘ Message');
86
- * // entry.level = 'info'
87
- * // entry.timestamp = '2026-02-05T21:35:28.944Z'
88
- * // entry.tags = ['API']
89
- * ```
90
- */
91
- export class LogParserService {
92
- /** ANSI parser instance */
93
- private ansiParser: AnsiParser;
94
-
95
- /** Log level detector instance */
96
- private levelDetector: LogLevelDetector;
97
-
98
- /** Badge formatter instance */
99
- private badgeFormatter: BadgeFormatter;
100
-
101
- /** Multiline aggregator instance */
102
- private multilineAggregator: MultilineAggregator;
103
-
104
- /** Parser options */
105
- private options: Required<ILogParserOptions>;
106
-
107
- /**
108
- * Create a new log parser service.
109
- *
110
- * @param options - Parser configuration options
111
- */
112
- constructor(options: ILogParserOptions = {}) {
113
- this.options = {
114
- enable_ansi: true,
115
- timestamp_format: 'time',
116
- enable_structured: true,
117
- enable_tags: true,
118
- max_line_length: 10000,
119
- level_patterns: {},
120
- ...options,
121
- };
122
-
123
- this.ansiParser = new AnsiParser();
124
- this.badgeFormatter = new BadgeFormatter();
125
- this.multilineAggregator = new MultilineAggregator();
126
-
127
- // Convert level_patterns from Partial<Record<TLogLevel, RegExp>> to ILogLevelPattern[]
128
- const customPatterns = this.options.level_patterns
129
- ? Object.entries(this.options.level_patterns).map(([level, regex]) => ({
130
- level: level as TLogLevel,
131
- regex,
132
- confidence: 0.9,
133
- }))
134
- : undefined;
135
-
136
- this.levelDetector = new LogLevelDetector({
137
- custom_patterns: customPatterns,
138
- });
139
- }
140
-
141
- /**
142
- * Parse a single log line into structured entry.
143
- *
144
- * @param line - Raw log line
145
- * @param lineNumber - Line number in stream
146
- * @param isStderr - Whether this is from stderr
147
- * @returns Parsed log entry
148
- */
149
- parseLine(line: string, lineNumber: number, isStderr = false): IParsedLogEntry {
150
- // Truncate if too long
151
- let raw = line;
152
- let wasTruncated = false;
153
-
154
- if (line.length > this.options.max_line_length) {
155
- raw = line.slice(0, this.options.max_line_length) + '... (truncated)';
156
- wasTruncated = true;
157
- }
158
-
159
- // Detect log level
160
- const levelDetection = this.levelDetector.detect(raw);
161
- const level =
162
- levelDetection.confidence >= 0.5 ? levelDetection.level : this.levelDetector.detectOrDefault(raw);
163
-
164
- // Extract timestamp
165
- const timestamp = this.extractTimestamp(raw);
166
- const timestampDisplay = this.formatTimestamp(timestamp);
167
-
168
- // Extract tags
169
- const tags = this.options.enable_tags ? this.extractTags(raw) : undefined;
170
-
171
- // Extract message (after level and metadata)
172
- const message = this.extractMessage(raw, timestamp, levelDetection.matched);
173
-
174
- // Parse ANSI if enabled
175
- let formatted = raw;
176
- if (this.options.enable_ansi) {
177
- const result = this.ansiParser.parse(raw);
178
- formatted = result.text;
179
- } else {
180
- formatted = AnsiParser.stripAnsi(raw);
181
- }
182
-
183
- // Detect structured data (JSON)
184
- let structured: Record<string, unknown> | undefined;
185
- if (this.options.enable_structured) {
186
- structured = this.parseStructured(raw);
187
- }
188
-
189
- return {
190
- raw: wasTruncated ? raw : line,
191
- formatted,
192
- level,
193
- timestamp,
194
- timestamp_display: timestampDisplay,
195
- line_number: lineNumber,
196
- is_stderr: isStderr,
197
- structured,
198
- tags,
199
- message,
200
- };
201
- }
202
-
203
- /**
204
- * Parse multiple lines (batch processing).
205
- *
206
- * @param lines - Array of raw log lines
207
- * @param startNumber - Starting line number (default: 1)
208
- * @returns Array of parsed log entries
209
- */
210
- parseLines(lines: string[], startNumber = 1): IParsedLogEntry[] {
211
- return lines.map((line, index) => this.parseLine(line, startNumber + index));
212
- }
213
-
214
- /**
215
- * Parse logs with incremental state (for streaming).
216
- *
217
- * Maintains state between chunks for proper multiline log
218
- * aggregation and line numbering. Applies multiline aggregation
219
- * to mark continuation lines.
220
- *
221
- * @param chunk - New log chunk
222
- * @param prevState - Previous parser state
223
- * @returns Parsed entries and new state
224
- */
225
- parseIncremental(chunk: string, prevState: IParserState): { entries: IParsedLogEntry[]; newState: IParserState } {
226
- // Append chunk to buffer
227
- const buffer = prevState.buffer + chunk;
228
-
229
- // Split by newlines
230
- const lines = buffer.split('\n');
231
-
232
- // Keep last incomplete line in buffer
233
- const lastLine = lines.pop() ?? '';
234
- let currentLineNumber = prevState.line_number;
235
-
236
- // Parse complete lines
237
- const entries: IParsedLogEntry[] = [];
238
- for (const line of lines) {
239
- if (line.length > 0) {
240
- currentLineNumber++;
241
- entries.push(this.parseLine(line, currentLineNumber));
242
- }
243
- }
244
-
245
- // Apply multiline aggregation to mark continuation lines
246
- // Convert parser multiline state to aggregator state format
247
- const initialMultilineState = prevState.multiline_state ? {
248
- buffer: [],
249
- isMultiline: prevState.multiline_state.isMultiline,
250
- depth: prevState.multiline_state.depth,
251
- expectedClose: prevState.multiline_state.expectedClose,
252
- parentEntry: prevState.multiline_state.parentEntry,
253
- } : undefined;
254
-
255
- const { entries: aggregated, state: newMultilineState } = this.multilineAggregator.aggregate(entries, initialMultilineState);
256
-
257
- // Convert aggregator state back to parser state format
258
- const lastEntry = aggregated.length > 0 ? aggregated[aggregated.length - 1] : undefined;
259
-
260
- const newState: IParserState = {
261
- buffer: lastLine,
262
- line_number: currentLineNumber,
263
- last_level: lastEntry?.level ?? prevState.last_level,
264
- last_timestamp: lastEntry?.timestamp ?? prevState.last_timestamp,
265
- multiline_state: newMultilineState.isMultiline || newMultilineState.depth > 0 ? {
266
- isMultiline: newMultilineState.isMultiline,
267
- depth: newMultilineState.depth,
268
- expectedClose: newMultilineState.expectedClose,
269
- parentEntry: newMultilineState.parentEntry,
270
- } : undefined,
271
- };
272
-
273
- return { entries: aggregated, newState };
274
- }
275
-
276
- /**
277
- * Format log entry for xterm.js display.
278
- *
279
- * Supports two modes:
280
- *
281
- * **'raw' mode (default for terminal):**
282
- * - Returns the log AS-IS without modifications
283
- * - Preserves original ANSI codes from the source (bun, supervisord, etc.)
284
- * - No badges, no formatting, just the raw log line
285
- * - Prevents ANSI mixing artifacts and visible escape codes
286
- *
287
- * **'parsed' mode (for React viewer):**
288
- * - Strips ANSI codes first
289
- * - Adds level badge, tag badges, timestamp badge
290
- * - Formats message content for React display
291
- * - Continuation lines get indented
292
- *
293
- * @param entry - Parsed log entry
294
- * @param mode - Format mode: 'raw' (default) or 'parsed'
295
- * @returns Formatted string for xterm.js or React viewer
296
- */
297
- formatForTerminal(entry: IParsedLogEntry, mode: 'raw' | 'parsed' = 'raw'): string {
298
- // RAW MODE: Return log as-is, no modifications
299
- // This preserves original ANSI codes from the source that work correctly with xterm.js
300
- if (mode === 'raw') {
301
- return entry.raw;
302
- }
303
-
304
- // PARSED MODE: Strip ANSI, add badges, format for React viewer
305
- // For continuation lines (multiline JSON), indent and return stripped
306
- if (entry.is_continuation) {
307
- const indent = ' ';
308
- return indent + AnsiParser.stripAnsi(entry.raw).trimEnd();
309
- }
310
-
311
- const parts: string[] = [];
312
-
313
- // 1. Level badge at start
314
- const levelBadge = this.badgeFormatter.createLevelBadge(entry.level);
315
- parts.push(levelBadge);
316
-
317
- // 2. Tag badges (if any)
318
- if (entry.tags && entry.tags.length > 0) {
319
- const tagBadges = this.badgeFormatter.createTagBadges(entry.tags);
320
- if (tagBadges) {
321
- parts.push(tagBadges);
322
- }
323
- }
324
-
325
- // 3. Message content - use STRIPPED message for parsed mode
326
- // entry.message is stripped of metadata but may be incomplete
327
- // entry.raw is the full line, we strip ANSI from it for parsed mode
328
- const messageContent = entry.message ?? AnsiParser.stripAnsi(entry.raw);
329
- parts.push(messageContent);
330
-
331
- // 4. Build line with timestamp at end
332
- let line = parts.join(' ');
333
-
334
- // Add timestamp at the end, right-aligned
335
- if (entry.timestamp_display) {
336
- const timestampBadge = this.badgeFormatter.createTimestampBadge(entry.timestamp_display);
337
- line = line + timestampBadge;
338
- }
339
-
340
- return line;
341
- }
342
-
343
- /**
344
- * Check if line contains structured data (JSON).
345
- *
346
- * @param line - Log line to check
347
- * @returns true if line contains valid JSON
348
- */
349
- isStructured(line: string): boolean {
350
- const trimmed = line.trim();
351
- if ((trimmed.startsWith('{') && trimmed.endsWith('}')) || (trimmed.startsWith('[') && trimmed.endsWith(']'))) {
352
- try {
353
- JSON.parse(trimmed);
354
- return true;
355
- } catch {
356
- return false;
357
- }
358
- }
359
- return false;
360
- }
361
-
362
- /**
363
- * Filter log entries by criteria.
364
- *
365
- * @param entries - Array of parsed log entries
366
- * @param filter - Filter options
367
- * @returns Filtered array of entries
368
- */
369
- filter(entries: IParsedLogEntry[], filter: ILogFilterOptions): IParsedLogEntry[] {
370
- return entries.filter((entry) => {
371
- // Minimum level
372
- if (filter.min_level !== undefined) {
373
- const entrySeverity = LogLevelDetector.getSeverity(entry.level);
374
- const minSeverity = LogLevelDetector.getSeverity(filter.min_level);
375
- if (entrySeverity < minSeverity) return false;
376
- }
377
-
378
- // stderr only
379
- if (filter.stderr_only !== undefined) {
380
- if (filter.stderr_only && !entry.is_stderr) return false;
381
- if (!filter.stderr_only && entry.is_stderr) return false;
382
- }
383
-
384
- // Pattern match
385
- if (filter.pattern) {
386
- if (!filter.pattern.test(entry.raw)) return false;
387
- }
388
-
389
- // Tags filter
390
- if (filter.tags && filter.tags.length > 0) {
391
- if (!entry.tags || !filter.tags.some((t) => entry.tags?.includes(t))) return false;
392
- }
393
-
394
- // Time range
395
- if (filter.after && entry.timestamp) {
396
- if (entry.timestamp < filter.after) return false;
397
- }
398
- if (filter.before && entry.timestamp) {
399
- if (entry.timestamp > filter.before) return false;
400
- }
401
-
402
- return true;
403
- });
404
- }
405
-
406
- /**
407
- * Calculate statistics for log entries.
408
- *
409
- * @param entries - Array of parsed log entries
410
- * @returns Log statistics
411
- */
412
- calculateStats(entries: IParsedLogEntry[]): ILogStats {
413
- const byLevel: Partial<Record<TLogLevel, number>> = {
414
- trace: 0,
415
- debug: 0,
416
- info: 0,
417
- warn: 0,
418
- error: 0,
419
- fatal: 0,
420
- unknown: 0,
421
- };
422
-
423
- let bytes = 0;
424
- let earliest: string | undefined;
425
- let latest: string | undefined;
426
-
427
- for (const entry of entries) {
428
- byLevel[entry.level] = (byLevel[entry.level] ?? 0) + 1;
429
- bytes += entry.raw.length;
430
-
431
- if (entry.timestamp) {
432
- if (!earliest || entry.timestamp < earliest) earliest = entry.timestamp;
433
- if (!latest || entry.timestamp > latest) latest = entry.timestamp;
434
- }
435
- }
436
-
437
- return {
438
- total: entries.length,
439
- by_level: byLevel,
440
- bytes,
441
- earliest,
442
- latest,
443
- };
444
- }
445
-
446
- /**
447
- * Create initial parser state.
448
- *
449
- * @returns Fresh parser state for incremental parsing
450
- */
451
- createInitialState(): IParserState {
452
- return {
453
- buffer: '',
454
- line_number: 0,
455
- last_level: 'info',
456
- last_timestamp: undefined,
457
- multiline_state: undefined,
458
- };
459
- }
460
-
461
- /**
462
- * Extract timestamp from log line.
463
- *
464
- * Handles multiple timestamp formats including:
465
- * - Double timestamp (ISO + time): 2026-02-05T22:41:05.372Z 22:41:05.372
466
- * - Supervisord: 2026-02-05 22:22:38,372
467
- * - Unix milliseconds: [1770328479225]
468
- *
469
- * @param line - Log line
470
- * @returns ISO timestamp string or undefined
471
- * @private
472
- */
473
- private extractTimestamp(line: string): string | undefined {
474
- for (const pattern of TIMESTAMP_PATTERNS) {
475
- const match = line.match(pattern.regex);
476
- if (match) {
477
- // For double timestamp, extract the time portion (index 2 if available, else 1)
478
- const captured = match[(pattern as { extractIndex?: number }).extractIndex ?? 1];
479
-
480
- if (pattern.format === 'unix') {
481
- return new Date(parseInt(captured, 10)).toISOString();
482
- }
483
-
484
- // For double timestamp, return the time portion for display
485
- // For ISO, convert to time portion later in formatTimestamp
486
- return captured;
487
- }
488
- }
489
- return undefined;
490
- }
491
-
492
- /**
493
- * Format timestamp for display.
494
- *
495
- * @param timestamp - ISO timestamp
496
- * @returns Formatted timestamp string
497
- * @private
498
- */
499
- private formatTimestamp(timestamp: string | undefined): string | undefined {
500
- if (!timestamp) return undefined;
501
-
502
- switch (this.options.timestamp_format) {
503
- case 'none':
504
- return undefined;
505
-
506
- case 'full':
507
- return timestamp;
508
-
509
- case 'time':
510
- // Extract time portion: 21:35:28.944
511
- const timeMatch = timestamp.match(/(\d{2}:\d{2}:\d{2}(?:\.\d+)?)/);
512
- return timeMatch ? timeMatch[1] : timestamp;
513
-
514
- case 'relative':
515
- const date = new Date(timestamp);
516
- const now = new Date();
517
- const diff = now.getTime() - date.getTime();
518
- if (diff < 1000) return 'just now';
519
- if (diff < 60000) return `${Math.floor(diff / 1000)}s ago`;
520
- if (diff < 3600000) return `${Math.floor(diff / 60000)}m ago`;
521
- return `${Math.floor(diff / 3600000)}h ago`;
522
-
523
- default:
524
- return timestamp;
525
- }
526
- }
527
-
528
- /**
529
- * Extract tags from log line.
530
- *
531
- * @param line - Log line
532
- * @returns Array of extracted tags
533
- * @private
534
- */
535
- private extractTags(line: string): string[] {
536
- const tags: string[] = [];
537
- let match: RegExpExecArray | null;
538
-
539
- // 1. Brackets format: [INFO], [WARN], [ERROR], [SUCCESS]
540
- const bracketPattern = /\[([A-Z]+)\]/g;
541
- bracketPattern.lastIndex = 0;
542
- while ((match = bracketPattern.exec(line)) !== null) {
543
- tags.push(match[1]);
544
- }
545
-
546
- // 2. Parentheses format: (INFO), (WARN), (ERROR)
547
- const parenPattern = /\(([^)]+)\)/g;
548
- parenPattern.lastIndex = 0;
549
- while ((match = parenPattern.exec(line)) !== null) {
550
- const tag = match[1].toUpperCase();
551
- if (!tags.includes(tag)) {
552
- tags.push(tag);
553
- }
554
- }
555
-
556
- // 3. Angle brackets: <INFO>, <WARN>, <ERROR>
557
- const anglePattern = /<([^>]+)>/g;
558
- anglePattern.lastIndex = 0;
559
- while ((match = anglePattern.exec(line)) !== null) {
560
- const tag = match[1].toUpperCase();
561
- if (!tags.includes(tag)) {
562
- tags.push(tag);
563
- }
564
- }
565
-
566
- // 4. Unicode tags: ⦗TAG⦘
567
- TAG_PATTERN.lastIndex = 0;
568
- while ((match = TAG_PATTERN.exec(line)) !== null) {
569
- const tag = match[1];
570
- if (!tags.includes(tag)) {
571
- tags.push(tag);
572
- }
573
- }
574
-
575
- return tags;
576
- }
577
-
578
- /**
579
- * Extract message content from log line.
580
- *
581
- * Removes ALL metadata including timestamps, levels, tags, and source locations
582
- * to return only the clean message content.
583
- *
584
- * @param line - Log line
585
- * @param _timestamp - Extracted timestamp (unused, kept for API compatibility)
586
- * @param _levelMatch - Level match string (unused, kept for API compatibility)
587
- * @returns Message content
588
- * @private
589
- */
590
- private extractMessage(line: string, _timestamp?: string, _levelMatch?: string): string {
591
- let message = line;
592
-
593
- // Remove ALL timestamps (multiple formats)
594
- message = message
595
- // Double timestamp: 2026-02-05T22:41:05.372991285Z 22:41:05.372
596
- .replace(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z?\s+\d{2}:\d{2}:\d{2}(?:\.\d+)?\s+/, '')
597
- // ISO timestamp: 2026-02-05T22:41:05.372991285Z
598
- .replace(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z?\s*/, '')
599
- // Time only: 22:41:05.372
600
- .replace(/^\d{2}:\d{2}:\d{2}(?:\.\d+)?\s*/, '')
601
- // Supervisord format: 2026-02-05 22:22:38,372
602
- .replace(/^\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2},\d+\s+/, '')
603
- // Unix timestamp: [1770328479225]
604
- .replace(/^\[\d{13,}\]\s*/, '')
605
- // Bracketed datetime: [2026-02-05 21:35:28]
606
- .replace(/^\[\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\]\s*/, '')
607
- // Syslog format: Feb 5 21:35:28
608
- .replace(/^[A-Z][a-z]{2}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2}\s+/, '');
609
-
610
- // Remove emoji + text level indicators: ℹ️ INFO, ⚠️ WARN, ❌ ERROR
611
- message = message
612
- .replace(/^\s*[ℹ️🔵💙📖📝]+\s+(?:INFO(?:RMATION)?\s*)?/i, '') // info
613
- .replace(/^\s*[⚠️🟡⚡🔶]+\s*(?:WARN(?:ING)?\s*)?/i, '') // warn
614
- .replace(/^\s*[❌🔴❗🚨⛔]+\s*(?:ERROR\s*)?/i, '') // error
615
- .replace(/^\s*[🐛🔍🔬⚙️]+\s*(?:DEBUG\s*)?/i, '') // debug
616
- .replace(/^\s*[💀🔥☠️⚰️]+\s*(?:FATAL|CRITICAL\s*)?/i, '') // fatal/critical
617
- // Next.js/symbol patterns
618
- .replace(/^\s*[▲✓✗⚡]+\s*/, '');
619
-
620
- // Remove bracketed level indicators: [INFO], (WARN), <ERROR>, {INFO}
621
- message = message
622
- .replace(/^\s*\[(?:TRACE|DEBUG|INFO|WARN(?:ING)?|ERROR|FATAL|CRITICAL)\]\s*/i, '')
623
- .replace(/^\s*(?:TRACE|DEBUG|INFO|WARN(?:ING)?|ERROR|FATAL|CRITICAL):\s*/i, '');
624
-
625
- // Remove ALL bracketed tags: ⦗COMPONENT⦘ ⦗WORKSPACEMANAGERROUTES⦘
626
- message = message.replace(/⦗[^⦘]+⦘\s*/g, '');
627
-
628
- // Remove source location: (native:7:39) or (file.ts:42:10)
629
- message = message.replace(/\([^)]+\d+:\d+\)\s*/, '');
630
-
631
- // Remove colon-prefixed tags: [ContainerLogs]
632
- message = message.replace(/^\[[\w\s]+\]\s*/, '');
633
-
634
- // Remove leading emoji remnants
635
- message = message.replace(/^\s*[ℹ️⚠️❌🐛💀🚨🔥☠️⚰️🔵🟡🔴💙📖📝🔍🔬⚙️🔶▲✓✗⚡]+\s*/, '');
636
-
637
- // Clean up extra whitespace and trailing commas/braces
638
- message = message
639
- .replace(/^\s+/, '') // Leading whitespace
640
- .replace(/\s+$/, '') // Trailing whitespace
641
- .replace(/^[,\s]+/, '') // Leading commas/whitespace from multiline JSON
642
- .trim();
643
-
644
- return message;
645
- }
646
-
647
- /**
648
- * Parse structured data (JSON) from log line.
649
- *
650
- * @param line - Log line
651
- * @returns Parsed object or undefined
652
- * @private
653
- */
654
- private parseStructured(line: string): Record<string, unknown> | undefined {
655
- // Try to find JSON in the line
656
- const jsonMatch = line.match(/\{[^{}]*\}/);
657
- if (!jsonMatch) return undefined;
658
-
659
- try {
660
- return JSON.parse(jsonMatch[0]) as Record<string, unknown>;
661
- } catch {
662
- return undefined;
663
- }
664
- }
665
-
666
- /**
667
- * Get ANSI color code for log level.
668
- *
669
- * @param level - Log level
670
- * @returns ANSI SGR color code
671
- * @private
672
- */
673
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
674
- private _getAnsiColorForLevel(level: TLogLevel): number {
675
- const colors: Record<TLogLevel, number> = {
676
- trace: 90, // Gray
677
- debug: 36, // Cyan
678
- info: 34, // Blue
679
- warn: 33, // Yellow
680
- error: 31, // Red
681
- fatal: 35, // Magenta
682
- unknown: 37, // White
683
- };
684
- return colors[level] ?? 37;
685
- }
686
- }