1import {
2 getMobileThemeColors,
3 getMobileThemeVariables,
4 themeColorToNativeColor,
5 type MobileThemeId,
6} from "../../lib/mobileTheme";
7
8export type TerminalAppearanceScheme = "light" | "dark";
9
10export interface TerminalTheme {
11 readonly background: string;
12 readonly foreground: string;
13 readonly mutedForeground: string;
14 readonly border: string;
15 readonly cursorForeground: string;
16 readonly cursorBackground: string;
17 /** The 16 ANSI colors, in order. A fixed tuple so indexed reads are never undefined. */
18 readonly palette: TerminalPalette;
19}
20
21type TerminalPalette = readonly [
22 string,
23 string,
24 string,
25 string,
26 string,
27 string,
28 string,
29 string,
30 string,
31 string,
32 string,
33 string,
34 string,
35 string,
36 string,
37 string,
38];
39
40const PIERRE_LIGHT_THEME: TerminalTheme = {
41 // Pierre terminal palette with the app's shared screen background.
42 background: "#fcfcfc",
43 foreground: "#6C6C71",
44 mutedForeground: "#8E8E95",
45 border: "#eeeeef",
46 cursorForeground: "#009fff",
47 cursorBackground: "#fcfcfc",
48 palette: [
49 "#1F1F21",
50 "#ff2e3f",
51 "#0dbe4e",
52 "#ffca00",
53 "#009fff",
54 "#c635e4",
55 "#08c0ef",
56 "#c6c6c8",
57 "#1F1F21",
58 "#ff2e3f",
59 "#0dbe4e",
60 "#ffca00",
61 "#009fff",
62 "#c635e4",
63 "#08c0ef",
64 "#c6c6c8",
65 ],
66};
67
68const PIERRE_DARK_THEME: TerminalTheme = {
69 // Pierre terminal palette with the app's shared screen background.
70 background: "#0a0a0a",
71 foreground: "#adadb1",
72 mutedForeground: "#8E8E95",
73 border: "#2e2e30",
74 cursorForeground: "#009fff",
75 cursorBackground: "#0a0a0a",
76 palette: [
77 "#141415",
78 "#ff2e3f",
79 "#0dbe4e",
80 "#ffca00",
81 "#009fff",
82 "#c635e4",
83 "#08c0ef",
84 "#c6c6c8",
85 "#141415",
86 "#ff2e3f",
87 "#0dbe4e",
88 "#ffca00",
89 "#009fff",
90 "#c635e4",
91 "#08c0ef",
92 "#c6c6c8",
93 ],
94};
95
96function getPierreTerminalTheme(scheme: TerminalAppearanceScheme): TerminalTheme {
97 return scheme === "light" ? PIERRE_LIGHT_THEME : PIERRE_DARK_THEME;
98}
99
100export function getMobileTerminalTheme(
101 themeId: MobileThemeId,
102 scheme: TerminalAppearanceScheme,
103): TerminalTheme {
104 const base = getPierreTerminalTheme(scheme);
105 const paletteId = themeId === "material-you" ? "t3-code" : themeId;
106 const palette = getMobileThemeColors(paletteId, scheme);
107 const colors = getMobileThemeVariables(paletteId, scheme);
108 const background = themeColorToNativeColor(palette.terminalBackground);
109 return {
110 ...base,
111 background,
112 foreground: themeColorToNativeColor(palette.terminalForeground),
113 mutedForeground: colors["--color-foreground-muted"],
114 border: colors["--color-border"],
115 cursorForeground: themeColorToNativeColor(palette.terminalCursor),
116 cursorBackground: background,
117 };
118}
119
120export function buildGhosttyThemeConfig(theme: TerminalTheme): string {
121 const lines = [
122 `background = ${theme.background}`,
123 `foreground = ${theme.foreground}`,
124 `cursor-color = ${theme.cursorForeground}`,
125 `cursor-text = ${theme.cursorBackground}`,
126 ];
127
128 for (const [index, color] of theme.palette.entries()) {
129 lines.push(`palette = ${index}=${color}`);
130 }
131
132 return `${lines.join("\n")}\n`;
133}