Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions packages/opencode/src/config/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const AgentSchema = Schema.StructWithRest(
description: "Hide this subagent from the @ autocomplete menu (default: false, only applies to mode: subagent)",
}),
options: Schema.optional(Schema.Record(Schema.String, Schema.Any)),
color: Schema.optional(Color).annotate({
color: Schema.optional(Schema.NullOr(Color)).annotate({
description: "Hex color code (e.g., #FF5733) or theme color (e.g., primary)",
}),
steps: Schema.optional(PositiveInt).annotate({
Expand Down Expand Up @@ -93,7 +93,9 @@ const normalize = (agent: Schema.Schema.Type<typeof AgentSchema>): Schema.Schema
globalThis.Object.assign(permission, agent.permission)

const steps = agent.steps ?? agent.maxSteps
return { ...agent, options, permission, ...(steps !== undefined ? { steps } : {}) }
const result = { ...agent, options, permission, ...(steps !== undefined ? { steps } : {}) }
if (result.color === null) delete result.color
return result
}

export const Info = AgentSchema.pipe(
Expand Down
38 changes: 38 additions & 0 deletions packages/opencode/test/config/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,44 @@ Nested agent prompt`,
})
})

test("loads many agents when unquoted hex colors parse as null", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
const agentsDir = path.join(dir, ".opencode", "agents")
await fs.mkdir(agentsDir, { recursive: true })

for (let i = 0; i < 184; i++) {
const name = `agent-${String(i).padStart(3, "0")}`
await Filesystem.write(
path.join(agentsDir, `${name}.md`),
`---
name: ${name}
description: Test agent
mode: subagent
color: #9B59B6
---
Agent prompt`,
)
}
},
})

await withTestInstance({
directory: tmp.path,
fn: async (ctx) => {
const config = await load(ctx)

expect(Object.keys(config.agent ?? {}).filter((name) => name.startsWith("agent-"))).toHaveLength(184)
expect(config.agent?.["agent-183"]).toMatchObject({
name: "agent-183",
mode: "subagent",
prompt: "Agent prompt",
})
expect(config.agent?.["agent-183"]?.color).toBeUndefined()
},
})
})

test("loads commands from .opencode/command (singular)", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
Expand Down
Loading