( pluginsToInstall: string[], onProgress?: (name: string, index: number, total: number) => void, scope: InstallableScope = 'user', )
| 270 | * @returns Installation results with succeeded and failed plugins |
| 271 | */ |
| 272 | export async function installSelectedPlugins( |
| 273 | pluginsToInstall: string[], |
| 274 | onProgress?: (name: string, index: number, total: number) => void, |
| 275 | scope: InstallableScope = 'user', |
| 276 | ): Promise<PluginInstallResult> { |
| 277 | // Get projectPath for non-user scopes |
| 278 | const projectPath = scope !== 'user' ? getCwd() : undefined |
| 279 | |
| 280 | // Get the correct settings source for this scope |
| 281 | const settingSource = scopeToSettingSource(scope) |
| 282 | const settings = getSettingsForSource(settingSource) |
| 283 | const updatedEnabledPlugins = { ...settings?.enabledPlugins } |
| 284 | const installed: string[] = [] |
| 285 | const failed: Array<{ name: string; error: string }> = [] |
| 286 | |
| 287 | for (let i = 0; i < pluginsToInstall.length; i++) { |
| 288 | const pluginId = pluginsToInstall[i] |
| 289 | if (!pluginId) continue |
| 290 | |
| 291 | if (onProgress) { |
| 292 | onProgress(pluginId, i + 1, pluginsToInstall.length) |
| 293 | } |
| 294 | |
| 295 | try { |
| 296 | const pluginInfo = await getPluginById(pluginId) |
| 297 | if (!pluginInfo) { |
| 298 | failed.push({ |
| 299 | name: pluginId, |
| 300 | error: 'Plugin not found in any marketplace', |
| 301 | }) |
| 302 | continue |
| 303 | } |
| 304 | |
| 305 | // Cache the plugin if it's from an external source |
| 306 | const { entry, marketplaceInstallLocation } = pluginInfo |
| 307 | if (!isLocalPluginSource(entry.source)) { |
| 308 | // External plugin - cache and register it with scope |
| 309 | await cacheAndRegisterPlugin(pluginId, entry, scope, projectPath) |
| 310 | } else { |
| 311 | // Local plugin - just register it with the install path and scope |
| 312 | registerPluginInstallation( |
| 313 | { |
| 314 | pluginId, |
| 315 | installPath: join(marketplaceInstallLocation, entry.source), |
| 316 | version: entry.version, |
| 317 | }, |
| 318 | scope, |
| 319 | projectPath, |
| 320 | ) |
| 321 | } |
| 322 | |
| 323 | // Mark as enabled in settings |
| 324 | updatedEnabledPlugins[pluginId] = true |
| 325 | installed.push(pluginId) |
| 326 | } catch (error) { |
| 327 | const errorMessage = |
| 328 | error instanceof Error ? error.message : String(error) |
| 329 | failed.push({ name: pluginId, error: errorMessage }) |
nothing calls this directly
no test coverage detected