From 4cbee4da97dcc2832cd354142aa9909a80070952 Mon Sep 17 00:00:00 2001 From: Fuwn Date: Mon, 19 Jan 2026 23:05:26 -0800 Subject: feat: Add OpenCode-compatible theme loader Add support for loading and applying OpenCode-compatible themes via URL. Fetches theme JSON, resolves color references, generates CSS variables and Tailwind class overrides to apply the theme seamlessly. Features: - Add theme_url config field under site section - Fetch and parse OpenCode theme.json format - Generate CSS custom properties (--theme-*) for all theme colors - Generate Tailwind class overrides to apply theme colors - Support both light and dark modes - Template.CSS type for safe CSS injection Example usage: site: theme_url: "https://raw.githubusercontent.com/anomalyco/opencode/.../opencode.json" Theme schema: https://opencode.ai/theme.json --- config.example.yaml | 2 + internal/config/config.go | 1 + internal/server/server.go | 20 ++- internal/server/templates/index.html | 6 + internal/theme/theme.go | 287 +++++++++++++++++++++++++++++++++++ 5 files changed, 314 insertions(+), 2 deletions(-) create mode 100644 internal/theme/theme.go diff --git a/config.example.yaml b/config.example.yaml index d751ac5..bf3ff0f 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -12,6 +12,8 @@ site: description: "Service Status Page" # logo: "https://example.com/logo.svg" # Optional logo URL # favicon: "https://example.com/favicon.ico" # Optional favicon URL + # theme_url: "https://raw.githubusercontent.com/anomalyco/opencode/main/packages/opencode/src/cli/cmd/tui/context/theme/opencode.json" + # ^ Optional: URL to OpenCode-compatible theme JSON (see https://opencode.ai/theme.json for schema) # HTTP server settings server: diff --git a/internal/config/config.go b/internal/config/config.go index f3c35e3..68a88f7 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -40,6 +40,7 @@ type SiteConfig struct { Description string `yaml:"description"` Logo string `yaml:"logo"` Favicon string `yaml:"favicon"` + ThemeURL string `yaml:"theme_url"` // URL to OpenCode-compatible theme JSON } // ServerConfig contains HTTP server settings diff --git a/internal/server/server.go b/internal/server/server.go index 8681873..6d76fa0 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -17,6 +17,7 @@ import ( "github.com/Fuwn/kaze/internal/config" "github.com/Fuwn/kaze/internal/monitor" "github.com/Fuwn/kaze/internal/storage" + "github.com/Fuwn/kaze/internal/theme" ) //go:embed templates/*.html @@ -126,8 +127,9 @@ type PageData struct { TickMode string // ping, minute, hour, day TickCount int ShowThemeToggle bool - Timezone string // Timezone for display - UseBrowserTimezone bool // Use client-side timezone conversion + Timezone string // Timezone for display + UseBrowserTimezone bool // Use client-side timezone conversion + ThemeCSS template.CSS // OpenCode theme CSS (safe CSS) } // GroupData contains data for a monitor group @@ -190,6 +192,19 @@ func (s *Server) handleIndex(w http.ResponseWriter, r *http.Request) { return } + // Load OpenCode theme if configured + var themeCSS template.CSS + if s.config.Site.ThemeURL != "" { + resolvedTheme, err := theme.LoadTheme(s.config.Site.ThemeURL) + if err != nil { + s.logger.Warn("failed to load theme", "url", s.config.Site.ThemeURL, "error", err) + } else if resolvedTheme != nil { + // Generate CSS variables and Tailwind mappings + cssString := resolvedTheme.GenerateCSS() + resolvedTheme.GenerateTailwindMappings() + themeCSS = template.CSS(cssString) + } + } + // Build page data data := PageData{ Site: s.config.Site, @@ -198,6 +213,7 @@ func (s *Server) handleIndex(w http.ResponseWriter, r *http.Request) { ShowThemeToggle: s.config.Display.ShowThemeToggle != nil && *s.config.Display.ShowThemeToggle, Timezone: s.config.Display.Timezone, UseBrowserTimezone: s.config.Display.Timezone == "Browser", + ThemeCSS: themeCSS, } overallUp := true diff --git a/internal/server/templates/index.html b/internal/server/templates/index.html index db4c61a..6bdfeff 100644 --- a/internal/server/templates/index.html +++ b/internal/server/templates/index.html @@ -11,6 +11,12 @@ {{end}} + {{if .ThemeCSS}} + + {{end}}