|
|
|
@@ -1,5 +1,6 @@
|
|
|
|
|
import * as fs from "node:fs";
|
|
|
|
|
import * as path from "node:path";
|
|
|
|
|
import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
|
|
|
|
|
import {
|
|
|
|
|
type EditorTheme,
|
|
|
|
|
getCapabilities,
|
|
|
|
@@ -88,6 +89,7 @@ const ThemeJsonSchema = Type.Object({
|
|
|
|
|
thinkingMedium: ColorValueSchema,
|
|
|
|
|
thinkingHigh: ColorValueSchema,
|
|
|
|
|
thinkingXhigh: ColorValueSchema,
|
|
|
|
|
thinkingMax: Type.Optional(ColorValueSchema),
|
|
|
|
|
// Bash Mode (1 color)
|
|
|
|
|
bashMode: ColorValueSchema,
|
|
|
|
|
}),
|
|
|
|
@@ -149,6 +151,7 @@ export type ThemeColor =
|
|
|
|
|
| "thinkingMedium"
|
|
|
|
|
| "thinkingHigh"
|
|
|
|
|
| "thinkingXhigh"
|
|
|
|
|
| "thinkingMax"
|
|
|
|
|
| "bashMode";
|
|
|
|
|
|
|
|
|
|
export type ThemeBg =
|
|
|
|
@@ -316,6 +319,10 @@ function resolveThemeColors<T extends Record<string, ColorValue>>(
|
|
|
|
|
return resolved as Record<keyof T, string | number>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function withThemeColorFallbacks(colors: ThemeJson["colors"]): ThemeJson["colors"] & { thinkingMax: ColorValue } {
|
|
|
|
|
return { ...colors, thinkingMax: colors.thinkingMax ?? colors.thinkingXhigh };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// Theme Class
|
|
|
|
|
// ============================================================================
|
|
|
|
@@ -339,7 +346,8 @@ export class Theme {
|
|
|
|
|
this.sourceInfo = options.sourceInfo;
|
|
|
|
|
this.mode = mode;
|
|
|
|
|
this.fgColors = new Map();
|
|
|
|
|
for (const [key, value] of Object.entries(fgColors) as [ThemeColor, string | number][]) {
|
|
|
|
|
const colors = { ...fgColors, thinkingMax: fgColors.thinkingMax ?? fgColors.thinkingXhigh };
|
|
|
|
|
for (const [key, value] of Object.entries(colors) as [ThemeColor, string | number][]) {
|
|
|
|
|
this.fgColors.set(key, fgAnsi(value, mode));
|
|
|
|
|
}
|
|
|
|
|
this.bgColors = new Map();
|
|
|
|
@@ -396,7 +404,7 @@ export class Theme {
|
|
|
|
|
return this.mode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getThinkingBorderColor(level: "off" | "minimal" | "low" | "medium" | "high" | "xhigh"): (str: string) => string {
|
|
|
|
|
getThinkingBorderColor(level: ThinkingLevel): (str: string) => string {
|
|
|
|
|
// Map thinking levels to dedicated theme colors
|
|
|
|
|
switch (level) {
|
|
|
|
|
case "off":
|
|
|
|
@@ -411,6 +419,8 @@ export class Theme {
|
|
|
|
|
return (str: string) => this.fg("thinkingHigh", str);
|
|
|
|
|
case "xhigh":
|
|
|
|
|
return (str: string) => this.fg("thinkingXhigh", str);
|
|
|
|
|
case "max":
|
|
|
|
|
return (str: string) => this.fg("thinkingMax", str);
|
|
|
|
|
default:
|
|
|
|
|
return (str: string) => this.fg("thinkingOff", str);
|
|
|
|
|
}
|
|
|
|
@@ -586,7 +596,7 @@ function loadThemeJson(name: string): ThemeJson {
|
|
|
|
|
|
|
|
|
|
function createTheme(themeJson: ThemeJson, mode?: ColorMode, sourcePath?: string): Theme {
|
|
|
|
|
const colorMode = mode ?? (getCapabilities().trueColor ? "truecolor" : "256color");
|
|
|
|
|
const resolvedColors = resolveThemeColors(themeJson.colors, themeJson.vars);
|
|
|
|
|
const resolvedColors = resolveThemeColors(withThemeColorFallbacks(themeJson.colors), themeJson.vars);
|
|
|
|
|
const fgColors: Record<ThemeColor, string | number> = {} as Record<ThemeColor, string | number>;
|
|
|
|
|
const bgColors: Record<ThemeBg, string | number> = {} as Record<ThemeBg, string | number>;
|
|
|
|
|
const bgColorKeys: Set<string> = new Set([
|
|
|
|
@@ -1013,7 +1023,7 @@ export function getResolvedThemeColors(themeName?: string): Record<string, strin
|
|
|
|
|
const name = themeName ?? currentThemeName ?? getDefaultTheme();
|
|
|
|
|
const isLight = name === "light";
|
|
|
|
|
const themeJson = loadThemeJson(name);
|
|
|
|
|
const resolved = resolveThemeColors(themeJson.colors, themeJson.vars);
|
|
|
|
|
const resolved = resolveThemeColors(withThemeColorFallbacks(themeJson.colors), themeJson.vars);
|
|
|
|
|
|
|
|
|
|
// Default text color for empty values (terminal uses default fg color)
|
|
|
|
|
const defaultText = isLight ? "#000000" : "#e5e5e7";
|
|
|
|
|