/ src / cli / handlers / agents.ts
agents.ts
 1  /**
 2   * Agents subcommand handler — prints the list of configured agents.
 3   * Dynamically imported only when `claude agents` runs.
 4   */
 5  
 6  import {
 7    AGENT_SOURCE_GROUPS,
 8    compareAgentsByName,
 9    getOverrideSourceLabel,
10    type ResolvedAgent,
11    resolveAgentModelDisplay,
12    resolveAgentOverrides,
13  } from '../../tools/AgentTool/agentDisplay.js'
14  import {
15    getActiveAgentsFromList,
16    getAgentDefinitionsWithOverrides,
17  } from '../../tools/AgentTool/loadAgentsDir.js'
18  import { getCwd } from '../../utils/cwd.js'
19  
20  function formatAgent(agent: ResolvedAgent): string {
21    const model = resolveAgentModelDisplay(agent)
22    const parts = [agent.agentType]
23    if (model) {
24      parts.push(model)
25    }
26    if (agent.memory) {
27      parts.push(`${agent.memory} memory`)
28    }
29    return parts.join(' · ')
30  }
31  
32  export async function agentsHandler(): Promise<void> {
33    const cwd = getCwd()
34    const { allAgents } = await getAgentDefinitionsWithOverrides(cwd)
35    const activeAgents = getActiveAgentsFromList(allAgents)
36    const resolvedAgents = resolveAgentOverrides(allAgents, activeAgents)
37  
38    const lines: string[] = []
39    let totalActive = 0
40  
41    for (const { label, source } of AGENT_SOURCE_GROUPS) {
42      const groupAgents = resolvedAgents
43        .filter(a => a.source === source)
44        .sort(compareAgentsByName)
45  
46      if (groupAgents.length === 0) continue
47  
48      lines.push(`${label}:`)
49      for (const agent of groupAgents) {
50        if (agent.overriddenBy) {
51          const winnerSource = getOverrideSourceLabel(agent.overriddenBy)
52          lines.push(`  (shadowed by ${winnerSource}) ${formatAgent(agent)}`)
53        } else {
54          lines.push(`  ${formatAgent(agent)}`)
55          totalActive++
56        }
57      }
58      lines.push('')
59    }
60  
61    if (lines.length === 0) {
62      // biome-ignore lint/suspicious/noConsole:: intentional console output
63      console.log('No agents found.')
64    } else {
65      // biome-ignore lint/suspicious/noConsole:: intentional console output
66      console.log(`${totalActive} active agents\n`)
67      // biome-ignore lint/suspicious/noConsole:: intentional console output
68      console.log(lines.join('\n').trimEnd())
69    }
70  }