@@ -2,8 +2,8 @@ import { rm } from 'node:fs/promises';
22import { join } from 'node:path' ;
33import { z } from 'zod' ;
44import { getConfigPath , getNotInitializedMessage , loadPluginsConfig } from '../config/loader' ;
5- import { DIR_CURSOR , DIR_MARKETPLACE , FILE_AIPM_CONFIG , FILE_AIPM_CONFIG_LOCAL } from '../constants' ;
6- import { saveConfig } from '../helpers/aipm-config' ;
5+ import { DIR_AIPM_NAMESPACE , DIR_CURSOR , FILE_AIPM_CONFIG , FILE_AIPM_CONFIG_LOCAL , PLUGIN_SUBDIRS } from '../constants' ;
6+ import { loadTargetConfig , saveConfig } from '../helpers/aipm-config' ;
77import { fileExists } from '../helpers/fs' ;
88import { defaultIO } from '../helpers/io' ;
99
@@ -29,38 +29,54 @@ export async function pluginUninstall(options: unknown): Promise<void> {
2929 throw error ;
3030 }
3131 const configName = cmd . local ? getConfigPath ( FILE_AIPM_CONFIG_LOCAL ) : getConfigPath ( FILE_AIPM_CONFIG ) ;
32+ const targetConfig = await loadTargetConfig ( cwd , cmd . local ) ;
3233
33- if ( ! config . plugins [ cmd . pluginId ] ) {
34+ if ( ! targetConfig . plugins [ cmd . pluginId ] ) {
35+ if ( config . plugins [ cmd . pluginId ] ) {
36+ const error = new Error (
37+ `Plugin '${ cmd . pluginId } ' is not in ${ configName } (exists in merged config from another source)` ,
38+ ) ;
39+ defaultIO . logError ( error . message ) ;
40+ throw error ;
41+ }
3442 const error = new Error ( `Plugin '${ cmd . pluginId } ' is not installed` ) ;
3543 defaultIO . logError ( error . message ) ;
3644 throw error ;
3745 }
3846
39- const { [ cmd . pluginId ] : _removed , ...remainingPlugins } = config . plugins ;
40-
41- const updatedConfig = {
42- ...config ,
43- plugins : remainingPlugins ,
44- } ;
45-
4647 if ( cmd . dryRun ) {
4748 defaultIO . logInfo ( `[DRY RUN] Would remove plugin '${ cmd . pluginId } ' from ${ configName } ` ) ;
4849 if ( cmd . removeFiles ) {
49- defaultIO . logInfo ( '[DRY RUN] Would delete files from .cursor/marketplace /' ) ;
50+ defaultIO . logInfo ( '[DRY RUN] Would delete plugin files from .cursor/' ) ;
5051 }
5152 } else {
53+ const { [ cmd . pluginId ] : _removed , ...remainingPlugins } = targetConfig . plugins ;
54+
55+ const updatedConfig = {
56+ ...targetConfig ,
57+ plugins : remainingPlugins ,
58+ } ;
59+
5260 await saveConfig ( cwd , updatedConfig , cmd . local ) ;
5361 defaultIO . logSuccess ( `Removed plugin '${ cmd . pluginId } ' from ${ configName } ` ) ;
5462
5563 if ( cmd . removeFiles ) {
5664 const [ pluginName , marketplaceName ] = cmd . pluginId . split ( '@' ) ;
5765
5866 if ( pluginName && marketplaceName ) {
59- const installedPath = join ( cwd , DIR_CURSOR , DIR_MARKETPLACE , marketplaceName , pluginName ) ;
67+ let deletedCount = 0 ;
68+
69+ for ( const subdir of PLUGIN_SUBDIRS ) {
70+ const installedPath = join ( cwd , DIR_CURSOR , subdir , DIR_AIPM_NAMESPACE , marketplaceName , pluginName ) ;
71+
72+ if ( await fileExists ( installedPath ) ) {
73+ await rm ( installedPath , { recursive : true , force : true } ) ;
74+ deletedCount ++ ;
75+ }
76+ }
6077
61- if ( await fileExists ( installedPath ) ) {
62- await rm ( installedPath , { recursive : true , force : true } ) ;
63- defaultIO . logSuccess ( `Deleted plugin files from .cursor/marketplace/${ marketplaceName } /${ pluginName } ` ) ;
78+ if ( deletedCount > 0 ) {
79+ defaultIO . logSuccess ( `Deleted plugin files from ${ deletedCount } location(s) in .cursor/` ) ;
6480 }
6581 }
6682 }
0 commit comments