From 39112144fbf97a335a45155cae8ec57bf34f8e26 Mon Sep 17 00:00:00 2001 From: sentisso <38100632+sentisso@users.noreply.github.com> Date: Tue, 28 Apr 2026 15:35:45 +0200 Subject: [PATCH 1/2] feat: add support for named agent colors --- packages/app/src/utils/agent.ts | 8 ++++++ .../src/cli/cmd/tui/context/local.tsx | 28 ++++++++++++++++++- packages/opencode/src/config/agent.ts | 1 + packages/ui/src/components/message-part.tsx | 8 ++++++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/packages/app/src/utils/agent.ts b/packages/app/src/utils/agent.ts index 59da53af102a..8b05ab1ee4ca 100644 --- a/packages/app/src/utils/agent.ts +++ b/packages/app/src/utils/agent.ts @@ -3,6 +3,14 @@ const defaults: Record = { build: "var(--icon-agent-build-base)", docs: "var(--icon-agent-docs-base)", plan: "var(--icon-agent-plan-base)", + red: "var(--syntax-critical)", + blue: "var(--syntax-info)", + green: "var(--syntax-success)", + yellow: "var(--syntax-warning)", + purple: "var(--syntax-property)", + orange: "var(--syntax-warning)", + pink: "var(--syntax-property)", + cyan: "var(--syntax-info)", } const palette = [ diff --git a/packages/opencode/src/cli/cmd/tui/context/local.tsx b/packages/opencode/src/cli/cmd/tui/context/local.tsx index 0b8c902c496f..57d7cdfa995c 100644 --- a/packages/opencode/src/cli/cmd/tui/context/local.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/local.tsx @@ -92,8 +92,34 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ if (agent?.color) { const color = agent.color if (color.startsWith("#")) return RGBA.fromHex(color) + + let mapped: string + switch (color.toLowerCase()) { + case "red": + mapped = "error" + break + case "blue": + mapped = "primary" + break + case "green": + mapped = "success" + break + case "yellow": + case "orange": + mapped = "warning" + break + case "purple": + case "pink": + mapped = "accent" + break + case "cyan": + mapped = "info" + break + default: + mapped = color + } // already validated by config, just satisfying TS here - return theme[color as keyof typeof theme] as RGBA + return theme[mapped as keyof typeof theme] as RGBA } return colors()[index % colors().length] }, diff --git a/packages/opencode/src/config/agent.ts b/packages/opencode/src/config/agent.ts index e673edbad4c9..61e46f4b23de 100644 --- a/packages/opencode/src/config/agent.ts +++ b/packages/opencode/src/config/agent.ts @@ -18,6 +18,7 @@ const log = Log.create({ service: "config" }) const Color = Schema.Union([ Schema.String.check(Schema.isPattern(/^#[0-9a-fA-F]{6}$/)), Schema.Literals(["primary", "secondary", "accent", "success", "warning", "error", "info"]), + Schema.Literals(["red", "blue", "green", "yellow", "purple", "orange", "pink", "cyan"]), ]) const AgentSchema = Schema.StructWithRest( diff --git a/packages/ui/src/components/message-part.tsx b/packages/ui/src/components/message-part.tsx index 013272205085..d1331fb85825 100644 --- a/packages/ui/src/components/message-part.tsx +++ b/packages/ui/src/components/message-part.tsx @@ -281,6 +281,14 @@ const agentTones: Record = { build: "var(--icon-agent-build-base)", docs: "var(--icon-agent-docs-base)", plan: "var(--icon-agent-plan-base)", + red: "var(--syntax-critical)", + blue: "var(--syntax-info)", + green: "var(--syntax-success)", + yellow: "var(--syntax-warning)", + purple: "var(--syntax-property)", + orange: "var(--syntax-warning)", + pink: "var(--syntax-property)", + cyan: "var(--syntax-info)", } const agentPalette = [ From de629794aa4ccd6c39db190264de2ec081f7d461 Mon Sep 17 00:00:00 2001 From: sentisso <38100632+sentisso@users.noreply.github.com> Date: Tue, 28 Apr 2026 16:08:19 +0200 Subject: [PATCH 2/2] update color parsing --- .../src/cli/cmd/tui/context/local.tsx | 32 +++---------------- packages/opencode/src/config/agent.ts | 2 +- packages/sdk/js/src/v2/gen/types.gen.ts | 28 ++++++++++++++-- packages/web/src/content/docs/agents.mdx | 2 +- 4 files changed, 33 insertions(+), 31 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/context/local.tsx b/packages/opencode/src/cli/cmd/tui/context/local.tsx index 57d7cdfa995c..25b20c962f1c 100644 --- a/packages/opencode/src/cli/cmd/tui/context/local.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/local.tsx @@ -93,33 +93,11 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ const color = agent.color if (color.startsWith("#")) return RGBA.fromHex(color) - let mapped: string - switch (color.toLowerCase()) { - case "red": - mapped = "error" - break - case "blue": - mapped = "primary" - break - case "green": - mapped = "success" - break - case "yellow": - case "orange": - mapped = "warning" - break - case "purple": - case "pink": - mapped = "accent" - break - case "cyan": - mapped = "info" - break - default: - mapped = color - } - // already validated by config, just satisfying TS here - return theme[mapped as keyof typeof theme] as RGBA + if (color in theme) return theme[color as keyof typeof theme] + + // fallback to built-in color parser + const hex = Bun.color(color, "hex") + if (hex) return RGBA.fromHex(hex) } return colors()[index % colors().length] }, diff --git a/packages/opencode/src/config/agent.ts b/packages/opencode/src/config/agent.ts index 61e46f4b23de..4eaf7b431037 100644 --- a/packages/opencode/src/config/agent.ts +++ b/packages/opencode/src/config/agent.ts @@ -41,7 +41,7 @@ const AgentSchema = Schema.StructWithRest( }), options: Schema.optional(Schema.Record(Schema.String, Schema.Any)), color: Schema.optional(Color).annotate({ - description: "Hex color code (e.g., #FF5733) or theme color (e.g., primary)", + description: "Hex color code (e.g., #FF5733), theme color (e.g., primary) or other valid CSS colors (e.g., red)", }), steps: Schema.optional(PositiveInt).annotate({ description: "Maximum number of agentic iterations before forcing text-only response", diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index f003ef063466..7c07b14b59da 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -1255,9 +1255,25 @@ export type AgentConfig = { [key: string]: unknown } /** - * Hex color code (e.g., #FF5733) or theme color (e.g., primary) + * Hex color code (e.g., #FF5733), theme color (e.g., primary) or other valid CSS colors (e.g., red) */ - color?: string | "primary" | "secondary" | "accent" | "success" | "warning" | "error" | "info" + color?: + | string + | "primary" + | "secondary" + | "accent" + | "success" + | "warning" + | "error" + | "info" + | "red" + | "blue" + | "green" + | "yellow" + | "purple" + | "orange" + | "pink" + | "cyan" /** * Maximum number of agentic iterations before forcing text-only response */ @@ -1289,6 +1305,14 @@ export type AgentConfig = { | "warning" | "error" | "info" + | "red" + | "blue" + | "green" + | "yellow" + | "purple" + | "orange" + | "pink" + | "cyan" | number | PermissionConfig | undefined diff --git a/packages/web/src/content/docs/agents.mdx b/packages/web/src/content/docs/agents.mdx index 7c5f21787828..de73ef1357bd 100644 --- a/packages/web/src/content/docs/agents.mdx +++ b/packages/web/src/content/docs/agents.mdx @@ -628,7 +628,7 @@ Users can always invoke any subagent directly via the `@` autocomplete menu, eve Customize the agent's visual appearance in the UI with the `color` option. This affects how the agent appears in the interface. -Use a valid hex color (e.g., `#FF5733`) or theme color: `primary`, `secondary`, `accent`, `success`, `warning`, `error`, `info`. +Use a valid hex color (e.g., `#FF5733`), theme color: `primary`, `secondary`, `accent`, `success`, `warning`, `error`, `info` or other valid CSS color (e.g., `red`). ```json title="opencode.json" {