@guanmu/ccprofile 0.1.14 → 0.1.15
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 +108 -141
- 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) {
|
|
@@ -341,17 +355,17 @@ async function listPlugins(profileName) {
|
|
|
341
355
|
p.log.success(pl);
|
|
342
356
|
}
|
|
343
357
|
}
|
|
344
|
-
async function searchPlugins(keyword) {
|
|
358
|
+
async function searchPlugins(keyword, currentProfile) {
|
|
345
359
|
if (!keyword) {
|
|
346
360
|
if (!canPrompt()) {
|
|
347
361
|
missingArg("Search keyword is required.", "ccx search <keyword>");
|
|
348
|
-
return;
|
|
362
|
+
return undefined;
|
|
349
363
|
}
|
|
350
364
|
keyword = (await p.text({
|
|
351
365
|
message: "Search plugins:",
|
|
352
366
|
}));
|
|
353
367
|
if (p.isCancel(keyword))
|
|
354
|
-
return;
|
|
368
|
+
return undefined;
|
|
355
369
|
}
|
|
356
370
|
const allPlugins = getAllPlugins();
|
|
357
371
|
const lower = keyword.toLowerCase();
|
|
@@ -360,7 +374,24 @@ async function searchPlugins(keyword) {
|
|
|
360
374
|
(pl.category || "").toLowerCase().includes(lower));
|
|
361
375
|
if (results.length === 0) {
|
|
362
376
|
p.log.warn(`No plugins matching "${keyword}".`);
|
|
363
|
-
return;
|
|
377
|
+
return undefined;
|
|
378
|
+
}
|
|
379
|
+
if (currentProfile) {
|
|
380
|
+
const data = readProfile(currentProfile);
|
|
381
|
+
const selected = await p.select({
|
|
382
|
+
message: `Search results for "${keyword}":`,
|
|
383
|
+
options: [
|
|
384
|
+
...results.map((pl) => ({
|
|
385
|
+
value: pl.name,
|
|
386
|
+
label: pl.name,
|
|
387
|
+
hint: pl.description.slice(0, 60) + (data.plugins.includes(pl.name) ? " ✓" : ""),
|
|
388
|
+
})),
|
|
389
|
+
{ value: "__back__", label: "Back", hint: "Return to menu" },
|
|
390
|
+
],
|
|
391
|
+
});
|
|
392
|
+
if (p.isCancel(selected) || selected === "__back__")
|
|
393
|
+
return undefined;
|
|
394
|
+
return selected;
|
|
364
395
|
}
|
|
365
396
|
const grouped = new Map();
|
|
366
397
|
for (const pl of results) {
|
|
@@ -379,6 +410,7 @@ async function searchPlugins(keyword) {
|
|
|
379
410
|
}
|
|
380
411
|
console.log();
|
|
381
412
|
}
|
|
413
|
+
return undefined;
|
|
382
414
|
}
|
|
383
415
|
async function executeProfile(profileName) {
|
|
384
416
|
const normalizedProfileName = normalizeProfileName(profileName);
|
|
@@ -409,103 +441,6 @@ async function executeProfile(profileName) {
|
|
|
409
441
|
s.stop(`${installed} installed${failed > 0 ? `, ${failed} failed` : ""}`);
|
|
410
442
|
p.log.success("Done.");
|
|
411
443
|
}
|
|
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
444
|
function printBanner() {
|
|
510
445
|
const require = createRequire(import.meta.url);
|
|
511
446
|
const pkg = require("../package.json");
|
|
@@ -518,40 +453,72 @@ async function interactiveMode() {
|
|
|
518
453
|
return;
|
|
519
454
|
}
|
|
520
455
|
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")
|
|
456
|
+
let currentProfile;
|
|
457
|
+
// Profile selection loop
|
|
458
|
+
while (true) {
|
|
459
|
+
currentProfile = await selectProfileOrNew();
|
|
460
|
+
if (!currentProfile)
|
|
535
461
|
break;
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
462
|
+
// Action loop — all operations on current profile
|
|
463
|
+
let stayInProfile = true;
|
|
464
|
+
while (stayInProfile && currentProfile) {
|
|
465
|
+
const data = readProfile(currentProfile);
|
|
466
|
+
const action = await p.select({
|
|
467
|
+
message: pc.bold(pc.cyan(`[${currentProfile}]`)) + ` ${data.plugins.length} plugin(s)`,
|
|
468
|
+
options: [
|
|
469
|
+
{ value: "install", label: "Install", hint: "Apply to current project" },
|
|
470
|
+
{ value: "add", label: "Add plugin", hint: "Search and add a plugin" },
|
|
471
|
+
{ value: "remove", label: "Remove plugin", hint: "Remove a plugin" },
|
|
472
|
+
{ value: "list", label: "List plugins", hint: "Show all plugins" },
|
|
473
|
+
{ value: "search", label: "Search marketplace", hint: "Find new plugins" },
|
|
474
|
+
{ value: "switch", label: "Switch profile", hint: "Choose a different profile" },
|
|
475
|
+
{ value: "delete", label: "Delete profile", hint: "Remove this profile" },
|
|
476
|
+
{ value: "exit", label: "Exit" },
|
|
477
|
+
],
|
|
478
|
+
});
|
|
479
|
+
if (p.isCancel(action) || action === "exit") {
|
|
480
|
+
currentProfile = undefined;
|
|
481
|
+
stayInProfile = false;
|
|
552
482
|
break;
|
|
483
|
+
}
|
|
484
|
+
switch (action) {
|
|
485
|
+
case "install":
|
|
486
|
+
await executeProfile(currentProfile);
|
|
487
|
+
break;
|
|
488
|
+
case "add":
|
|
489
|
+
await addPlugin(currentProfile);
|
|
490
|
+
break;
|
|
491
|
+
case "remove":
|
|
492
|
+
await removePlugin(currentProfile);
|
|
493
|
+
break;
|
|
494
|
+
case "list":
|
|
495
|
+
await listPlugins(currentProfile);
|
|
496
|
+
break;
|
|
497
|
+
case "search": {
|
|
498
|
+
const found = await searchPlugins(undefined, currentProfile);
|
|
499
|
+
if (found) {
|
|
500
|
+
const d = readProfile(currentProfile);
|
|
501
|
+
if (d.plugins.includes(found)) {
|
|
502
|
+
p.log.warn(`"${found}" already in profile "${currentProfile}".`);
|
|
503
|
+
}
|
|
504
|
+
else {
|
|
505
|
+
d.plugins.push(found);
|
|
506
|
+
writeProfile(currentProfile, d);
|
|
507
|
+
p.log.success(`Added "${found}" to profile "${currentProfile}".`);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
break;
|
|
511
|
+
}
|
|
512
|
+
case "switch":
|
|
513
|
+
stayInProfile = false;
|
|
514
|
+
break;
|
|
515
|
+
case "delete":
|
|
516
|
+
await removeProfile(currentProfile);
|
|
517
|
+
currentProfile = undefined;
|
|
518
|
+
stayInProfile = false;
|
|
519
|
+
break;
|
|
520
|
+
}
|
|
553
521
|
}
|
|
554
|
-
shouldExit = result === "exit";
|
|
555
522
|
}
|
|
556
523
|
p.outro("Done.");
|
|
557
524
|
}
|