ccjk 9.13.0 → 9.14.0

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.
@@ -197,6 +197,130 @@ async function installCometixLine() {
197
197
  }
198
198
  }
199
199
 
200
+ function formatError(error, context) {
201
+ const errorMsg = typeof error === "string" ? error : error.message;
202
+ const patterns = [
203
+ {
204
+ pattern: /not initialized|Call initialize/i,
205
+ formatter: () => ({
206
+ title: "\u26A0\uFE0F Configuration Not Ready",
207
+ message: "CCJK needs to be initialized first.",
208
+ suggestion: "Run the initialization command to set up your environment.",
209
+ command: "ccjk init"
210
+ })
211
+ },
212
+ {
213
+ pattern: /Failed to (start|connect|fetch)/i,
214
+ formatter: (match) => ({
215
+ title: "\u274C Connection Failed",
216
+ message: `Unable to ${match[1]} the service.`,
217
+ suggestion: "Check your internet connection and try again.",
218
+ command: "ccjk doctor"
219
+ })
220
+ },
221
+ {
222
+ pattern: /does not exist|not found/i,
223
+ formatter: () => ({
224
+ title: "\u{1F50D} File Not Found",
225
+ message: "The requested file or directory does not exist.",
226
+ suggestion: "Verify the path and try again."
227
+ })
228
+ },
229
+ {
230
+ pattern: /permission denied|EACCES/i,
231
+ formatter: () => ({
232
+ title: "\u{1F512} Permission Denied",
233
+ message: "You do not have permission to access this resource.",
234
+ suggestion: "Check file permissions or run with appropriate privileges.",
235
+ command: "sudo ccjk <command>"
236
+ })
237
+ },
238
+ {
239
+ pattern: /network|timeout|ETIMEDOUT|ECONNREFUSED/i,
240
+ formatter: () => ({
241
+ title: "\u{1F310} Network Error",
242
+ message: "Unable to connect to the server.",
243
+ suggestion: "Check your internet connection and firewall settings."
244
+ })
245
+ }
246
+ ];
247
+ for (const { pattern, formatter } of patterns) {
248
+ const match = errorMsg.match(pattern);
249
+ if (match) {
250
+ return formatter(match);
251
+ }
252
+ }
253
+ return {
254
+ title: "\u274C Error",
255
+ message: errorMsg,
256
+ suggestion: context ? `Context: ${context}` : "Run ccjk doctor for diagnostics.",
257
+ command: "ccjk doctor"
258
+ };
259
+ }
260
+ function displayError(error, context) {
261
+ const formatted = formatError(error, context);
262
+ console.error();
263
+ console.error(ansis.red.bold(formatted.title));
264
+ console.error(ansis.white(formatted.message));
265
+ if (formatted.suggestion) {
266
+ console.error();
267
+ console.error(ansis.yellow("\u{1F4A1} Suggestion:"), ansis.white(formatted.suggestion));
268
+ }
269
+ if (formatted.command) {
270
+ console.error(ansis.cyan(" Run:"), ansis.green(formatted.command));
271
+ }
272
+ if (formatted.docsUrl) {
273
+ console.error(ansis.cyan(" Docs:"), ansis.blue(formatted.docsUrl));
274
+ }
275
+ console.error();
276
+ }
277
+
278
+ class ProgressTracker {
279
+ currentStep = 0;
280
+ totalSteps;
281
+ steps;
282
+ startTime;
283
+ constructor(steps) {
284
+ this.steps = steps;
285
+ this.totalSteps = steps.length;
286
+ this.startTime = Date.now();
287
+ }
288
+ start() {
289
+ console.log();
290
+ console.log(ansis.cyan.bold("\u{1F680} Starting setup..."));
291
+ console.log(ansis.gray(` ${this.totalSteps} steps to complete`));
292
+ console.log();
293
+ }
294
+ nextStep(message) {
295
+ this.currentStep++;
296
+ const stepName = message || this.steps[this.currentStep - 1];
297
+ const progress = Math.round(this.currentStep / this.totalSteps * 100);
298
+ const bar = this.renderProgressBar(progress);
299
+ console.log();
300
+ console.log(ansis.cyan(`[${this.currentStep}/${this.totalSteps}]`), ansis.white(stepName));
301
+ console.log(ansis.gray(` ${bar} ${progress}%`));
302
+ }
303
+ complete() {
304
+ const duration = ((Date.now() - this.startTime) / 1e3).toFixed(1);
305
+ console.log();
306
+ console.log(ansis.green.bold("\u2705 Setup complete!"));
307
+ console.log(ansis.gray(` Completed in ${duration}s`));
308
+ console.log();
309
+ }
310
+ error(message) {
311
+ console.log();
312
+ console.log(ansis.red.bold("\u274C Setup failed"));
313
+ console.log(ansis.white(` ${message}`));
314
+ console.log();
315
+ }
316
+ renderProgressBar(percent) {
317
+ const width = 20;
318
+ const filled = Math.round(percent / 100 * width);
319
+ const empty = width - filled;
320
+ return ansis.green("\u2588".repeat(filled)) + ansis.gray("\u2591".repeat(empty));
321
+ }
322
+ }
323
+
200
324
  async function validateSkipPromptOptions(options) {
201
325
  if (options.allLang) {
202
326
  if (options.allLang === "zh-CN" || options.allLang === "en") {
@@ -405,7 +529,20 @@ async function init(options = {}) {
405
529
  await validateSkipPromptOptions(options);
406
530
  }
407
531
  try {
532
+ const tracker = new ProgressTracker([
533
+ "Reading configuration",
534
+ "Selecting code tool",
535
+ "Configuring API",
536
+ "Installing MCP services",
537
+ "Setting up workflows",
538
+ "Finalizing setup"
539
+ ]);
540
+ if (!options.skipPrompt && !options.skipBanner) {
541
+ tracker.start();
542
+ }
543
+ if (!options.skipPrompt && !options.skipBanner) tracker.nextStep();
408
544
  const zcfConfig = readZcfConfig();
545
+ if (!options.skipPrompt && !options.skipBanner) tracker.nextStep();
409
546
  let codeToolType;
410
547
  try {
411
548
  codeToolType = await resolveCodeType(options.codeType);
@@ -645,6 +782,7 @@ async function init(options = {}) {
645
782
  } else if (options.skipPrompt && options.configAction) {
646
783
  action = options.configAction;
647
784
  }
785
+ if (!options.skipPrompt && !options.skipBanner) tracker.nextStep("Configuring API");
648
786
  let apiConfig = null;
649
787
  const isNewInstall = !existsSync(SETTINGS_FILE);
650
788
  if (action !== "docs-only" && (isNewInstall || ["backup", "merge", "new"].includes(action))) {
@@ -814,6 +952,7 @@ async function init(options = {}) {
814
952
  console.log(ansis.gray(` Opus: ${options.apiOpusModel}`));
815
953
  }
816
954
  }
955
+ if (!options.skipPrompt && !options.skipBanner) tracker.nextStep("Installing MCP services");
817
956
  if (action !== "docs-only") {
818
957
  let shouldConfigureMcp = false;
819
958
  if (options.skipPrompt) {
@@ -895,7 +1034,7 @@ async function init(options = {}) {
895
1034
  console.log(formatPerformanceWarning(perfWarning, i18n.language));
896
1035
  }
897
1036
  } catch (error) {
898
- console.error(ansis.red(`${i18n.t("errors:failedToWriteMcpConfig")} ${error}`));
1037
+ displayError(error, "MCP configuration");
899
1038
  }
900
1039
  }
901
1040
  }
@@ -932,6 +1071,7 @@ async function init(options = {}) {
932
1071
  } catch {
933
1072
  console.log(ansis.gray(`\u2139 ${i18n.t("smartGuide:skipped")}`));
934
1073
  }
1074
+ if (!options.skipPrompt && !options.skipBanner) tracker.nextStep("Finalizing setup");
935
1075
  updateZcfConfig({
936
1076
  version,
937
1077
  preferredLang: i18n.language,
@@ -963,6 +1103,7 @@ async function init(options = {}) {
963
1103
  console.log();
964
1104
  }
965
1105
  }
1106
+ if (!options.skipPrompt && !options.skipBanner) tracker.complete();
966
1107
  console.log("");
967
1108
  console.log(ansis.bold.green("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
968
1109
  console.log(ansis.bold.green("\u2551") + ansis.bold.white(padToDisplayWidth(` ${i18n.t("configuration:setupCompleteTitle")}`, 62)) + ansis.bold.green("\u2551"));
@@ -984,6 +1125,7 @@ async function init(options = {}) {
984
1125
  console.log("");
985
1126
  } catch (error) {
986
1127
  if (!handleExitPromptError(error)) {
1128
+ displayError(error, "Initialization");
987
1129
  handleGeneralError(error);
988
1130
  }
989
1131
  }
@@ -1017,7 +1159,7 @@ async function handleMultiConfigurations(options, codeToolType) {
1017
1159
  }
1018
1160
  console.log(ansis.green(`\u2714 ${i18n.t("multi-config:configsAddedSuccessfully")}`));
1019
1161
  } catch (error) {
1020
- console.error(ansis.red(`${i18n.t("multi-config:configsFailed")}: ${error instanceof Error ? error.message : String(error)}`));
1162
+ displayError(error, "Multi-config setup");
1021
1163
  throw error;
1022
1164
  }
1023
1165
  }
@@ -1,4 +1,4 @@
1
- const version = "9.13.0";
1
+ const version = "9.14.0";
2
2
  const homepage = "https://github.com/miounet11/ccjk";
3
3
 
4
4
  export { homepage, version };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ccjk",
3
3
  "type": "module",
4
- "version": "9.13.0",
4
+ "version": "9.14.0",
5
5
  "packageManager": "pnpm@10.17.1",
6
6
  "description": "The missing toolkit for Claude Code. One command setup, 73% token savings, persistent memory, cloud sync, and Agent Teams. Zero config, 10x productivity.",
7
7
  "author": {