fix(coding-agent): respect plugin scope and handle multiple registry entries

- P1: Use root.scope instead of hardcoded 'user' level in claude-plugins provider
- P2: Iterate all registry entries per plugin ID, not just first one
- P3: Add home parameter to discoverAgents() for test isolation
- P4: Add test coverage for claude-plugins discovery (12 tests)
- P5: Cache listClaudePluginRoots results to avoid repeated parsing

Addresses issues found in adversarial review of PR #49
This commit is contained in:
kylesnowschwartz
2026-02-13 11:11:05 +13:00
parent 842bf84a2b
commit 7a6b42353e
4 changed files with 346 additions and 27 deletions
+3 -3
View File
@@ -55,7 +55,7 @@ async function loadAgentsFromDir(dir: string, source: AgentSource): Promise<Agen
*
* @param cwd - Current working directory for project agent discovery
*/
export async function discoverAgents(cwd: string): Promise<DiscoveryResult> {
export async function discoverAgents(cwd: string, home: string = os.homedir()): Promise<DiscoveryResult> {
const resolvedCwd = path.resolve(cwd);
const agentSources = Array.from(new Set(getConfigDirs("", { project: false }).map(entry => entry.source)));
@@ -88,10 +88,10 @@ export async function discoverAgents(cwd: string): Promise<DiscoveryResult> {
}
// Load agents from Claude Code marketplace plugins
const { roots: pluginRoots } = await listClaudePluginRoots(os.homedir());
const { roots: pluginRoots } = await listClaudePluginRoots(home);
for (const plugin of pluginRoots) {
const agentsDir = path.join(plugin.path, "agents");
orderedDirs.push({ dir: agentsDir, source: "user" });
orderedDirs.push({ dir: agentsDir, source: plugin.scope === "project" ? "project" : "user" });
}
const seen = new Set<string>();