Add theme-configurable HTML export colors (from PR #387)

- Add optional 'export' section to theme JSON with pageBg, cardBg, infoBg
- If not specified, colors are auto-derived from userMessageBg
- Add export colors to dark.json and light.json
- Update theme-schema.json and TypeBox schema
- Add documentation to docs/theme.md
- Add margin-top back to tool-output for spacing between header and content
This commit is contained in:
Mario Zechner 2026-01-01 22:21:40 +01:00
parent d612bc45f5
commit 6267720660
7 changed files with 104 additions and 6 deletions

View file

@ -76,5 +76,10 @@
"thinkingXhigh": "#d183e8",
"bashMode": "green"
},
"export": {
"pageBg": "#18181e",
"cardBg": "#1e1e24",
"infoBg": "#3c3728"
}
}

View file

@ -75,5 +75,10 @@
"thinkingXhigh": "#8b008b",
"bashMode": "green"
},
"export": {
"pageBg": "#f8f8f8",
"cardBg": "#ffffff",
"infoBg": "#fffae6"
}
}

View file

@ -267,6 +267,25 @@
}
},
"additionalProperties": false
},
"export": {
"type": "object",
"description": "Optional colors for HTML export (defaults derived from userMessageBg if not specified)",
"properties": {
"pageBg": {
"$ref": "#/$defs/colorValue",
"description": "Page background color"
},
"cardBg": {
"$ref": "#/$defs/colorValue",
"description": "Card/container background color"
},
"infoBg": {
"$ref": "#/$defs/colorValue",
"description": "Info sections background (system prompt, notices)"
}
},
"additionalProperties": false
}
},
"additionalProperties": false,

View file

@ -82,6 +82,13 @@ const ThemeJsonSchema = Type.Object({
// Bash Mode (1 color)
bashMode: ColorValueSchema,
}),
export: Type.Optional(
Type.Object({
pageBg: Type.Optional(ColorValueSchema),
cardBg: Type.Optional(ColorValueSchema),
infoBg: Type.Optional(ColorValueSchema),
}),
),
});
type ThemeJson = Static<typeof ThemeJsonSchema>;
@ -737,6 +744,44 @@ export function isLightTheme(themeName?: string): boolean {
return themeName === "light";
}
/**
* Get explicit export colors from theme JSON, if specified.
* Returns undefined for each color that isn't explicitly set.
*/
export function getThemeExportColors(themeName?: string): {
pageBg?: string;
cardBg?: string;
infoBg?: string;
} {
const name = themeName ?? getDefaultTheme();
try {
const themeJson = loadThemeJson(name);
const exportSection = themeJson.export;
if (!exportSection) return {};
const vars = themeJson.vars ?? {};
const resolve = (value: string | number | undefined): string | undefined => {
if (value === undefined) return undefined;
if (typeof value === "number") return ansi256ToHex(value);
if (value.startsWith("$")) {
const resolved = vars[value];
if (resolved === undefined) return undefined;
if (typeof resolved === "number") return ansi256ToHex(resolved);
return resolved;
}
return value;
};
return {
pageBg: resolve(exportSection.pageBg),
cardBg: resolve(exportSection.cardBg),
infoBg: resolve(exportSection.infoBg),
};
} catch {
return {};
}
}
// ============================================================================
// TUI Helpers
// ============================================================================