@guanmu/ccprofile 0.1.17 → 0.1.19
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/README.md +8 -0
- package/dist/index.js +101 -29
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# ccx
|
|
2
2
|
|
|
3
|
+
```text
|
|
4
|
+
______ ______ __ __
|
|
5
|
+
/ ____// ____/ \ \ / /
|
|
6
|
+
| | | | \ V /
|
|
7
|
+
| |___ | |___ / . \
|
|
8
|
+
\____/ \____/ /_/ \_\
|
|
9
|
+
```
|
|
10
|
+
|
|
3
11
|
Agent Profile Manager for Claude Code.
|
|
4
12
|
|
|
5
13
|
`ccx` lets you save named Claude Code plugin profiles and install a whole profile into the current project with one command. It is designed as a command-first CLI, with a lightweight interactive wizard for manual use.
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,16 @@ import pc from "picocolors";
|
|
|
8
8
|
const PROFILES_DIR = path.join(process.env.HOME, ".ccx", "profiles");
|
|
9
9
|
const MARKETPLACES_DIR = path.join(process.env.HOME, ".claude", "plugins", "marketplaces");
|
|
10
10
|
const PROJECT_CONFIG_FILE = ".ccx.json";
|
|
11
|
+
const LOGO_LINES = [
|
|
12
|
+
" ______ ______ __ __",
|
|
13
|
+
" / ____// ____/ \\ \\ / /",
|
|
14
|
+
" | | | | \\ V /",
|
|
15
|
+
" | |___ | |___ / . \\",
|
|
16
|
+
" \\____/ \\____/ /_/ \\_\\",
|
|
17
|
+
];
|
|
18
|
+
function renderLogo() {
|
|
19
|
+
return LOGO_LINES.map((line, index) => index < 2 ? pc.cyan(line) : pc.magenta(line)).join("\n");
|
|
20
|
+
}
|
|
11
21
|
function ensureProfilesDir() {
|
|
12
22
|
fs.mkdirSync(PROFILES_DIR, { recursive: true });
|
|
13
23
|
}
|
|
@@ -568,10 +578,39 @@ function syncProjectConfig() {
|
|
|
568
578
|
writeProjectConfig(plugins);
|
|
569
579
|
p.log.success(`Synced ${plugins.length} plugin(s) to ${PROJECT_CONFIG_FILE}.`);
|
|
570
580
|
}
|
|
581
|
+
async function saveToProfile(name) {
|
|
582
|
+
const plugins = readProjectConfig();
|
|
583
|
+
if (!name) {
|
|
584
|
+
if (!canPrompt()) {
|
|
585
|
+
missingArg("Profile name is required.", "ccx save <name>");
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
name = (await p.text({
|
|
589
|
+
message: "Save as profile:",
|
|
590
|
+
}));
|
|
591
|
+
if (p.isCancel(name))
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
name = normalizeProfileName(name);
|
|
595
|
+
if (!name)
|
|
596
|
+
return;
|
|
597
|
+
const file = profilePath(name);
|
|
598
|
+
if (fs.existsSync(file)) {
|
|
599
|
+
const overwrite = await p.confirm({
|
|
600
|
+
message: `Profile "${name}" already exists. Overwrite?`,
|
|
601
|
+
initialValue: false,
|
|
602
|
+
});
|
|
603
|
+
if (p.isCancel(overwrite) || !overwrite)
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
writeProfile(name, { name, plugins });
|
|
607
|
+
p.log.success(`Saved ${plugins.length} plugin(s) to profile "${name}".`);
|
|
608
|
+
}
|
|
571
609
|
function printBanner() {
|
|
572
610
|
const require = createRequire(import.meta.url);
|
|
573
611
|
const pkg = require("../package.json");
|
|
574
|
-
|
|
612
|
+
console.log(`${renderLogo()}\n`);
|
|
613
|
+
p.note(pc.bold("ccx") + pc.dim(" - Agent Profile Manager ") + pc.gray(`v${pkg.version}`));
|
|
575
614
|
}
|
|
576
615
|
async function interactiveMode() {
|
|
577
616
|
if (!canPrompt()) {
|
|
@@ -597,12 +636,16 @@ async function interactiveMode() {
|
|
|
597
636
|
const action = await p.select({
|
|
598
637
|
message: "Choose action:",
|
|
599
638
|
options: [
|
|
600
|
-
{ value: "install", label: "Install", hint: "
|
|
601
|
-
{ value: "add", label: "Add plugin", hint: "
|
|
602
|
-
{ value: "remove", label: "Remove plugin", hint: "Remove a plugin" },
|
|
603
|
-
{ value: "
|
|
639
|
+
{ value: "install", label: "Install", hint: "Install all plugins from profile" },
|
|
640
|
+
{ value: "add", label: "Add plugin", hint: "Add a plugin to profile" },
|
|
641
|
+
{ value: "remove", label: "Remove plugin", hint: "Remove a plugin from profile" },
|
|
642
|
+
{ value: "list", label: "List plugins", hint: "List plugins in current profile" },
|
|
643
|
+
{ value: "search", label: "Search marketplace", hint: "Search plugins in marketplaces" },
|
|
644
|
+
{ value: "init", label: "Init project", hint: "Create .ccx.json for this project" },
|
|
645
|
+
{ value: "sync", label: "Sync project", hint: "Sync .claude/plugins/ to .ccx.json" },
|
|
646
|
+
{ value: "save", label: "Save as profile", hint: "Save .ccx.json plugins to a profile" },
|
|
604
647
|
{ value: "switch", label: "Switch profile", hint: "Choose a different profile" },
|
|
605
|
-
{ value: "delete", label: "Delete profile", hint: "
|
|
648
|
+
{ value: "delete", label: "Delete profile", hint: "Delete this profile" },
|
|
606
649
|
{ value: "exit", label: "Exit" },
|
|
607
650
|
],
|
|
608
651
|
});
|
|
@@ -621,6 +664,9 @@ async function interactiveMode() {
|
|
|
621
664
|
case "remove":
|
|
622
665
|
await removePlugin(currentProfile);
|
|
623
666
|
break;
|
|
667
|
+
case "list":
|
|
668
|
+
await listPlugins(currentProfile);
|
|
669
|
+
break;
|
|
624
670
|
case "search": {
|
|
625
671
|
const found = await browsePlugins(currentProfile);
|
|
626
672
|
if (found.length > 0) {
|
|
@@ -631,6 +677,15 @@ async function interactiveMode() {
|
|
|
631
677
|
}
|
|
632
678
|
break;
|
|
633
679
|
}
|
|
680
|
+
case "init":
|
|
681
|
+
await initProjectConfig();
|
|
682
|
+
break;
|
|
683
|
+
case "sync":
|
|
684
|
+
syncProjectConfig();
|
|
685
|
+
break;
|
|
686
|
+
case "save":
|
|
687
|
+
await saveToProfile();
|
|
688
|
+
break;
|
|
634
689
|
case "switch":
|
|
635
690
|
stayInProfile = false;
|
|
636
691
|
break;
|
|
@@ -645,30 +700,44 @@ async function interactiveMode() {
|
|
|
645
700
|
p.outro("Done.");
|
|
646
701
|
}
|
|
647
702
|
function printHelp() {
|
|
648
|
-
|
|
703
|
+
const require = createRequire(import.meta.url);
|
|
704
|
+
const pkg = require("../package.json");
|
|
705
|
+
console.log(`${renderLogo()}
|
|
706
|
+
${pc.bold("ccx")} ${pc.dim("- Agent Profile Manager for Claude Code")} ${pc.gray(`v${pkg.version}`)}
|
|
707
|
+
|
|
708
|
+
${pc.bold("Usage:")}
|
|
709
|
+
${pc.cyan("ccx")} Interactive mode (TTY)
|
|
710
|
+
${pc.cyan("ccx ui")} Interactive mode (TTY)
|
|
711
|
+
|
|
712
|
+
${pc.bold("Project:")}
|
|
713
|
+
${pc.cyan("ccx init")} Create .ccx.json for current project
|
|
714
|
+
${pc.cyan("ccx sync")} Sync installed plugins to .ccx.json
|
|
715
|
+
${pc.cyan("ccx install")} Install plugins from .ccx.json
|
|
716
|
+
${pc.cyan("ccx save")} ${pc.dim("[name]")} Save .ccx.json as a reusable profile
|
|
649
717
|
|
|
650
|
-
|
|
651
|
-
ccx
|
|
652
|
-
ccx
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
ccx install <profile> Install all plugins from profile
|
|
657
|
-
ccx
|
|
658
|
-
ccx
|
|
659
|
-
ccx
|
|
660
|
-
ccx
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
ccx
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
ccx <profile>
|
|
667
|
-
ccx <profile>
|
|
668
|
-
ccx
|
|
669
|
-
ccx
|
|
670
|
-
ccx
|
|
671
|
-
ccx
|
|
718
|
+
${pc.bold("Profiles:")}
|
|
719
|
+
${pc.cyan("ccx create")} ${pc.dim("<name>")} Create a new profile
|
|
720
|
+
${pc.cyan("ccx delete")} ${pc.dim("<name>")} Delete a profile
|
|
721
|
+
${pc.cyan("ccx profiles")} List all profiles
|
|
722
|
+
|
|
723
|
+
${pc.bold("Plugins:")}
|
|
724
|
+
${pc.cyan("ccx install")} ${pc.dim("<profile>")} Install all plugins from a profile
|
|
725
|
+
${pc.cyan("ccx add")} ${pc.dim("<profile> <plugin>")} Add a plugin to a profile
|
|
726
|
+
${pc.cyan("ccx remove")} ${pc.dim("<profile> <plugin>")} Remove a plugin from a profile
|
|
727
|
+
${pc.cyan("ccx list")} ${pc.dim("<profile>")} List plugins in a profile
|
|
728
|
+
${pc.cyan("ccx search")} ${pc.dim("<keyword>")} Search plugins in marketplaces
|
|
729
|
+
|
|
730
|
+
${pc.bold("Options:")}
|
|
731
|
+
${pc.cyan("ccx -v, --version")} Show version
|
|
732
|
+
|
|
733
|
+
${pc.dim("Legacy:")}
|
|
734
|
+
${pc.dim("ccx <profile>")} ${pc.dim("Same as ccx install <profile>")}
|
|
735
|
+
${pc.dim("ccx <profile> add [plugin]")} ${pc.dim("Same as ccx add <profile> <plugin>")}
|
|
736
|
+
${pc.dim("ccx <profile> remove [plugin]")} ${pc.dim("Same as ccx remove <profile> <plugin>")}
|
|
737
|
+
${pc.dim("ccx <profile> list")} ${pc.dim("Same as ccx list <profile>")}
|
|
738
|
+
${pc.dim("ccx add <name>")} ${pc.dim("Same as ccx create <name>")}
|
|
739
|
+
${pc.dim("ccx remove <name>")} ${pc.dim("Same as ccx delete <name>")}
|
|
740
|
+
${pc.dim("ccx list")} ${pc.dim("Same as ccx profiles")}`);
|
|
672
741
|
}
|
|
673
742
|
// ── Main ──────────────────────────────────────────────────
|
|
674
743
|
async function main(args) {
|
|
@@ -694,6 +763,9 @@ async function main(args) {
|
|
|
694
763
|
case "sync":
|
|
695
764
|
syncProjectConfig();
|
|
696
765
|
break;
|
|
766
|
+
case "save":
|
|
767
|
+
await saveToProfile(args[1]);
|
|
768
|
+
break;
|
|
697
769
|
case "ui":
|
|
698
770
|
case "tui":
|
|
699
771
|
case "interactive":
|