/** * agent-list.ts — Rich agent list with source grouping and override indicators. * * Displays agents grouped by source (built-in, project, personal) * with model resolution, source indicators, and disabled state markers. */ import type { ExtensionCommandContext } from "@mariozechner/pi-coding-agent"; import { getAgentConfig, getAllTypes } from "../agent-types.js"; import { getModelLabel } from "../model-resolver.js"; /** * Show the rich agent list grouped by source. * User selects an agent → calls the detail callback. * * @param ctx Extension command context * @param onSelect Callback when user selects an agent (receives name) */ export async function showAgentList( ctx: ExtensionCommandContext, onSelect: (name: string) => Promise, ): Promise { const allNames = getAllTypes(); if (allNames.length === 0) { ctx.ui.notify("No agents found.", "info"); return; } // Categorize agents by source const builtins: string[] = []; const project: string[] = []; const personal: string[] = []; const disabled: string[] = []; for (const name of allNames) { const cfg = getAgentConfig(name); if (!cfg) continue; const isDisabled = cfg.enabled === false; if (isDisabled) { disabled.push(name); } else if (cfg.source === "project") { project.push(name); } else if (cfg.source === "global") { personal.push(name); } else { builtins.push(name); } } // Build grouped options const options: string[] = []; const nameMap = new Map(); // display label → agent name const addGroup = (label: string, names: string[], indicator: string) => { if (names.length === 0) return; options.push(`─── ${label} ───`); for (const name of names.sort()) { const cfg = getAgentConfig(name); const model = getModelLabel(cfg?.model ?? "inherit"); const display = `${indicator} ${name} · ${model}`; options.push(` ${display}`); nameMap.set(` ${display}`, name); } }; addGroup("Built-in", builtins, ""); addGroup("Project (.pi/agents/)", project, "•"); addGroup("Personal (~/.pi/agent/agents/)", personal, "◦"); // Disabled group at the end if (disabled.length > 0) { options.push("─── Disabled ───"); for (const name of disabled.sort()) { options.push(` ✕ ${name} (disabled)`); nameMap.set(` ✕ ${name} (disabled)`, name); } } const choice = await ctx.ui.select("Agent types", options); if (!choice) return; const agentName = nameMap.get(choice); if (agentName) { await onSelect(agentName); } }