Feature Description
Add support for user-defined named agents, discovered from markdown files, advertised to the LLM through the subagent tool, and with per-agent tool allowlists. Three connected pieces (based on research comparing Kit against opencode's agent system):
1. Named agent definitions in .agents/agents/*.md
Currently every subagent is an ad-hoc prompt via the subagent tool or ctx.SpawnSubagent — there is no registry of reusable agent personas. Following Kit's existing .agents/prompts/ and .agents/skills/ conventions, discover agent definitions from project-local .agents/agents/*.md and a global config dir (e.g. ~/.config/kit/agents/). Filename becomes the agent name; YAML frontmatter configures it; body is the system prompt:
---
description: Reviews code for quality and best practices # required
model: anthropic/claude-sonnet-4
tools: [read, grep, find, ls]
temperature: 0.1
timeout: 300
hidden: false
disabled: false
---
You are in code review mode. Focus on...
A named agent is essentially a preset SubagentConfig, so this composes naturally with the existing Kit.Subagent() machinery (pkg/kit/kit.go).
2. Advertise named agents in the subagent tool description
The subagent tool description (internal/core/subagent.go) is static, so the LLM has no way to know specialist agents exist. opencode dynamically appends the available subagent list to its task tool description (describeTask in its tool registry):
Available agent types and the tools they have access to:
- explore: Fast agent specialized for exploring codebases...
- general: General-purpose agent for researching complex questions...
Proposed:
- Add an optional
agent field to subagentArgs ({task, agent?, model?, system_prompt?, timeout_seconds?}) that resolves a named agent's model/system prompt/tools/timeout as defaults (explicit args still override).
- Generate the tool description at registration time, listing discovered agents with their
description frontmatter.
- Ship 1–2 built-ins analogous to opencode's
general and explore (read-only research agent).
3. Per-agent tool allowlists
SubagentConfig.Tools already supports explicit tool slices, but there is no declarative way to restrict a reusable agent. Map the tools: frontmatter list to SubagentConfig.Tools so e.g. a read-only explore agent is just tools: [read, grep, find, ls]. Agents without a tools: field get the default SubagentTools() set (all core tools minus subagent, preserving the existing recursion guard from GetToolsForSubagent()).
Motivation / Use Case
Users repeatedly spawn the same kinds of subagents (code reviewer, codebase explorer, test writer) and must re-specify prompts/models/tool sets every time — or bake them into extensions. Named agents make these reusable, shareable via the project repo (.agents/agents/ checked into git), and discoverable by the LLM itself so the main agent can delegate to the right specialist. Tool allowlists make delegation safer (e.g. guarantee an explore agent cannot edit files).
Proposed Implementation
- New
internal/agents/ (or extend internal/core/) package: discovery, frontmatter parsing (YAML), validation, precedence (project overrides global).
internal/core/subagent.go: add agent param; build tool description dynamically from the registry.
pkg/kit/: expose GetAgents() / agent resolution in the SDK following the existing SDK naming rules (no dependency name leakage).
- Follow-on (out of scope here):
/agents list command and @agent-name prompt routing in the TUI.
Checklist
Feature Description
Add support for user-defined named agents, discovered from markdown files, advertised to the LLM through the
subagenttool, and with per-agent tool allowlists. Three connected pieces (based on research comparing Kit against opencode's agent system):1. Named agent definitions in
.agents/agents/*.mdCurrently every subagent is an ad-hoc prompt via the
subagenttool orctx.SpawnSubagent— there is no registry of reusable agent personas. Following Kit's existing.agents/prompts/and.agents/skills/conventions, discover agent definitions from project-local.agents/agents/*.mdand a global config dir (e.g.~/.config/kit/agents/). Filename becomes the agent name; YAML frontmatter configures it; body is the system prompt:A named agent is essentially a preset
SubagentConfig, so this composes naturally with the existingKit.Subagent()machinery (pkg/kit/kit.go).2. Advertise named agents in the subagent tool description
The
subagenttool description (internal/core/subagent.go) is static, so the LLM has no way to know specialist agents exist. opencode dynamically appends the available subagent list to its task tool description (describeTaskin its tool registry):Proposed:
agentfield tosubagentArgs({task, agent?, model?, system_prompt?, timeout_seconds?}) that resolves a named agent's model/system prompt/tools/timeout as defaults (explicit args still override).descriptionfrontmatter.generalandexplore(read-only research agent).3. Per-agent tool allowlists
SubagentConfig.Toolsalready supports explicit tool slices, but there is no declarative way to restrict a reusable agent. Map thetools:frontmatter list toSubagentConfig.Toolsso e.g. a read-onlyexploreagent is justtools: [read, grep, find, ls]. Agents without atools:field get the defaultSubagentTools()set (all core tools minussubagent, preserving the existing recursion guard fromGetToolsForSubagent()).Motivation / Use Case
Users repeatedly spawn the same kinds of subagents (code reviewer, codebase explorer, test writer) and must re-specify prompts/models/tool sets every time — or bake them into extensions. Named agents make these reusable, shareable via the project repo (
.agents/agents/checked into git), and discoverable by the LLM itself so the main agent can delegate to the right specialist. Tool allowlists make delegation safer (e.g. guarantee an explore agent cannot edit files).Proposed Implementation
internal/agents/(or extendinternal/core/) package: discovery, frontmatter parsing (YAML), validation, precedence (project overrides global).internal/core/subagent.go: addagentparam; build tool description dynamically from the registry.pkg/kit/: exposeGetAgents()/ agent resolution in the SDK following the existing SDK naming rules (no dependency name leakage)./agentslist command and@agent-nameprompt routing in the TUI.Checklist