mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-21 17:54:23 +01:00
feat: custom themes
This commit is contained in:
73
README.md
73
README.md
@@ -67,7 +67,7 @@ OpenCode looks for configuration in the following locations:
|
|||||||
You can configure OpenCode using environment variables:
|
You can configure OpenCode using environment variables:
|
||||||
|
|
||||||
| Environment Variable | Purpose |
|
| Environment Variable | Purpose |
|
||||||
|----------------------------|--------------------------------------------------------|
|
| -------------------------- | ------------------------------------------------------ |
|
||||||
| `ANTHROPIC_API_KEY` | For Claude models |
|
| `ANTHROPIC_API_KEY` | For Claude models |
|
||||||
| `OPENAI_API_KEY` | For OpenAI models |
|
| `OPENAI_API_KEY` | For OpenAI models |
|
||||||
| `GEMINI_API_KEY` | For Google Gemini models |
|
| `GEMINI_API_KEY` | For Google Gemini models |
|
||||||
@@ -79,7 +79,6 @@ You can configure OpenCode using environment variables:
|
|||||||
| `AZURE_OPENAI_API_KEY` | For Azure OpenAI models (optional when using Entra ID) |
|
| `AZURE_OPENAI_API_KEY` | For Azure OpenAI models (optional when using Entra ID) |
|
||||||
| `AZURE_OPENAI_API_VERSION` | For Azure OpenAI models |
|
| `AZURE_OPENAI_API_VERSION` | For Azure OpenAI models |
|
||||||
|
|
||||||
|
|
||||||
### Configuration File Structure
|
### Configuration File Structure
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@@ -303,6 +302,76 @@ OpenCode's AI assistant has access to various tools to help with coding tasks:
|
|||||||
| `sourcegraph` | Search code across public repositories | `query` (required), `count` (optional), `context_window` (optional), `timeout` (optional) |
|
| `sourcegraph` | Search code across public repositories | `query` (required), `count` (optional), `context_window` (optional), `timeout` (optional) |
|
||||||
| `agent` | Run sub-tasks with the AI agent | `prompt` (required) |
|
| `agent` | Run sub-tasks with the AI agent | `prompt` (required) |
|
||||||
|
|
||||||
|
## Theming
|
||||||
|
|
||||||
|
OpenCode supports multiple themes for customizing the appearance of the terminal interface.
|
||||||
|
|
||||||
|
### Available Themes
|
||||||
|
|
||||||
|
The following predefined themes are available:
|
||||||
|
|
||||||
|
- `opencode` (default)
|
||||||
|
- `catppuccin`
|
||||||
|
- `dracula`
|
||||||
|
- `flexoki`
|
||||||
|
- `gruvbox`
|
||||||
|
- `monokai`
|
||||||
|
- `onedark`
|
||||||
|
- `tokyonight`
|
||||||
|
- `tron`
|
||||||
|
- `custom` (user-defined)
|
||||||
|
|
||||||
|
### Setting a Theme
|
||||||
|
|
||||||
|
You can set a theme in your `.opencode.json` configuration file:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"tui": {
|
||||||
|
"theme": "monokai"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom Themes
|
||||||
|
|
||||||
|
You can define your own custom theme by setting the `theme` to `"custom"` and providing color definitions in the `customTheme` map:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"tui": {
|
||||||
|
"theme": "custom",
|
||||||
|
"customTheme": {
|
||||||
|
"primary": "#ffcc00",
|
||||||
|
"secondary": "#00ccff",
|
||||||
|
"accent": { "dark": "#aa00ff", "light": "#ddccff" },
|
||||||
|
"error": "#ff0000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Color Definition Formats
|
||||||
|
|
||||||
|
Custom theme colors support two formats:
|
||||||
|
|
||||||
|
1. **Simple Hex String**: A single hex color string (e.g., `"#aabbcc"`) that will be used for both light and dark terminal backgrounds.
|
||||||
|
|
||||||
|
2. **Adaptive Object**: An object with `dark` and `light` keys, each holding a hex color string. This allows for adaptive colors based on the terminal's background.
|
||||||
|
|
||||||
|
#### Available Color Keys
|
||||||
|
|
||||||
|
You can define any of the following color keys in your `customTheme`:
|
||||||
|
|
||||||
|
- Base colors: `primary`, `secondary`, `accent`
|
||||||
|
- Status colors: `error`, `warning`, `success`, `info`
|
||||||
|
- Text colors: `text`, `textMuted`, `textEmphasized`
|
||||||
|
- Background colors: `background`, `backgroundSecondary`, `backgroundDarker`
|
||||||
|
- Border colors: `borderNormal`, `borderFocused`, `borderDim`
|
||||||
|
- Diff view colors: `diffAdded`, `diffRemoved`, `diffContext`, etc.
|
||||||
|
|
||||||
|
You don't need to define all colors. Any undefined colors will fall back to the default "opencode" theme colors.
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
OpenCode is built with a modular architecture:
|
OpenCode is built with a modular architecture:
|
||||||
|
|||||||
@@ -116,6 +116,34 @@ func generateSchema() map[string]any {
|
|||||||
"onedark",
|
"onedark",
|
||||||
"tokyonight",
|
"tokyonight",
|
||||||
"tron",
|
"tron",
|
||||||
|
"custom",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"customTheme": map[string]any{
|
||||||
|
"type": "object",
|
||||||
|
"description": "Custom theme color definitions",
|
||||||
|
"additionalProperties": map[string]any{
|
||||||
|
"oneOf": []map[string]any{
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^#[0-9a-fA-F]{6}$",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": map[string]any{
|
||||||
|
"dark": map[string]any{
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^#[0-9a-fA-F]{6}$",
|
||||||
|
},
|
||||||
|
"light": map[string]any{
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^#[0-9a-fA-F]{6}$",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": []string{"dark", "light"},
|
||||||
|
"additionalProperties": false,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ type LSPConfig struct {
|
|||||||
// TUIConfig defines the configuration for the Terminal User Interface.
|
// TUIConfig defines the configuration for the Terminal User Interface.
|
||||||
type TUIConfig struct {
|
type TUIConfig struct {
|
||||||
Theme string `json:"theme,omitempty"`
|
Theme string `json:"theme,omitempty"`
|
||||||
|
CustomTheme map[string]any `json:"customTheme,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config is the main configuration structure for the application.
|
// Config is the main configuration structure for the application.
|
||||||
@@ -747,16 +748,16 @@ func UpdateTheme(themeName string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse the JSON
|
// Parse the JSON
|
||||||
var configMap map[string]interface{}
|
var configMap map[string]any
|
||||||
if err := json.Unmarshal(configData, &configMap); err != nil {
|
if err := json.Unmarshal(configData, &configMap); err != nil {
|
||||||
return fmt.Errorf("failed to parse config file: %w", err)
|
return fmt.Errorf("failed to parse config file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update just the theme value
|
// Update just the theme value
|
||||||
tuiConfig, ok := configMap["tui"].(map[string]interface{})
|
tuiConfig, ok := configMap["tui"].(map[string]any)
|
||||||
if !ok {
|
if !ok {
|
||||||
// TUI config doesn't exist yet, create it
|
// TUI config doesn't exist yet, create it
|
||||||
configMap["tui"] = map[string]interface{}{"theme": themeName}
|
configMap["tui"] = map[string]any{"theme": themeName}
|
||||||
} else {
|
} else {
|
||||||
// Update existing TUI config
|
// Update existing TUI config
|
||||||
tuiConfig["theme"] = themeName
|
tuiConfig["theme"] = themeName
|
||||||
|
|||||||
@@ -11,4 +11,3 @@ const (
|
|||||||
SpinnerIcon string = "..."
|
SpinnerIcon string = "..."
|
||||||
LoadingIcon string = "⟳"
|
LoadingIcon string = "⟳"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ var globalManager = &Manager{
|
|||||||
currentName: "",
|
currentName: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default theme instance for custom theme defaulting
|
||||||
|
var defaultThemeColors = NewOpenCodeTheme()
|
||||||
|
|
||||||
// RegisterTheme adds a new theme to the registry.
|
// RegisterTheme adds a new theme to the registry.
|
||||||
// If this is the first theme registered, it becomes the default.
|
// If this is the first theme registered, it becomes the default.
|
||||||
func RegisterTheme(name string, theme Theme) {
|
func RegisterTheme(name string, theme Theme) {
|
||||||
@@ -46,7 +49,22 @@ func SetTheme(name string) error {
|
|||||||
defer globalManager.mu.Unlock()
|
defer globalManager.mu.Unlock()
|
||||||
|
|
||||||
delete(styles.Registry, "charm")
|
delete(styles.Registry, "charm")
|
||||||
if _, exists := globalManager.themes[name]; !exists {
|
|
||||||
|
// Handle custom theme
|
||||||
|
if name == "custom" {
|
||||||
|
cfg := config.Get()
|
||||||
|
if cfg == nil || cfg.TUI.CustomTheme == nil || len(cfg.TUI.CustomTheme) == 0 {
|
||||||
|
return fmt.Errorf("custom theme selected but no custom theme colors defined in config")
|
||||||
|
}
|
||||||
|
|
||||||
|
customTheme, err := LoadCustomTheme(cfg.TUI.CustomTheme)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to load custom theme: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register the custom theme
|
||||||
|
globalManager.themes["custom"] = customTheme
|
||||||
|
} else if _, exists := globalManager.themes[name]; !exists {
|
||||||
return fmt.Errorf("theme '%s' not found", name)
|
return fmt.Errorf("theme '%s' not found", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,6 +129,87 @@ func GetTheme(name string) Theme {
|
|||||||
return globalManager.themes[name]
|
return globalManager.themes[name]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadCustomTheme creates a new theme instance based on the custom theme colors
|
||||||
|
// defined in the configuration. It uses the default OpenCode theme as a base
|
||||||
|
// and overrides colors that are specified in the customTheme map.
|
||||||
|
func LoadCustomTheme(customTheme map[string]any) (Theme, error) {
|
||||||
|
// Create a new theme based on the default OpenCode theme
|
||||||
|
theme := NewOpenCodeTheme()
|
||||||
|
|
||||||
|
// Process each color in the custom theme map
|
||||||
|
for key, value := range customTheme {
|
||||||
|
adaptiveColor, err := ParseAdaptiveColor(value)
|
||||||
|
if err != nil {
|
||||||
|
logging.Warn("Invalid color definition in custom theme", "key", key, "error", err)
|
||||||
|
continue // Skip this color but continue processing others
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the color in the theme based on the key
|
||||||
|
switch strings.ToLower(key) {
|
||||||
|
case "primary":
|
||||||
|
theme.PrimaryColor = adaptiveColor
|
||||||
|
case "secondary":
|
||||||
|
theme.SecondaryColor = adaptiveColor
|
||||||
|
case "accent":
|
||||||
|
theme.AccentColor = adaptiveColor
|
||||||
|
case "error":
|
||||||
|
theme.ErrorColor = adaptiveColor
|
||||||
|
case "warning":
|
||||||
|
theme.WarningColor = adaptiveColor
|
||||||
|
case "success":
|
||||||
|
theme.SuccessColor = adaptiveColor
|
||||||
|
case "info":
|
||||||
|
theme.InfoColor = adaptiveColor
|
||||||
|
case "text":
|
||||||
|
theme.TextColor = adaptiveColor
|
||||||
|
case "textmuted":
|
||||||
|
theme.TextMutedColor = adaptiveColor
|
||||||
|
case "textemphasized":
|
||||||
|
theme.TextEmphasizedColor = adaptiveColor
|
||||||
|
case "background":
|
||||||
|
theme.BackgroundColor = adaptiveColor
|
||||||
|
case "backgroundsecondary":
|
||||||
|
theme.BackgroundSecondaryColor = adaptiveColor
|
||||||
|
case "backgrounddarker":
|
||||||
|
theme.BackgroundDarkerColor = adaptiveColor
|
||||||
|
case "bordernormal":
|
||||||
|
theme.BorderNormalColor = adaptiveColor
|
||||||
|
case "borderfocused":
|
||||||
|
theme.BorderFocusedColor = adaptiveColor
|
||||||
|
case "borderdim":
|
||||||
|
theme.BorderDimColor = adaptiveColor
|
||||||
|
case "diffadded":
|
||||||
|
theme.DiffAddedColor = adaptiveColor
|
||||||
|
case "diffremoved":
|
||||||
|
theme.DiffRemovedColor = adaptiveColor
|
||||||
|
case "diffcontext":
|
||||||
|
theme.DiffContextColor = adaptiveColor
|
||||||
|
case "diffhunkheader":
|
||||||
|
theme.DiffHunkHeaderColor = adaptiveColor
|
||||||
|
case "diffhighlightadded":
|
||||||
|
theme.DiffHighlightAddedColor = adaptiveColor
|
||||||
|
case "diffhighlightremoved":
|
||||||
|
theme.DiffHighlightRemovedColor = adaptiveColor
|
||||||
|
case "diffaddedbg":
|
||||||
|
theme.DiffAddedBgColor = adaptiveColor
|
||||||
|
case "diffremovedbg":
|
||||||
|
theme.DiffRemovedBgColor = adaptiveColor
|
||||||
|
case "diffcontextbg":
|
||||||
|
theme.DiffContextBgColor = adaptiveColor
|
||||||
|
case "difflinenumber":
|
||||||
|
theme.DiffLineNumberColor = adaptiveColor
|
||||||
|
case "diffaddedlinenumberbg":
|
||||||
|
theme.DiffAddedLineNumberBgColor = adaptiveColor
|
||||||
|
case "diffremovedlinenumberbg":
|
||||||
|
theme.DiffRemovedLineNumberBgColor = adaptiveColor
|
||||||
|
default:
|
||||||
|
logging.Warn("Unknown color key in custom theme", "key", key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return theme, nil
|
||||||
|
}
|
||||||
|
|
||||||
// updateConfigTheme updates the theme setting in the configuration file
|
// updateConfigTheme updates the theme setting in the configuration file
|
||||||
func updateConfigTheme(themeName string) error {
|
func updateConfigTheme(themeName string) error {
|
||||||
// Use the config package to update the theme
|
// Use the config package to update the theme
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package theme
|
package theme
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -206,3 +209,49 @@ func (t *BaseTheme) SyntaxNumber() lipgloss.AdaptiveColor { return t.SyntaxNumbe
|
|||||||
func (t *BaseTheme) SyntaxType() lipgloss.AdaptiveColor { return t.SyntaxTypeColor }
|
func (t *BaseTheme) SyntaxType() lipgloss.AdaptiveColor { return t.SyntaxTypeColor }
|
||||||
func (t *BaseTheme) SyntaxOperator() lipgloss.AdaptiveColor { return t.SyntaxOperatorColor }
|
func (t *BaseTheme) SyntaxOperator() lipgloss.AdaptiveColor { return t.SyntaxOperatorColor }
|
||||||
func (t *BaseTheme) SyntaxPunctuation() lipgloss.AdaptiveColor { return t.SyntaxPunctuationColor }
|
func (t *BaseTheme) SyntaxPunctuation() lipgloss.AdaptiveColor { return t.SyntaxPunctuationColor }
|
||||||
|
|
||||||
|
// ParseAdaptiveColor parses a color value from the config file into a lipgloss.AdaptiveColor.
|
||||||
|
// It accepts either a string (hex color) or a map with "dark" and "light" keys.
|
||||||
|
func ParseAdaptiveColor(value any) (lipgloss.AdaptiveColor, error) {
|
||||||
|
// Regular expression to validate hex color format
|
||||||
|
hexColorRegex := regexp.MustCompile(`^#[0-9a-fA-F]{6}$`)
|
||||||
|
|
||||||
|
// Case 1: String value (same color for both dark and light modes)
|
||||||
|
if hexColor, ok := value.(string); ok {
|
||||||
|
if !hexColorRegex.MatchString(hexColor) {
|
||||||
|
return lipgloss.AdaptiveColor{}, fmt.Errorf("invalid hex color format: %s", hexColor)
|
||||||
|
}
|
||||||
|
return lipgloss.AdaptiveColor{
|
||||||
|
Dark: hexColor,
|
||||||
|
Light: hexColor,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case 2: Map with dark and light keys
|
||||||
|
if colorMap, ok := value.(map[string]any); ok {
|
||||||
|
darkVal, darkOk := colorMap["dark"]
|
||||||
|
lightVal, lightOk := colorMap["light"]
|
||||||
|
|
||||||
|
if !darkOk || !lightOk {
|
||||||
|
return lipgloss.AdaptiveColor{}, fmt.Errorf("color map must contain both 'dark' and 'light' keys")
|
||||||
|
}
|
||||||
|
|
||||||
|
darkHex, darkIsString := darkVal.(string)
|
||||||
|
lightHex, lightIsString := lightVal.(string)
|
||||||
|
|
||||||
|
if !darkIsString || !lightIsString {
|
||||||
|
return lipgloss.AdaptiveColor{}, fmt.Errorf("color values must be strings")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hexColorRegex.MatchString(darkHex) || !hexColorRegex.MatchString(lightHex) {
|
||||||
|
return lipgloss.AdaptiveColor{}, fmt.Errorf("invalid hex color format")
|
||||||
|
}
|
||||||
|
|
||||||
|
return lipgloss.AdaptiveColor{
|
||||||
|
Dark: darkHex,
|
||||||
|
Light: lightHex,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return lipgloss.AdaptiveColor{}, fmt.Errorf("color must be either a hex string or an object with dark/light keys")
|
||||||
|
}
|
||||||
@@ -12,63 +12,63 @@
|
|||||||
"model": {
|
"model": {
|
||||||
"description": "Model ID for the agent",
|
"description": "Model ID for the agent",
|
||||||
"enum": [
|
"enum": [
|
||||||
"gpt-4o-mini",
|
|
||||||
"o1-pro",
|
|
||||||
"azure.gpt-4o-mini",
|
|
||||||
"openrouter.gpt-4.1-mini",
|
|
||||||
"openrouter.o1-mini",
|
|
||||||
"bedrock.claude-3.7-sonnet",
|
|
||||||
"meta-llama/llama-4-scout-17b-16e-instruct",
|
|
||||||
"openrouter.gpt-4o-mini",
|
|
||||||
"gemini-2.0-flash",
|
|
||||||
"deepseek-r1-distill-llama-70b",
|
|
||||||
"openrouter.claude-3.7-sonnet",
|
|
||||||
"openrouter.gpt-4.5-preview",
|
|
||||||
"azure.o3-mini",
|
|
||||||
"openrouter.claude-3.5-haiku",
|
|
||||||
"azure.o1-mini",
|
"azure.o1-mini",
|
||||||
"openrouter.o1",
|
|
||||||
"openrouter.gemini-2.5",
|
|
||||||
"llama-3.3-70b-versatile",
|
|
||||||
"gpt-4.5-preview",
|
|
||||||
"openrouter.claude-3-opus",
|
|
||||||
"openrouter.claude-3.5-sonnet",
|
|
||||||
"o4-mini",
|
|
||||||
"gemini-2.0-flash-lite",
|
|
||||||
"azure.gpt-4.5-preview",
|
|
||||||
"openrouter.gpt-4o",
|
|
||||||
"o1",
|
|
||||||
"azure.gpt-4o",
|
|
||||||
"openrouter.gpt-4.1-nano",
|
|
||||||
"o3",
|
|
||||||
"gpt-4.1",
|
|
||||||
"azure.o1",
|
|
||||||
"claude-3-haiku",
|
|
||||||
"claude-3-opus",
|
|
||||||
"gpt-4.1-mini",
|
|
||||||
"openrouter.o4-mini",
|
|
||||||
"openrouter.gemini-2.5-flash",
|
"openrouter.gemini-2.5-flash",
|
||||||
"claude-3.5-haiku",
|
"claude-3-haiku",
|
||||||
"o3-mini",
|
|
||||||
"azure.o3",
|
|
||||||
"gpt-4o",
|
|
||||||
"azure.gpt-4.1",
|
|
||||||
"openrouter.claude-3-haiku",
|
|
||||||
"gpt-4.1-nano",
|
|
||||||
"azure.gpt-4.1-nano",
|
|
||||||
"claude-3.7-sonnet",
|
|
||||||
"gemini-2.5",
|
|
||||||
"azure.o4-mini",
|
|
||||||
"o1-mini",
|
"o1-mini",
|
||||||
"qwen-qwq",
|
"qwen-qwq",
|
||||||
|
"llama-3.3-70b-versatile",
|
||||||
|
"openrouter.claude-3.5-sonnet",
|
||||||
|
"o3-mini",
|
||||||
|
"o4-mini",
|
||||||
|
"gpt-4.1",
|
||||||
|
"azure.o3-mini",
|
||||||
|
"openrouter.gpt-4.1-nano",
|
||||||
|
"openrouter.gpt-4o",
|
||||||
|
"gemini-2.5",
|
||||||
|
"azure.gpt-4o",
|
||||||
|
"azure.gpt-4o-mini",
|
||||||
|
"claude-3.7-sonnet",
|
||||||
|
"azure.gpt-4.1-nano",
|
||||||
|
"openrouter.o1",
|
||||||
|
"openrouter.claude-3-haiku",
|
||||||
|
"bedrock.claude-3.7-sonnet",
|
||||||
|
"gemini-2.5-flash",
|
||||||
|
"azure.o3",
|
||||||
|
"openrouter.gemini-2.5",
|
||||||
|
"openrouter.o3",
|
||||||
|
"openrouter.o3-mini",
|
||||||
|
"openrouter.gpt-4.1-mini",
|
||||||
|
"openrouter.gpt-4.5-preview",
|
||||||
|
"openrouter.gpt-4o-mini",
|
||||||
|
"gpt-4.1-mini",
|
||||||
|
"meta-llama/llama-4-scout-17b-16e-instruct",
|
||||||
|
"openrouter.o1-mini",
|
||||||
|
"gpt-4.5-preview",
|
||||||
|
"o3",
|
||||||
|
"openrouter.claude-3.5-haiku",
|
||||||
|
"claude-3-opus",
|
||||||
|
"o1-pro",
|
||||||
|
"gemini-2.0-flash",
|
||||||
|
"azure.o4-mini",
|
||||||
|
"openrouter.o4-mini",
|
||||||
|
"claude-3.5-sonnet",
|
||||||
"meta-llama/llama-4-maverick-17b-128e-instruct",
|
"meta-llama/llama-4-maverick-17b-128e-instruct",
|
||||||
|
"azure.o1",
|
||||||
"openrouter.gpt-4.1",
|
"openrouter.gpt-4.1",
|
||||||
"openrouter.o1-pro",
|
"openrouter.o1-pro",
|
||||||
"openrouter.o3",
|
"gpt-4.1-nano",
|
||||||
"claude-3.5-sonnet",
|
"azure.gpt-4.5-preview",
|
||||||
"gemini-2.5-flash",
|
"openrouter.claude-3-opus",
|
||||||
|
"gpt-4o-mini",
|
||||||
|
"o1",
|
||||||
|
"deepseek-r1-distill-llama-70b",
|
||||||
|
"azure.gpt-4.1",
|
||||||
|
"gpt-4o",
|
||||||
"azure.gpt-4.1-mini",
|
"azure.gpt-4.1-mini",
|
||||||
"openrouter.o3-mini"
|
"openrouter.claude-3.7-sonnet",
|
||||||
|
"claude-3.5-haiku",
|
||||||
|
"gemini-2.0-flash-lite"
|
||||||
],
|
],
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -102,63 +102,63 @@
|
|||||||
"model": {
|
"model": {
|
||||||
"description": "Model ID for the agent",
|
"description": "Model ID for the agent",
|
||||||
"enum": [
|
"enum": [
|
||||||
"gpt-4o-mini",
|
|
||||||
"o1-pro",
|
|
||||||
"azure.gpt-4o-mini",
|
|
||||||
"openrouter.gpt-4.1-mini",
|
|
||||||
"openrouter.o1-mini",
|
|
||||||
"bedrock.claude-3.7-sonnet",
|
|
||||||
"meta-llama/llama-4-scout-17b-16e-instruct",
|
|
||||||
"openrouter.gpt-4o-mini",
|
|
||||||
"gemini-2.0-flash",
|
|
||||||
"deepseek-r1-distill-llama-70b",
|
|
||||||
"openrouter.claude-3.7-sonnet",
|
|
||||||
"openrouter.gpt-4.5-preview",
|
|
||||||
"azure.o3-mini",
|
|
||||||
"openrouter.claude-3.5-haiku",
|
|
||||||
"azure.o1-mini",
|
"azure.o1-mini",
|
||||||
"openrouter.o1",
|
|
||||||
"openrouter.gemini-2.5",
|
|
||||||
"llama-3.3-70b-versatile",
|
|
||||||
"gpt-4.5-preview",
|
|
||||||
"openrouter.claude-3-opus",
|
|
||||||
"openrouter.claude-3.5-sonnet",
|
|
||||||
"o4-mini",
|
|
||||||
"gemini-2.0-flash-lite",
|
|
||||||
"azure.gpt-4.5-preview",
|
|
||||||
"openrouter.gpt-4o",
|
|
||||||
"o1",
|
|
||||||
"azure.gpt-4o",
|
|
||||||
"openrouter.gpt-4.1-nano",
|
|
||||||
"o3",
|
|
||||||
"gpt-4.1",
|
|
||||||
"azure.o1",
|
|
||||||
"claude-3-haiku",
|
|
||||||
"claude-3-opus",
|
|
||||||
"gpt-4.1-mini",
|
|
||||||
"openrouter.o4-mini",
|
|
||||||
"openrouter.gemini-2.5-flash",
|
"openrouter.gemini-2.5-flash",
|
||||||
"claude-3.5-haiku",
|
"claude-3-haiku",
|
||||||
"o3-mini",
|
|
||||||
"azure.o3",
|
|
||||||
"gpt-4o",
|
|
||||||
"azure.gpt-4.1",
|
|
||||||
"openrouter.claude-3-haiku",
|
|
||||||
"gpt-4.1-nano",
|
|
||||||
"azure.gpt-4.1-nano",
|
|
||||||
"claude-3.7-sonnet",
|
|
||||||
"gemini-2.5",
|
|
||||||
"azure.o4-mini",
|
|
||||||
"o1-mini",
|
"o1-mini",
|
||||||
"qwen-qwq",
|
"qwen-qwq",
|
||||||
|
"llama-3.3-70b-versatile",
|
||||||
|
"openrouter.claude-3.5-sonnet",
|
||||||
|
"o3-mini",
|
||||||
|
"o4-mini",
|
||||||
|
"gpt-4.1",
|
||||||
|
"azure.o3-mini",
|
||||||
|
"openrouter.gpt-4.1-nano",
|
||||||
|
"openrouter.gpt-4o",
|
||||||
|
"gemini-2.5",
|
||||||
|
"azure.gpt-4o",
|
||||||
|
"azure.gpt-4o-mini",
|
||||||
|
"claude-3.7-sonnet",
|
||||||
|
"azure.gpt-4.1-nano",
|
||||||
|
"openrouter.o1",
|
||||||
|
"openrouter.claude-3-haiku",
|
||||||
|
"bedrock.claude-3.7-sonnet",
|
||||||
|
"gemini-2.5-flash",
|
||||||
|
"azure.o3",
|
||||||
|
"openrouter.gemini-2.5",
|
||||||
|
"openrouter.o3",
|
||||||
|
"openrouter.o3-mini",
|
||||||
|
"openrouter.gpt-4.1-mini",
|
||||||
|
"openrouter.gpt-4.5-preview",
|
||||||
|
"openrouter.gpt-4o-mini",
|
||||||
|
"gpt-4.1-mini",
|
||||||
|
"meta-llama/llama-4-scout-17b-16e-instruct",
|
||||||
|
"openrouter.o1-mini",
|
||||||
|
"gpt-4.5-preview",
|
||||||
|
"o3",
|
||||||
|
"openrouter.claude-3.5-haiku",
|
||||||
|
"claude-3-opus",
|
||||||
|
"o1-pro",
|
||||||
|
"gemini-2.0-flash",
|
||||||
|
"azure.o4-mini",
|
||||||
|
"openrouter.o4-mini",
|
||||||
|
"claude-3.5-sonnet",
|
||||||
"meta-llama/llama-4-maverick-17b-128e-instruct",
|
"meta-llama/llama-4-maverick-17b-128e-instruct",
|
||||||
|
"azure.o1",
|
||||||
"openrouter.gpt-4.1",
|
"openrouter.gpt-4.1",
|
||||||
"openrouter.o1-pro",
|
"openrouter.o1-pro",
|
||||||
"openrouter.o3",
|
"gpt-4.1-nano",
|
||||||
"claude-3.5-sonnet",
|
"azure.gpt-4.5-preview",
|
||||||
"gemini-2.5-flash",
|
"openrouter.claude-3-opus",
|
||||||
|
"gpt-4o-mini",
|
||||||
|
"o1",
|
||||||
|
"deepseek-r1-distill-llama-70b",
|
||||||
|
"azure.gpt-4.1",
|
||||||
|
"gpt-4o",
|
||||||
"azure.gpt-4.1-mini",
|
"azure.gpt-4.1-mini",
|
||||||
"openrouter.o3-mini"
|
"openrouter.claude-3.7-sonnet",
|
||||||
|
"claude-3.5-haiku",
|
||||||
|
"gemini-2.0-flash-lite"
|
||||||
],
|
],
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -354,6 +354,36 @@
|
|||||||
"tui": {
|
"tui": {
|
||||||
"description": "Terminal User Interface configuration",
|
"description": "Terminal User Interface configuration",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"customTheme": {
|
||||||
|
"additionalProperties": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"pattern": "^#[0-9a-fA-F]{6}$",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"dark": {
|
||||||
|
"pattern": "^#[0-9a-fA-F]{6}$",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"pattern": "^#[0-9a-fA-F]{6}$",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"dark",
|
||||||
|
"light"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"description": "Custom theme color definitions",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"theme": {
|
"theme": {
|
||||||
"default": "opencode",
|
"default": "opencode",
|
||||||
"description": "TUI theme name",
|
"description": "TUI theme name",
|
||||||
@@ -366,7 +396,8 @@
|
|||||||
"monokai",
|
"monokai",
|
||||||
"onedark",
|
"onedark",
|
||||||
"tokyonight",
|
"tokyonight",
|
||||||
"tron"
|
"tron",
|
||||||
|
"custom"
|
||||||
],
|
],
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user