ccjk 7.0.2 → 7.0.3
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/chunks/index3.mjs +2 -2
- package/dist/chunks/init.mjs +1 -1
- package/dist/chunks/package.mjs +1 -1
- package/dist/chunks/preset.mjs +3 -871
- package/dist/cli.mjs +10 -13
- package/package.json +2 -2
package/dist/chunks/index3.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export { B as BUILTIN_PRESETS, P as PresetManager,
|
|
1
|
+
export { B as BUILTIN_PRESETS, P as PresetManager, g as getPresetById, a as getPresetManager, s as selectPreset } from './preset.mjs';
|
|
2
2
|
import 'ansis';
|
|
3
|
+
import 'inquirer';
|
|
3
4
|
import './index2.mjs';
|
|
4
5
|
import 'node:fs';
|
|
5
6
|
import 'node:process';
|
|
@@ -7,5 +8,4 @@ import 'node:url';
|
|
|
7
8
|
import 'i18next';
|
|
8
9
|
import 'i18next-fs-backend';
|
|
9
10
|
import 'pathe';
|
|
10
|
-
import 'inquirer';
|
|
11
11
|
import 'node:os';
|
package/dist/chunks/init.mjs
CHANGED
|
@@ -1775,7 +1775,7 @@ function showValueDrivenWelcome() {
|
|
|
1775
1775
|
}
|
|
1776
1776
|
async function init(options = {}) {
|
|
1777
1777
|
if (options.preset || options.presetInteractive) {
|
|
1778
|
-
const { handlePresetOption, getPresetConfiguration } = await import('./preset.mjs').then(function (n) { return n.
|
|
1778
|
+
const { handlePresetOption, getPresetConfiguration } = await import('./preset.mjs').then(function (n) { return n.p; });
|
|
1779
1779
|
const selectedPreset = await handlePresetOption(options.preset, options.presetInteractive);
|
|
1780
1780
|
if (selectedPreset) {
|
|
1781
1781
|
console.log(ansis__default.cyan(`
|
package/dist/chunks/package.mjs
CHANGED
package/dist/chunks/preset.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ansis__default from 'ansis';
|
|
2
|
-
import { i18n, ensureI18nInitialized } from './index2.mjs';
|
|
3
2
|
import inquirer from 'inquirer';
|
|
3
|
+
import { i18n } from './index2.mjs';
|
|
4
4
|
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
5
5
|
import { homedir } from 'node:os';
|
|
6
6
|
import { join } from 'pathe';
|
|
@@ -878,859 +878,7 @@ async function confirmRecommendedPreset(recommendedId, manager) {
|
|
|
878
878
|
]);
|
|
879
879
|
return confirm;
|
|
880
880
|
}
|
|
881
|
-
async function createCustomPreset(options = {}) {
|
|
882
|
-
const manager = getPresetManager();
|
|
883
|
-
console.log(ansis__default.cyan.bold(`
|
|
884
|
-
\u{1F4DD} ${i18n.t("preset.create.title")}`));
|
|
885
|
-
const answers = await inquirer.prompt([
|
|
886
|
-
{
|
|
887
|
-
type: "input",
|
|
888
|
-
name: "id",
|
|
889
|
-
message: i18n.t("preset.create.id"),
|
|
890
|
-
validate: (input) => {
|
|
891
|
-
if (!input)
|
|
892
|
-
return i18n.t("preset.create.idRequired");
|
|
893
|
-
if (!/^[a-z0-9-]+$/.test(input))
|
|
894
|
-
return i18n.t("preset.create.idInvalid");
|
|
895
|
-
return true;
|
|
896
|
-
}
|
|
897
|
-
},
|
|
898
|
-
{
|
|
899
|
-
type: "input",
|
|
900
|
-
name: "name",
|
|
901
|
-
message: i18n.t("preset.create.name"),
|
|
902
|
-
default: (answers2) => answers2.id
|
|
903
|
-
},
|
|
904
|
-
{
|
|
905
|
-
type: "input",
|
|
906
|
-
name: "description",
|
|
907
|
-
message: i18n.t("preset.create.description")
|
|
908
|
-
},
|
|
909
|
-
{
|
|
910
|
-
type: "input",
|
|
911
|
-
name: "icon",
|
|
912
|
-
message: i18n.t("preset.create.icon"),
|
|
913
|
-
default: "\u{1F4C1}"
|
|
914
|
-
}
|
|
915
|
-
]);
|
|
916
|
-
const currentConfig = {};
|
|
917
|
-
try {
|
|
918
|
-
const preset = await manager.createPresetFromCurrent(
|
|
919
|
-
answers.id,
|
|
920
|
-
answers.name,
|
|
921
|
-
answers.description,
|
|
922
|
-
currentConfig,
|
|
923
|
-
{
|
|
924
|
-
tags: ["custom"]
|
|
925
|
-
}
|
|
926
|
-
);
|
|
927
|
-
console.log(ansis__default.green(i18n.t("preset.create.success", { name: answers.name })));
|
|
928
|
-
} catch (error) {
|
|
929
|
-
console.error(ansis__default.red(i18n.t("preset.create.error", { error: error instanceof Error ? error.message : String(error) })));
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
async function exportPreset(presetId, outputPath) {
|
|
933
|
-
const manager = getPresetManager();
|
|
934
|
-
const preset = await manager.loadPreset(presetId);
|
|
935
|
-
if (!preset) {
|
|
936
|
-
console.error(ansis__default.red(i18n.t("preset.export.notFound", { id: presetId })));
|
|
937
|
-
return;
|
|
938
|
-
}
|
|
939
|
-
const json = manager.exportPreset(preset);
|
|
940
|
-
const path = outputPath || `${presetId}-preset.json`;
|
|
941
|
-
try {
|
|
942
|
-
const { writeFileSync } = await import('node:fs');
|
|
943
|
-
writeFileSync(path, json, "utf-8");
|
|
944
|
-
console.log(ansis__default.green(i18n.t("preset.export.success", { path })));
|
|
945
|
-
} catch (error) {
|
|
946
|
-
console.error(ansis__default.red(i18n.t("preset.export.error", { error: error instanceof Error ? error.message : String(error) })));
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
async function importPreset(inputPath) {
|
|
950
|
-
const manager = getPresetManager();
|
|
951
|
-
try {
|
|
952
|
-
const { readFileSync } = await import('node:fs');
|
|
953
|
-
const json = readFileSync(inputPath, "utf-8");
|
|
954
|
-
const preset = manager.importPreset(json);
|
|
955
|
-
await manager.savePreset(preset);
|
|
956
|
-
console.log(ansis__default.green(i18n.t("preset.import.success", { name: preset.name })));
|
|
957
|
-
} catch (error) {
|
|
958
|
-
console.error(ansis__default.red(i18n.t("preset.import.error", { error: error instanceof Error ? error.message : String(error) })));
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
async function switchPreset(presetId) {
|
|
962
|
-
const manager = getPresetManager();
|
|
963
|
-
const preset = await manager.loadPreset(presetId);
|
|
964
|
-
if (!preset) {
|
|
965
|
-
console.error(ansis__default.red(i18n.t("preset.switch.notFound", { id: presetId })));
|
|
966
|
-
return;
|
|
967
|
-
}
|
|
968
|
-
console.log(ansis__default.cyan.bold(i18n.t("preset.switch.title", { preset: `${preset.icon} ${i18n.t(preset.name)}` })));
|
|
969
|
-
const result = await manager.applyPreset(preset);
|
|
970
|
-
if (result.success) {
|
|
971
|
-
console.log(ansis__default.green(i18n.t("preset.switch.success")));
|
|
972
|
-
if (result.recommendations && result.recommendations.length > 0) {
|
|
973
|
-
console.log(ansis__default.yellow(`
|
|
974
|
-
${i18n.t("preset.switch.recommendations")}`));
|
|
975
|
-
result.recommendations.forEach((rec) => console.log(` \u2022 ${rec}`));
|
|
976
|
-
}
|
|
977
|
-
} else {
|
|
978
|
-
console.error(ansis__default.red(i18n.t("preset.switch.error")));
|
|
979
|
-
if (result.errors) {
|
|
980
|
-
result.errors.forEach((err) => console.error(` \u2022 ${err}`));
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
async function listPresets() {
|
|
985
|
-
const manager = getPresetManager();
|
|
986
|
-
const presets = await manager.getAllPresets();
|
|
987
|
-
console.log(ansis__default.cyan.bold(i18n.t("preset.list.title")));
|
|
988
|
-
console.log();
|
|
989
|
-
presets.forEach((preset) => {
|
|
990
|
-
const category = i18n.t(`preset.category.${preset.metadata.category}`);
|
|
991
|
-
console.log(`${preset.icon} ${ansis__default.bold(i18n.t(preset.name))} - ${i18n.t(preset.description)}`);
|
|
992
|
-
console.log(` ${ansis__default.gray(category)} | ${ansis__default.gray(preset.metadata.version)}`);
|
|
993
|
-
console.log();
|
|
994
|
-
});
|
|
995
|
-
}
|
|
996
|
-
async function showPresetDetails(presetId) {
|
|
997
|
-
const manager = getPresetManager();
|
|
998
|
-
const preset = await manager.loadPreset(presetId);
|
|
999
|
-
if (!preset) {
|
|
1000
|
-
console.error(ansis__default.red(i18n.t("preset.show.notFound", { id: presetId })));
|
|
1001
|
-
return;
|
|
1002
|
-
}
|
|
1003
|
-
console.log(ansis__default.cyan.bold(`
|
|
1004
|
-
${preset.icon} ${i18n.t(preset.name)}`));
|
|
1005
|
-
console.log(`${ansis__default.gray(i18n.t(preset.description))}`);
|
|
1006
|
-
console.log();
|
|
1007
|
-
console.log(ansis__default.bold(i18n.t("preset.show.features")));
|
|
1008
|
-
console.log(` MCP Services: ${preset.features.mcpServices.enabled ? "\u2713" : "\u2717"}`);
|
|
1009
|
-
console.log(` Workflows: ${preset.features.workflows.enabled ? "\u2713" : "\u2717"}`);
|
|
1010
|
-
console.log(` Hooks: ${preset.features.hooks.enabled ? "\u2713" : "\u2717"}`);
|
|
1011
|
-
console.log(` Cloud: ${preset.features.cloud.enabled ? "\u2713" : "\u2717"}`);
|
|
1012
|
-
console.log(` Skills: ${preset.features.skills.enabled ? "\u2713" : "\u2717"}`);
|
|
1013
|
-
const toolCount = Object.values(preset.features.tools).filter(Boolean).length;
|
|
1014
|
-
console.log(` Tools: ${toolCount}`);
|
|
1015
|
-
console.log();
|
|
1016
|
-
console.log(ansis__default.bold(i18n.t("preset.show.metadata")));
|
|
1017
|
-
console.log(` Version: ${preset.metadata.version}`);
|
|
1018
|
-
console.log(` Category: ${i18n.t(`preset.category.${preset.metadata.category}`)}`);
|
|
1019
|
-
console.log(` Created: ${preset.metadata.createdAt}`);
|
|
1020
|
-
if (preset.metadata.tags.length > 0) {
|
|
1021
|
-
console.log(` Tags: ${preset.metadata.tags.join(", ")}`);
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
async function deleteCustomPreset(presetId) {
|
|
1025
|
-
const manager = getPresetManager();
|
|
1026
|
-
const preset = await manager.loadPreset(presetId);
|
|
1027
|
-
if (!preset) {
|
|
1028
|
-
console.error(ansis__default.red(i18n.t("preset.delete.notFound", { id: presetId })));
|
|
1029
|
-
return;
|
|
1030
|
-
}
|
|
1031
|
-
if (preset.metadata.category === "built-in") {
|
|
1032
|
-
console.error(ansis__default.red(i18n.t("preset.delete.builtIn", { id: presetId })));
|
|
1033
|
-
return;
|
|
1034
|
-
}
|
|
1035
|
-
const { confirm } = await inquirer.prompt([
|
|
1036
|
-
{
|
|
1037
|
-
type: "confirm",
|
|
1038
|
-
name: "confirm",
|
|
1039
|
-
message: i18n.t("preset.delete.confirm", { name: preset.name }),
|
|
1040
|
-
default: false
|
|
1041
|
-
}
|
|
1042
|
-
]);
|
|
1043
|
-
if (confirm) {
|
|
1044
|
-
const deleted = await manager.deletePreset(presetId);
|
|
1045
|
-
if (deleted) {
|
|
1046
|
-
console.log(ansis__default.green(i18n.t("preset.delete.success", { name: preset.name })));
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
async function createTeamPreset(options) {
|
|
1051
|
-
const manager = getPresetManager();
|
|
1052
|
-
console.log(ansis__default.cyan.bold(i18n.t("preset.team.title")));
|
|
1053
|
-
const answers = await inquirer.prompt([
|
|
1054
|
-
{
|
|
1055
|
-
type: "input",
|
|
1056
|
-
name: "teamId",
|
|
1057
|
-
message: i18n.t("preset.team.id"),
|
|
1058
|
-
validate: (input) => input ? true : i18n.t("preset.team.idRequired")
|
|
1059
|
-
},
|
|
1060
|
-
{
|
|
1061
|
-
type: "input",
|
|
1062
|
-
name: "teamName",
|
|
1063
|
-
message: i18n.t("preset.team.name"),
|
|
1064
|
-
default: options.name
|
|
1065
|
-
},
|
|
1066
|
-
{
|
|
1067
|
-
type: "input",
|
|
1068
|
-
name: "password",
|
|
1069
|
-
message: i18n.t("preset.team.password"),
|
|
1070
|
-
validate: (input) => input.length >= 8 ? true : i18n.t("preset.team.passwordTooShort"),
|
|
1071
|
-
when: () => !options.public
|
|
1072
|
-
},
|
|
1073
|
-
{
|
|
1074
|
-
type: "input",
|
|
1075
|
-
name: "expiresAt",
|
|
1076
|
-
message: i18n.t("preset.team.expiresAt"),
|
|
1077
|
-
default: new Date(Date.now() + 30 * 24 * 60 * 60 * 1e3).toISOString(),
|
|
1078
|
-
// 30 days
|
|
1079
|
-
when: () => !options.public
|
|
1080
|
-
}
|
|
1081
|
-
]);
|
|
1082
|
-
const currentConfig = {};
|
|
1083
|
-
try {
|
|
1084
|
-
const preset = await manager.createPresetFromCurrent(
|
|
1085
|
-
`team-${options.name}`,
|
|
1086
|
-
options.name,
|
|
1087
|
-
options.description || "",
|
|
1088
|
-
currentConfig,
|
|
1089
|
-
{
|
|
1090
|
-
team: {
|
|
1091
|
-
id: answers.teamId,
|
|
1092
|
-
name: answers.teamName,
|
|
1093
|
-
description: options.description
|
|
1094
|
-
},
|
|
1095
|
-
sharing: {
|
|
1096
|
-
public: options.public || false,
|
|
1097
|
-
password: answers.password,
|
|
1098
|
-
expiresAt: answers.expiresAt
|
|
1099
|
-
},
|
|
1100
|
-
tags: ["team", options.name]
|
|
1101
|
-
}
|
|
1102
|
-
);
|
|
1103
|
-
console.log(ansis__default.green(i18n.t("preset.team.success", { name: options.name })));
|
|
1104
|
-
if (options.public) {
|
|
1105
|
-
console.log(ansis__default.yellow(i18n.t("preset.team.publicLink")));
|
|
1106
|
-
console.log(` npx ccjk preset import https://ccjk.cloud/team-presets/${preset.id}`);
|
|
1107
|
-
} else {
|
|
1108
|
-
console.log(ansis__default.yellow(i18n.t("preset.team.privateInfo")));
|
|
1109
|
-
console.log(` ${i18n.t("preset.team.teamId")}: ${answers.teamId}`);
|
|
1110
|
-
if (answers.password) {
|
|
1111
|
-
console.log(` ${i18n.t("preset.team.password")}: ${answers.password}`);
|
|
1112
|
-
}
|
|
1113
|
-
}
|
|
1114
|
-
} catch (error) {
|
|
1115
|
-
console.error(ansis__default.red(i18n.t("preset.team.error", { error: error instanceof Error ? error.message : String(error) })));
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
async function generatePresetFromTemplate(templateId, options) {
|
|
1119
|
-
const templates = {
|
|
1120
|
-
"typescript-project": {
|
|
1121
|
-
name: "TypeScript Project",
|
|
1122
|
-
description: "Optimized for TypeScript development",
|
|
1123
|
-
features: {
|
|
1124
|
-
mcpServices: { enabled: true, services: ["filesystem", "git", "brave-search"] },
|
|
1125
|
-
workflows: { enabled: true, selected: ["interviewWorkflow", "essentialTools"] },
|
|
1126
|
-
apiConfig: { type: "prompt" },
|
|
1127
|
-
tools: { ccr: true, cometix: true, superpowers: false, codex: false },
|
|
1128
|
-
outputStyles: { enabled: true, default: "engineer-professional" },
|
|
1129
|
-
hooks: { enabled: true },
|
|
1130
|
-
skills: { enabled: true },
|
|
1131
|
-
cloud: { enabled: false }
|
|
1132
|
-
}
|
|
1133
|
-
},
|
|
1134
|
-
"python-project": {
|
|
1135
|
-
name: "Python Project",
|
|
1136
|
-
description: "Optimized for Python development",
|
|
1137
|
-
features: {
|
|
1138
|
-
mcpServices: { enabled: true, services: ["filesystem", "git", "postgres", "sqlite"] },
|
|
1139
|
-
workflows: { enabled: true, selected: ["interviewWorkflow", "essentialTools"] },
|
|
1140
|
-
apiConfig: { type: "prompt" },
|
|
1141
|
-
tools: { ccr: true, cometix: false, superpowers: true, codex: false },
|
|
1142
|
-
outputStyles: { enabled: true, default: "concise" },
|
|
1143
|
-
hooks: { enabled: false },
|
|
1144
|
-
skills: { enabled: true },
|
|
1145
|
-
cloud: { enabled: false }
|
|
1146
|
-
}
|
|
1147
|
-
},
|
|
1148
|
-
"full-stack": {
|
|
1149
|
-
name: "Full Stack Project",
|
|
1150
|
-
description: "Complete configuration for full-stack development",
|
|
1151
|
-
features: {
|
|
1152
|
-
mcpServices: { enabled: true, services: ["filesystem", "git", "brave-search", "postgres", "sqlite"] },
|
|
1153
|
-
workflows: { enabled: true, selected: ["interviewWorkflow", "essentialTools", "gitWorkflow"] },
|
|
1154
|
-
apiConfig: { type: "prompt" },
|
|
1155
|
-
tools: { ccr: true, cometix: true, superpowers: true, codex: false },
|
|
1156
|
-
outputStyles: { enabled: true, default: "engineer-professional" },
|
|
1157
|
-
hooks: { enabled: true },
|
|
1158
|
-
skills: { enabled: true },
|
|
1159
|
-
cloud: { enabled: true }
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
};
|
|
1163
|
-
const template = templates[templateId];
|
|
1164
|
-
if (!template) {
|
|
1165
|
-
console.error(ansis__default.red(i18n.t("preset.template.notFound", { id: templateId })));
|
|
1166
|
-
return;
|
|
1167
|
-
}
|
|
1168
|
-
const manager = getPresetManager();
|
|
1169
|
-
try {
|
|
1170
|
-
const preset = {
|
|
1171
|
-
id: `template-${templateId}`,
|
|
1172
|
-
name: template.name,
|
|
1173
|
-
description: template.description,
|
|
1174
|
-
icon: "\u{1F4CB}",
|
|
1175
|
-
features: template.features,
|
|
1176
|
-
configuration: {
|
|
1177
|
-
claudeSettings: { model: "sonnet" },
|
|
1178
|
-
mcpConfig: { autoStart: true, timeout: 6e4 },
|
|
1179
|
-
flags: { verboseLogging: true, autoBackup: true, checkUpdates: true },
|
|
1180
|
-
ui: { interactive: true, showHints: true, confirmActions: true, progressBars: true }
|
|
1181
|
-
},
|
|
1182
|
-
metadata: {
|
|
1183
|
-
version: "1.0.0",
|
|
1184
|
-
description: `Generated from ${templateId} template`,
|
|
1185
|
-
category: "custom",
|
|
1186
|
-
tags: ["template", templateId],
|
|
1187
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1188
|
-
compatibility: { minVersion: "4.0.0" }
|
|
1189
|
-
}
|
|
1190
|
-
};
|
|
1191
|
-
await manager.savePreset(preset);
|
|
1192
|
-
console.log(ansis__default.green(i18n.t("preset.template.success", { name: template.name })));
|
|
1193
|
-
} catch (error) {
|
|
1194
|
-
console.error(ansis__default.red(i18n.t("preset.template.error", { error: error instanceof Error ? error.message : String(error) })));
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1197
|
-
async function validatePresetFile(filePath) {
|
|
1198
|
-
const manager = getPresetManager();
|
|
1199
|
-
try {
|
|
1200
|
-
const { readFileSync } = await import('node:fs');
|
|
1201
|
-
const json = readFileSync(filePath, "utf-8");
|
|
1202
|
-
const preset = manager.importPreset(json);
|
|
1203
|
-
console.log(ansis__default.green(i18n.t("preset.validate.success", { name: preset.name })));
|
|
1204
|
-
console.log(` ID: ${preset.id}`);
|
|
1205
|
-
console.log(` Version: ${preset.metadata.version}`);
|
|
1206
|
-
console.log(` Category: ${i18n.t(`preset.category.${preset.metadata.category}`)}`);
|
|
1207
|
-
} catch (error) {
|
|
1208
|
-
console.error(ansis__default.red(i18n.t("preset.validate.error", { error: error instanceof Error ? error.message : String(error) })));
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1211
|
-
|
|
1212
|
-
async function exportTeamPreset(presetId, options = {}) {
|
|
1213
|
-
const manager = getPresetManager();
|
|
1214
|
-
const preset = await manager.loadPreset(presetId);
|
|
1215
|
-
if (!preset) {
|
|
1216
|
-
throw new Error(i18n.t("preset.export.notFound", { id: presetId }));
|
|
1217
|
-
}
|
|
1218
|
-
const teamMetadata = {
|
|
1219
|
-
...preset.metadata,
|
|
1220
|
-
category: "team",
|
|
1221
|
-
team: {
|
|
1222
|
-
id: options.public ? "public" : `team-${Date.now()}`,
|
|
1223
|
-
name: `${preset.name} Team`,
|
|
1224
|
-
description: `Team preset based on ${preset.name}`
|
|
1225
|
-
},
|
|
1226
|
-
sharing: {
|
|
1227
|
-
public: options.public || false,
|
|
1228
|
-
password: options.password,
|
|
1229
|
-
expiresAt: options.expiresAt
|
|
1230
|
-
},
|
|
1231
|
-
tags: [...preset.metadata.tags, "team"]
|
|
1232
|
-
};
|
|
1233
|
-
const teamPreset = {
|
|
1234
|
-
...preset,
|
|
1235
|
-
id: `team-${presetId}`,
|
|
1236
|
-
metadata: teamMetadata
|
|
1237
|
-
};
|
|
1238
|
-
const exportDir = join(homedir(), ".ccjk", "team-presets");
|
|
1239
|
-
if (!existsSync(exportDir)) {
|
|
1240
|
-
const { mkdirSync } = await import('node:fs');
|
|
1241
|
-
mkdirSync(exportDir, { recursive: true });
|
|
1242
|
-
}
|
|
1243
|
-
const filePath = join(exportDir, `${teamPreset.id}.json`);
|
|
1244
|
-
writeFileSync(filePath, JSON.stringify(teamPreset, null, 2), "utf-8");
|
|
1245
|
-
return filePath;
|
|
1246
|
-
}
|
|
1247
|
-
async function importTeamPreset(pathOrUrl, options = {}) {
|
|
1248
|
-
let presetJson;
|
|
1249
|
-
if (pathOrUrl.startsWith("http://") || pathOrUrl.startsWith("https://")) {
|
|
1250
|
-
presetJson = await fetchPresetFromUrl(pathOrUrl);
|
|
1251
|
-
} else {
|
|
1252
|
-
if (!existsSync(pathOrUrl)) {
|
|
1253
|
-
throw new Error(i18n.t("preset.import.error", { error: "File not found" }));
|
|
1254
|
-
}
|
|
1255
|
-
presetJson = readFileSync(pathOrUrl, "utf-8");
|
|
1256
|
-
}
|
|
1257
|
-
const preset = JSON.parse(presetJson);
|
|
1258
|
-
if (preset.metadata.category !== "team") {
|
|
1259
|
-
throw new Error(i18n.t("preset.import.error", { error: "Not a team preset" }));
|
|
1260
|
-
}
|
|
1261
|
-
const teamMetadata = preset.metadata;
|
|
1262
|
-
if (teamMetadata.sharing?.password && teamMetadata.sharing.password !== options.password) {
|
|
1263
|
-
if (!options.password) {
|
|
1264
|
-
const { password } = await inquirer.prompt([
|
|
1265
|
-
{
|
|
1266
|
-
type: "password",
|
|
1267
|
-
name: "password",
|
|
1268
|
-
message: i18n.t("preset.team.password"),
|
|
1269
|
-
mask: "*"
|
|
1270
|
-
}
|
|
1271
|
-
]);
|
|
1272
|
-
if (password !== teamMetadata.sharing.password) {
|
|
1273
|
-
throw new Error(i18n.t("preset.import.error", { error: "Invalid password" }));
|
|
1274
|
-
}
|
|
1275
|
-
} else {
|
|
1276
|
-
throw new Error(i18n.t("preset.import.error", { error: "Invalid password" }));
|
|
1277
|
-
}
|
|
1278
|
-
}
|
|
1279
|
-
if (teamMetadata.sharing?.expiresAt) {
|
|
1280
|
-
const expiresAt = new Date(teamMetadata.sharing.expiresAt);
|
|
1281
|
-
if (expiresAt < /* @__PURE__ */ new Date()) {
|
|
1282
|
-
throw new Error(i18n.t("preset.import.error", { error: "Preset has expired" }));
|
|
1283
|
-
}
|
|
1284
|
-
}
|
|
1285
|
-
if (!options.skipValidation) {
|
|
1286
|
-
const manager = getPresetManager();
|
|
1287
|
-
await manager.savePreset(preset);
|
|
1288
|
-
}
|
|
1289
|
-
return preset;
|
|
1290
|
-
}
|
|
1291
|
-
async function listTeamPresets() {
|
|
1292
|
-
const manager = getPresetManager();
|
|
1293
|
-
const allPresets = await manager.getAllPresets();
|
|
1294
|
-
return allPresets.filter((p) => p.metadata.category === "team");
|
|
1295
|
-
}
|
|
1296
|
-
async function shareTeamPreset(presetId, options = {}) {
|
|
1297
|
-
const filePath = await exportTeamPreset(presetId, {
|
|
1298
|
-
public: options.public
|
|
1299
|
-
});
|
|
1300
|
-
if (options.repository) {
|
|
1301
|
-
return {
|
|
1302
|
-
type: "repository",
|
|
1303
|
-
location: options.repository,
|
|
1304
|
-
instructions: [
|
|
1305
|
-
`1. Copy preset file to repository: ${filePath}`,
|
|
1306
|
-
`2. Commit and push to repository: ${options.repository}`,
|
|
1307
|
-
`3. Team members can import with: npx ccjk preset import ${presetId}.json`
|
|
1308
|
-
]
|
|
1309
|
-
};
|
|
1310
|
-
}
|
|
1311
|
-
if (options.public) {
|
|
1312
|
-
return {
|
|
1313
|
-
type: "url",
|
|
1314
|
-
location: `https://ccjk.cloud/team-presets/${presetId}`,
|
|
1315
|
-
instructions: [
|
|
1316
|
-
`1. Share this URL with your team`,
|
|
1317
|
-
`2. Team members can import with: npx ccjk preset import ${presetId}`,
|
|
1318
|
-
`3. Or use the direct URL: npx ccjk preset import https://ccjk.cloud/team-presets/${presetId}`
|
|
1319
|
-
]
|
|
1320
|
-
};
|
|
1321
|
-
}
|
|
1322
|
-
return {
|
|
1323
|
-
type: "file",
|
|
1324
|
-
location: filePath,
|
|
1325
|
-
instructions: [
|
|
1326
|
-
`1. Share this file with your team: ${filePath}`,
|
|
1327
|
-
`2. Team members can import with: npx ccjk preset import ${filePath}`,
|
|
1328
|
-
`3. For password-protected presets, share the password separately`
|
|
1329
|
-
]
|
|
1330
|
-
};
|
|
1331
|
-
}
|
|
1332
|
-
async function createTeamPresetInteractive() {
|
|
1333
|
-
console.log(ansis__default.cyan.bold(`
|
|
1334
|
-
${i18n.t("preset.team.title")}`));
|
|
1335
|
-
const manager = getPresetManager();
|
|
1336
|
-
const allPresets = await manager.getAllPresets();
|
|
1337
|
-
const basePresets = allPresets.filter((p) => p.metadata.category === "built-in");
|
|
1338
|
-
const answers = await inquirer.prompt([
|
|
1339
|
-
{
|
|
1340
|
-
type: "list",
|
|
1341
|
-
name: "basePreset",
|
|
1342
|
-
message: "Select base preset:",
|
|
1343
|
-
choices: basePresets.map((p) => ({
|
|
1344
|
-
name: `${p.icon} ${p.name}`,
|
|
1345
|
-
value: p.id
|
|
1346
|
-
}))
|
|
1347
|
-
},
|
|
1348
|
-
{
|
|
1349
|
-
type: "input",
|
|
1350
|
-
name: "teamName",
|
|
1351
|
-
message: i18n.t("preset.team.name"),
|
|
1352
|
-
validate: (input) => input ? true : i18n.t("preset.team.idRequired")
|
|
1353
|
-
},
|
|
1354
|
-
{
|
|
1355
|
-
type: "input",
|
|
1356
|
-
name: "teamDescription",
|
|
1357
|
-
message: "Team Description (optional):"
|
|
1358
|
-
},
|
|
1359
|
-
{
|
|
1360
|
-
type: "list",
|
|
1361
|
-
name: "accessType",
|
|
1362
|
-
message: "Access Type:",
|
|
1363
|
-
choices: [
|
|
1364
|
-
{ name: "Private (password protected)", value: "private" },
|
|
1365
|
-
{ name: "Public (no password)", value: "public" }
|
|
1366
|
-
]
|
|
1367
|
-
},
|
|
1368
|
-
{
|
|
1369
|
-
type: "password",
|
|
1370
|
-
name: "password",
|
|
1371
|
-
message: i18n.t("preset.team.password"),
|
|
1372
|
-
mask: "*",
|
|
1373
|
-
validate: (input) => input.length >= 8 || "Password must be at least 8 characters",
|
|
1374
|
-
when: (answers2) => answers2.accessType === "private"
|
|
1375
|
-
},
|
|
1376
|
-
{
|
|
1377
|
-
type: "input",
|
|
1378
|
-
name: "expiresIn",
|
|
1379
|
-
message: "Expiration (days, 0 for never):",
|
|
1380
|
-
default: "30",
|
|
1381
|
-
validate: (input) => {
|
|
1382
|
-
const days = Number.parseInt(input);
|
|
1383
|
-
return !Number.isNaN(days) && days >= 0 || "Please enter a valid number";
|
|
1384
|
-
},
|
|
1385
|
-
filter: (input) => Number.parseInt(input)
|
|
1386
|
-
}
|
|
1387
|
-
]);
|
|
1388
|
-
const expiresAt = answers.expiresIn > 0 ? new Date(Date.now() + answers.expiresIn * 24 * 60 * 60 * 1e3).toISOString() : void 0;
|
|
1389
|
-
const basePreset = await manager.loadPreset(answers.basePreset);
|
|
1390
|
-
const teamPreset = {
|
|
1391
|
-
...basePreset,
|
|
1392
|
-
id: `team-${answers.teamName.toLowerCase().replace(/\s+/g, "-")}`,
|
|
1393
|
-
name: answers.teamName,
|
|
1394
|
-
description: answers.teamDescription || basePreset.description,
|
|
1395
|
-
metadata: {
|
|
1396
|
-
...basePreset.metadata,
|
|
1397
|
-
category: "team",
|
|
1398
|
-
team: {
|
|
1399
|
-
id: `team-${Date.now()}`,
|
|
1400
|
-
name: answers.teamName,
|
|
1401
|
-
description: answers.teamDescription
|
|
1402
|
-
},
|
|
1403
|
-
sharing: {
|
|
1404
|
-
public: answers.accessType === "public",
|
|
1405
|
-
password: answers.password,
|
|
1406
|
-
expiresAt
|
|
1407
|
-
},
|
|
1408
|
-
tags: [...basePreset.metadata.tags, "team", answers.teamName.toLowerCase()]
|
|
1409
|
-
}
|
|
1410
|
-
};
|
|
1411
|
-
await manager.savePreset(teamPreset);
|
|
1412
|
-
console.log(ansis__default.green(i18n.t("preset.team.success", { name: answers.teamName })));
|
|
1413
|
-
const shareInfo = await shareTeamPreset(teamPreset.id, {
|
|
1414
|
-
public: answers.accessType === "public"
|
|
1415
|
-
});
|
|
1416
|
-
console.log();
|
|
1417
|
-
console.log(ansis__default.yellow.bold("Sharing Information:"));
|
|
1418
|
-
console.log(` File: ${shareInfo.location}`);
|
|
1419
|
-
shareInfo.instructions.forEach((instruction, i) => {
|
|
1420
|
-
console.log(` ${i + 1}. ${instruction}`);
|
|
1421
|
-
});
|
|
1422
|
-
}
|
|
1423
|
-
async function fetchPresetFromUrl(url) {
|
|
1424
|
-
try {
|
|
1425
|
-
const response = await fetch(url);
|
|
1426
|
-
if (!response.ok) {
|
|
1427
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
1428
|
-
}
|
|
1429
|
-
return await response.text();
|
|
1430
|
-
} catch (error) {
|
|
1431
|
-
throw new Error(i18n.t("preset.import.error", { error: error instanceof Error ? error.message : String(error) }));
|
|
1432
|
-
}
|
|
1433
|
-
}
|
|
1434
|
-
async function getTeamPresetInfo(presetId) {
|
|
1435
|
-
const manager = getPresetManager();
|
|
1436
|
-
const preset = await manager.loadPreset(presetId);
|
|
1437
|
-
if (!preset || preset.metadata.category !== "team") {
|
|
1438
|
-
return { exists: false };
|
|
1439
|
-
}
|
|
1440
|
-
const teamMetadata = preset.metadata;
|
|
1441
|
-
let isExpired = false;
|
|
1442
|
-
let daysUntilExpiration;
|
|
1443
|
-
if (teamMetadata.sharing?.expiresAt) {
|
|
1444
|
-
const expiresAt = new Date(teamMetadata.sharing.expiresAt);
|
|
1445
|
-
isExpired = expiresAt < /* @__PURE__ */ new Date();
|
|
1446
|
-
daysUntilExpiration = Math.ceil((expiresAt.getTime() - Date.now()) / (1e3 * 60 * 60 * 24));
|
|
1447
|
-
}
|
|
1448
|
-
return {
|
|
1449
|
-
preset,
|
|
1450
|
-
exists: true,
|
|
1451
|
-
isExpired,
|
|
1452
|
-
daysUntilExpiration
|
|
1453
|
-
};
|
|
1454
|
-
}
|
|
1455
881
|
|
|
1456
|
-
function registerPresetCommands(cli) {
|
|
1457
|
-
const presetCmd = cli.command("preset [action]", i18n.t("cli.preset.description")).alias("p").option("-l, --list", i18n.t("cli.preset.list")).option("-c, --create", i18n.t("cli.preset.create")).option("-e, --export <preset>", i18n.t("cli.preset.export")).option("-i, --import <file>", i18n.t("cli.preset.import")).option("-d, --delete <preset>", i18n.t("cli.preset.delete")).option("-s, --switch <preset>", i18n.t("cli.preset.switch")).option("--show <preset>", i18n.t("cli.preset.show")).option("--template <id>", i18n.t("cli.preset.template")).option("--team", i18n.t("cli.preset.team")).option("--validate <file>", i18n.t("cli.preset.validate")).option("--lang <lang>", i18n.t("cli.preset.lang")).action(async (action, options) => {
|
|
1458
|
-
ensureI18nInitialized();
|
|
1459
|
-
try {
|
|
1460
|
-
await handlePresetAction(action, options);
|
|
1461
|
-
} catch (error) {
|
|
1462
|
-
console.error(ansis__default.red(i18n.t("cli.preset.error", { error: error instanceof Error ? error.message : String(error) })));
|
|
1463
|
-
process.exit(1);
|
|
1464
|
-
}
|
|
1465
|
-
});
|
|
1466
|
-
presetCmd.command("list", i18n.t("cli.preset.list")).alias("ls").option("--lang <lang>", i18n.t("cli.preset.lang")).action(async (options) => {
|
|
1467
|
-
ensureI18nInitialized();
|
|
1468
|
-
await listPresets();
|
|
1469
|
-
});
|
|
1470
|
-
presetCmd.command("create [name]", i18n.t("cli.preset.create")).option("--lang <lang>", i18n.t("cli.preset.lang")).option("--team", i18n.t("cli.preset.team")).option("--description <desc>", i18n.t("cli.preset.description")).option("--public", i18n.t("cli.preset.public")).action(async (name, options) => {
|
|
1471
|
-
ensureI18nInitialized();
|
|
1472
|
-
if (options.team) {
|
|
1473
|
-
await createTeamPreset({
|
|
1474
|
-
name: name || "team-standard",
|
|
1475
|
-
description: options.description,
|
|
1476
|
-
public: options.public
|
|
1477
|
-
});
|
|
1478
|
-
} else {
|
|
1479
|
-
await createCustomPreset({ lang: options.lang });
|
|
1480
|
-
}
|
|
1481
|
-
});
|
|
1482
|
-
presetCmd.command("export <preset>", i18n.t("cli.preset.export")).option("-o, --output <file>", i18n.t("cli.preset.output")).action(async (preset, options) => {
|
|
1483
|
-
ensureI18nInitialized();
|
|
1484
|
-
await exportPreset(preset, options.output);
|
|
1485
|
-
});
|
|
1486
|
-
presetCmd.command("import <file>", i18n.t("cli.preset.import")).action(async (file) => {
|
|
1487
|
-
ensureI18nInitialized();
|
|
1488
|
-
await importPreset(file);
|
|
1489
|
-
});
|
|
1490
|
-
presetCmd.command("delete <preset>", i18n.t("cli.preset.delete")).alias("rm").action(async (preset) => {
|
|
1491
|
-
ensureI18nInitialized();
|
|
1492
|
-
await deleteCustomPreset(preset);
|
|
1493
|
-
});
|
|
1494
|
-
presetCmd.command("switch <preset>", i18n.t("cli.preset.switch")).alias("use").action(async (preset) => {
|
|
1495
|
-
ensureI18nInitialized();
|
|
1496
|
-
await switchPreset(preset);
|
|
1497
|
-
});
|
|
1498
|
-
presetCmd.command("show <preset>", i18n.t("cli.preset.show")).action(async (preset) => {
|
|
1499
|
-
ensureI18nInitialized();
|
|
1500
|
-
await showPresetDetails(preset);
|
|
1501
|
-
});
|
|
1502
|
-
presetCmd.command("validate <file>", i18n.t("cli.preset.validate")).action(async (file) => {
|
|
1503
|
-
ensureI18nInitialized();
|
|
1504
|
-
await validatePresetFile(file);
|
|
1505
|
-
});
|
|
1506
|
-
presetCmd.command("generate <template>", i18n.t("cli.preset.generate")).action(async (template, options) => {
|
|
1507
|
-
ensureI18nInitialized();
|
|
1508
|
-
await generatePresetFromTemplate(template);
|
|
1509
|
-
});
|
|
1510
|
-
presetCmd.command("current", "Show currently active preset").alias("active").action(async () => {
|
|
1511
|
-
ensureI18nInitialized();
|
|
1512
|
-
await showCurrentPreset();
|
|
1513
|
-
});
|
|
1514
|
-
presetCmd.command("diff <preset1> <preset2>", "Compare two presets").action(async (preset1, preset2) => {
|
|
1515
|
-
ensureI18nInitialized();
|
|
1516
|
-
await comparePresets(preset1, preset2);
|
|
1517
|
-
});
|
|
1518
|
-
presetCmd.command("team-create [basePreset]", "Create a team preset interactively").action(async (basePreset) => {
|
|
1519
|
-
ensureI18nInitialized();
|
|
1520
|
-
await createTeamPresetInteractive();
|
|
1521
|
-
});
|
|
1522
|
-
presetCmd.command("team-export <preset>", "Export a preset as team preset").option("--public", "Make preset public (no password)").option("--password <pwd>", "Set access password").option("--expires <days>", "Expiration in days (0 = never)").action(async (preset, options) => {
|
|
1523
|
-
ensureI18nInitialized();
|
|
1524
|
-
const expiresAt = options.expires ? new Date(Date.now() + Number.parseInt(options.expires) * 24 * 60 * 60 * 1e3).toISOString() : void 0;
|
|
1525
|
-
const filePath = await exportTeamPreset(preset, {
|
|
1526
|
-
public: options.public,
|
|
1527
|
-
password: options.password,
|
|
1528
|
-
expiresAt
|
|
1529
|
-
});
|
|
1530
|
-
console.log(ansis__default.green(`Team preset exported to: ${filePath}`));
|
|
1531
|
-
});
|
|
1532
|
-
presetCmd.command("team-import <pathOrUrl>", "Import a team preset").option("--password <pwd>", "Access password for protected preset").action(async (pathOrUrl, options) => {
|
|
1533
|
-
ensureI18nInitialized();
|
|
1534
|
-
try {
|
|
1535
|
-
const preset = await importTeamPreset(pathOrUrl, {
|
|
1536
|
-
password: options.password
|
|
1537
|
-
});
|
|
1538
|
-
console.log(ansis__default.green(`Team preset imported: ${preset.name}`));
|
|
1539
|
-
} catch (error) {
|
|
1540
|
-
console.error(ansis__default.red(`Import failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
1541
|
-
}
|
|
1542
|
-
});
|
|
1543
|
-
presetCmd.command("team-list", "List all team presets").action(async () => {
|
|
1544
|
-
ensureI18nInitialized();
|
|
1545
|
-
const teamPresets = await listTeamPresets();
|
|
1546
|
-
console.log(ansis__default.cyan.bold("\nTeam Presets:"));
|
|
1547
|
-
console.log();
|
|
1548
|
-
for (const preset of teamPresets) {
|
|
1549
|
-
const info = await getTeamPresetInfo(preset.id);
|
|
1550
|
-
console.log(`${preset.icon} ${ansis__default.bold(preset.name)} (${preset.id})`);
|
|
1551
|
-
if (info.daysUntilExpiration !== void 0) {
|
|
1552
|
-
console.log(` Expires: ${info.isExpired ? ansis__default.red("EXPIRED") : ansis__default.green(`${info.daysUntilExpiration} days`)}`);
|
|
1553
|
-
}
|
|
1554
|
-
}
|
|
1555
|
-
});
|
|
1556
|
-
}
|
|
1557
|
-
async function showCurrentPreset() {
|
|
1558
|
-
const currentPresetId = await loadPresetPreference();
|
|
1559
|
-
if (!currentPresetId) {
|
|
1560
|
-
console.log(ansis__default.yellow("No active preset configured."));
|
|
1561
|
-
console.log("Use `npx ccjk preset switch <id>` to set an active preset.");
|
|
1562
|
-
return;
|
|
1563
|
-
}
|
|
1564
|
-
const { getPresetManager } = await import('./index3.mjs');
|
|
1565
|
-
const manager = getPresetManager();
|
|
1566
|
-
const preset = await manager.loadPreset(currentPresetId);
|
|
1567
|
-
if (!preset) {
|
|
1568
|
-
console.log(ansis__default.yellow(`Active preset '${currentPresetId}' not found.`));
|
|
1569
|
-
return;
|
|
1570
|
-
}
|
|
1571
|
-
console.log(ansis__default.cyan.bold(`
|
|
1572
|
-
Current Preset: ${preset.icon} ${i18n.t(preset.name)}`));
|
|
1573
|
-
console.log(ansis__default.gray(i18n.t(preset.description)));
|
|
1574
|
-
console.log();
|
|
1575
|
-
console.log(ansis__default.bold("Features:"));
|
|
1576
|
-
console.log(` MCP Services: ${preset.features.mcpServices.enabled ? "Enabled" : "Disabled"}`);
|
|
1577
|
-
console.log(` Workflows: ${preset.features.workflows.enabled ? "Enabled" : "Disabled"}`);
|
|
1578
|
-
console.log(` Cloud: ${preset.features.cloud.enabled ? "Enabled" : "Disabled"}`);
|
|
1579
|
-
console.log(` Skills: ${preset.features.skills.enabled ? "Enabled" : "Disabled"}`);
|
|
1580
|
-
const toolCount = Object.values(preset.features.tools).filter(Boolean).length;
|
|
1581
|
-
console.log(` Tools: ${toolCount} enabled`);
|
|
1582
|
-
}
|
|
1583
|
-
async function comparePresets(presetId1, presetId2) {
|
|
1584
|
-
const { getPresetManager } = await import('./index3.mjs');
|
|
1585
|
-
const manager = getPresetManager();
|
|
1586
|
-
const preset1 = await manager.loadPreset(presetId1);
|
|
1587
|
-
const preset2 = await manager.loadPreset(presetId2);
|
|
1588
|
-
if (!preset1) {
|
|
1589
|
-
console.error(ansis__default.red(`Preset not found: ${presetId1}`));
|
|
1590
|
-
return;
|
|
1591
|
-
}
|
|
1592
|
-
if (!preset2) {
|
|
1593
|
-
console.error(ansis__default.red(`Preset not found: ${presetId2}`));
|
|
1594
|
-
return;
|
|
1595
|
-
}
|
|
1596
|
-
console.log(ansis__default.cyan.bold(`
|
|
1597
|
-
Comparing Presets:`));
|
|
1598
|
-
console.log();
|
|
1599
|
-
Math.max(preset1.name.length, preset2.name.length) + 4;
|
|
1600
|
-
console.log(`${ansis__default.bold(presetId1.padEnd(20))} | ${ansis__default.bold(presetId2.padEnd(20))} | Feature`);
|
|
1601
|
-
console.log("=".repeat(60));
|
|
1602
|
-
console.log(`${`${preset1.icon} ${preset1.name}`.padEnd(20)} | ${`${preset2.icon} ${preset2.name}`.padEnd(20)} | Name`);
|
|
1603
|
-
const features = [
|
|
1604
|
-
{ key: "mcpServices.enabled", label: "MCP Services" },
|
|
1605
|
-
{ key: "workflows.enabled", label: "Workflows" },
|
|
1606
|
-
{ key: "cloud.enabled", label: "Cloud" },
|
|
1607
|
-
{ key: "skills.enabled", label: "Skills" },
|
|
1608
|
-
{ key: "hooks.enabled", label: "Hooks" }
|
|
1609
|
-
];
|
|
1610
|
-
for (const feature of features) {
|
|
1611
|
-
const keys = feature.key.split(".");
|
|
1612
|
-
const value1 = keys.reduce((obj, k) => obj?.[k], preset1.features) ?? false;
|
|
1613
|
-
const value2 = keys.reduce((obj, k) => obj?.[k], preset2.features) ?? false;
|
|
1614
|
-
const sym1 = value1 ? "\u2713" : "\u2717";
|
|
1615
|
-
const sym2 = value2 ? "\u2713" : "\u2717";
|
|
1616
|
-
const color1 = value1 ? ansis__default.green : ansis__default.red;
|
|
1617
|
-
const color2 = value2 ? ansis__default.green : ansis__default.red;
|
|
1618
|
-
console.log(`${color1(sym1).padEnd(20)} | ${color2(sym2).padEnd(20)} | ${feature.label}`);
|
|
1619
|
-
}
|
|
1620
|
-
const toolCount1 = Object.values(preset1.features.tools).filter(Boolean).length;
|
|
1621
|
-
const toolCount2 = Object.values(preset2.features.tools).filter(Boolean).length;
|
|
1622
|
-
console.log(`${String(toolCount1).padEnd(20)} | ${String(toolCount2).padEnd(20)} | Tools`);
|
|
1623
|
-
const getComplexity = (id) => {
|
|
1624
|
-
if (id === "beginner")
|
|
1625
|
-
return "Low";
|
|
1626
|
-
if (id === "advanced")
|
|
1627
|
-
return "Medium";
|
|
1628
|
-
if (id === "expert")
|
|
1629
|
-
return "High";
|
|
1630
|
-
return "Custom";
|
|
1631
|
-
};
|
|
1632
|
-
console.log(`${getComplexity(presetId1).padEnd(20)} | ${getComplexity(presetId2).padEnd(20)} | Complexity`);
|
|
1633
|
-
console.log();
|
|
1634
|
-
}
|
|
1635
|
-
async function handlePresetAction(action, options) {
|
|
1636
|
-
if (options.list) {
|
|
1637
|
-
await listPresets();
|
|
1638
|
-
return;
|
|
1639
|
-
}
|
|
1640
|
-
if (options.create) {
|
|
1641
|
-
if (options.team) {
|
|
1642
|
-
await createTeamPreset({
|
|
1643
|
-
name: "team-standard",
|
|
1644
|
-
description: options.description,
|
|
1645
|
-
public: false
|
|
1646
|
-
});
|
|
1647
|
-
} else {
|
|
1648
|
-
await createCustomPreset({ lang: options.lang });
|
|
1649
|
-
}
|
|
1650
|
-
return;
|
|
1651
|
-
}
|
|
1652
|
-
if (options.export) {
|
|
1653
|
-
await exportPreset(options.export);
|
|
1654
|
-
return;
|
|
1655
|
-
}
|
|
1656
|
-
if (options.import) {
|
|
1657
|
-
await importPreset(options.import);
|
|
1658
|
-
return;
|
|
1659
|
-
}
|
|
1660
|
-
if (options.delete) {
|
|
1661
|
-
await deleteCustomPreset(options.delete);
|
|
1662
|
-
return;
|
|
1663
|
-
}
|
|
1664
|
-
if (options.switch) {
|
|
1665
|
-
await switchPreset(options.switch);
|
|
1666
|
-
return;
|
|
1667
|
-
}
|
|
1668
|
-
if (options.show) {
|
|
1669
|
-
await showPresetDetails(options.show);
|
|
1670
|
-
return;
|
|
1671
|
-
}
|
|
1672
|
-
if (options.template) {
|
|
1673
|
-
await generatePresetFromTemplate(options.template);
|
|
1674
|
-
return;
|
|
1675
|
-
}
|
|
1676
|
-
if (options.validate) {
|
|
1677
|
-
await validatePresetFile(options.validate);
|
|
1678
|
-
return;
|
|
1679
|
-
}
|
|
1680
|
-
switch (action) {
|
|
1681
|
-
case "list":
|
|
1682
|
-
case "ls":
|
|
1683
|
-
await listPresets();
|
|
1684
|
-
break;
|
|
1685
|
-
case "create":
|
|
1686
|
-
if (options.team) {
|
|
1687
|
-
await createTeamPreset({
|
|
1688
|
-
name: "team-standard",
|
|
1689
|
-
description: options.description,
|
|
1690
|
-
public: false
|
|
1691
|
-
});
|
|
1692
|
-
} else {
|
|
1693
|
-
await createCustomPreset({ lang: options.lang });
|
|
1694
|
-
}
|
|
1695
|
-
break;
|
|
1696
|
-
case "export":
|
|
1697
|
-
console.error(ansis__default.red(i18n.t("cli.preset.exportRequired")));
|
|
1698
|
-
break;
|
|
1699
|
-
case "import":
|
|
1700
|
-
console.error(ansis__default.red(i18n.t("cli.preset.importRequired")));
|
|
1701
|
-
break;
|
|
1702
|
-
case "delete":
|
|
1703
|
-
case "rm":
|
|
1704
|
-
console.error(ansis__default.red(i18n.t("cli.preset.deleteRequired")));
|
|
1705
|
-
break;
|
|
1706
|
-
case "switch":
|
|
1707
|
-
case "use":
|
|
1708
|
-
console.error(ansis__default.red(i18n.t("cli.preset.switchRequired")));
|
|
1709
|
-
break;
|
|
1710
|
-
case "show":
|
|
1711
|
-
console.error(ansis__default.red(i18n.t("cli.preset.showRequired")));
|
|
1712
|
-
break;
|
|
1713
|
-
case "validate":
|
|
1714
|
-
console.error(ansis__default.red(i18n.t("cli.preset.validateRequired")));
|
|
1715
|
-
break;
|
|
1716
|
-
case "generate":
|
|
1717
|
-
console.error(ansis__default.red(i18n.t("cli.preset.generateRequired")));
|
|
1718
|
-
break;
|
|
1719
|
-
default:
|
|
1720
|
-
const selected = await selectPreset({
|
|
1721
|
-
lang: options.lang,
|
|
1722
|
-
showComparison: true,
|
|
1723
|
-
allowCustom: true,
|
|
1724
|
-
skipQuestionnaire: false
|
|
1725
|
-
});
|
|
1726
|
-
if (selected) {
|
|
1727
|
-
await switchPreset(selected);
|
|
1728
|
-
} else {
|
|
1729
|
-
console.log(ansis__default.yellow(i18n.t("cli.preset.cancelled")));
|
|
1730
|
-
}
|
|
1731
|
-
break;
|
|
1732
|
-
}
|
|
1733
|
-
}
|
|
1734
882
|
async function handlePresetOption(presetId, interactive) {
|
|
1735
883
|
if (presetId) {
|
|
1736
884
|
return presetId;
|
|
@@ -1799,27 +947,11 @@ async function getPresetConfiguration(presetId) {
|
|
|
1799
947
|
}
|
|
1800
948
|
return initOptions;
|
|
1801
949
|
}
|
|
1802
|
-
async function loadPresetPreference() {
|
|
1803
|
-
try {
|
|
1804
|
-
const { homedir } = await import('node:os');
|
|
1805
|
-
const { join } = await import('pathe');
|
|
1806
|
-
const { readFileSync, existsSync } = await import('node:fs');
|
|
1807
|
-
const configFile = join(homedir(), ".ccjk", "config.json");
|
|
1808
|
-
if (existsSync(configFile)) {
|
|
1809
|
-
const config = JSON.parse(readFileSync(configFile, "utf-8"));
|
|
1810
|
-
return config.preset || null;
|
|
1811
|
-
}
|
|
1812
|
-
} catch {
|
|
1813
|
-
}
|
|
1814
|
-
return null;
|
|
1815
|
-
}
|
|
1816
950
|
|
|
1817
951
|
const preset = {
|
|
1818
952
|
__proto__: null,
|
|
1819
953
|
getPresetConfiguration: getPresetConfiguration,
|
|
1820
|
-
handlePresetOption: handlePresetOption
|
|
1821
|
-
loadPresetPreference: loadPresetPreference,
|
|
1822
|
-
registerPresetCommands: registerPresetCommands
|
|
954
|
+
handlePresetOption: handlePresetOption
|
|
1823
955
|
};
|
|
1824
956
|
|
|
1825
|
-
export { BUILTIN_PRESETS as B, PresetManager as P,
|
|
957
|
+
export { BUILTIN_PRESETS as B, PresetManager as P, getPresetManager as a, getPresetById as g, preset as p, selectPreset as s };
|
package/dist/cli.mjs
CHANGED
|
@@ -1021,13 +1021,16 @@ ${chalk.yellow("By Status:")}`);
|
|
|
1021
1021
|
{ flags: "--validate <file>", description: "Validate preset file" }
|
|
1022
1022
|
],
|
|
1023
1023
|
loader: async () => {
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1024
|
+
return async (options, _action) => {
|
|
1025
|
+
console.log("\n\u{1F39B}\uFE0F Preset System");
|
|
1026
|
+
console.log('Run "ccjk preset" with specific subcommand:');
|
|
1027
|
+
console.log(" ccjk preset list - List presets");
|
|
1028
|
+
console.log(" ccjk preset create - Create a preset");
|
|
1029
|
+
console.log(" ccjk preset import - Import preset from a JSON file");
|
|
1030
|
+
console.log(" ccjk preset export - Export preset to a JSON file");
|
|
1031
|
+
console.log(" ccjk preset switch - Switch to a different preset");
|
|
1032
|
+
console.log(" ccjk preset validate - Validate preset file");
|
|
1033
|
+
console.log(" ccjk preset show - Show preset details\n");
|
|
1031
1034
|
};
|
|
1032
1035
|
}
|
|
1033
1036
|
}
|
|
@@ -1296,10 +1299,4 @@ function bootstrapCloudServices() {
|
|
|
1296
1299
|
});
|
|
1297
1300
|
}
|
|
1298
1301
|
|
|
1299
|
-
const cliLazy = {
|
|
1300
|
-
__proto__: null,
|
|
1301
|
-
runLazyCli: runLazyCli,
|
|
1302
|
-
setupCommandsLazy: setupCommandsLazy
|
|
1303
|
-
};
|
|
1304
|
-
|
|
1305
1302
|
runLazyCli().catch(console.error);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccjk",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "7.0.
|
|
4
|
+
"version": "7.0.3",
|
|
5
5
|
"packageManager": "pnpm@10.17.1",
|
|
6
6
|
"description": "Claude Code JinKu - Advanced AI-powered development assistant with skills, agents, and LLM-driven audit",
|
|
7
7
|
"author": {
|
|
@@ -189,4 +189,4 @@
|
|
|
189
189
|
"pnpm lint"
|
|
190
190
|
]
|
|
191
191
|
}
|
|
192
|
-
}
|
|
192
|
+
}
|