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.
@@ -1,5 +1,6 @@
1
- export { B as BUILTIN_PRESETS, P as PresetManager, c as createCustomPreset, a as createTeamPreset, k as createTeamPresetInteractive, d as deleteCustomPreset, e as exportPreset, m as exportTeamPreset, b as generatePresetFromTemplate, g as getPresetById, j as getPresetManager, n as getTeamPresetInfo, i as importPreset, o as importTeamPreset, l as listPresets, p as listTeamPresets, s as selectPreset, q as shareTeamPreset, f as showPresetDetails, h as switchPreset, v as validatePresetFile } from './preset.mjs';
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';
@@ -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.r; });
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(`
@@ -1,4 +1,4 @@
1
- const version = "7.0.2";
1
+ const version = "7.0.3";
2
2
  const homepage = "https://github.com/miounet11/ccjk";
3
3
 
4
4
  export { homepage, version };
@@ -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, createTeamPreset as a, generatePresetFromTemplate as b, createCustomPreset as c, deleteCustomPreset as d, exportPreset as e, showPresetDetails as f, getPresetById as g, switchPreset as h, importPreset as i, getPresetManager as j, createTeamPresetInteractive as k, listPresets as l, exportTeamPreset as m, getTeamPresetInfo as n, importTeamPreset as o, listTeamPresets as p, shareTeamPreset as q, preset as r, selectPreset as s, validatePresetFile as v };
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
- const { registerPresetCommands } = await import('./chunks/preset.mjs').then(function (n) { return n.r; });
1025
- return async (options, action) => {
1026
- const { cli } = await Promise.resolve().then(function () { return cliLazy; });
1027
- registerPresetCommands(cli);
1028
- if (action) {
1029
- console.error(`Use 'ccjk preset ${action}' for specific preset operations`);
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.2",
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
+ }