feat(tui): allow theme colors in agent customization (#11444)

This commit is contained in:
Idris Gadi
2026-02-04 02:39:21 +05:30
committed by GitHub
parent 6b5cf936a2
commit 95211a8854
4 changed files with 26 additions and 9 deletions

View File

@@ -35,6 +35,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
const agent = iife(() => { const agent = iife(() => {
const agents = createMemo(() => sync.data.agent.filter((x) => x.mode !== "subagent" && !x.hidden)) 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<{ const [agentStore, setAgentStore] = createStore<{
current: string current: string
}>({ }>({
@@ -48,6 +49,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
theme.warning, theme.warning,
theme.primary, theme.primary,
theme.error, theme.error,
theme.info,
]) ])
return { return {
list() { list() {
@@ -75,11 +77,16 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
}) })
}, },
color(name: string) { color(name: string) {
const all = sync.data.agent const index = visibleAgents().findIndex((x) => x.name === name)
const agent = all.find((x) => x.name === name)
if (agent?.color) return RGBA.fromHex(agent.color)
const index = all.findIndex((x) => x.name === name)
if (index === -1) return colors()[0] 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] return colors()[index % colors().length]
}, },
} }

View File

@@ -645,10 +645,12 @@ export namespace Config {
.describe("Hide this subagent from the @ autocomplete menu (default: false, only applies to mode: subagent)"), .describe("Hide this subagent from the @ autocomplete menu (default: false, only applies to mode: subagent)"),
options: z.record(z.string(), z.any()).optional(), options: z.record(z.string(), z.any()).optional(),
color: z color: z
.string() .union([
.regex(/^#[0-9a-fA-F]{6}$/, "Invalid hex color format") z.string().regex(/^#[0-9a-fA-F]{6}$/, "Invalid hex color format"),
z.enum(["primary", "secondary", "accent", "success", "warning", "error", "info"]),
])
.optional() .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 steps: z
.number() .number()
.int() .int()

View File

@@ -15,6 +15,7 @@ test("agent color parsed from project config", async () => {
$schema: "https://opencode.ai/config.json", $schema: "https://opencode.ai/config.json",
agent: { agent: {
build: { color: "#FFA500" }, build: { color: "#FFA500" },
plan: { color: "primary" },
}, },
}), }),
) )
@@ -25,6 +26,7 @@ test("agent color parsed from project config", async () => {
fn: async () => { fn: async () => {
const cfg = await Config.get() const cfg = await Config.get()
expect(cfg.agent?.["build"]?.color).toBe("#FFA500") 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", $schema: "https://opencode.ai/config.json",
agent: { agent: {
plan: { color: "#A855F7" }, plan: { color: "#A855F7" },
build: { color: "accent" },
}, },
}), }),
) )
@@ -48,6 +51,8 @@ test("Agent.get includes color from config", async () => {
fn: async () => { fn: async () => {
const plan = await AgentSvc.get("plan") const plan = await AgentSvc.get("plan")
expect(plan?.color).toBe("#A855F7") expect(plan?.color).toBe("#A855F7")
const build = await AgentSvc.get("build")
expect(build?.color).toBe("accent")
}, },
}) })
}) })

View File

@@ -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. 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" ```json title="opencode.json"
{ {
"agent": { "agent": {
"creative": { "creative": {
"color": "#ff6b6b" "color": "#ff6b6b"
},
"code-reviewer": {
"color": "accent"
} }
} }
} }
``` ```
Must be a valid hex color code like `#FF5733`.
--- ---
### Top P ### Top P