@guanmu/ccprofile 0.1.14 → 0.1.16
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/index.js +133 -172
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -141,19 +141,33 @@ function missingArg(message, usage) {
|
|
|
141
141
|
console.error(`Usage: ${usage}`);
|
|
142
142
|
process.exitCode = 1;
|
|
143
143
|
}
|
|
144
|
-
async function
|
|
144
|
+
async function selectProfileOrNew() {
|
|
145
145
|
const names = getProfileNames();
|
|
146
146
|
if (names.length === 0) {
|
|
147
|
-
p.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
147
|
+
const create = await p.confirm({
|
|
148
|
+
message: "No profiles found. Create one?",
|
|
149
|
+
initialValue: true,
|
|
150
|
+
});
|
|
151
|
+
if (p.isCancel(create) || !create)
|
|
152
|
+
return undefined;
|
|
153
|
+
await addProfile();
|
|
154
|
+
return getProfileNames()[0];
|
|
155
|
+
}
|
|
156
|
+
const selected = await p.select({
|
|
157
|
+
message: "Select profile:",
|
|
158
|
+
options: [
|
|
159
|
+
...names.map((n) => ({ value: n, label: n })),
|
|
160
|
+
{ value: "__create__", label: "Create new profile...", hint: "Add a new profile" },
|
|
161
|
+
],
|
|
153
162
|
});
|
|
154
|
-
if (p.isCancel(
|
|
163
|
+
if (p.isCancel(selected))
|
|
155
164
|
return undefined;
|
|
156
|
-
|
|
165
|
+
if (selected === "__create__") {
|
|
166
|
+
await addProfile();
|
|
167
|
+
const updated = getProfileNames();
|
|
168
|
+
return updated[updated.length - 1];
|
|
169
|
+
}
|
|
170
|
+
return selected;
|
|
157
171
|
}
|
|
158
172
|
// ── Commands ──────────────────────────────────────────────
|
|
159
173
|
async function addProfile(name) {
|
|
@@ -257,29 +271,27 @@ async function addPlugin(profileName, plugin) {
|
|
|
257
271
|
}
|
|
258
272
|
}
|
|
259
273
|
}
|
|
260
|
-
const selected = await p.
|
|
261
|
-
message: `
|
|
274
|
+
const selected = await p.multiselect({
|
|
275
|
+
message: `Select plugins to add to "${profileName}":`,
|
|
262
276
|
options: [
|
|
263
277
|
...filtered.map((pl) => ({
|
|
264
278
|
value: pl.name,
|
|
265
279
|
label: pl.name,
|
|
266
|
-
hint: pl.description.slice(0,
|
|
280
|
+
hint: pl.description.slice(0, 50),
|
|
267
281
|
})),
|
|
268
|
-
{ value: "__url__", label: "Enter URL manually...", hint: "Input a GitHub URL or plugin name" },
|
|
269
282
|
],
|
|
283
|
+
required: false,
|
|
270
284
|
});
|
|
271
285
|
if (p.isCancel(selected))
|
|
272
286
|
return;
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
message: "Plugin URL or name:",
|
|
276
|
-
}));
|
|
277
|
-
if (p.isCancel(plugin))
|
|
278
|
-
return;
|
|
287
|
+
for (const name of selected) {
|
|
288
|
+
data.plugins.push(name);
|
|
279
289
|
}
|
|
280
|
-
|
|
281
|
-
|
|
290
|
+
writeProfile(normalizedProfileName, data);
|
|
291
|
+
if (selected.length > 0) {
|
|
292
|
+
p.log.success(`Added ${selected.length} plugin(s) to profile "${normalizedProfileName}".`);
|
|
282
293
|
}
|
|
294
|
+
return;
|
|
283
295
|
}
|
|
284
296
|
plugin = normalizePluginName(plugin);
|
|
285
297
|
if (!plugin)
|
|
@@ -341,37 +353,55 @@ async function listPlugins(profileName) {
|
|
|
341
353
|
p.log.success(pl);
|
|
342
354
|
}
|
|
343
355
|
}
|
|
344
|
-
async function
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
356
|
+
async function browsePlugins(currentProfile) {
|
|
357
|
+
const allPlugins = getAllPlugins();
|
|
358
|
+
if (allPlugins.length === 0) {
|
|
359
|
+
p.log.warn("No plugins available in marketplaces.");
|
|
360
|
+
return [];
|
|
361
|
+
}
|
|
362
|
+
let plugins = allPlugins;
|
|
363
|
+
if (allPlugins.length > 15) {
|
|
364
|
+
const query = (await p.text({
|
|
365
|
+
message: "Search plugins (leave empty to list all):",
|
|
352
366
|
}));
|
|
353
|
-
if (p.isCancel(
|
|
354
|
-
return;
|
|
367
|
+
if (p.isCancel(query))
|
|
368
|
+
return [];
|
|
369
|
+
const q = query.trim().toLowerCase();
|
|
370
|
+
if (q) {
|
|
371
|
+
plugins = allPlugins.filter((pl) => pl.name.toLowerCase().includes(q) ||
|
|
372
|
+
pl.description.toLowerCase().includes(q) ||
|
|
373
|
+
(pl.category || "").toLowerCase().includes(q));
|
|
374
|
+
if (plugins.length === 0) {
|
|
375
|
+
p.log.warn(`No plugins matching "${query.trim()}".`);
|
|
376
|
+
return [];
|
|
377
|
+
}
|
|
378
|
+
}
|
|
355
379
|
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
380
|
+
if (currentProfile) {
|
|
381
|
+
const data = readProfile(currentProfile);
|
|
382
|
+
const selected = await p.multiselect({
|
|
383
|
+
message: "Select plugins to add:",
|
|
384
|
+
options: plugins.map((pl) => ({
|
|
385
|
+
value: pl.name,
|
|
386
|
+
label: pl.name,
|
|
387
|
+
hint: pl.description.slice(0, 50) + (data.plugins.includes(pl.name) ? " (installed)" : ""),
|
|
388
|
+
})),
|
|
389
|
+
required: false,
|
|
390
|
+
});
|
|
391
|
+
if (p.isCancel(selected))
|
|
392
|
+
return [];
|
|
393
|
+
return selected.filter((name) => !data.plugins.includes(name));
|
|
364
394
|
}
|
|
365
395
|
const grouped = new Map();
|
|
366
|
-
for (const pl of
|
|
396
|
+
for (const pl of plugins) {
|
|
367
397
|
const list = grouped.get(pl.marketplace) || [];
|
|
368
398
|
list.push(pl);
|
|
369
399
|
grouped.set(pl.marketplace, list);
|
|
370
400
|
}
|
|
371
|
-
console.log(`\n
|
|
372
|
-
for (const [marketplace,
|
|
401
|
+
console.log(`\n ${plugins.length} plugin(s) available:\n`);
|
|
402
|
+
for (const [marketplace, mPlugins] of grouped) {
|
|
373
403
|
console.log(` [${marketplace}]`);
|
|
374
|
-
for (const pl of
|
|
404
|
+
for (const pl of mPlugins) {
|
|
375
405
|
const desc = pl.description.length > 70
|
|
376
406
|
? pl.description.slice(0, 67) + "..."
|
|
377
407
|
: pl.description;
|
|
@@ -379,6 +409,7 @@ async function searchPlugins(keyword) {
|
|
|
379
409
|
}
|
|
380
410
|
console.log();
|
|
381
411
|
}
|
|
412
|
+
return [];
|
|
382
413
|
}
|
|
383
414
|
async function executeProfile(profileName) {
|
|
384
415
|
const normalizedProfileName = normalizeProfileName(profileName);
|
|
@@ -409,103 +440,6 @@ async function executeProfile(profileName) {
|
|
|
409
440
|
s.stop(`${installed} installed${failed > 0 ? `, ${failed} failed` : ""}`);
|
|
410
441
|
p.log.success("Done.");
|
|
411
442
|
}
|
|
412
|
-
async function installWizard() {
|
|
413
|
-
while (true) {
|
|
414
|
-
const action = await p.select({
|
|
415
|
-
message: "Install",
|
|
416
|
-
options: [
|
|
417
|
-
{ value: "install", label: "Install profile plugins", hint: "Run a profile" },
|
|
418
|
-
{ value: "back", label: "Back" },
|
|
419
|
-
{ value: "exit", label: "Exit" },
|
|
420
|
-
],
|
|
421
|
-
});
|
|
422
|
-
if (p.isCancel(action) || action === "exit")
|
|
423
|
-
return "exit";
|
|
424
|
-
if (action === "back")
|
|
425
|
-
return "back";
|
|
426
|
-
const name = await selectProfile("Select profile to install:");
|
|
427
|
-
if (name)
|
|
428
|
-
await executeProfile(name);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
async function profilesWizard() {
|
|
432
|
-
while (true) {
|
|
433
|
-
const action = await p.select({
|
|
434
|
-
message: "Profiles",
|
|
435
|
-
options: [
|
|
436
|
-
{ value: "create", label: "Create profile", hint: "Create a new empty profile" },
|
|
437
|
-
{ value: "list", label: "List profiles", hint: "Show all profiles" },
|
|
438
|
-
{ value: "delete", label: "Delete profile", hint: "Remove a profile" },
|
|
439
|
-
{ value: "back", label: "Back" },
|
|
440
|
-
{ value: "exit", label: "Exit" },
|
|
441
|
-
],
|
|
442
|
-
});
|
|
443
|
-
if (p.isCancel(action) || action === "exit")
|
|
444
|
-
return "exit";
|
|
445
|
-
if (action === "back")
|
|
446
|
-
return "back";
|
|
447
|
-
switch (action) {
|
|
448
|
-
case "create":
|
|
449
|
-
await addProfile();
|
|
450
|
-
break;
|
|
451
|
-
case "list":
|
|
452
|
-
await listProfiles();
|
|
453
|
-
break;
|
|
454
|
-
case "delete":
|
|
455
|
-
await removeProfile();
|
|
456
|
-
break;
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
async function pluginsWizard() {
|
|
461
|
-
while (true) {
|
|
462
|
-
const action = await p.select({
|
|
463
|
-
message: "Plugins",
|
|
464
|
-
options: [
|
|
465
|
-
{ value: "add", label: "Add plugin to profile", hint: "Choose a profile, then a plugin" },
|
|
466
|
-
{ value: "remove", label: "Remove plugin from profile", hint: "Choose a profile, then a plugin" },
|
|
467
|
-
{ value: "list", label: "List profile plugins", hint: "Show plugins in a profile" },
|
|
468
|
-
{ value: "back", label: "Back" },
|
|
469
|
-
{ value: "exit", label: "Exit" },
|
|
470
|
-
],
|
|
471
|
-
});
|
|
472
|
-
if (p.isCancel(action) || action === "exit")
|
|
473
|
-
return "exit";
|
|
474
|
-
if (action === "back")
|
|
475
|
-
return "back";
|
|
476
|
-
const name = await selectProfile("Select profile:");
|
|
477
|
-
if (!name)
|
|
478
|
-
continue;
|
|
479
|
-
switch (action) {
|
|
480
|
-
case "add":
|
|
481
|
-
await addPlugin(name);
|
|
482
|
-
break;
|
|
483
|
-
case "remove":
|
|
484
|
-
await removePlugin(name);
|
|
485
|
-
break;
|
|
486
|
-
case "list":
|
|
487
|
-
await listPlugins(name);
|
|
488
|
-
break;
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
async function marketplaceWizard() {
|
|
493
|
-
while (true) {
|
|
494
|
-
const action = await p.select({
|
|
495
|
-
message: "Marketplace",
|
|
496
|
-
options: [
|
|
497
|
-
{ value: "search", label: "Search plugins", hint: "Search installed marketplaces" },
|
|
498
|
-
{ value: "back", label: "Back" },
|
|
499
|
-
{ value: "exit", label: "Exit" },
|
|
500
|
-
],
|
|
501
|
-
});
|
|
502
|
-
if (p.isCancel(action) || action === "exit")
|
|
503
|
-
return "exit";
|
|
504
|
-
if (action === "back")
|
|
505
|
-
return "back";
|
|
506
|
-
await searchPlugins();
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
443
|
function printBanner() {
|
|
510
444
|
const require = createRequire(import.meta.url);
|
|
511
445
|
const pkg = require("../package.json");
|
|
@@ -518,40 +452,67 @@ async function interactiveMode() {
|
|
|
518
452
|
return;
|
|
519
453
|
}
|
|
520
454
|
printBanner();
|
|
521
|
-
let
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
{ value: "install", label: "Install", hint: "Run a profile" },
|
|
527
|
-
{ value: "profiles", label: "Profiles", hint: "Create, list, or delete profiles" },
|
|
528
|
-
{ value: "plugins", label: "Plugins", hint: "Manage plugins inside profiles" },
|
|
529
|
-
{ value: "marketplace", label: "Marketplace", hint: "Search available plugins" },
|
|
530
|
-
{ value: "help", label: "Help", hint: "Show command usage" },
|
|
531
|
-
{ value: "exit", label: "Exit" },
|
|
532
|
-
],
|
|
533
|
-
});
|
|
534
|
-
if (p.isCancel(area) || area === "exit")
|
|
455
|
+
let currentProfile;
|
|
456
|
+
// Profile selection loop
|
|
457
|
+
while (true) {
|
|
458
|
+
currentProfile = await selectProfileOrNew();
|
|
459
|
+
if (!currentProfile)
|
|
535
460
|
break;
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
461
|
+
// Action loop — all operations on current profile
|
|
462
|
+
let stayInProfile = true;
|
|
463
|
+
while (stayInProfile && currentProfile) {
|
|
464
|
+
const data = readProfile(currentProfile);
|
|
465
|
+
const pluginList = data.plugins.length > 0
|
|
466
|
+
? data.plugins.map((pl) => ` ${pc.dim("•")} ${pl}`).join("\n")
|
|
467
|
+
: pc.dim(" (empty)");
|
|
468
|
+
p.note(`${pc.bold(pc.cyan(currentProfile))}\n${pluginList}`);
|
|
469
|
+
const action = await p.select({
|
|
470
|
+
message: "Choose action:",
|
|
471
|
+
options: [
|
|
472
|
+
{ value: "install", label: "Install", hint: "Apply to current project" },
|
|
473
|
+
{ value: "add", label: "Add plugin", hint: "Search and add plugins" },
|
|
474
|
+
{ value: "remove", label: "Remove plugin", hint: "Remove a plugin" },
|
|
475
|
+
{ value: "search", label: "Search marketplace", hint: "Find new plugins" },
|
|
476
|
+
{ value: "switch", label: "Switch profile", hint: "Choose a different profile" },
|
|
477
|
+
{ value: "delete", label: "Delete profile", hint: "Remove this profile" },
|
|
478
|
+
{ value: "exit", label: "Exit" },
|
|
479
|
+
],
|
|
480
|
+
});
|
|
481
|
+
if (p.isCancel(action) || action === "exit") {
|
|
482
|
+
currentProfile = undefined;
|
|
483
|
+
stayInProfile = false;
|
|
552
484
|
break;
|
|
485
|
+
}
|
|
486
|
+
switch (action) {
|
|
487
|
+
case "install":
|
|
488
|
+
await executeProfile(currentProfile);
|
|
489
|
+
break;
|
|
490
|
+
case "add":
|
|
491
|
+
await addPlugin(currentProfile);
|
|
492
|
+
break;
|
|
493
|
+
case "remove":
|
|
494
|
+
await removePlugin(currentProfile);
|
|
495
|
+
break;
|
|
496
|
+
case "search": {
|
|
497
|
+
const found = await browsePlugins(currentProfile);
|
|
498
|
+
if (found.length > 0) {
|
|
499
|
+
const d = readProfile(currentProfile);
|
|
500
|
+
d.plugins.push(...found);
|
|
501
|
+
writeProfile(currentProfile, d);
|
|
502
|
+
p.log.success(`Added ${found.length} plugin(s) to profile "${currentProfile}".`);
|
|
503
|
+
}
|
|
504
|
+
break;
|
|
505
|
+
}
|
|
506
|
+
case "switch":
|
|
507
|
+
stayInProfile = false;
|
|
508
|
+
break;
|
|
509
|
+
case "delete":
|
|
510
|
+
await removeProfile(currentProfile);
|
|
511
|
+
currentProfile = undefined;
|
|
512
|
+
stayInProfile = false;
|
|
513
|
+
break;
|
|
514
|
+
}
|
|
553
515
|
}
|
|
554
|
-
shouldExit = result === "exit";
|
|
555
516
|
}
|
|
556
517
|
p.outro("Done.");
|
|
557
518
|
}
|
|
@@ -642,7 +603,7 @@ async function main(args) {
|
|
|
642
603
|
}
|
|
643
604
|
break;
|
|
644
605
|
case "search":
|
|
645
|
-
await
|
|
606
|
+
await browsePlugins();
|
|
646
607
|
break;
|
|
647
608
|
default: {
|
|
648
609
|
const profileName = cmd;
|