diff --git a/packages/opencode/src/cli/cmd/tui/context/local.tsx b/packages/opencode/src/cli/cmd/tui/context/local.tsx index d058ce54fb..72c72dc5bb 100644 --- a/packages/opencode/src/cli/cmd/tui/context/local.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/local.tsx @@ -35,6 +35,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ const agent = iife(() => { const agents = createMemo(() => sync.data.agent.filter((x) => x.mode !== "subagent" && !x.hidden)) + const visibleAgents = createMemo(() => sync.data.agent.filter((x) => !x.hidden)) const [agentStore, setAgentStore] = createStore<{ current: string }>({ @@ -48,6 +49,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ theme.warning, theme.primary, theme.error, + theme.info, ]) return { list() { @@ -75,11 +77,16 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ }) }, color(name: string) { - const all = sync.data.agent - const agent = all.find((x) => x.name === name) - if (agent?.color) return RGBA.fromHex(agent.color) - const index = all.findIndex((x) => x.name === name) + const index = visibleAgents().findIndex((x) => x.name === name) if (index === -1) return colors()[0] + const agent = visibleAgents()[index] + + if (agent?.color) { + const color = agent.color + if (color.startsWith("#")) return RGBA.fromHex(color) + // already validated by config, just satisfying TS here + return theme[color as keyof typeof theme] as RGBA + } return colors()[index % colors().length] }, } diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 7969e30795..4f9968f2d5 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -606,10 +606,12 @@ export namespace Config { .describe("Hide this subagent from the @ autocomplete menu (default: false, only applies to mode: subagent)"), options: z.record(z.string(), z.any()).optional(), color: z - .string() - .regex(/^#[0-9a-fA-F]{6}$/, "Invalid hex color format") + .union([ + z.string().regex(/^#[0-9a-fA-F]{6}$/, "Invalid hex color format"), + z.enum(["primary", "secondary", "accent", "success", "warning", "error", "info"]), + ]) .optional() - .describe("Hex color code for the agent (e.g., #FF5733)"), + .describe("Hex color code (e.g., #FF5733) or theme color (e.g., primary)"), steps: z .number() .int() diff --git a/packages/opencode/test/config/agent-color.test.ts b/packages/opencode/test/config/agent-color.test.ts index a2c3742967..b9c7cccc48 100644 --- a/packages/opencode/test/config/agent-color.test.ts +++ b/packages/opencode/test/config/agent-color.test.ts @@ -15,6 +15,7 @@ test("agent color parsed from project config", async () => { $schema: "https://opencode.ai/config.json", agent: { build: { color: "#FFA500" }, + plan: { color: "primary" }, }, }), ) @@ -25,6 +26,7 @@ test("agent color parsed from project config", async () => { fn: async () => { const cfg = await Config.get() expect(cfg.agent?.["build"]?.color).toBe("#FFA500") + expect(cfg.agent?.["plan"]?.color).toBe("primary") }, }) }) @@ -38,6 +40,7 @@ test("Agent.get includes color from config", async () => { $schema: "https://opencode.ai/config.json", agent: { plan: { color: "#A855F7" }, + build: { color: "accent" }, }, }), ) @@ -48,6 +51,8 @@ test("Agent.get includes color from config", async () => { fn: async () => { const plan = await AgentSvc.get("plan") expect(plan?.color).toBe("#A855F7") + const build = await AgentSvc.get("build") + expect(build?.color).toBe("accent") }, }) }) diff --git a/packages/web/src/content/docs/agents.mdx b/packages/web/src/content/docs/agents.mdx index 62957ad911..755c4ba25a 100644 --- a/packages/web/src/content/docs/agents.mdx +++ b/packages/web/src/content/docs/agents.mdx @@ -576,18 +576,21 @@ 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`. + ```json title="opencode.json" { "agent": { "creative": { "color": "#ff6b6b" + }, + "code-reviewer": { + "color": "accent" } } } ``` -Must be a valid hex color code like `#FF5733`. - --- ### Top P