MCPcopy Index your code
hub / github.com/codeaashu/claude-code / createPluginFromPath

Function createPluginFromPath

src/utils/plugins/pluginLoader.ts:1348–1770  ·  view source on GitHub ↗
(
  pluginPath: string,
  source: string,
  enabled: boolean,
  fallbackName: string,
  strict = true,
)

Source from the content-addressed store, hash-verified

1346 * @returns Object containing the LoadedPlugin and any errors encountered
1347 */
1348export async function createPluginFromPath(
1349 pluginPath: string,
1350 source: string,
1351 enabled: boolean,
1352 fallbackName: string,
1353 strict = true,
1354): Promise<{ plugin: LoadedPlugin; errors: PluginError[] }> {
1355 const errors: PluginError[] = []
1356
1357 // Step 1: Load or create the plugin manifest
1358 // This provides metadata about the plugin (name, version, etc.)
1359 const manifestPath = join(pluginPath, '.claude-plugin', 'plugin.json')
1360 const manifest = await loadPluginManifest(manifestPath, fallbackName, source)
1361
1362 // Step 2: Create the base plugin object
1363 // Start with required fields from manifest and parameters
1364 const plugin: LoadedPlugin = {
1365 name: manifest.name, // Use name from manifest (or fallback)
1366 manifest, // Store full manifest for later use
1367 path: pluginPath, // Absolute path to plugin directory
1368 source, // Source identifier (e.g., "git:repo" or ".claude-plugin/name")
1369 repository: source, // For backward compatibility with Plugin Repository
1370 enabled, // Current enabled state
1371 }
1372
1373 // Step 3: Auto-detect optional directories in parallel
1374 const [
1375 commandsDirExists,
1376 agentsDirExists,
1377 skillsDirExists,
1378 outputStylesDirExists,
1379 ] = await Promise.all([
1380 !manifest.commands ? pathExists(join(pluginPath, 'commands')) : false,
1381 !manifest.agents ? pathExists(join(pluginPath, 'agents')) : false,
1382 !manifest.skills ? pathExists(join(pluginPath, 'skills')) : false,
1383 !manifest.outputStyles
1384 ? pathExists(join(pluginPath, 'output-styles'))
1385 : false,
1386 ])
1387
1388 const commandsPath = join(pluginPath, 'commands')
1389 if (commandsDirExists) {
1390 plugin.commandsPath = commandsPath
1391 }
1392
1393 // Step 3a: Process additional command paths from manifest
1394 if (manifest.commands) {
1395 // Check if it's an object mapping (record of command name → metadata)
1396 const firstValue = Object.values(manifest.commands)[0]
1397 if (
1398 typeof manifest.commands === 'object' &&
1399 !Array.isArray(manifest.commands) &&
1400 firstValue &&
1401 typeof firstValue === 'object' &&
1402 ('source' in firstValue || 'content' in firstValue)
1403 ) {
1404 // Object mapping format: { "about": { "source": "./README.md", ... } }
1405 const commandsMetadata: Record<string, CommandMetadata> = {}

Callers 2

loadSessionOnlyPluginsFunction · 0.85

Calls 15

loadPluginManifestFunction · 0.85
pathExistsFunction · 0.85
logForDebuggingFunction · 0.85
validatePluginPathsFunction · 0.85
loadPluginHooksFunction · 0.85
toErrorFunction · 0.85
mergeHooksSettingsFunction · 0.85
loadPluginSettingsFunction · 0.85
valuesMethod · 0.80
entriesMethod · 0.80
keysMethod · 0.80
logErrorFunction · 0.50

Tested by

no test coverage detected