feat(coding-agent): add Claude Code marketplace plugin discovery

Add discovery provider that loads skills, commands, hooks, tools, and
agents from ~/.claude/plugins/cache/ based on installed_plugins.json.

- Add parseClaudePluginsRegistry() and listClaudePluginRoots() helpers
- Create claude-plugins.ts provider with priority 70 (below claude.ts)
- Register provider for skills, slash-commands, hooks, and tools
- Integrate plugin agents into task/discovery.ts

Closes #48
This commit is contained in:
kylesnowschwartz
2026-02-13 10:23:15 +13:00
parent 3dbd6b6f02
commit 842bf84a2b
5 changed files with 326 additions and 0 deletions
@@ -12,9 +12,11 @@
* Agent files use markdown with YAML frontmatter.
*/
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import { logger } from "@oh-my-pi/pi-utils";
import { findAllNearestProjectConfigDirs, getConfigDirs } from "../config";
import { listClaudePluginRoots } from "../discovery/helpers";
import { loadBundledAgents, parseAgent } from "./agents";
import type { AgentDefinition, AgentSource } from "./types";
@@ -85,6 +87,13 @@ export async function discoverAgents(cwd: string): Promise<DiscoveryResult> {
if (user) orderedDirs.push({ dir: user.path, source: "user" });
}
// Load agents from Claude Code marketplace plugins
const { roots: pluginRoots } = await listClaudePluginRoots(os.homedir());
for (const plugin of pluginRoots) {
const agentsDir = path.join(plugin.path, "agents");
orderedDirs.push({ dir: agentsDir, source: "user" });
}
const seen = new Set<string>();
const loadedAgents = (await Promise.all(orderedDirs.map(({ dir, source }) => loadAgentsFromDir(dir, source))))
.flat()