@@ -46,6 +46,56 @@ const LOG_LEVEL_COLOR_CODE: Record<string, string> = {
4646 MARK : '\x1b[90m' , // 灰色
4747}
4848
49+ /**
50+ * 将 ANSI 256 色索引转换为 RGB 字符串
51+ * 兼容 xterm 256 色标准:
52+ * - 0-15: 基本/高亮颜色
53+ * - 16-231: 6x6x6 色彩立方体
54+ * - 232-255: 灰度
55+ */
56+ const ansi256ToRgb = ( idx : number ) : string | null => {
57+ if ( idx < 0 || idx > 255 || Number . isNaN ( idx ) ) return null
58+
59+ // 0-15 映射到基础前景色,尽量与 ANSI_COLOR_MAP 保持接近
60+ const basicPalette : string [ ] = [
61+ '#020617' , // 0: black
62+ '#ef4444' , // 1: red
63+ '#22c55e' , // 2: green
64+ '#eab308' , // 3: yellow
65+ '#3b82f6' , // 4: blue
66+ '#ec4899' , // 5: magenta
67+ '#06b6d4' , // 6: cyan
68+ '#e5e7eb' , // 7: white (light gray)
69+ '#6b7280' , // 8: bright black (gray)
70+ '#f97373' , // 9: bright red
71+ '#4ade80' , // 10: bright green
72+ '#fde047' , // 11: bright yellow
73+ '#60a5fa' , // 12: bright blue
74+ '#a855f7' , // 13: bright magenta
75+ '#38bdf8' , // 14: bright cyan
76+ '#f9fafb' , // 15: bright white
77+ ]
78+
79+ if ( idx <= 15 ) {
80+ return basicPalette [ idx ]
81+ }
82+
83+ // 16-231: 6x6x6 色彩立方体
84+ if ( idx >= 16 && idx <= 231 ) {
85+ const n = idx - 16
86+ const r = Math . floor ( n / 36 )
87+ const g = Math . floor ( ( n % 36 ) / 6 )
88+ const b = n % 6
89+
90+ const conv = ( c : number ) => ( c === 0 ? 0 : 55 + c * 40 )
91+ return `rgb(${ conv ( r ) } , ${ conv ( g ) } , ${ conv ( b ) } )`
92+ }
93+
94+ // 232-255: 灰度
95+ const gray = 8 + ( idx - 232 ) * 10
96+ return `rgb(${ gray } , ${ gray } , ${ gray } )`
97+ }
98+
4999/**
50100 * 将 ANSI 颜色码转换为带样式的 HTML 片段
51101 */
@@ -85,6 +135,17 @@ const ansiToHtml = (text: string): string => {
85135 return ''
86136 }
87137
138+ // 256 色: 38;5;n
139+ if ( codes [ 0 ] === 38 && codes [ 1 ] === 5 && codes . length >= 3 ) {
140+ const idx = codes [ 2 ]
141+ const rgb = ansi256ToRgb ( idx )
142+ if ( rgb ) {
143+ openSpan = `color: ${ rgb } `
144+ result += `<span style="${ openSpan } ">`
145+ }
146+ return ''
147+ }
148+
88149 // 重置 (0) 或 默认前景色 (39)
89150 // 仅当它们是唯一的代码时才视为重置,避免误伤 24bit 颜色中的 0 分量
90151 if ( codes . length === 1 && ( codes [ 0 ] === 0 || codes [ 0 ] === 39 ) ) {
0 commit comments