Browse Source

fix: handle ANSI color indexes in theme resolution (#4842)

Dalton Alexandre 2 months ago
parent
commit
702fb2562c
1 changed files with 48 additions and 0 deletions
  1. 48 0
      packages/opencode/src/cli/cmd/tui/context/theme.tsx

+ 48 - 0
packages/opencode/src/cli/cmd/tui/context/theme.tsx

@@ -169,6 +169,9 @@ function resolveTheme(theme: ThemeJson, mode: "dark" | "light") {
         throw new Error(`Color reference "${c}" not found in defs or theme`)
       }
     }
+    if (typeof c === "number") {
+      return ansiToRgba(c)
+    }
     return resolveColor(c[mode])
   }
 
@@ -203,6 +206,51 @@ function resolveTheme(theme: ThemeJson, mode: "dark" | "light") {
   } as Theme
 }
 
+function ansiToRgba(code: number): RGBA {
+  // Standard ANSI colors (0-15)
+  if (code < 16) {
+    const ansiColors = [
+      "#000000", // Black
+      "#800000", // Red
+      "#008000", // Green
+      "#808000", // Yellow
+      "#000080", // Blue
+      "#800080", // Magenta
+      "#008080", // Cyan
+      "#c0c0c0", // White
+      "#808080", // Bright Black
+      "#ff0000", // Bright Red
+      "#00ff00", // Bright Green
+      "#ffff00", // Bright Yellow
+      "#0000ff", // Bright Blue
+      "#ff00ff", // Bright Magenta
+      "#00ffff", // Bright Cyan
+      "#ffffff", // Bright White
+    ]
+    return RGBA.fromHex(ansiColors[code] ?? "#000000")
+  }
+
+  // 6x6x6 Color Cube (16-231)
+  if (code < 232) {
+    const index = code - 16
+    const b = index % 6
+    const g = Math.floor(index / 6) % 6
+    const r = Math.floor(index / 36)
+
+    const val = (x: number) => (x === 0 ? 0 : x * 40 + 55)
+    return RGBA.fromInts(val(r), val(g), val(b))
+  }
+
+  // Grayscale Ramp (232-255)
+  if (code < 256) {
+    const gray = (code - 232) * 10 + 8
+    return RGBA.fromInts(gray, gray, gray)
+  }
+
+  // Fallback for invalid codes
+  return RGBA.fromInts(0, 0, 0)
+}
+
 export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
   name: "Theme",
   init: (props: { mode: "dark" | "light" }) => {