( pluginId: string, metadata: InstalledPlugin, scope: PersistableScope = 'user', projectPath?: string, )
| 872 | * @param projectPath - Project path (for project/local scopes) |
| 873 | */ |
| 874 | export function addInstalledPlugin( |
| 875 | pluginId: string, |
| 876 | metadata: InstalledPlugin, |
| 877 | scope: PersistableScope = 'user', |
| 878 | projectPath?: string, |
| 879 | ): void { |
| 880 | const v2Data = loadInstalledPluginsFromDisk() |
| 881 | const v2Entry: PluginInstallationEntry = { |
| 882 | scope, |
| 883 | installPath: metadata.installPath, |
| 884 | version: metadata.version, |
| 885 | installedAt: metadata.installedAt, |
| 886 | lastUpdated: metadata.lastUpdated, |
| 887 | gitCommitSha: metadata.gitCommitSha, |
| 888 | ...(projectPath && { projectPath }), |
| 889 | } |
| 890 | |
| 891 | // Get or create array for this plugin (preserves other scope installations) |
| 892 | const installations = v2Data.plugins[pluginId] || [] |
| 893 | |
| 894 | // Find existing entry for this scope+projectPath |
| 895 | const existingIndex = installations.findIndex( |
| 896 | entry => entry.scope === scope && entry.projectPath === projectPath, |
| 897 | ) |
| 898 | |
| 899 | const isUpdate = existingIndex >= 0 |
| 900 | if (isUpdate) { |
| 901 | installations[existingIndex] = v2Entry |
| 902 | } else { |
| 903 | installations.push(v2Entry) |
| 904 | } |
| 905 | |
| 906 | v2Data.plugins[pluginId] = installations |
| 907 | saveInstalledPluginsV2(v2Data) |
| 908 | |
| 909 | logForDebugging( |
| 910 | `${isUpdate ? 'Updated' : 'Added'} installed plugin: ${pluginId} (scope: ${scope})`, |
| 911 | ) |
| 912 | } |
| 913 | |
| 914 | /** |
| 915 | * Remove a plugin from the installed plugins registry |
no test coverage detected