The agent definition, typed at the source
Everything this site stores is a direct mapping of AgentConfig in crates/schema/src/agent.rs, this repo's typed representation of a Claude Code sub-agent. The upstream format those structs serialize to is Claude Code's own sub-agent spec: code.claude.com/docs/en/sub-agents.
The pipeline
Definitions flow one way, and YAML is never the source of truth:
crates/agent-gen/src/agents.rs — the typed list (one AgentConfig per agent)
│ cargo run -p agent-gen
▼
.claude/agents/<name>.yaml — generated; header says "do not edit by hand"
│ read by Claude Code at session startup
▼
delegation — Claude reads each description to decide whether to hand a task over
The module doc in agent.rs puts it in one sentence: "The description field is the trigger -- Claude reads it to decide whether to delegate a task to this agent." That's why the descriptions in this catalog read the way they do -- every one starts "Delegate when…" and most end with an explicit anti-pattern ("Do NOT delegate for…"), per the struct's own guidance to "include anti-patterns (what NOT to use this agent for) for precision."
The real schema
pub enum AgentModel {
#[serde(rename = "claude-opus-4-8")] Opus48, // Best for complex multi-step reasoning; highest cost.
#[serde(rename = "claude-sonnet-4-6")] Sonnet46, // Balanced speed + intelligence; recommended default.
#[serde(rename = "claude-haiku-4-5-20251001")] Haiku45, // Fastest/cheapest; well-scoped mechanical tasks.
#[serde(rename = "claude-fable-5")] Fable5, // Next-gen, long-horizon agentic work; highest cost.
}
pub struct AgentConfig {
pub name: String, // YAML filename, e.g. "cargo-check"
pub description: String, // trigger text Claude reads to decide whether to delegate
pub model: Option<AgentModel>,
pub tools: Vec<AgentTool>, // e.g. Bash, Read, Write, Edit, Glob, Grep, WebFetch, ...
pub max_turns: Option<u32>,
pub system_prompt: String,
}
AgentTool is a 21-variant enum (Bash, Read, Write, Edit, Glob, Grep, Task, the TaskCreate/TaskUpdate/TaskGet/TaskList/TaskStop family, WebFetch, WebSearch, Skill, and more) -- "only list tools the agent actually needs -- principle of least privilege. This list is validated at generation time so typos fail the build." AgentConfig::validate() enforces the rest at generation time: name must be [a-z0-9-], description at least 20 characters, system_prompt non-empty. to_yaml() emits the description and system prompt as YAML block scalars so multi-line prompts diff cleanly.
The 1:1 mapping into this site's table
| AgentConfig field (Rust) | agent_definitions column (D1) | Notes |
|---|---|---|
name | name | Also the YAML filename stem. |
description | description | Full trigger text, newlines flattened to spaces. |
model: Option<AgentModel> | model | The serde rename string, verbatim -- e.g. claude-fable-5. Writes validated against the same four IDs. |
tools: Vec<AgentTool> | tools_json | JSON array of variant names, e.g. ["Bash","Read"]. The API returns it parsed as tools. |
max_turns: Option<u32> | max_turns | Nullable INTEGER, mirroring the Option. |
system_prompt | not stored | Deliberate. Prompts live in the generated YAML; source_yaml points at the file (e.g. .claude/agents/cargo-check.yaml). This site catalogs the delegation surface, not the full prompt. |
| — | id, generated_by, source_site, created_at | Provenance columns, same discipline as every primitive in this family. generated_by defaults to cargo run -p agent-gen because that is literally what produced these definitions. |
Same generalization move as the rest of the family: subagenttasks.com mapped the real TaskCreate/TaskUpdate/TaskList tool schema 1:1; subagentcitations.com mapped the real Citations API response schema 1:1; this site maps a real Rust struct that already governs how this repo's agents behave. Nothing invented, one field honestly omitted, everything else column-for-field.
See it live: the board · the JSON API.