Problem
Kai now ships agent definitions for multiple platforms — OpenCode (agents/*.md), Claude Code (claude/agents/*.md, #7), and Gemini CLI (gemini/agents/*.md, #8). Diffing agents/kai.md against claude/agents/kai.md shows the pattern clearly:
- Frontmatter: OpenCode uses a YAML
permission/tools/mode block; Claude Code uses tools:/model:/color:; Gemini CLI has its own dialect again.
- Mention syntax: OpenCode uses
@developer; Claude Code/Gemini use bare developer.
- Body content (persona, routing table, workflows, quality gates, standards): ~95% identical across all three platforms.
Today each platform's copy is maintained by hand. This has already caused drift independent of intentional platform differences — e.g. compare the "Funny"/"Factual" persona bullets between agents/kai.md and claude/agents/kai.md: extra clauses on one side, trimmed wording on the other, with no functional reason for the difference. That's generator debt accumulating silently.
Cost of the status quo: adding a 4th platform (or fixing a wording issue across all 22 agents × 3 platforms) means touching up to 66 files by hand, with no mechanism to catch drift.
Proposal
Split each agent definition into two layers and generate the platform copies instead of hand-authoring them:
- Content layer (new):
sources/agents/<name>.md — one canonical file per agent. Frontmatter-free. Persona, routing logic, workflows, and standards live here. Mentions use a neutral placeholder syntax, e.g. {{mention:developer}}, instead of baking in @developer or developer.
- Adapter layer (new):
sources/platforms/<platform>.yaml — per-platform config: frontmatter template, mention-syntax transform, tool-name alias map (e.g. OpenCode bash: true ↔ Claude Code Bash ↔ Gemini CLI equivalent).
- Generator (new):
docs/scripts/build-agents.{sh,js} — renders sources/agents/*.md through each platform adapter into agents/*.md, claude/agents/*.md, gemini/agents/*.md.
- CI drift check: a workflow step (or pre-commit hook) that regenerates and diffs against committed output, failing if they've diverged — so hand-edits to a generated file get caught instead of silently drifting from source.
Why not adopt an existing external standard instead?
Evaluated and none directly fit today:
- AGENTS.md (OpenAI-backed, multi-vendor) — good fit for a single root-level "how to work in this repo" file, but not designed for defining a graph of subagents with routing/handoff logic.
- Anthropic Agent Skills (
SKILL.md + frontmatter) — Claude Code's shape already resembles this; doesn't cover OpenCode's or Gemini CLI's dialects.
- MCP (Model Context Protocol) — standardizes tool wiring, not agent personas/prompts. Orthogonal to the problem here.
There's currently no cross-vendor standard for "subagent definition + orchestration graph," so the practical fix is internal: stop hand-copying, generate from one source.
Scope / non-goals
- No behavior change to any existing agent — this is a refactor of how the files are produced, not their content.
- Existing
agents/, claude/agents/, gemini/agents/ remain the build output (still committed, still what installers/releases consume) — nothing downstream changes.
- Out of scope for v1: templating logic beyond frontmatter + mention syntax (e.g. no attempt to unify tool capabilities across platforms where they genuinely differ).
References
Suggested next step
Route to architect to spec the sources/platforms/*.yaml schema and generator design in detail before implementation.
Problem
Kai now ships agent definitions for multiple platforms — OpenCode (
agents/*.md), Claude Code (claude/agents/*.md, #7), and Gemini CLI (gemini/agents/*.md, #8). Diffingagents/kai.mdagainstclaude/agents/kai.mdshows the pattern clearly:permission/tools/modeblock; Claude Code usestools:/model:/color:; Gemini CLI has its own dialect again.@developer; Claude Code/Gemini use baredeveloper.Today each platform's copy is maintained by hand. This has already caused drift independent of intentional platform differences — e.g. compare the "Funny"/"Factual" persona bullets between
agents/kai.mdandclaude/agents/kai.md: extra clauses on one side, trimmed wording on the other, with no functional reason for the difference. That's generator debt accumulating silently.Cost of the status quo: adding a 4th platform (or fixing a wording issue across all 22 agents × 3 platforms) means touching up to 66 files by hand, with no mechanism to catch drift.
Proposal
Split each agent definition into two layers and generate the platform copies instead of hand-authoring them:
sources/agents/<name>.md— one canonical file per agent. Frontmatter-free. Persona, routing logic, workflows, and standards live here. Mentions use a neutral placeholder syntax, e.g.{{mention:developer}}, instead of baking in@developerordeveloper.sources/platforms/<platform>.yaml— per-platform config: frontmatter template, mention-syntax transform, tool-name alias map (e.g. OpenCodebash: true↔ Claude CodeBash↔ Gemini CLI equivalent).docs/scripts/build-agents.{sh,js}— renderssources/agents/*.mdthrough each platform adapter intoagents/*.md,claude/agents/*.md,gemini/agents/*.md.Why not adopt an existing external standard instead?
Evaluated and none directly fit today:
SKILL.md+ frontmatter) — Claude Code's shape already resembles this; doesn't cover OpenCode's or Gemini CLI's dialects.There's currently no cross-vendor standard for "subagent definition + orchestration graph," so the practical fix is internal: stop hand-copying, generate from one source.
Scope / non-goals
agents/,claude/agents/,gemini/agents/remain the build output (still committed, still what installers/releases consume) — nothing downstream changes.References
Suggested next step
Route to
architectto spec thesources/platforms/*.yamlschema and generator design in detail before implementation.