SIGN IN SIGN UP

fix(opencode): normalize agent tools array into boolean map (#10)

* fix(opencode): normalize agent tools array into boolean map

OpenCode's agent config schema requires `tools` to be an object of
`toolName: boolean` (or omitted), not an array. Source agent
frontmatter with `tools: ["Read", "Grep", "Glob"]` (Claude-style)
was being copied through verbatim, causing OpenCode to refuse to
start with "Expected object | undefined, got [...] tools".

Add OpenCodeAgentRenderer, which delegates id/title/description
handling to ForgeCodeAgentRenderer and converts any tools array into
a lowercase boolean map using the yaml package. Register it in
AgentRendererFactory and wire OpenCodeAdapter to use it explicitly
instead of falling back to the forgecode renderer.

Kilo is an OpenCode fork with an identical agent schema
(tools: Schema.optional(Schema.Record(Schema.String, Schema.Boolean))
in kilocode's packages/opencode/src/config/agent.ts), so it hits the
same failure and reuses the same renderer via AgentRendererFactory.

* fix(opencode): guard against malformed frontmatter crash in tools normalizer

parseDocument() doesn't throw on invalid YAML — it records errors in
doc.errors and keeps going. If tools still resolved as a sequence
despite an unrelated parse error elsewhere in the frontmatter, the
renderer proceeded to doc.toString(), which throws for documents with
errors ("Document with errors cannot be stringified"). Since
syncAgentsAsMarkdown renders all agents via Promise.all, one
malformed agent file would fail the entire apply batch.

Guard on doc.errors.length and fail open (return original content)
instead, matching the pre-existing ForgeCodeAgentRenderer behavior of
passing malformed frontmatter through untouched.

Also drop the unused BaseAgentRenderer inheritance — all id/title/
description handling is delegated to the composed
ForgeCodeAgentRenderer instance, so the base class added coupling
without being used.
A
Ahmet Çetinkaya committed
e133c62f09789697725e15c19bc94d700250c5e9
Parent: edfe23b
Committed by GitHub <noreply@github.com> on 7/15/2026, 2:52:37 PM