@mks2508/mks-ui 0.3.2 → 0.4.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.
- package/dist/react-ui/blocks/Terminal/ResttyAdapter.d.ts +146 -0
- package/dist/react-ui/blocks/Terminal/ResttyAdapter.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/ResttyAdapter.js +213 -0
- package/dist/react-ui/blocks/Terminal/Terminal.adapter.d.ts +55 -0
- package/dist/react-ui/blocks/Terminal/Terminal.adapter.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/Terminal.adapter.js +68 -0
- package/dist/react-ui/blocks/Terminal/Terminal.theme.d.ts +43 -0
- package/dist/react-ui/blocks/Terminal/Terminal.theme.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/Terminal.theme.js +59 -0
- package/dist/react-ui/blocks/Terminal/Terminal.theme.restty.d.ts +63 -0
- package/dist/react-ui/blocks/Terminal/Terminal.theme.restty.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/Terminal.theme.restty.js +109 -0
- package/dist/react-ui/blocks/Terminal/Terminal.types.d.ts +351 -0
- package/dist/react-ui/blocks/Terminal/Terminal.types.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/TerminalPanel.d.ts +60 -0
- package/dist/react-ui/blocks/Terminal/TerminalPanel.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/TerminalPanel.js +183 -0
- package/dist/react-ui/blocks/Terminal/TerminalRestty.d.ts +111 -0
- package/dist/react-ui/blocks/Terminal/TerminalRestty.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/TerminalRestty.js +185 -0
- package/dist/react-ui/blocks/Terminal/TerminalXterm.d.ts +58 -0
- package/dist/react-ui/blocks/Terminal/TerminalXterm.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/TerminalXterm.js +143 -0
- package/dist/react-ui/blocks/Terminal/XTermAdapter.d.ts +87 -0
- package/dist/react-ui/blocks/Terminal/XTermAdapter.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/XTermAdapter.js +135 -0
- package/dist/react-ui/blocks/Terminal/components/LogLineBadges.d.ts +160 -0
- package/dist/react-ui/blocks/Terminal/components/LogLineBadges.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/components/LogLineBadges.js +185 -0
- package/dist/react-ui/blocks/Terminal/components/SpecializedSyntaxHighlighter.d.ts +48 -0
- package/dist/react-ui/blocks/Terminal/components/SpecializedSyntaxHighlighter.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/components/SpecializedSyntaxHighlighter.js +139 -0
- package/dist/react-ui/blocks/Terminal/components/SyntaxHighlight.d.ts +60 -0
- package/dist/react-ui/blocks/Terminal/components/SyntaxHighlight.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/components/SyntaxHighlight.js +352 -0
- package/dist/react-ui/blocks/Terminal/components/TerminalLogBadge.d.ts +36 -0
- package/dist/react-ui/blocks/Terminal/components/TerminalLogBadge.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/components/TerminalLogBadge.js +52 -0
- package/dist/react-ui/blocks/Terminal/components/index.d.ts +10 -0
- package/dist/react-ui/blocks/Terminal/components/index.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/components/index.js +4 -0
- package/dist/react-ui/blocks/Terminal/hooks/index.d.ts +11 -0
- package/dist/react-ui/blocks/Terminal/hooks/index.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/hooks/index.js +2 -0
- package/dist/react-ui/blocks/Terminal/hooks/useTerminalSettings.d.ts +69 -0
- package/dist/react-ui/blocks/Terminal/hooks/useTerminalSettings.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/hooks/useTerminalSettings.js +162 -0
- package/dist/react-ui/blocks/Terminal/hooks/useTerminalWebSocket.d.ts +104 -0
- package/dist/react-ui/blocks/Terminal/hooks/useTerminalWebSocket.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/hooks/useTerminalWebSocket.js +180 -0
- package/dist/react-ui/blocks/Terminal/index.d.ts +39 -0
- package/dist/react-ui/blocks/Terminal/index.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/index.js +38 -0
- package/dist/react-ui/blocks/Terminal/panel/LogLinesViewer.d.ts +58 -0
- package/dist/react-ui/blocks/Terminal/panel/LogLinesViewer.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/LogLinesViewer.js +222 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalDebugPanel.d.ts +74 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalDebugPanel.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalDebugPanel.js +168 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalFilterDropdown.d.ts +42 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalFilterDropdown.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalFilterDropdown.js +175 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalFilterTabs.d.ts +43 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalFilterTabs.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalInteractivePanel.d.ts +38 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalInteractivePanel.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalInteractivePanel.js +62 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalInteractivePanel.types.d.ts +67 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalInteractivePanel.types.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalInteractivePanelRestty.d.ts +32 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalInteractivePanelRestty.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalInteractivePanelRestty.js +326 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalInteractivePanelXterm.d.ts +36 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalInteractivePanelXterm.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalInteractivePanelXterm.js +371 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalLogsPanel.d.ts +67 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalLogsPanel.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalLogsPanel.js +417 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalLogsPanel.types.d.ts +197 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalLogsPanel.types.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalPanelChrome.d.ts +54 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalPanelChrome.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalPanelChrome.js +193 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalPanelChrome.types.d.ts +57 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalPanelChrome.types.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalPanelFooter.d.ts +30 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalPanelFooter.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalPanelFooter.js +126 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalPanelHeader.d.ts +31 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalPanelHeader.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalPanelHeader.js +149 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalPanelToolbar.d.ts +35 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalPanelToolbar.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalSessionControl.d.ts +58 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalSessionControl.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalSessionTabs.d.ts +63 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalSessionTabs.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalSessionTabs.js +245 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalSettingsPopover.d.ts +24 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalSettingsPopover.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalSettingsPopover.js +225 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalThemeSelector.d.ts +35 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalThemeSelector.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/TerminalThemeSelector.js +187 -0
- package/dist/react-ui/blocks/Terminal/panel/index.d.ts +30 -0
- package/dist/react-ui/blocks/Terminal/panel/index.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/panel/terminal-filter-dropdown.module-Bovc57nm.css +60 -0
- package/dist/react-ui/blocks/Terminal/panel/terminal-filter-dropdown.module.js +5 -0
- package/dist/react-ui/blocks/Terminal/panel/terminal-session-tabs.module-QyxHO7cN.css +60 -0
- package/dist/react-ui/blocks/Terminal/panel/terminal-session-tabs.module.js +5 -0
- package/dist/react-ui/blocks/Terminal/parsing/BadgeFormatter.d.ts +73 -0
- package/dist/react-ui/blocks/Terminal/parsing/BadgeFormatter.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/parsing/BadgeFormatter.js +136 -0
- package/dist/react-ui/blocks/Terminal/parsing/HttpLogParser.d.ts +117 -0
- package/dist/react-ui/blocks/Terminal/parsing/HttpLogParser.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/parsing/HttpLogParser.js +174 -0
- package/dist/react-ui/blocks/Terminal/parsing/LogParser.types.d.ts +221 -0
- package/dist/react-ui/blocks/Terminal/parsing/LogParser.types.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/parsing/LogParserService.d.ts +184 -0
- package/dist/react-ui/blocks/Terminal/parsing/LogParserService.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/parsing/LogParserService.js +478 -0
- package/dist/react-ui/blocks/Terminal/parsing/MultilineAggregator.d.ts +173 -0
- package/dist/react-ui/blocks/Terminal/parsing/MultilineAggregator.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/parsing/MultilineAggregator.js +313 -0
- package/dist/react-ui/blocks/Terminal/parsing/PersistentLogBuffer.d.ts +181 -0
- package/dist/react-ui/blocks/Terminal/parsing/PersistentLogBuffer.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/parsing/PersistentLogBuffer.js +221 -0
- package/dist/react-ui/blocks/Terminal/parsing/SyntaxHighlighter.d.ts +69 -0
- package/dist/react-ui/blocks/Terminal/parsing/SyntaxHighlighter.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/parsing/SyntaxHighlighter.js +142 -0
- package/dist/react-ui/blocks/Terminal/parsing/TableParser.d.ts +125 -0
- package/dist/react-ui/blocks/Terminal/parsing/TableParser.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/parsing/TableParser.js +245 -0
- package/dist/react-ui/blocks/Terminal/parsing/ansi/AnsiColorMapper.d.ts +165 -0
- package/dist/react-ui/blocks/Terminal/parsing/ansi/AnsiColorMapper.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/parsing/ansi/AnsiColorMapper.js +225 -0
- package/dist/react-ui/blocks/Terminal/parsing/ansi/AnsiParser.d.ts +164 -0
- package/dist/react-ui/blocks/Terminal/parsing/ansi/AnsiParser.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/parsing/ansi/AnsiParser.js +285 -0
- package/dist/react-ui/blocks/Terminal/parsing/ansi/ansi.constants.d.ts +188 -0
- package/dist/react-ui/blocks/Terminal/parsing/ansi/ansi.constants.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/parsing/ansi/ansi.constants.js +178 -0
- package/dist/react-ui/blocks/Terminal/parsing/ansi/index.d.ts +12 -0
- package/dist/react-ui/blocks/Terminal/parsing/ansi/index.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/parsing/index.d.ts +24 -0
- package/dist/react-ui/blocks/Terminal/parsing/index.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/parsing/levels/LogLevel.types.d.ts +56 -0
- package/dist/react-ui/blocks/Terminal/parsing/levels/LogLevel.types.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/parsing/levels/LogLevelDetector.d.ts +140 -0
- package/dist/react-ui/blocks/Terminal/parsing/levels/LogLevelDetector.d.ts.map +1 -0
- package/dist/react-ui/blocks/Terminal/parsing/levels/LogLevelDetector.js +325 -0
- package/dist/react-ui/blocks/Terminal/parsing/levels/index.d.ts +10 -0
- package/dist/react-ui/blocks/Terminal/parsing/levels/index.d.ts.map +1 -0
- package/dist/react-ui/blocks/index.d.ts +11 -0
- package/dist/react-ui/blocks/index.d.ts.map +1 -0
- package/dist/react-ui/icons/lucide-animated/activity.js +1 -1
- package/dist/react-ui/icons/lucide-animated/bell-electric.js +1 -1
- package/dist/react-ui/icons/lucide-animated/bell.js +1 -1
- package/dist/react-ui/icons/lucide-animated/bot.js +1 -1
- package/dist/react-ui/icons/lucide-animated/box.js +1 -1
- package/dist/react-ui/icons/lucide-animated/circle-check.js +1 -1
- package/dist/react-ui/icons/lucide-animated/delete.js +1 -1
- package/dist/react-ui/icons/lucide-animated/download.js +1 -1
- package/dist/react-ui/icons/lucide-animated/home.js +1 -1
- package/dist/react-ui/icons/lucide-animated/layout-panel-top.js +1 -1
- package/dist/react-ui/icons/lucide-animated/plus.js +1 -1
- package/dist/react-ui/icons/lucide-animated/search.js +1 -1
- package/dist/react-ui/icons/lucide-animated/settings.js +1 -1
- package/dist/react-ui/icons/lucide-animated/trending-down.js +1 -1
- package/dist/react-ui/icons/lucide-animated/trending-up.js +1 -1
- package/dist/react-ui/icons/lucide-animated/x.js +1 -1
- package/dist/react-ui/index.js +3 -1
- package/dist/react-ui/lib/icon-wrapper.d.ts +37 -0
- package/dist/react-ui/lib/icon-wrapper.d.ts.map +1 -0
- package/dist/react-ui/lib/icon-wrapper.js +55 -0
- package/dist/react-ui/lib/index.d.ts +1 -0
- package/dist/react-ui/lib/index.d.ts.map +1 -1
- package/dist/react-ui/lib/index.js +1 -0
- package/dist/react-ui/primitives/AutoHeight/index.d.ts +1 -1
- package/dist/react-ui/primitives/CountingNumber/index.d.ts +1 -1
- package/dist/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.styles.d.ts +1 -1
- package/dist/react-ui/primitives/waapi/SlidingText/SlidingText.styles.d.ts +1 -1
- package/dist/react-ui/ui/Accordion/Accordion.styles.d.ts +1 -1
- package/dist/react-ui/ui/Accordion/Accordion.types.d.ts +1 -1
- package/dist/react-ui/ui/AlertDialog/AlertDialog.styles.d.ts +1 -1
- package/dist/react-ui/ui/AlertDialog/AlertDialog.types.d.ts +1 -1
- package/dist/react-ui/ui/Badge/Badge.styles.d.ts +1 -1
- package/dist/react-ui/ui/Badge/Badge.types.d.ts +1 -1
- package/dist/react-ui/ui/Button/Button.styles.d.ts +2 -2
- package/dist/react-ui/ui/Button/Button.types.d.ts +1 -1
- package/dist/react-ui/ui/Card/Card.styles.d.ts +1 -1
- package/dist/react-ui/ui/Card/Card.types.d.ts +1 -1
- package/dist/react-ui/ui/Checkbox/Checkbox.styles.d.ts +1 -1
- package/dist/react-ui/ui/Checkbox/Checkbox.types.d.ts +1 -1
- package/dist/react-ui/ui/Combobox/Combobox.styles.d.ts +1 -1
- package/dist/react-ui/ui/Combobox/Combobox.types.d.ts +1 -1
- package/dist/react-ui/ui/CornerBracket/CornerBracket.styles.d.ts +2 -2
- package/dist/react-ui/ui/CornerBracket/CornerBracket.styles.js +1 -1
- package/dist/react-ui/ui/CornerBracket/CornerBracket.types.d.ts +1 -1
- package/dist/react-ui/ui/DataCard/DataCard.styles.d.ts +1 -1
- package/dist/react-ui/ui/DataCard/DataCard.types.d.ts +1 -1
- package/dist/react-ui/ui/DataCard/index.d.ts +1 -1
- package/dist/react-ui/ui/Dialog/Dialog.styles.d.ts +1 -1
- package/dist/react-ui/ui/Dialog/Dialog.types.d.ts +1 -1
- package/dist/react-ui/ui/DropdownMenu/DropdownMenu.styles.d.ts +1 -1
- package/dist/react-ui/ui/DropdownMenu/DropdownMenu.types.d.ts +1 -1
- package/dist/react-ui/ui/Field/Field.styles.d.ts +1 -1
- package/dist/react-ui/ui/Field/Field.types.d.ts +1 -1
- package/dist/react-ui/ui/Input/Input.styles.d.ts +1 -1
- package/dist/react-ui/ui/Input/Input.types.d.ts +1 -1
- package/dist/react-ui/ui/InputGroup/InputGroup.styles.d.ts +1 -1
- package/dist/react-ui/ui/InputGroup/InputGroup.types.d.ts +1 -1
- package/dist/react-ui/ui/Label/Label.styles.d.ts +1 -1
- package/dist/react-ui/ui/Label/Label.types.d.ts +1 -1
- package/dist/react-ui/ui/Menu/Menu.styles.d.ts +1 -1
- package/dist/react-ui/ui/Menu/Menu.types.d.ts +2 -2
- package/dist/react-ui/ui/Popover/Popover.styles.d.ts +1 -1
- package/dist/react-ui/ui/Popover/Popover.types.d.ts +1 -1
- package/dist/react-ui/ui/Progress/Progress.styles.d.ts +1 -1
- package/dist/react-ui/ui/Progress/Progress.types.d.ts +2 -2
- package/dist/react-ui/ui/Select/Select.styles.d.ts +1 -1
- package/dist/react-ui/ui/Select/Select.types.d.ts +1 -1
- package/dist/react-ui/ui/Separator/Separator.styles.d.ts +1 -1
- package/dist/react-ui/ui/Separator/Separator.types.d.ts +1 -1
- package/dist/react-ui/ui/Switch/Switch.styles.d.ts +1 -1
- package/dist/react-ui/ui/Switch/Switch.types.d.ts +1 -1
- package/dist/react-ui/ui/Tabs/Tabs.styles.d.ts +43 -25
- package/dist/react-ui/ui/Tabs/Tabs.styles.d.ts.map +1 -1
- package/dist/react-ui/ui/Tabs/Tabs.styles.js +105 -13
- package/dist/react-ui/ui/Tabs/Tabs.types.d.ts +9 -6
- package/dist/react-ui/ui/Tabs/Tabs.types.d.ts.map +1 -1
- package/dist/react-ui/ui/Tabs/index.d.ts +18 -9
- package/dist/react-ui/ui/Tabs/index.d.ts.map +1 -1
- package/dist/react-ui/ui/Tabs/index.js +99 -27
- package/dist/react-ui/ui/TextFlow/TextFlow.styles.d.ts +1 -1
- package/dist/react-ui/ui/Textarea/Textarea.styles.d.ts +1 -1
- package/dist/react-ui/ui/Textarea/Textarea.types.d.ts +1 -1
- package/dist/react-ui/ui/Tooltip/Tooltip.styles.d.ts +1 -1
- package/dist/react-ui/ui/Tooltip/Tooltip.types.d.ts +1 -1
- package/dist/react-ui/ui/index.js +1 -0
- package/package.json +54 -6
- package/src/react-ui/blocks/Terminal/ResttyAdapter.ts +278 -0
- package/src/react-ui/blocks/Terminal/Terminal.adapter.ts +97 -0
- package/src/react-ui/blocks/Terminal/Terminal.theme.restty.ts +155 -0
- package/src/react-ui/blocks/Terminal/Terminal.theme.ts +80 -0
- package/src/react-ui/blocks/Terminal/Terminal.types.ts +438 -0
- package/src/react-ui/blocks/Terminal/TerminalPanel.tsx +269 -0
- package/src/react-ui/blocks/Terminal/TerminalRestty.tsx +326 -0
- package/src/react-ui/blocks/Terminal/TerminalXterm.tsx +230 -0
- package/src/react-ui/blocks/Terminal/XTermAdapter.ts +163 -0
- package/src/react-ui/blocks/Terminal/components/LogLineBadges.tsx +316 -0
- package/src/react-ui/blocks/Terminal/components/SpecializedSyntaxHighlighter.tsx +218 -0
- package/src/react-ui/blocks/Terminal/components/SyntaxHighlight.tsx +386 -0
- package/src/react-ui/blocks/Terminal/components/TerminalLogBadge.tsx +67 -0
- package/src/react-ui/blocks/Terminal/components/index.ts +10 -0
- package/src/react-ui/blocks/Terminal/hooks/index.ts +22 -0
- package/src/react-ui/blocks/Terminal/hooks/useTerminalSettings.ts +229 -0
- package/src/react-ui/blocks/Terminal/hooks/useTerminalWebSocket.ts +292 -0
- package/src/react-ui/blocks/Terminal/index.ts +103 -0
- package/src/react-ui/blocks/Terminal/panel/LogLinesViewer.tsx +330 -0
- package/src/react-ui/blocks/Terminal/panel/TerminalDebugPanel.tsx +242 -0
- package/src/react-ui/blocks/Terminal/panel/TerminalFilterDropdown.tsx +202 -0
- package/src/react-ui/blocks/Terminal/panel/TerminalFilterTabs.tsx +140 -0
- package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanel.tsx +68 -0
- package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanel.types.ts +85 -0
- package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanelRestty.tsx +383 -0
- package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanelXterm.tsx +439 -0
- package/src/react-ui/blocks/Terminal/panel/TerminalLogsPanel.tsx +550 -0
- package/src/react-ui/blocks/Terminal/panel/TerminalLogsPanel.types.ts +259 -0
- package/src/react-ui/blocks/Terminal/panel/TerminalPanelChrome.tsx +237 -0
- package/src/react-ui/blocks/Terminal/panel/TerminalPanelChrome.types.ts +76 -0
- package/src/react-ui/blocks/Terminal/panel/TerminalPanelFooter.tsx +112 -0
- package/src/react-ui/blocks/Terminal/panel/TerminalPanelHeader.tsx +178 -0
- package/src/react-ui/blocks/Terminal/panel/TerminalPanelToolbar.tsx +203 -0
- package/src/react-ui/blocks/Terminal/panel/TerminalSessionControl.tsx +252 -0
- package/src/react-ui/blocks/Terminal/panel/TerminalSessionTabs.tsx +334 -0
- package/src/react-ui/blocks/Terminal/panel/TerminalSettingsPopover.tsx +261 -0
- package/src/react-ui/blocks/Terminal/panel/TerminalThemeSelector.tsx +248 -0
- package/src/react-ui/blocks/Terminal/panel/index.ts +72 -0
- package/src/react-ui/blocks/Terminal/panel/terminal-filter-dropdown.module.css +59 -0
- package/src/react-ui/blocks/Terminal/panel/terminal-session-tabs.module.css +59 -0
- package/src/react-ui/blocks/Terminal/parsing/BadgeFormatter.ts +180 -0
- package/src/react-ui/blocks/Terminal/parsing/HttpLogParser.ts +248 -0
- package/src/react-ui/blocks/Terminal/parsing/LogParser.types.ts +283 -0
- package/src/react-ui/blocks/Terminal/parsing/LogParserService.ts +686 -0
- package/src/react-ui/blocks/Terminal/parsing/MultilineAggregator.ts +466 -0
- package/src/react-ui/blocks/Terminal/parsing/PersistentLogBuffer.ts +343 -0
- package/src/react-ui/blocks/Terminal/parsing/SyntaxHighlighter.ts +167 -0
- package/src/react-ui/blocks/Terminal/parsing/TableParser.ts +348 -0
- package/src/react-ui/blocks/Terminal/parsing/ansi/AnsiColorMapper.ts +251 -0
- package/src/react-ui/blocks/Terminal/parsing/ansi/AnsiParser.ts +390 -0
- package/src/react-ui/blocks/Terminal/parsing/ansi/ansi.constants.ts +320 -0
- package/src/react-ui/blocks/Terminal/parsing/ansi/index.ts +20 -0
- package/src/react-ui/blocks/Terminal/parsing/index.ts +69 -0
- package/src/react-ui/blocks/Terminal/parsing/levels/LogLevel.types.ts +68 -0
- package/src/react-ui/blocks/Terminal/parsing/levels/LogLevelDetector.ts +436 -0
- package/src/react-ui/blocks/Terminal/parsing/levels/index.ts +14 -0
- package/src/react-ui/blocks/index.ts +11 -0
- package/src/react-ui/icons/lucide-animated/activity.tsx +2 -2
- package/src/react-ui/icons/lucide-animated/bell-electric.tsx +1 -1
- package/src/react-ui/icons/lucide-animated/bell.tsx +2 -2
- package/src/react-ui/icons/lucide-animated/bot.tsx +1 -1
- package/src/react-ui/icons/lucide-animated/box.tsx +2 -2
- package/src/react-ui/icons/lucide-animated/circle-check.tsx +2 -2
- package/src/react-ui/icons/lucide-animated/delete.tsx +2 -2
- package/src/react-ui/icons/lucide-animated/download.tsx +2 -2
- package/src/react-ui/icons/lucide-animated/home.tsx +2 -2
- package/src/react-ui/icons/lucide-animated/layout-panel-top.tsx +1 -1
- package/src/react-ui/icons/lucide-animated/plus.tsx +1 -1
- package/src/react-ui/icons/lucide-animated/search.tsx +1 -1
- package/src/react-ui/icons/lucide-animated/settings.tsx +1 -1
- package/src/react-ui/icons/lucide-animated/trending-down.tsx +2 -2
- package/src/react-ui/icons/lucide-animated/trending-up.tsx +2 -2
- package/src/react-ui/icons/lucide-animated/x.tsx +2 -2
- package/src/react-ui/lib/icon-wrapper.tsx +70 -0
- package/src/react-ui/lib/index.ts +1 -0
- package/src/react-ui/ui/CornerBracket/CornerBracket.styles.ts +1 -1
- package/src/react-ui/ui/Tabs/Tabs.css +39 -0
- package/src/react-ui/ui/Tabs/Tabs.styles.ts +119 -31
- package/src/react-ui/ui/Tabs/Tabs.types.ts +8 -3
- package/src/react-ui/ui/Tabs/index.tsx +135 -27
- package/dist/index.css +0 -129
|
@@ -0,0 +1,686 @@
|
|
|
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
|
+
}
|