Files
oh-my-pi/packages/coding-agent/src/discovery/plugin-dir-roots.ts
T
Miroslav Drbal 4e199f93f7 feat: add marketplace plugin system
Add Claude Code-compatible marketplace plugin infrastructure:

- Registry: types, ID helpers, atomic read/write for marketplaces.json
  and installed_plugins.json (Claude Code format with version: 2)
- Fetcher: classifySource (6 ordered rules), parseMarketplaceCatalog,
  fetchMarketplace (local sources; git/http stubs for Phase 2)
- Resolver + Cache: resolvePluginSource with pathIsWithin containment,
  cachePlugin, removeCachedPlugin, cleanOrphanedCache
- MarketplaceManager: orchestrates add/remove/update marketplaces,
  install/uninstall/enable plugins, clearPluginRootsCache on mutation
- CLI: omp plugin marketplace add|remove|update|list,
  omp plugin discover, classifyInstallTarget for name@marketplace
- Discovery: listClaudePluginRoots reads OMP registry alongside
  Claude's, OMP authoritative for duplicate plugin IDs
- Args: --plugin-dir repeatable flag (parsing only, runtime wiring TBD)
- Slash command: /reload-plugins clears fs + roots cache
- Test fixtures and 130 tests across 8 test files
2026-03-30 13:44:53 +02:00

29 lines
819 B
TypeScript

import * as path from "node:path";
/** Synthetic plugin root for a --plugin-dir path. Shape-compatible with ClaudePluginRoot. */
export interface PluginDirRoot {
id: string;
marketplace: string;
plugin: string;
version: string;
path: string;
scope: "user" | "project";
}
/**
* Build a synthetic plugin root from a --plugin-dir resolved path.
* @param resolvedPath Absolute path to the plugin directory
* @param manifestName Plugin name from manifest; falls back to directory basename
*/
export function buildPluginDirRoot(resolvedPath: string, manifestName?: string): PluginDirRoot {
const pluginName = manifestName || path.basename(resolvedPath);
return {
id: `${pluginName}@__local__`,
marketplace: "__local__",
plugin: pluginName,
version: "local",
path: resolvedPath,
scope: "user",
};
}