diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index fee65414e..7ed198382 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -29,6 +29,66 @@ import { Session as SessionApi } from "@/session" import { TuiEvent } from "./event" import { KVProvider, useKV } from "./context/kv" +async function getTerminalBackgroundColor(): Promise<"dark" | "light"> { + return new Promise((resolve) => { + let timeout: NodeJS.Timeout + + const cleanup = () => { + process.stdin.setRawMode(false) + process.stdin.removeListener("data", handler) + clearTimeout(timeout) + } + + const handler = (data: Buffer) => { + const str = data.toString() + const match = str.match(/\x1b]11;([^\x07]+)\x07/) + if (match) { + cleanup() + const color = match[1] + console.log(color) + + // Parse RGB values from color string + // Formats: rgb:RR/GG/BB or #RRGGBB or rgb(R,G,B) + let r = 0, + g = 0, + b = 0 + + if (color.startsWith("rgb:")) { + const parts = color.substring(4).split("/") + r = parseInt(parts[0], 16) >> 8 // Convert 16-bit to 8-bit + g = parseInt(parts[1], 16) >> 8 // Convert 16-bit to 8-bit + b = parseInt(parts[2], 16) >> 8 // Convert 16-bit to 8-bit + } else if (color.startsWith("#")) { + r = parseInt(color.substring(1, 3), 16) + g = parseInt(color.substring(3, 5), 16) + b = parseInt(color.substring(5, 7), 16) + } else if (color.startsWith("rgb(")) { + const parts = color.substring(4, color.length - 1).split(",") + r = parseInt(parts[0]) + g = parseInt(parts[1]) + b = parseInt(parts[2]) + } + console.log(r, g, b) + + // Calculate luminance using relative luminance formula + const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255 + + // Determine if dark or light based on luminance threshold + resolve(luminance > 0.5 ? "light" : "dark") + } + } + + process.stdin.setRawMode(true) + process.stdin.on("data", handler) + process.stdout.write("\x1b]11;?\x07") + + timeout = setTimeout(() => { + cleanup() + resolve("dark") + }, 1000) + }) +} + export function tui(input: { url: string sessionID?: string @@ -38,7 +98,10 @@ export function tui(input: { onExit?: () => Promise }) { // promise to prevent immediate exit - return new Promise((resolve) => { + return new Promise(async (resolve) => { + const backgroundTheme = await getTerminalBackgroundColor() + console.log("Terminal background theme:", backgroundTheme) + const routeData: Route | undefined = input.sessionID ? { type: "session", @@ -66,7 +129,11 @@ export function tui(input: { - + @@ -251,7 +318,7 @@ function App() { value: "app.exit", onSelect: exit, category: "System", - } + }, ]) createEffect(() => {