MCPcopy
hub / github.com/claude-code-best/claude-code / mergePluginSources

Function mergePluginSources

src/utils/plugins/pluginLoader.ts:3012–3067  ·  view source on GitHub ↗
(sources: {
  session: LoadedPlugin[]
  marketplace: LoadedPlugin[]
  builtin: LoadedPlugin[]
  managedNames?: Set<string> | null
})

Source from the content-addressed store, hash-verified

3010 * installed plugin.
3011 */
3012export function mergePluginSources(sources: {
3013 session: LoadedPlugin[]
3014 marketplace: LoadedPlugin[]
3015 builtin: LoadedPlugin[]
3016 managedNames?: Set<string> | null
3017}): { plugins: LoadedPlugin[]; errors: PluginError[] } {
3018 const errors: PluginError[] = []
3019 const managed = sources.managedNames
3020
3021 // Managed settings win over --plugin-dir. Drop session plugins whose
3022 // name appears in policySettings.enabledPlugins (whether force-enabled
3023 // OR force-disabled — both are admin intent that --plugin-dir must not
3024 // bypass). Surface an error so the user knows why their dev copy was
3025 // ignored.
3026 //
3027 // NOTE: managedNames contains the pluginId prefix (entry.name), which is
3028 // expected to equal manifest.name by convention (schema description at
3029 // schemas.ts PluginMarketplaceEntry.name). If a marketplace publishes a
3030 // plugin where entry.name ≠ manifest.name, this guard will silently miss —
3031 // but that's a marketplace misconfiguration that breaks other things too
3032 // (e.g., ManagePlugins constructs pluginIds from manifest.name).
3033 const sessionPlugins = sources.session.filter(p => {
3034 if (managed?.has(p.name)) {
3035 logForDebugging(
3036 `Plugin "${p.name}" from --plugin-dir is blocked by managed settings`,
3037 { level: 'warn' },
3038 )
3039 errors.push({
3040 type: 'generic-error',
3041 source: p.source,
3042 plugin: p.name,
3043 error: `--plugin-dir copy of "${p.name}" ignored: plugin is locked by managed settings`,
3044 })
3045 return false
3046 }
3047 return true
3048 })
3049
3050 const sessionNames = new Set(sessionPlugins.map(p => p.name))
3051 const marketplacePlugins = sources.marketplace.filter(p => {
3052 if (sessionNames.has(p.name)) {
3053 logForDebugging(
3054 `Plugin "${p.name}" from --plugin-dir overrides installed version`,
3055 )
3056 return false
3057 }
3058 return true
3059 })
3060 // Session first, then non-overridden marketplace, then builtin.
3061 // Downstream first-match consumers see session plugins before
3062 // installed ones for any that slipped past the name filter.
3063 return {
3064 plugins: [...sessionPlugins, ...marketplacePlugins, ...sources.builtin],
3065 errors,
3066 }
3067}
3068
3069/**

Callers 1

assemblePluginLoadResultFunction · 0.85

Calls 3

logForDebuggingFunction · 0.50
hasMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected