wave-agent-sdk 0.17.4 → 0.17.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/services/MarketplaceService.d.ts +15 -0
- package/dist/services/MarketplaceService.d.ts.map +1 -1
- package/dist/services/MarketplaceService.js +83 -2
- package/dist/types/marketplace.d.ts +1 -0
- package/dist/types/marketplace.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/services/MarketplaceService.ts +130 -2
- package/src/types/marketplace.ts +1 -0
|
@@ -33,6 +33,15 @@ export declare class MarketplaceService {
|
|
|
33
33
|
* to user-level settings if they aren't already declared there.
|
|
34
34
|
*/
|
|
35
35
|
private runMigration;
|
|
36
|
+
/**
|
|
37
|
+
* Seeds the builtin marketplace on first startup.
|
|
38
|
+
* Adds it to user-scope settings and marks the cache as seeded.
|
|
39
|
+
*/
|
|
40
|
+
private seedBuiltinMarketplace;
|
|
41
|
+
/**
|
|
42
|
+
* Sets the builtinSeeded flag in the cache registry, preserving all other fields.
|
|
43
|
+
*/
|
|
44
|
+
private setBuiltinSeeded;
|
|
36
45
|
/**
|
|
37
46
|
* Check if a lock file is stale by reading its PID and checking if the process is alive.
|
|
38
47
|
* Returns true if the lock is stale and safe to remove.
|
|
@@ -97,6 +106,12 @@ export declare class MarketplaceService {
|
|
|
97
106
|
* Removes a marketplace by name from the specified scope
|
|
98
107
|
*/
|
|
99
108
|
removeMarketplace(name: string, scope?: Scope): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* Uninstalls all plugins belonging to a given marketplace.
|
|
111
|
+
* Removes them from installed_plugins.json, deletes cache files,
|
|
112
|
+
* and cleans up enabledPlugins entries from all scopes.
|
|
113
|
+
*/
|
|
114
|
+
private uninstallPluginsByMarketplace;
|
|
100
115
|
/**
|
|
101
116
|
* Updates a specific marketplace or all marketplaces
|
|
102
117
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarketplaceService.d.ts","sourceRoot":"","sources":["../../src/services/MarketplaceService.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,gBAAgB,EAChB,yBAAyB,EACzB,eAAe,EACf,wBAAwB,EACxB,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAqB,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAG1E;;;;;;;;GAQG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAS;IACzC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,qBAAqB,CAAS;IACtC,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAOzC;gBAGA,OAAO,GAAE,MAAsB,EAC/B,oBAAoB,GAAE,oBAAiD;
|
|
1
|
+
{"version":3,"file":"MarketplaceService.d.ts","sourceRoot":"","sources":["../../src/services/MarketplaceService.ts"],"names":[],"mappings":"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"}
|
|
@@ -28,6 +28,9 @@ export class MarketplaceService {
|
|
|
28
28
|
this.gitService = new GitService();
|
|
29
29
|
this.ensureDirectoryStructure();
|
|
30
30
|
this.runMigration();
|
|
31
|
+
// Stored dynamically to avoid widening keyof MarketplaceService
|
|
32
|
+
this._seedComplete =
|
|
33
|
+
this.seedBuiltinMarketplace();
|
|
31
34
|
}
|
|
32
35
|
/**
|
|
33
36
|
* Ensures the required directory structure exists in ~/.wave/plugins
|
|
@@ -65,6 +68,46 @@ export class MarketplaceService {
|
|
|
65
68
|
// Migration failure should not block startup
|
|
66
69
|
}
|
|
67
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Seeds the builtin marketplace on first startup.
|
|
73
|
+
* Adds it to user-scope settings and marks the cache as seeded.
|
|
74
|
+
*/
|
|
75
|
+
async seedBuiltinMarketplace() {
|
|
76
|
+
try {
|
|
77
|
+
const cache = await this.getCacheRegistry();
|
|
78
|
+
if (cache?.builtinSeeded)
|
|
79
|
+
return;
|
|
80
|
+
const builtin = MarketplaceService.BUILTIN_MARKETPLACE;
|
|
81
|
+
// Add to user-scope settings if not already in any scope
|
|
82
|
+
const scoped = this.configurationService.getMergedMarketplaces(this.workdir);
|
|
83
|
+
if (!scoped[builtin.name]) {
|
|
84
|
+
await this.configurationService.addMarketplaceToScope(this.workdir, "user", builtin.name, { source: builtin.source, autoUpdate: builtin.autoUpdate });
|
|
85
|
+
}
|
|
86
|
+
// Update cache: add entry + set builtinSeeded flag
|
|
87
|
+
await this.updateCacheMarketplace(builtin.name, {
|
|
88
|
+
source: builtin.source,
|
|
89
|
+
autoUpdate: builtin.autoUpdate,
|
|
90
|
+
isBuiltin: true,
|
|
91
|
+
declaredScope: "builtin",
|
|
92
|
+
});
|
|
93
|
+
await this.setBuiltinSeeded(true);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// Seeding failure should not block startup
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Sets the builtinSeeded flag in the cache registry, preserving all other fields.
|
|
101
|
+
*/
|
|
102
|
+
async setBuiltinSeeded(value) {
|
|
103
|
+
const registry = await this.getCacheRegistry();
|
|
104
|
+
const tmpPath = `${this.knownMarketplacesPath}.tmp`;
|
|
105
|
+
await fs.writeFile(tmpPath, JSON.stringify({
|
|
106
|
+
builtinSeeded: value,
|
|
107
|
+
marketplaces: registry?.marketplaces ?? [],
|
|
108
|
+
}, null, 2));
|
|
109
|
+
await fs.rename(tmpPath, this.knownMarketplacesPath);
|
|
110
|
+
}
|
|
68
111
|
/**
|
|
69
112
|
* Check if a lock file is stale by reading its PID and checking if the process is alive.
|
|
70
113
|
* Returns true if the lock is stale and safe to remove.
|
|
@@ -192,7 +235,10 @@ export class MarketplaceService {
|
|
|
192
235
|
});
|
|
193
236
|
}
|
|
194
237
|
const tmpPath = `${this.knownMarketplacesPath}.tmp`;
|
|
195
|
-
await fs.writeFile(tmpPath, JSON.stringify({
|
|
238
|
+
await fs.writeFile(tmpPath, JSON.stringify({
|
|
239
|
+
builtinSeeded: registry?.builtinSeeded ?? false,
|
|
240
|
+
marketplaces,
|
|
241
|
+
}, null, 2));
|
|
196
242
|
await fs.rename(tmpPath, this.knownMarketplacesPath);
|
|
197
243
|
}
|
|
198
244
|
/**
|
|
@@ -203,7 +249,10 @@ export class MarketplaceService {
|
|
|
203
249
|
const marketplaces = registry?.marketplaces ?? [];
|
|
204
250
|
const filtered = marketplaces.filter((m) => m.name !== name);
|
|
205
251
|
const tmpPath = `${this.knownMarketplacesPath}.tmp`;
|
|
206
|
-
await fs.writeFile(tmpPath, JSON.stringify({
|
|
252
|
+
await fs.writeFile(tmpPath, JSON.stringify({
|
|
253
|
+
builtinSeeded: registry?.builtinSeeded ?? false,
|
|
254
|
+
marketplaces: filtered,
|
|
255
|
+
}, null, 2));
|
|
207
256
|
await fs.rename(tmpPath, this.knownMarketplacesPath);
|
|
208
257
|
}
|
|
209
258
|
/**
|
|
@@ -402,6 +451,8 @@ export class MarketplaceService {
|
|
|
402
451
|
async removeMarketplace(name, scope) {
|
|
403
452
|
return this.withLock(async () => {
|
|
404
453
|
const targetScope = scope || this.getMarketplaceDeclaringSource(name) || "user";
|
|
454
|
+
// Uninstall all plugins from this marketplace
|
|
455
|
+
await this.uninstallPluginsByMarketplace(name);
|
|
405
456
|
if (targetScope !== "builtin") {
|
|
406
457
|
await this.configurationService.removeMarketplaceFromScope(this.workdir, targetScope, name);
|
|
407
458
|
}
|
|
@@ -409,6 +460,36 @@ export class MarketplaceService {
|
|
|
409
460
|
await this.removeFromCache(name);
|
|
410
461
|
});
|
|
411
462
|
}
|
|
463
|
+
/**
|
|
464
|
+
* Uninstalls all plugins belonging to a given marketplace.
|
|
465
|
+
* Removes them from installed_plugins.json, deletes cache files,
|
|
466
|
+
* and cleans up enabledPlugins entries from all scopes.
|
|
467
|
+
*/
|
|
468
|
+
async uninstallPluginsByMarketplace(marketplaceName) {
|
|
469
|
+
const installedRegistry = await this.getInstalledPlugins();
|
|
470
|
+
const pluginsFromMarketplace = installedRegistry.plugins.filter((p) => p.marketplace === marketplaceName);
|
|
471
|
+
if (pluginsFromMarketplace.length === 0)
|
|
472
|
+
return;
|
|
473
|
+
// Remove all plugins from this marketplace from the registry
|
|
474
|
+
installedRegistry.plugins = installedRegistry.plugins.filter((p) => p.marketplace !== marketplaceName);
|
|
475
|
+
await this.saveInstalledPlugins(installedRegistry);
|
|
476
|
+
// Delete cache files that are no longer referenced
|
|
477
|
+
const remainingCachePaths = new Set(installedRegistry.plugins.map((p) => p.cachePath));
|
|
478
|
+
for (const plugin of pluginsFromMarketplace) {
|
|
479
|
+
if (!remainingCachePaths.has(plugin.cachePath) &&
|
|
480
|
+
existsSync(plugin.cachePath)) {
|
|
481
|
+
await fs.rm(plugin.cachePath, { recursive: true, force: true });
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
// Remove enabledPlugins entries from all scopes
|
|
485
|
+
const scopes = ["user", "project", "local"];
|
|
486
|
+
for (const plugin of pluginsFromMarketplace) {
|
|
487
|
+
const pluginId = `${plugin.name}@${plugin.marketplace}`;
|
|
488
|
+
for (const s of scopes) {
|
|
489
|
+
await this.configurationService.removeEnabledPlugin(this.workdir, s, pluginId);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
412
493
|
/**
|
|
413
494
|
* Updates a specific marketplace or all marketplaces
|
|
414
495
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"marketplace.d.ts","sourceRoot":"","sources":["../../src/types/marketplace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,uBAAwB,SAAQ,sBAAsB;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,sBAAsB,EAAE,CAAC;CACnC;AAED,MAAM,MAAM,iBAAiB,GACzB;IACE,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,MAAM,EAAE,QAAQ,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GACD;IACE,MAAM,EAAE,KAAK,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEN,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;CAC1D;AAED,MAAM,WAAW,yBAAyB;IACxC,YAAY,EAAE,gBAAgB,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B"}
|
|
1
|
+
{"version":3,"file":"marketplace.d.ts","sourceRoot":"","sources":["../../src/types/marketplace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,uBAAwB,SAAQ,sBAAsB;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,sBAAsB,EAAE,CAAC;CACnC;AAED,MAAM,MAAM,iBAAiB,GACzB;IACE,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,MAAM,EAAE,QAAQ,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GACD;IACE,MAAM,EAAE,KAAK,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEN,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;CAC1D;AAED,MAAM,WAAW,yBAAyB;IACxC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,gBAAgB,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B"}
|
package/package.json
CHANGED
|
@@ -68,6 +68,9 @@ export class MarketplaceService {
|
|
|
68
68
|
|
|
69
69
|
this.ensureDirectoryStructure();
|
|
70
70
|
this.runMigration();
|
|
71
|
+
// Stored dynamically to avoid widening keyof MarketplaceService
|
|
72
|
+
(this as Record<string, unknown>)._seedComplete =
|
|
73
|
+
this.seedBuiltinMarketplace();
|
|
71
74
|
}
|
|
72
75
|
|
|
73
76
|
/**
|
|
@@ -121,6 +124,63 @@ export class MarketplaceService {
|
|
|
121
124
|
}
|
|
122
125
|
}
|
|
123
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Seeds the builtin marketplace on first startup.
|
|
129
|
+
* Adds it to user-scope settings and marks the cache as seeded.
|
|
130
|
+
*/
|
|
131
|
+
private async seedBuiltinMarketplace(): Promise<void> {
|
|
132
|
+
try {
|
|
133
|
+
const cache = await this.getCacheRegistry();
|
|
134
|
+
if (cache?.builtinSeeded) return;
|
|
135
|
+
|
|
136
|
+
const builtin = MarketplaceService.BUILTIN_MARKETPLACE;
|
|
137
|
+
|
|
138
|
+
// Add to user-scope settings if not already in any scope
|
|
139
|
+
const scoped = this.configurationService.getMergedMarketplaces(
|
|
140
|
+
this.workdir,
|
|
141
|
+
);
|
|
142
|
+
if (!scoped[builtin.name]) {
|
|
143
|
+
await this.configurationService.addMarketplaceToScope(
|
|
144
|
+
this.workdir,
|
|
145
|
+
"user",
|
|
146
|
+
builtin.name,
|
|
147
|
+
{ source: builtin.source, autoUpdate: builtin.autoUpdate },
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Update cache: add entry + set builtinSeeded flag
|
|
152
|
+
await this.updateCacheMarketplace(builtin.name, {
|
|
153
|
+
source: builtin.source,
|
|
154
|
+
autoUpdate: builtin.autoUpdate,
|
|
155
|
+
isBuiltin: true,
|
|
156
|
+
declaredScope: "builtin",
|
|
157
|
+
});
|
|
158
|
+
await this.setBuiltinSeeded(true);
|
|
159
|
+
} catch {
|
|
160
|
+
// Seeding failure should not block startup
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Sets the builtinSeeded flag in the cache registry, preserving all other fields.
|
|
166
|
+
*/
|
|
167
|
+
private async setBuiltinSeeded(value: boolean): Promise<void> {
|
|
168
|
+
const registry = await this.getCacheRegistry();
|
|
169
|
+
const tmpPath = `${this.knownMarketplacesPath}.tmp`;
|
|
170
|
+
await fs.writeFile(
|
|
171
|
+
tmpPath,
|
|
172
|
+
JSON.stringify(
|
|
173
|
+
{
|
|
174
|
+
builtinSeeded: value,
|
|
175
|
+
marketplaces: registry?.marketplaces ?? [],
|
|
176
|
+
},
|
|
177
|
+
null,
|
|
178
|
+
2,
|
|
179
|
+
),
|
|
180
|
+
);
|
|
181
|
+
await fs.rename(tmpPath, this.knownMarketplacesPath);
|
|
182
|
+
}
|
|
183
|
+
|
|
124
184
|
/**
|
|
125
185
|
* Check if a lock file is stale by reading its PID and checking if the process is alive.
|
|
126
186
|
* Returns true if the lock is stale and safe to remove.
|
|
@@ -258,7 +318,17 @@ export class MarketplaceService {
|
|
|
258
318
|
});
|
|
259
319
|
}
|
|
260
320
|
const tmpPath = `${this.knownMarketplacesPath}.tmp`;
|
|
261
|
-
await fs.writeFile(
|
|
321
|
+
await fs.writeFile(
|
|
322
|
+
tmpPath,
|
|
323
|
+
JSON.stringify(
|
|
324
|
+
{
|
|
325
|
+
builtinSeeded: registry?.builtinSeeded ?? false,
|
|
326
|
+
marketplaces,
|
|
327
|
+
},
|
|
328
|
+
null,
|
|
329
|
+
2,
|
|
330
|
+
),
|
|
331
|
+
);
|
|
262
332
|
await fs.rename(tmpPath, this.knownMarketplacesPath);
|
|
263
333
|
}
|
|
264
334
|
|
|
@@ -272,7 +342,14 @@ export class MarketplaceService {
|
|
|
272
342
|
const tmpPath = `${this.knownMarketplacesPath}.tmp`;
|
|
273
343
|
await fs.writeFile(
|
|
274
344
|
tmpPath,
|
|
275
|
-
JSON.stringify(
|
|
345
|
+
JSON.stringify(
|
|
346
|
+
{
|
|
347
|
+
builtinSeeded: registry?.builtinSeeded ?? false,
|
|
348
|
+
marketplaces: filtered,
|
|
349
|
+
},
|
|
350
|
+
null,
|
|
351
|
+
2,
|
|
352
|
+
),
|
|
276
353
|
);
|
|
277
354
|
await fs.rename(tmpPath, this.knownMarketplacesPath);
|
|
278
355
|
}
|
|
@@ -536,6 +613,9 @@ export class MarketplaceService {
|
|
|
536
613
|
const targetScope =
|
|
537
614
|
scope || this.getMarketplaceDeclaringSource(name) || "user";
|
|
538
615
|
|
|
616
|
+
// Uninstall all plugins from this marketplace
|
|
617
|
+
await this.uninstallPluginsByMarketplace(name);
|
|
618
|
+
|
|
539
619
|
if (targetScope !== "builtin") {
|
|
540
620
|
await this.configurationService.removeMarketplaceFromScope(
|
|
541
621
|
this.workdir,
|
|
@@ -549,6 +629,54 @@ export class MarketplaceService {
|
|
|
549
629
|
});
|
|
550
630
|
}
|
|
551
631
|
|
|
632
|
+
/**
|
|
633
|
+
* Uninstalls all plugins belonging to a given marketplace.
|
|
634
|
+
* Removes them from installed_plugins.json, deletes cache files,
|
|
635
|
+
* and cleans up enabledPlugins entries from all scopes.
|
|
636
|
+
*/
|
|
637
|
+
private async uninstallPluginsByMarketplace(
|
|
638
|
+
marketplaceName: string,
|
|
639
|
+
): Promise<void> {
|
|
640
|
+
const installedRegistry = await this.getInstalledPlugins();
|
|
641
|
+
const pluginsFromMarketplace = installedRegistry.plugins.filter(
|
|
642
|
+
(p) => p.marketplace === marketplaceName,
|
|
643
|
+
);
|
|
644
|
+
|
|
645
|
+
if (pluginsFromMarketplace.length === 0) return;
|
|
646
|
+
|
|
647
|
+
// Remove all plugins from this marketplace from the registry
|
|
648
|
+
installedRegistry.plugins = installedRegistry.plugins.filter(
|
|
649
|
+
(p) => p.marketplace !== marketplaceName,
|
|
650
|
+
);
|
|
651
|
+
await this.saveInstalledPlugins(installedRegistry);
|
|
652
|
+
|
|
653
|
+
// Delete cache files that are no longer referenced
|
|
654
|
+
const remainingCachePaths = new Set(
|
|
655
|
+
installedRegistry.plugins.map((p) => p.cachePath),
|
|
656
|
+
);
|
|
657
|
+
for (const plugin of pluginsFromMarketplace) {
|
|
658
|
+
if (
|
|
659
|
+
!remainingCachePaths.has(plugin.cachePath) &&
|
|
660
|
+
existsSync(plugin.cachePath)
|
|
661
|
+
) {
|
|
662
|
+
await fs.rm(plugin.cachePath, { recursive: true, force: true });
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
// Remove enabledPlugins entries from all scopes
|
|
667
|
+
const scopes: Scope[] = ["user", "project", "local"];
|
|
668
|
+
for (const plugin of pluginsFromMarketplace) {
|
|
669
|
+
const pluginId = `${plugin.name}@${plugin.marketplace}`;
|
|
670
|
+
for (const s of scopes) {
|
|
671
|
+
await this.configurationService.removeEnabledPlugin(
|
|
672
|
+
this.workdir,
|
|
673
|
+
s,
|
|
674
|
+
pluginId,
|
|
675
|
+
);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
|
|
552
680
|
/**
|
|
553
681
|
* Updates a specific marketplace or all marketplaces
|
|
554
682
|
*/
|