diff --git a/cmd/schema/main.go b/cmd/schema/main.go index 4a242404..31508d74 100644 --- a/cmd/schema/main.go +++ b/cmd/schema/main.go @@ -106,7 +106,16 @@ func generateSchema() map[string]any { "type": "string", "description": "TUI theme name", "default": "opencode", - "enum": []string{"opencode", "catppuccin", "dracula", "flexoki", "gruvbox", "monokai", "onedark"}, + "enum": []string{ + "opencode", + "catppuccin", + "dracula", + "flexoki", + "gruvbox", + "monokai", + "onedark", + "tokyonight", + }, }, }, } diff --git a/internal/tui/theme/tokyonight.go b/internal/tui/theme/tokyonight.go new file mode 100644 index 00000000..acd9dbf6 --- /dev/null +++ b/internal/tui/theme/tokyonight.go @@ -0,0 +1,274 @@ +package theme + +import ( + "github.com/charmbracelet/lipgloss" +) + +// TokyoNightTheme implements the Theme interface with Tokyo Night colors. +// It provides both dark and light variants. +type TokyoNightTheme struct { + BaseTheme +} + +// NewTokyoNightTheme creates a new instance of the Tokyo Night theme. +func NewTokyoNightTheme() *TokyoNightTheme { + // Tokyo Night color palette + // Dark mode colors + darkBackground := "#222436" + darkCurrentLine := "#1e2030" + darkSelection := "#2f334d" + darkForeground := "#c8d3f5" + darkComment := "#636da6" + darkRed := "#ff757f" + darkOrange := "#ff966c" + darkYellow := "#ffc777" + darkGreen := "#c3e88d" + darkCyan := "#86e1fc" + darkBlue := "#82aaff" + darkPurple := "#c099ff" + darkBorder := "#3b4261" + + // Light mode colors (Tokyo Night Day) + lightBackground := "#e1e2e7" + lightCurrentLine := "#d5d6db" + lightSelection := "#c8c9ce" + lightForeground := "#3760bf" + lightComment := "#848cb5" + lightRed := "#f52a65" + lightOrange := "#b15c00" + lightYellow := "#8c6c3e" + lightGreen := "#587539" + lightCyan := "#007197" + lightBlue := "#2e7de9" + lightPurple := "#9854f1" + lightBorder := "#a8aecb" + + theme := &TokyoNightTheme{} + + // Base colors + theme.PrimaryColor = lipgloss.AdaptiveColor{ + Dark: darkBlue, + Light: lightBlue, + } + theme.SecondaryColor = lipgloss.AdaptiveColor{ + Dark: darkPurple, + Light: lightPurple, + } + theme.AccentColor = lipgloss.AdaptiveColor{ + Dark: darkOrange, + Light: lightOrange, + } + + // Status colors + theme.ErrorColor = lipgloss.AdaptiveColor{ + Dark: darkRed, + Light: lightRed, + } + theme.WarningColor = lipgloss.AdaptiveColor{ + Dark: darkOrange, + Light: lightOrange, + } + theme.SuccessColor = lipgloss.AdaptiveColor{ + Dark: darkGreen, + Light: lightGreen, + } + theme.InfoColor = lipgloss.AdaptiveColor{ + Dark: darkBlue, + Light: lightBlue, + } + + // Text colors + theme.TextColor = lipgloss.AdaptiveColor{ + Dark: darkForeground, + Light: lightForeground, + } + theme.TextMutedColor = lipgloss.AdaptiveColor{ + Dark: darkComment, + Light: lightComment, + } + theme.TextEmphasizedColor = lipgloss.AdaptiveColor{ + Dark: darkYellow, + Light: lightYellow, + } + + // Background colors + theme.BackgroundColor = lipgloss.AdaptiveColor{ + Dark: darkBackground, + Light: lightBackground, + } + theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{ + Dark: darkCurrentLine, + Light: lightCurrentLine, + } + theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{ + Dark: "#191B29", // Darker background from palette + Light: "#f0f0f5", // Slightly lighter than background + } + + // Border colors + theme.BorderNormalColor = lipgloss.AdaptiveColor{ + Dark: darkBorder, + Light: lightBorder, + } + theme.BorderFocusedColor = lipgloss.AdaptiveColor{ + Dark: darkBlue, + Light: lightBlue, + } + theme.BorderDimColor = lipgloss.AdaptiveColor{ + Dark: darkSelection, + Light: lightSelection, + } + + // Diff view colors + theme.DiffAddedColor = lipgloss.AdaptiveColor{ + Dark: "#4fd6be", // teal from palette + Light: "#1e725c", + } + theme.DiffRemovedColor = lipgloss.AdaptiveColor{ + Dark: "#c53b53", // red1 from palette + Light: "#c53b53", + } + theme.DiffContextColor = lipgloss.AdaptiveColor{ + Dark: "#828bb8", // fg_dark from palette + Light: "#7086b5", + } + theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{ + Dark: "#828bb8", // fg_dark from palette + Light: "#7086b5", + } + theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{ + Dark: "#b8db87", // git.add from palette + Light: "#4db380", + } + theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{ + Dark: "#e26a75", // git.delete from palette + Light: "#f52a65", + } + theme.DiffAddedBgColor = lipgloss.AdaptiveColor{ + Dark: "#20303b", + Light: "#d5e5d5", + } + theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{ + Dark: "#37222c", + Light: "#f7d8db", + } + theme.DiffContextBgColor = lipgloss.AdaptiveColor{ + Dark: darkBackground, + Light: lightBackground, + } + theme.DiffLineNumberColor = lipgloss.AdaptiveColor{ + Dark: "#545c7e", // dark3 from palette + Light: "#848cb5", + } + theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{ + Dark: "#1b2b34", + Light: "#c5d5c5", + } + theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{ + Dark: "#2d1f26", + Light: "#e7c8cb", + } + + // Markdown colors + theme.MarkdownTextColor = lipgloss.AdaptiveColor{ + Dark: darkForeground, + Light: lightForeground, + } + theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{ + Dark: darkPurple, + Light: lightPurple, + } + theme.MarkdownLinkColor = lipgloss.AdaptiveColor{ + Dark: darkBlue, + Light: lightBlue, + } + theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{ + Dark: darkCyan, + Light: lightCyan, + } + theme.MarkdownCodeColor = lipgloss.AdaptiveColor{ + Dark: darkGreen, + Light: lightGreen, + } + theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{ + Dark: darkYellow, + Light: lightYellow, + } + theme.MarkdownEmphColor = lipgloss.AdaptiveColor{ + Dark: darkYellow, + Light: lightYellow, + } + theme.MarkdownStrongColor = lipgloss.AdaptiveColor{ + Dark: darkOrange, + Light: lightOrange, + } + theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{ + Dark: darkComment, + Light: lightComment, + } + theme.MarkdownListItemColor = lipgloss.AdaptiveColor{ + Dark: darkBlue, + Light: lightBlue, + } + theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{ + Dark: darkCyan, + Light: lightCyan, + } + theme.MarkdownImageColor = lipgloss.AdaptiveColor{ + Dark: darkBlue, + Light: lightBlue, + } + theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{ + Dark: darkCyan, + Light: lightCyan, + } + theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{ + Dark: darkForeground, + Light: lightForeground, + } + + // Syntax highlighting colors + theme.SyntaxCommentColor = lipgloss.AdaptiveColor{ + Dark: darkComment, + Light: lightComment, + } + theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{ + Dark: darkPurple, + Light: lightPurple, + } + theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{ + Dark: darkBlue, + Light: lightBlue, + } + theme.SyntaxVariableColor = lipgloss.AdaptiveColor{ + Dark: darkRed, + Light: lightRed, + } + theme.SyntaxStringColor = lipgloss.AdaptiveColor{ + Dark: darkGreen, + Light: lightGreen, + } + theme.SyntaxNumberColor = lipgloss.AdaptiveColor{ + Dark: darkOrange, + Light: lightOrange, + } + theme.SyntaxTypeColor = lipgloss.AdaptiveColor{ + Dark: darkYellow, + Light: lightYellow, + } + theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{ + Dark: darkCyan, + Light: lightCyan, + } + theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{ + Dark: darkForeground, + Light: lightForeground, + } + + return theme +} + +func init() { + // Register the Tokyo Night theme with the theme manager + RegisterTheme("tokyonight", NewTokyoNightTheme()) +} \ No newline at end of file diff --git a/opencode-schema.json b/opencode-schema.json index 9cdd1511..381715f8 100644 --- a/opencode-schema.json +++ b/opencode-schema.json @@ -12,63 +12,63 @@ "model": { "description": "Model ID for the agent", "enum": [ - "openrouter.gpt-4.5-preview", - "gemini-2.5", - "qwen-qwq", - "openrouter.gpt-4.1-mini", - "openrouter.o1-mini", - "gpt-4.1", - "deepseek-r1-distill-llama-70b", + "claude-3.7-sonnet", + "gpt-4o", "meta-llama/llama-4-scout-17b-16e-instruct", - "bedrock.claude-3.7-sonnet", - "gpt-4o-mini", - "o1-pro", - "claude-3-haiku", - "gemini-2.5-flash", - "azure.o3", + "azure.o4-mini", + "openrouter.gpt-4o", + "claude-3-opus", + "azure.o3-mini", + "azure.gpt-4.1-mini", + "azure.o1", "openrouter.gpt-4.1", "openrouter.o1-pro", - "openrouter.o4-mini", - "o1-mini", - "o3", - "gpt-4.1-nano", - "azure.gpt-4o", "openrouter.claude-3.5-sonnet", - "o4-mini", - "openrouter.gpt-4o", - "gemini-2.0-flash", - "azure.gpt-4o-mini", - "o3-mini", - "azure.gpt-4.1", - "gpt-4.1-mini", - "azure.o1-mini", - "openrouter.gemini-2.5-flash", - "gemini-2.0-flash-lite", - "azure.gpt-4.5-preview", - "azure.o3-mini", - "openrouter.claude-3.7-sonnet", - "o1", + "o1-mini", + "bedrock.claude-3.7-sonnet", "claude-3.5-sonnet", - "claude-3.5-haiku", - "llama-3.3-70b-versatile", - "azure.gpt-4.1-mini", - "openrouter.gemini-2.5", - "openrouter.o3-mini", - "openrouter.claude-3-opus", - "openrouter.gpt-4.1-nano", - "openrouter.gpt-4o-mini", - "claude-3.7-sonnet", - "claude-3-opus", - "openrouter.o1", - "gpt-4.5-preview", - "azure.gpt-4.1-nano", - "azure.o1", "openrouter.o3", "openrouter.claude-3-haiku", - "gpt-4o", + "gpt-4.1", + "openrouter.o1-mini", + "openrouter.claude-3-opus", + "o4-mini", + "gemini-2.5-flash", + "llama-3.3-70b-versatile", + "azure.gpt-4.1", + "azure.o1-mini", + "openrouter.gpt-4o-mini", + "claude-3.5-haiku", + "o1", + "deepseek-r1-distill-llama-70b", "meta-llama/llama-4-maverick-17b-128e-instruct", - "azure.o4-mini", - "openrouter.claude-3.5-haiku" + "openrouter.claude-3.5-haiku", + "openrouter.gpt-4.5-preview", + "openrouter.o1", + "gemini-2.0-flash", + "openrouter.o3-mini", + "claude-3-haiku", + "o1-pro", + "o3", + "gemini-2.5", + "openrouter.claude-3.7-sonnet", + "gpt-4.1-mini", + "openrouter.gpt-4.1-mini", + "openrouter.gpt-4.1-nano", + "openrouter.o4-mini", + "azure.gpt-4o-mini", + "gpt-4.5-preview", + "gpt-4o-mini", + "azure.gpt-4.5-preview", + "azure.gpt-4o", + "gpt-4.1-nano", + "qwen-qwq", + "azure.gpt-4.1-nano", + "azure.o3", + "openrouter.gemini-2.5-flash", + "openrouter.gemini-2.5", + "o3-mini", + "gemini-2.0-flash-lite" ], "type": "string" }, @@ -102,63 +102,63 @@ "model": { "description": "Model ID for the agent", "enum": [ - "openrouter.gpt-4.5-preview", - "gemini-2.5", - "qwen-qwq", - "openrouter.gpt-4.1-mini", - "openrouter.o1-mini", - "gpt-4.1", - "deepseek-r1-distill-llama-70b", + "claude-3.7-sonnet", + "gpt-4o", "meta-llama/llama-4-scout-17b-16e-instruct", - "bedrock.claude-3.7-sonnet", - "gpt-4o-mini", - "o1-pro", - "claude-3-haiku", - "gemini-2.5-flash", - "azure.o3", + "azure.o4-mini", + "openrouter.gpt-4o", + "claude-3-opus", + "azure.o3-mini", + "azure.gpt-4.1-mini", + "azure.o1", "openrouter.gpt-4.1", "openrouter.o1-pro", - "openrouter.o4-mini", - "o1-mini", - "o3", - "gpt-4.1-nano", - "azure.gpt-4o", "openrouter.claude-3.5-sonnet", - "o4-mini", - "openrouter.gpt-4o", - "gemini-2.0-flash", - "azure.gpt-4o-mini", - "o3-mini", - "azure.gpt-4.1", - "gpt-4.1-mini", - "azure.o1-mini", - "openrouter.gemini-2.5-flash", - "gemini-2.0-flash-lite", - "azure.gpt-4.5-preview", - "azure.o3-mini", - "openrouter.claude-3.7-sonnet", - "o1", + "o1-mini", + "bedrock.claude-3.7-sonnet", "claude-3.5-sonnet", - "claude-3.5-haiku", - "llama-3.3-70b-versatile", - "azure.gpt-4.1-mini", - "openrouter.gemini-2.5", - "openrouter.o3-mini", - "openrouter.claude-3-opus", - "openrouter.gpt-4.1-nano", - "openrouter.gpt-4o-mini", - "claude-3.7-sonnet", - "claude-3-opus", - "openrouter.o1", - "gpt-4.5-preview", - "azure.gpt-4.1-nano", - "azure.o1", "openrouter.o3", "openrouter.claude-3-haiku", - "gpt-4o", + "gpt-4.1", + "openrouter.o1-mini", + "openrouter.claude-3-opus", + "o4-mini", + "gemini-2.5-flash", + "llama-3.3-70b-versatile", + "azure.gpt-4.1", + "azure.o1-mini", + "openrouter.gpt-4o-mini", + "claude-3.5-haiku", + "o1", + "deepseek-r1-distill-llama-70b", "meta-llama/llama-4-maverick-17b-128e-instruct", - "azure.o4-mini", - "openrouter.claude-3.5-haiku" + "openrouter.claude-3.5-haiku", + "openrouter.gpt-4.5-preview", + "openrouter.o1", + "gemini-2.0-flash", + "openrouter.o3-mini", + "claude-3-haiku", + "o1-pro", + "o3", + "gemini-2.5", + "openrouter.claude-3.7-sonnet", + "gpt-4.1-mini", + "openrouter.gpt-4.1-mini", + "openrouter.gpt-4.1-nano", + "openrouter.o4-mini", + "azure.gpt-4o-mini", + "gpt-4.5-preview", + "gpt-4o-mini", + "azure.gpt-4.5-preview", + "azure.gpt-4o", + "gpt-4.1-nano", + "qwen-qwq", + "azure.gpt-4.1-nano", + "azure.o3", + "openrouter.gemini-2.5-flash", + "openrouter.gemini-2.5", + "o3-mini", + "gemini-2.0-flash-lite" ], "type": "string" }, @@ -364,7 +364,8 @@ "flexoki", "gruvbox", "monokai", - "onedark" + "onedark", + "tokyonight" ], "type": "string" }