claudeup 4.5.3 → 4.5.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/package.json
CHANGED
package/src/prerunner/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import os from "node:os";
|
|
|
4
4
|
import { UpdateCache } from "../services/update-cache.js";
|
|
5
5
|
import { getAvailablePlugins, clearMarketplaceCache, } from "../services/plugin-manager.js";
|
|
6
6
|
import { runClaude } from "../services/claude-runner.js";
|
|
7
|
-
import { recoverMarketplaceSettings, migrateMarketplaceRename, getGlobalEnabledPlugins, getEnabledPlugins, getLocalEnabledPlugins, readGlobalSettings, writeGlobalSettings, saveGlobalInstalledPluginVersion, } from "../services/claude-settings.js";
|
|
7
|
+
import { recoverMarketplaceSettings, migrateMarketplaceRename, cleanupExtraKnownMarketplaces, getGlobalEnabledPlugins, getEnabledPlugins, getLocalEnabledPlugins, readGlobalSettings, writeGlobalSettings, saveGlobalInstalledPluginVersion, } from "../services/claude-settings.js";
|
|
8
8
|
import { parsePluginId } from "../utils/string-utils.js";
|
|
9
9
|
import { defaultMarketplaces } from "../data/marketplaces.js";
|
|
10
10
|
import { updatePlugin, addMarketplace, updateMarketplace, isClaudeAvailable, } from "../services/claude-cli.js";
|
|
@@ -170,6 +170,17 @@ export async function prerunClaude(claudeArgs, options = {}) {
|
|
|
170
170
|
console.log(`✓ Auto-added marketplace(s): ${addedMarketplaces.join(", ")}`);
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
|
+
// STEP 0.55: Clean up extraKnownMarketplaces entries that are now in known_marketplaces.json
|
|
174
|
+
// extraKnownMarketplaces was the old install mechanism; the official way is known_marketplaces.json
|
|
175
|
+
try {
|
|
176
|
+
const cleaned = await cleanupExtraKnownMarketplaces();
|
|
177
|
+
if (cleaned.length > 0) {
|
|
178
|
+
console.log(`✓ Cleaned up legacy extraKnownMarketplaces: ${cleaned.join(", ")}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
// Non-fatal: cleanup is best-effort
|
|
183
|
+
}
|
|
173
184
|
// STEP 0.6: Ensure tmux-claude-continuity hooks are configured
|
|
174
185
|
const addedHooks = await ensureTmuxContinuityHooks();
|
|
175
186
|
if (addedHooks) {
|
package/src/prerunner/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { runClaude } from "../services/claude-runner.js";
|
|
|
10
10
|
import {
|
|
11
11
|
recoverMarketplaceSettings,
|
|
12
12
|
migrateMarketplaceRename,
|
|
13
|
+
cleanupExtraKnownMarketplaces,
|
|
13
14
|
getGlobalEnabledPlugins,
|
|
14
15
|
getEnabledPlugins,
|
|
15
16
|
getLocalEnabledPlugins,
|
|
@@ -234,6 +235,19 @@ export async function prerunClaude(
|
|
|
234
235
|
}
|
|
235
236
|
}
|
|
236
237
|
|
|
238
|
+
// STEP 0.55: Clean up extraKnownMarketplaces entries that are now in known_marketplaces.json
|
|
239
|
+
// extraKnownMarketplaces was the old install mechanism; the official way is known_marketplaces.json
|
|
240
|
+
try {
|
|
241
|
+
const cleaned = await cleanupExtraKnownMarketplaces();
|
|
242
|
+
if (cleaned.length > 0) {
|
|
243
|
+
console.log(
|
|
244
|
+
`✓ Cleaned up legacy extraKnownMarketplaces: ${cleaned.join(", ")}`,
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
} catch {
|
|
248
|
+
// Non-fatal: cleanup is best-effort
|
|
249
|
+
}
|
|
250
|
+
|
|
237
251
|
// STEP 0.6: Ensure tmux-claude-continuity hooks are configured
|
|
238
252
|
const addedHooks = await ensureTmuxContinuityHooks();
|
|
239
253
|
if (addedHooks) {
|
|
@@ -279,16 +279,48 @@ export async function getEnabledMcpServers(projectPath) {
|
|
|
279
279
|
}
|
|
280
280
|
return enabled;
|
|
281
281
|
}
|
|
282
|
-
// Get all configured marketplaces
|
|
282
|
+
// Get all configured marketplaces — merges known_marketplaces.json (primary) with extraKnownMarketplaces (legacy fallback)
|
|
283
283
|
export async function getConfiguredMarketplaces(projectPath) {
|
|
284
|
+
const result = {};
|
|
285
|
+
// Primary: known_marketplaces.json (official Claude Code registry)
|
|
286
|
+
const known = await readKnownMarketplaces();
|
|
287
|
+
for (const [name, entry] of Object.entries(known)) {
|
|
288
|
+
if (entry.source?.repo) {
|
|
289
|
+
result[name] = {
|
|
290
|
+
source: { source: "github", repo: entry.source.repo },
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
// Fallback: extraKnownMarketplaces (legacy — only adds entries not already in known)
|
|
284
295
|
const settings = await readSettings(projectPath);
|
|
285
|
-
|
|
296
|
+
for (const [name, config] of Object.entries(settings.extraKnownMarketplaces || {})) {
|
|
297
|
+
if (!result[name]) {
|
|
298
|
+
result[name] = config;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return result;
|
|
286
302
|
}
|
|
287
303
|
// Global marketplace management - READ ONLY
|
|
288
304
|
// Marketplaces are managed via Claude Code's native system
|
|
289
305
|
export async function getGlobalConfiguredMarketplaces() {
|
|
306
|
+
const result = {};
|
|
307
|
+
// Primary: known_marketplaces.json
|
|
308
|
+
const known = await readKnownMarketplaces();
|
|
309
|
+
for (const [name, entry] of Object.entries(known)) {
|
|
310
|
+
if (entry.source?.repo) {
|
|
311
|
+
result[name] = {
|
|
312
|
+
source: { source: "github", repo: entry.source.repo },
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
// Fallback: extraKnownMarketplaces
|
|
290
317
|
const settings = await readGlobalSettings();
|
|
291
|
-
|
|
318
|
+
for (const [name, config] of Object.entries(settings.extraKnownMarketplaces || {})) {
|
|
319
|
+
if (!result[name]) {
|
|
320
|
+
result[name] = config;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return result;
|
|
292
324
|
}
|
|
293
325
|
// Global plugin management
|
|
294
326
|
export async function enableGlobalPlugin(pluginId, enabled) {
|
|
@@ -331,13 +363,29 @@ export async function removeGlobalInstalledPluginVersion(pluginId) {
|
|
|
331
363
|
await removeFromInstalledPluginsRegistry(pluginId, "user");
|
|
332
364
|
}
|
|
333
365
|
// Shared logic for discovering marketplaces from settings
|
|
334
|
-
function discoverMarketplacesFromSettings(settings) {
|
|
366
|
+
function discoverMarketplacesFromSettings(settings, knownMarketplaces) {
|
|
335
367
|
const discovered = new Map();
|
|
336
|
-
// 1. From
|
|
368
|
+
// 1. From known_marketplaces.json (official Claude Code registry — primary source)
|
|
369
|
+
if (knownMarketplaces) {
|
|
370
|
+
for (const [name, entry] of Object.entries(knownMarketplaces)) {
|
|
371
|
+
if (entry.source?.repo) {
|
|
372
|
+
discovered.set(name, {
|
|
373
|
+
name,
|
|
374
|
+
source: "configured",
|
|
375
|
+
config: {
|
|
376
|
+
source: { source: "github", repo: entry.source.repo },
|
|
377
|
+
},
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
// 2. From extraKnownMarketplaces (legacy/team fallback — only adds entries not already in known_marketplaces.json)
|
|
337
383
|
for (const [name, config] of Object.entries(settings.extraKnownMarketplaces || {})) {
|
|
338
|
-
discovered.
|
|
384
|
+
if (!discovered.has(name)) {
|
|
385
|
+
discovered.set(name, { name, source: "configured", config });
|
|
386
|
+
}
|
|
339
387
|
}
|
|
340
|
-
//
|
|
388
|
+
// 3. From enabledPlugins (infer marketplace from plugin ID format: pluginName@marketplaceName)
|
|
341
389
|
for (const pluginId of Object.keys(settings.enabledPlugins || {})) {
|
|
342
390
|
const parsed = parsePluginId(pluginId);
|
|
343
391
|
if (parsed && !discovered.has(parsed.marketplace)) {
|
|
@@ -347,7 +395,7 @@ function discoverMarketplacesFromSettings(settings) {
|
|
|
347
395
|
});
|
|
348
396
|
}
|
|
349
397
|
}
|
|
350
|
-
//
|
|
398
|
+
// 4. From installedPluginVersions (same format)
|
|
351
399
|
for (const pluginId of Object.keys(settings.installedPluginVersions || {})) {
|
|
352
400
|
const parsed = parsePluginId(pluginId);
|
|
353
401
|
if (parsed && !discovered.has(parsed.marketplace)) {
|
|
@@ -363,7 +411,8 @@ function discoverMarketplacesFromSettings(settings) {
|
|
|
363
411
|
export async function discoverAllMarketplaces(projectPath) {
|
|
364
412
|
try {
|
|
365
413
|
const settings = await readSettings(projectPath);
|
|
366
|
-
|
|
414
|
+
const known = await readKnownMarketplaces();
|
|
415
|
+
return discoverMarketplacesFromSettings(settings, known);
|
|
367
416
|
}
|
|
368
417
|
catch (error) {
|
|
369
418
|
// Graceful degradation - return empty array instead of crashing
|
|
@@ -375,7 +424,8 @@ export async function discoverAllMarketplaces(projectPath) {
|
|
|
375
424
|
export async function discoverAllGlobalMarketplaces() {
|
|
376
425
|
try {
|
|
377
426
|
const settings = await readGlobalSettings();
|
|
378
|
-
|
|
427
|
+
const known = await readKnownMarketplaces();
|
|
428
|
+
return discoverMarketplacesFromSettings(settings, known);
|
|
379
429
|
}
|
|
380
430
|
catch (error) {
|
|
381
431
|
// Graceful degradation - return empty array instead of crashing
|
|
@@ -758,6 +808,74 @@ export async function recoverMarketplaceSettings() {
|
|
|
758
808
|
}
|
|
759
809
|
return result;
|
|
760
810
|
}
|
|
811
|
+
/**
|
|
812
|
+
* Clean up extraKnownMarketplaces entries that are now properly registered
|
|
813
|
+
* in known_marketplaces.json (the official Claude Code marketplace registry).
|
|
814
|
+
*
|
|
815
|
+
* extraKnownMarketplaces was the old claudeup install mechanism. The official
|
|
816
|
+
* way is `claude plugin marketplace add` which writes to known_marketplaces.json.
|
|
817
|
+
* extraKnownMarketplaces should only be used in project settings for team
|
|
818
|
+
* marketplace suggestions — not in user settings as a primary install path.
|
|
819
|
+
*
|
|
820
|
+
* This function removes magus-related entries from extraKnownMarketplaces in
|
|
821
|
+
* both user and project settings when they're already in known_marketplaces.json.
|
|
822
|
+
*/
|
|
823
|
+
export async function cleanupExtraKnownMarketplaces(projectPath) {
|
|
824
|
+
const known = await readKnownMarketplaces();
|
|
825
|
+
const cleaned = [];
|
|
826
|
+
// Clean user-level settings
|
|
827
|
+
try {
|
|
828
|
+
const globalSettings = await readGlobalSettings();
|
|
829
|
+
if (globalSettings.extraKnownMarketplaces) {
|
|
830
|
+
let changed = false;
|
|
831
|
+
for (const name of Object.keys(globalSettings.extraKnownMarketplaces)) {
|
|
832
|
+
if (known[name]) {
|
|
833
|
+
delete globalSettings.extraKnownMarketplaces[name];
|
|
834
|
+
cleaned.push(`user:${name}`);
|
|
835
|
+
changed = true;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
// Remove the field entirely if empty
|
|
839
|
+
if (changed &&
|
|
840
|
+
Object.keys(globalSettings.extraKnownMarketplaces).length === 0) {
|
|
841
|
+
delete globalSettings.extraKnownMarketplaces;
|
|
842
|
+
}
|
|
843
|
+
if (changed) {
|
|
844
|
+
await writeGlobalSettings(globalSettings);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
catch {
|
|
849
|
+
// Non-fatal: user settings cleanup is best-effort
|
|
850
|
+
}
|
|
851
|
+
// Clean project-level settings
|
|
852
|
+
if (projectPath) {
|
|
853
|
+
try {
|
|
854
|
+
const projectSettings = await readSettings(projectPath);
|
|
855
|
+
if (projectSettings.extraKnownMarketplaces) {
|
|
856
|
+
let changed = false;
|
|
857
|
+
for (const name of Object.keys(projectSettings.extraKnownMarketplaces)) {
|
|
858
|
+
if (known[name]) {
|
|
859
|
+
delete projectSettings.extraKnownMarketplaces[name];
|
|
860
|
+
cleaned.push(`project:${name}`);
|
|
861
|
+
changed = true;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
if (changed &&
|
|
865
|
+
Object.keys(projectSettings.extraKnownMarketplaces).length === 0) {
|
|
866
|
+
delete projectSettings.extraKnownMarketplaces;
|
|
867
|
+
}
|
|
868
|
+
if (changed) {
|
|
869
|
+
await writeSettings(projectSettings, projectPath);
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
catch {
|
|
874
|
+
// Non-fatal: project settings cleanup is best-effort
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
return cleaned;
|
|
878
|
+
}
|
|
761
879
|
/**
|
|
762
880
|
* Read known_marketplaces.json to get marketplace source info
|
|
763
881
|
*/
|
|
@@ -415,12 +415,33 @@ export async function getEnabledMcpServers(
|
|
|
415
415
|
return enabled;
|
|
416
416
|
}
|
|
417
417
|
|
|
418
|
-
// Get all configured marketplaces
|
|
418
|
+
// Get all configured marketplaces — merges known_marketplaces.json (primary) with extraKnownMarketplaces (legacy fallback)
|
|
419
419
|
export async function getConfiguredMarketplaces(
|
|
420
420
|
projectPath?: string,
|
|
421
421
|
): Promise<Record<string, MarketplaceSource>> {
|
|
422
|
+
const result: Record<string, MarketplaceSource> = {};
|
|
423
|
+
|
|
424
|
+
// Primary: known_marketplaces.json (official Claude Code registry)
|
|
425
|
+
const known = await readKnownMarketplaces();
|
|
426
|
+
for (const [name, entry] of Object.entries(known)) {
|
|
427
|
+
if (entry.source?.repo) {
|
|
428
|
+
result[name] = {
|
|
429
|
+
source: { source: "github" as const, repo: entry.source.repo },
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Fallback: extraKnownMarketplaces (legacy — only adds entries not already in known)
|
|
422
435
|
const settings = await readSettings(projectPath);
|
|
423
|
-
|
|
436
|
+
for (const [name, config] of Object.entries(
|
|
437
|
+
settings.extraKnownMarketplaces || {},
|
|
438
|
+
)) {
|
|
439
|
+
if (!result[name]) {
|
|
440
|
+
result[name] = config;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
return result;
|
|
424
445
|
}
|
|
425
446
|
|
|
426
447
|
// Global marketplace management - READ ONLY
|
|
@@ -429,8 +450,29 @@ export async function getConfiguredMarketplaces(
|
|
|
429
450
|
export async function getGlobalConfiguredMarketplaces(): Promise<
|
|
430
451
|
Record<string, MarketplaceSource>
|
|
431
452
|
> {
|
|
453
|
+
const result: Record<string, MarketplaceSource> = {};
|
|
454
|
+
|
|
455
|
+
// Primary: known_marketplaces.json
|
|
456
|
+
const known = await readKnownMarketplaces();
|
|
457
|
+
for (const [name, entry] of Object.entries(known)) {
|
|
458
|
+
if (entry.source?.repo) {
|
|
459
|
+
result[name] = {
|
|
460
|
+
source: { source: "github" as const, repo: entry.source.repo },
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// Fallback: extraKnownMarketplaces
|
|
432
466
|
const settings = await readGlobalSettings();
|
|
433
|
-
|
|
467
|
+
for (const [name, config] of Object.entries(
|
|
468
|
+
settings.extraKnownMarketplaces || {},
|
|
469
|
+
)) {
|
|
470
|
+
if (!result[name]) {
|
|
471
|
+
result[name] = config;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
return result;
|
|
434
476
|
}
|
|
435
477
|
|
|
436
478
|
// Global plugin management
|
|
@@ -494,17 +536,35 @@ export async function removeGlobalInstalledPluginVersion(
|
|
|
494
536
|
// Shared logic for discovering marketplaces from settings
|
|
495
537
|
function discoverMarketplacesFromSettings(
|
|
496
538
|
settings: ClaudeSettings,
|
|
539
|
+
knownMarketplaces?: KnownMarketplaces,
|
|
497
540
|
): DiscoveredMarketplace[] {
|
|
498
541
|
const discovered = new Map<string, DiscoveredMarketplace>();
|
|
499
542
|
|
|
500
|
-
// 1. From
|
|
543
|
+
// 1. From known_marketplaces.json (official Claude Code registry — primary source)
|
|
544
|
+
if (knownMarketplaces) {
|
|
545
|
+
for (const [name, entry] of Object.entries(knownMarketplaces)) {
|
|
546
|
+
if (entry.source?.repo) {
|
|
547
|
+
discovered.set(name, {
|
|
548
|
+
name,
|
|
549
|
+
source: "configured",
|
|
550
|
+
config: {
|
|
551
|
+
source: { source: "github" as const, repo: entry.source.repo },
|
|
552
|
+
},
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// 2. From extraKnownMarketplaces (legacy/team fallback — only adds entries not already in known_marketplaces.json)
|
|
501
559
|
for (const [name, config] of Object.entries(
|
|
502
560
|
settings.extraKnownMarketplaces || {},
|
|
503
561
|
)) {
|
|
504
|
-
discovered.
|
|
562
|
+
if (!discovered.has(name)) {
|
|
563
|
+
discovered.set(name, { name, source: "configured", config });
|
|
564
|
+
}
|
|
505
565
|
}
|
|
506
566
|
|
|
507
|
-
//
|
|
567
|
+
// 3. From enabledPlugins (infer marketplace from plugin ID format: pluginName@marketplaceName)
|
|
508
568
|
for (const pluginId of Object.keys(settings.enabledPlugins || {})) {
|
|
509
569
|
const parsed = parsePluginId(pluginId);
|
|
510
570
|
if (parsed && !discovered.has(parsed.marketplace)) {
|
|
@@ -515,7 +575,7 @@ function discoverMarketplacesFromSettings(
|
|
|
515
575
|
}
|
|
516
576
|
}
|
|
517
577
|
|
|
518
|
-
//
|
|
578
|
+
// 4. From installedPluginVersions (same format)
|
|
519
579
|
for (const pluginId of Object.keys(settings.installedPluginVersions || {})) {
|
|
520
580
|
const parsed = parsePluginId(pluginId);
|
|
521
581
|
if (parsed && !discovered.has(parsed.marketplace)) {
|
|
@@ -535,7 +595,8 @@ export async function discoverAllMarketplaces(
|
|
|
535
595
|
): Promise<DiscoveredMarketplace[]> {
|
|
536
596
|
try {
|
|
537
597
|
const settings = await readSettings(projectPath);
|
|
538
|
-
|
|
598
|
+
const known = await readKnownMarketplaces();
|
|
599
|
+
return discoverMarketplacesFromSettings(settings, known);
|
|
539
600
|
} catch (error) {
|
|
540
601
|
// Graceful degradation - return empty array instead of crashing
|
|
541
602
|
console.error(
|
|
@@ -552,7 +613,8 @@ export async function discoverAllGlobalMarketplaces(): Promise<
|
|
|
552
613
|
> {
|
|
553
614
|
try {
|
|
554
615
|
const settings = await readGlobalSettings();
|
|
555
|
-
|
|
616
|
+
const known = await readKnownMarketplaces();
|
|
617
|
+
return discoverMarketplacesFromSettings(settings, known);
|
|
556
618
|
} catch (error) {
|
|
557
619
|
// Graceful degradation - return empty array instead of crashing
|
|
558
620
|
console.error(
|
|
@@ -1019,6 +1081,84 @@ export async function recoverMarketplaceSettings(): Promise<MarketplaceRecoveryR
|
|
|
1019
1081
|
return result;
|
|
1020
1082
|
}
|
|
1021
1083
|
|
|
1084
|
+
/**
|
|
1085
|
+
* Clean up extraKnownMarketplaces entries that are now properly registered
|
|
1086
|
+
* in known_marketplaces.json (the official Claude Code marketplace registry).
|
|
1087
|
+
*
|
|
1088
|
+
* extraKnownMarketplaces was the old claudeup install mechanism. The official
|
|
1089
|
+
* way is `claude plugin marketplace add` which writes to known_marketplaces.json.
|
|
1090
|
+
* extraKnownMarketplaces should only be used in project settings for team
|
|
1091
|
+
* marketplace suggestions — not in user settings as a primary install path.
|
|
1092
|
+
*
|
|
1093
|
+
* This function removes magus-related entries from extraKnownMarketplaces in
|
|
1094
|
+
* both user and project settings when they're already in known_marketplaces.json.
|
|
1095
|
+
*/
|
|
1096
|
+
export async function cleanupExtraKnownMarketplaces(
|
|
1097
|
+
projectPath?: string,
|
|
1098
|
+
): Promise<string[]> {
|
|
1099
|
+
const known = await readKnownMarketplaces();
|
|
1100
|
+
const cleaned: string[] = [];
|
|
1101
|
+
|
|
1102
|
+
// Clean user-level settings
|
|
1103
|
+
try {
|
|
1104
|
+
const globalSettings = await readGlobalSettings();
|
|
1105
|
+
if (globalSettings.extraKnownMarketplaces) {
|
|
1106
|
+
let changed = false;
|
|
1107
|
+
for (const name of Object.keys(globalSettings.extraKnownMarketplaces)) {
|
|
1108
|
+
if (known[name]) {
|
|
1109
|
+
delete globalSettings.extraKnownMarketplaces[name];
|
|
1110
|
+
cleaned.push(`user:${name}`);
|
|
1111
|
+
changed = true;
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
// Remove the field entirely if empty
|
|
1115
|
+
if (
|
|
1116
|
+
changed &&
|
|
1117
|
+
Object.keys(globalSettings.extraKnownMarketplaces).length === 0
|
|
1118
|
+
) {
|
|
1119
|
+
delete globalSettings.extraKnownMarketplaces;
|
|
1120
|
+
}
|
|
1121
|
+
if (changed) {
|
|
1122
|
+
await writeGlobalSettings(globalSettings);
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
} catch {
|
|
1126
|
+
// Non-fatal: user settings cleanup is best-effort
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
// Clean project-level settings
|
|
1130
|
+
if (projectPath) {
|
|
1131
|
+
try {
|
|
1132
|
+
const projectSettings = await readSettings(projectPath);
|
|
1133
|
+
if (projectSettings.extraKnownMarketplaces) {
|
|
1134
|
+
let changed = false;
|
|
1135
|
+
for (const name of Object.keys(
|
|
1136
|
+
projectSettings.extraKnownMarketplaces,
|
|
1137
|
+
)) {
|
|
1138
|
+
if (known[name]) {
|
|
1139
|
+
delete projectSettings.extraKnownMarketplaces[name];
|
|
1140
|
+
cleaned.push(`project:${name}`);
|
|
1141
|
+
changed = true;
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
if (
|
|
1145
|
+
changed &&
|
|
1146
|
+
Object.keys(projectSettings.extraKnownMarketplaces).length === 0
|
|
1147
|
+
) {
|
|
1148
|
+
delete projectSettings.extraKnownMarketplaces;
|
|
1149
|
+
}
|
|
1150
|
+
if (changed) {
|
|
1151
|
+
await writeSettings(projectSettings, projectPath);
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
} catch {
|
|
1155
|
+
// Non-fatal: project settings cleanup is best-effort
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
return cleaned;
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1022
1162
|
/**
|
|
1023
1163
|
* Read known_marketplaces.json to get marketplace source info
|
|
1024
1164
|
*/
|
|
@@ -325,20 +325,22 @@ export function SkillsScreen() {
|
|
|
325
325
|
}
|
|
326
326
|
return;
|
|
327
327
|
}
|
|
328
|
-
// Action keys
|
|
329
|
-
if (
|
|
330
|
-
if (
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
if (
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
328
|
+
// Action keys only when NOT actively typing in search
|
|
329
|
+
if (!isSearchActive) {
|
|
330
|
+
if (event.name === "u" && selectedSkill) {
|
|
331
|
+
if (selectedSkill.installed && selectedSkill.installedScope === "user")
|
|
332
|
+
handleUninstall();
|
|
333
|
+
else
|
|
334
|
+
handleInstall("user");
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
else if (event.name === "p" && selectedSkill) {
|
|
338
|
+
if (selectedSkill.installed && selectedSkill.installedScope === "project")
|
|
339
|
+
handleUninstall();
|
|
340
|
+
else
|
|
341
|
+
handleInstall("project");
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
342
344
|
}
|
|
343
345
|
if (isSearchActive) {
|
|
344
346
|
if (event.name === "k" || event.name === "j") {
|
|
@@ -358,15 +358,17 @@ export function SkillsScreen() {
|
|
|
358
358
|
return;
|
|
359
359
|
}
|
|
360
360
|
|
|
361
|
-
// Action keys
|
|
362
|
-
if (
|
|
363
|
-
if (
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
if (
|
|
368
|
-
|
|
369
|
-
|
|
361
|
+
// Action keys only when NOT actively typing in search
|
|
362
|
+
if (!isSearchActive) {
|
|
363
|
+
if (event.name === "u" && selectedSkill) {
|
|
364
|
+
if (selectedSkill.installed && selectedSkill.installedScope === "user") handleUninstall();
|
|
365
|
+
else handleInstall("user");
|
|
366
|
+
return;
|
|
367
|
+
} else if (event.name === "p" && selectedSkill) {
|
|
368
|
+
if (selectedSkill.installed && selectedSkill.installedScope === "project") handleUninstall();
|
|
369
|
+
else handleInstall("project");
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
370
372
|
}
|
|
371
373
|
|
|
372
374
|
if (isSearchActive) {
|