ccjk 1.3.1

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.
Files changed (109) hide show
  1. package/LICENSE +21 -0
  2. package/README.ja.md +455 -0
  3. package/README.ko.md +455 -0
  4. package/README.md +550 -0
  5. package/README.zh-CN.md +488 -0
  6. package/bin/ccjk.mjs +2 -0
  7. package/dist/chunks/api-providers.mjs +89 -0
  8. package/dist/chunks/claude-code-config-manager.mjs +733 -0
  9. package/dist/chunks/claude-code-incremental-manager.mjs +603 -0
  10. package/dist/chunks/codex-config-switch.mjs +427 -0
  11. package/dist/chunks/codex-provider-manager.mjs +232 -0
  12. package/dist/chunks/codex-uninstaller.mjs +404 -0
  13. package/dist/chunks/commands.mjs +120 -0
  14. package/dist/chunks/features.mjs +642 -0
  15. package/dist/chunks/simple-config.mjs +10445 -0
  16. package/dist/cli.d.mts +1 -0
  17. package/dist/cli.d.ts +1 -0
  18. package/dist/cli.mjs +5972 -0
  19. package/dist/i18n/locales/en/api.json +63 -0
  20. package/dist/i18n/locales/en/ccjk.json +276 -0
  21. package/dist/i18n/locales/en/ccr.json +65 -0
  22. package/dist/i18n/locales/en/cli.json +57 -0
  23. package/dist/i18n/locales/en/codex.json +124 -0
  24. package/dist/i18n/locales/en/cometix.json +29 -0
  25. package/dist/i18n/locales/en/common.json +20 -0
  26. package/dist/i18n/locales/en/configuration.json +77 -0
  27. package/dist/i18n/locales/en/errors.json +26 -0
  28. package/dist/i18n/locales/en/installation.json +80 -0
  29. package/dist/i18n/locales/en/interview.json +104 -0
  30. package/dist/i18n/locales/en/language.json +19 -0
  31. package/dist/i18n/locales/en/mcp.json +38 -0
  32. package/dist/i18n/locales/en/menu.json +51 -0
  33. package/dist/i18n/locales/en/multi-config.json +79 -0
  34. package/dist/i18n/locales/en/shencha.json +14 -0
  35. package/dist/i18n/locales/en/team.json +7 -0
  36. package/dist/i18n/locales/en/tools.json +42 -0
  37. package/dist/i18n/locales/en/uninstall.json +56 -0
  38. package/dist/i18n/locales/en/updater.json +25 -0
  39. package/dist/i18n/locales/en/workflow.json +25 -0
  40. package/dist/i18n/locales/zh-CN/api.json +63 -0
  41. package/dist/i18n/locales/zh-CN/ccjk.json +276 -0
  42. package/dist/i18n/locales/zh-CN/ccr.json +65 -0
  43. package/dist/i18n/locales/zh-CN/cli.json +57 -0
  44. package/dist/i18n/locales/zh-CN/codex.json +124 -0
  45. package/dist/i18n/locales/zh-CN/cometix.json +29 -0
  46. package/dist/i18n/locales/zh-CN/common.json +20 -0
  47. package/dist/i18n/locales/zh-CN/configuration.json +77 -0
  48. package/dist/i18n/locales/zh-CN/errors.json +26 -0
  49. package/dist/i18n/locales/zh-CN/installation.json +80 -0
  50. package/dist/i18n/locales/zh-CN/interview.json +104 -0
  51. package/dist/i18n/locales/zh-CN/language.json +19 -0
  52. package/dist/i18n/locales/zh-CN/mcp.json +38 -0
  53. package/dist/i18n/locales/zh-CN/menu.json +51 -0
  54. package/dist/i18n/locales/zh-CN/multi-config.json +79 -0
  55. package/dist/i18n/locales/zh-CN/shencha.json +14 -0
  56. package/dist/i18n/locales/zh-CN/team.json +7 -0
  57. package/dist/i18n/locales/zh-CN/tools.json +42 -0
  58. package/dist/i18n/locales/zh-CN/uninstall.json +56 -0
  59. package/dist/i18n/locales/zh-CN/updater.json +25 -0
  60. package/dist/i18n/locales/zh-CN/workflow.json +25 -0
  61. package/dist/index.d.mts +2644 -0
  62. package/dist/index.d.ts +2644 -0
  63. package/dist/index.mjs +1706 -0
  64. package/package.json +157 -0
  65. package/templates/CLAUDE.md +219 -0
  66. package/templates/claude-code/CLAUDE.md +250 -0
  67. package/templates/claude-code/common/settings.json +38 -0
  68. package/templates/claude-code/en/workflow/bmad/commands/bmad-init.md +165 -0
  69. package/templates/claude-code/en/workflow/common/agents/get-current-datetime.md +29 -0
  70. package/templates/claude-code/en/workflow/common/agents/init-architect.md +114 -0
  71. package/templates/claude-code/en/workflow/common/commands/init-project.md +53 -0
  72. package/templates/claude-code/en/workflow/plan/agents/planner.md +116 -0
  73. package/templates/claude-code/en/workflow/plan/agents/ui-ux-designer.md +91 -0
  74. package/templates/claude-code/en/workflow/plan/commands/feat.md +105 -0
  75. package/templates/claude-code/zh-CN/workflow/bmad/commands/bmad-init.md +172 -0
  76. package/templates/claude-code/zh-CN/workflow/common/agents/get-current-datetime.md +29 -0
  77. package/templates/claude-code/zh-CN/workflow/common/agents/init-architect.md +114 -0
  78. package/templates/claude-code/zh-CN/workflow/common/commands/init-project.md +53 -0
  79. package/templates/claude-code/zh-CN/workflow/plan/agents/planner.md +116 -0
  80. package/templates/claude-code/zh-CN/workflow/plan/agents/ui-ux-designer.md +91 -0
  81. package/templates/claude-code/zh-CN/workflow/plan/commands/feat.md +105 -0
  82. package/templates/codex/common/config.toml +0 -0
  83. package/templates/common/output-styles/en/casual-friendly.md +97 -0
  84. package/templates/common/output-styles/en/engineer-professional.md +88 -0
  85. package/templates/common/output-styles/en/expert-concise.md +93 -0
  86. package/templates/common/output-styles/en/laowang-engineer.md +127 -0
  87. package/templates/common/output-styles/en/nekomata-engineer.md +120 -0
  88. package/templates/common/output-styles/en/ojousama-engineer.md +121 -0
  89. package/templates/common/output-styles/en/teaching-mode.md +102 -0
  90. package/templates/common/output-styles/en/technical-precise.md +101 -0
  91. package/templates/common/output-styles/zh-CN/engineer-professional.md +89 -0
  92. package/templates/common/output-styles/zh-CN/laowang-engineer.md +127 -0
  93. package/templates/common/output-styles/zh-CN/nekomata-engineer.md +120 -0
  94. package/templates/common/output-styles/zh-CN/ojousama-engineer.md +121 -0
  95. package/templates/common/workflow/git/en/git-cleanBranches.md +102 -0
  96. package/templates/common/workflow/git/en/git-commit.md +205 -0
  97. package/templates/common/workflow/git/en/git-rollback.md +90 -0
  98. package/templates/common/workflow/git/en/git-worktree.md +276 -0
  99. package/templates/common/workflow/git/zh-CN/git-cleanBranches.md +102 -0
  100. package/templates/common/workflow/git/zh-CN/git-commit.md +205 -0
  101. package/templates/common/workflow/git/zh-CN/git-rollback.md +90 -0
  102. package/templates/common/workflow/git/zh-CN/git-worktree.md +276 -0
  103. package/templates/common/workflow/interview/en/interview.md +212 -0
  104. package/templates/common/workflow/interview/zh-CN/interview.md +212 -0
  105. package/templates/common/workflow/sixStep/en/workflow.md +251 -0
  106. package/templates/common/workflow/sixStep/zh-CN/workflow.md +215 -0
  107. package/templates/industry/devops/en/ci-cd-pipeline.md +410 -0
  108. package/templates/industry/web-dev/en/api-design.md +299 -0
  109. package/templates/industry/web-dev/en/react-nextjs-setup.md +236 -0
@@ -0,0 +1,404 @@
1
+ import { pathExists } from 'fs-extra';
2
+ import { join } from 'pathe';
3
+ import { x as CODEX_DIR, y as CODEX_CONFIG_FILE, cE as moveToTrash, cj as i18n, z as CODEX_AUTH_FILE, B as CODEX_AGENTS_FILE, D as CODEX_PROMPTS_DIR } from './simple-config.mjs';
4
+ import 'node:fs';
5
+ import 'node:process';
6
+ import 'ansis';
7
+ import 'inquirer';
8
+ import 'smol-toml';
9
+ import 'dayjs';
10
+ import 'node:child_process';
11
+ import 'node:os';
12
+ import 'node:util';
13
+ import 'node:url';
14
+ import 'inquirer-toggle';
15
+ import 'ora';
16
+ import 'tinyexec';
17
+ import 'semver';
18
+ import 'node:fs/promises';
19
+ import 'trash';
20
+ import 'i18next';
21
+ import 'i18next-fs-backend';
22
+
23
+ class CodexUninstaller {
24
+ _lang;
25
+ conflictResolution = /* @__PURE__ */ new Map();
26
+ CODEX_BACKUP_DIR = join(CODEX_DIR, "backup");
27
+ constructor(lang = "en") {
28
+ this._lang = lang;
29
+ this.conflictResolution.set("cli-package", ["config", "auth"]);
30
+ this.conflictResolution.set("config", ["api-config", "mcp-config"]);
31
+ void this._lang;
32
+ }
33
+ /**
34
+ * Remove config file (config.toml)
35
+ */
36
+ async removeConfig() {
37
+ const result = {
38
+ success: false,
39
+ removed: [],
40
+ removedConfigs: [],
41
+ errors: [],
42
+ warnings: []
43
+ };
44
+ try {
45
+ if (await pathExists(CODEX_CONFIG_FILE)) {
46
+ const trashResult = await moveToTrash(CODEX_CONFIG_FILE);
47
+ if (!trashResult[0]?.success) {
48
+ result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
49
+ }
50
+ result.removed.push("config.toml");
51
+ result.success = true;
52
+ } else {
53
+ result.warnings.push(i18n.t("codex:configNotFound"));
54
+ result.success = true;
55
+ }
56
+ } catch (error) {
57
+ result.errors.push(`Failed to remove config: ${error.message}`);
58
+ }
59
+ return result;
60
+ }
61
+ /**
62
+ * Remove auth file (auth.json)
63
+ */
64
+ async removeAuth() {
65
+ const result = {
66
+ success: false,
67
+ removed: [],
68
+ removedConfigs: [],
69
+ errors: [],
70
+ warnings: []
71
+ };
72
+ try {
73
+ if (await pathExists(CODEX_AUTH_FILE)) {
74
+ const trashResult = await moveToTrash(CODEX_AUTH_FILE);
75
+ if (!trashResult[0]?.success) {
76
+ result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
77
+ }
78
+ result.removed.push("auth.json");
79
+ result.success = true;
80
+ } else {
81
+ result.warnings.push(i18n.t("codex:authNotFound"));
82
+ result.success = true;
83
+ }
84
+ } catch (error) {
85
+ result.errors.push(`Failed to remove auth: ${error.message}`);
86
+ }
87
+ return result;
88
+ }
89
+ /**
90
+ * Remove system prompt file (AGENTS.md)
91
+ */
92
+ async removeSystemPrompt() {
93
+ const result = {
94
+ success: false,
95
+ removed: [],
96
+ removedConfigs: [],
97
+ errors: [],
98
+ warnings: []
99
+ };
100
+ try {
101
+ if (await pathExists(CODEX_AGENTS_FILE)) {
102
+ const trashResult = await moveToTrash(CODEX_AGENTS_FILE);
103
+ if (!trashResult[0]?.success) {
104
+ result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
105
+ }
106
+ result.removed.push("AGENTS.md");
107
+ result.success = true;
108
+ } else {
109
+ result.warnings.push(i18n.t("codex:systemPromptNotFound"));
110
+ result.success = true;
111
+ }
112
+ } catch (error) {
113
+ result.errors.push(`Failed to remove system prompt: ${error.message}`);
114
+ }
115
+ return result;
116
+ }
117
+ /**
118
+ * Remove workflow directory (prompts/)
119
+ */
120
+ async removeWorkflow() {
121
+ const result = {
122
+ success: false,
123
+ removed: [],
124
+ removedConfigs: [],
125
+ errors: [],
126
+ warnings: []
127
+ };
128
+ try {
129
+ if (await pathExists(CODEX_PROMPTS_DIR)) {
130
+ const trashResult = await moveToTrash(CODEX_PROMPTS_DIR);
131
+ if (!trashResult[0]?.success) {
132
+ result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
133
+ }
134
+ result.removed.push("prompts/");
135
+ result.success = true;
136
+ } else {
137
+ result.warnings.push(i18n.t("codex:workflowNotFound"));
138
+ result.success = true;
139
+ }
140
+ } catch (error) {
141
+ result.errors.push(`Failed to remove workflow: ${error.message}`);
142
+ }
143
+ return result;
144
+ }
145
+ /**
146
+ * Uninstall Codex CLI package
147
+ */
148
+ async uninstallCliPackage() {
149
+ const result = {
150
+ success: false,
151
+ removed: [],
152
+ removedConfigs: [],
153
+ errors: [],
154
+ warnings: []
155
+ };
156
+ try {
157
+ const { uninstallCodeTool } = await import('./simple-config.mjs').then(function (n) { return n.db; });
158
+ const success = await uninstallCodeTool("codex");
159
+ if (success) {
160
+ result.removed.push("@openai/codex");
161
+ result.success = true;
162
+ } else {
163
+ result.errors.push(i18n.t("uninstall:uninstallFailed", { codeType: i18n.t("common:codex"), message: "" }));
164
+ }
165
+ } catch (error) {
166
+ if (error.message.includes("not found") || error.message.includes("not installed")) {
167
+ result.warnings.push(i18n.t("codex:packageNotFound"));
168
+ result.success = true;
169
+ } else {
170
+ result.errors.push(i18n.t("uninstall:uninstallFailed", { codeType: i18n.t("common:codex"), message: `: ${error.message}` }));
171
+ }
172
+ }
173
+ return result;
174
+ }
175
+ /**
176
+ * Remove API configuration from config.toml
177
+ */
178
+ async removeApiConfig() {
179
+ const result = {
180
+ success: false,
181
+ removed: [],
182
+ removedConfigs: [],
183
+ errors: [],
184
+ warnings: []
185
+ };
186
+ try {
187
+ if (await pathExists(CODEX_CONFIG_FILE)) {
188
+ const { readFileSync, writeFileSync } = await import('node:fs');
189
+ const content = readFileSync(CODEX_CONFIG_FILE, "utf-8");
190
+ const lines = content.split("\n");
191
+ const newLines = [];
192
+ let inProviderSection = false;
193
+ let configModified = false;
194
+ for (const line of lines) {
195
+ if (line.trim().match(/^\[model_providers\./)) {
196
+ inProviderSection = true;
197
+ configModified = true;
198
+ continue;
199
+ }
200
+ if (inProviderSection && line.trim().startsWith("[") && !line.trim().match(/^\[model_providers\./)) {
201
+ inProviderSection = false;
202
+ }
203
+ if (inProviderSection) {
204
+ continue;
205
+ }
206
+ if (line.trim().startsWith("model_provider")) {
207
+ configModified = true;
208
+ continue;
209
+ }
210
+ newLines.push(line);
211
+ }
212
+ if (configModified) {
213
+ writeFileSync(CODEX_CONFIG_FILE, newLines.join("\n"));
214
+ result.removedConfigs.push(i18n.t("codex:apiConfigRemoved"));
215
+ }
216
+ result.success = true;
217
+ } else {
218
+ result.warnings.push(i18n.t("codex:configNotFound"));
219
+ result.success = true;
220
+ }
221
+ } catch (error) {
222
+ result.errors.push(`Failed to remove API config: ${error.message}`);
223
+ }
224
+ return result;
225
+ }
226
+ /**
227
+ * Remove backup directory (~/.codex/backup/)
228
+ */
229
+ async removeBackups() {
230
+ const result = {
231
+ success: false,
232
+ removed: [],
233
+ removedConfigs: [],
234
+ errors: [],
235
+ warnings: []
236
+ };
237
+ try {
238
+ if (await pathExists(this.CODEX_BACKUP_DIR)) {
239
+ const trashResult = await moveToTrash(this.CODEX_BACKUP_DIR);
240
+ if (!trashResult[0]?.success) {
241
+ result.warnings.push(trashResult[0]?.error || "Failed to move backup directory to trash");
242
+ }
243
+ result.removed.push("backup/");
244
+ result.success = true;
245
+ } else {
246
+ result.warnings.push(i18n.t("codex:backupNotFound"));
247
+ result.success = true;
248
+ }
249
+ } catch (error) {
250
+ result.errors.push(`Failed to remove backups: ${error.message}`);
251
+ }
252
+ return result;
253
+ }
254
+ /**
255
+ * Remove MCP configuration from config.toml
256
+ */
257
+ async removeMcpConfig() {
258
+ const result = {
259
+ success: false,
260
+ removed: [],
261
+ removedConfigs: [],
262
+ errors: [],
263
+ warnings: []
264
+ };
265
+ try {
266
+ if (await pathExists(CODEX_CONFIG_FILE)) {
267
+ const { readFileSync, writeFileSync } = await import('node:fs');
268
+ const content = readFileSync(CODEX_CONFIG_FILE, "utf-8");
269
+ const lines = content.split("\n");
270
+ const newLines = [];
271
+ let inMcpSection = false;
272
+ let configModified = false;
273
+ for (const line of lines) {
274
+ if (line.trim().match(/^\[mcp_servers\./)) {
275
+ inMcpSection = true;
276
+ configModified = true;
277
+ continue;
278
+ }
279
+ if (inMcpSection && line.trim().startsWith("[") && !line.trim().match(/^\[mcp_servers\./)) {
280
+ inMcpSection = false;
281
+ }
282
+ if (inMcpSection) {
283
+ continue;
284
+ }
285
+ newLines.push(line);
286
+ }
287
+ if (configModified) {
288
+ writeFileSync(CODEX_CONFIG_FILE, newLines.join("\n"));
289
+ result.removedConfigs.push(i18n.t("codex:mcpConfigRemoved"));
290
+ }
291
+ result.success = true;
292
+ } else {
293
+ result.warnings.push(i18n.t("codex:configNotFound"));
294
+ result.success = true;
295
+ }
296
+ } catch (error) {
297
+ result.errors.push(`Failed to remove MCP config: ${error.message}`);
298
+ }
299
+ return result;
300
+ }
301
+ /**
302
+ * Complete uninstall - remove all directories and packages
303
+ */
304
+ async completeUninstall() {
305
+ const result = {
306
+ success: true,
307
+ removed: [],
308
+ removedConfigs: [],
309
+ errors: [],
310
+ warnings: []
311
+ };
312
+ try {
313
+ if (await pathExists(CODEX_DIR)) {
314
+ const trashResult = await moveToTrash(CODEX_DIR);
315
+ if (!trashResult[0]?.success) {
316
+ result.warnings.push(`Failed to move ~/.codex/ to trash: ${trashResult[0]?.error || "Unknown error"}`);
317
+ }
318
+ result.removed.push("~/.codex/");
319
+ }
320
+ const cliUninstallResult = await this.uninstallCliPackage();
321
+ result.removed.push(...cliUninstallResult.removed);
322
+ result.removedConfigs.push(...cliUninstallResult.removedConfigs);
323
+ result.errors.push(...cliUninstallResult.errors);
324
+ result.warnings.push(...cliUninstallResult.warnings);
325
+ result.success = result.success && cliUninstallResult.success;
326
+ } catch (error) {
327
+ result.errors.push(`Complete uninstall failed: ${error.message}`);
328
+ result.success = false;
329
+ }
330
+ return result;
331
+ }
332
+ /**
333
+ * Custom uninstall with conflict resolution
334
+ */
335
+ async customUninstall(selectedItems) {
336
+ const resolvedItems = this.resolveConflicts(selectedItems);
337
+ const results = [];
338
+ for (const item of resolvedItems) {
339
+ try {
340
+ const result = await this.executeUninstallItem(item);
341
+ results.push(result);
342
+ } catch (error) {
343
+ results.push({
344
+ success: false,
345
+ removed: [],
346
+ removedConfigs: [],
347
+ errors: [`Failed to execute ${item}: ${error.message}`],
348
+ warnings: []
349
+ });
350
+ }
351
+ }
352
+ return results;
353
+ }
354
+ /**
355
+ * Resolve conflicts between uninstall items
356
+ */
357
+ resolveConflicts(items) {
358
+ const resolved = [...items];
359
+ for (const [primary, conflicts] of this.conflictResolution) {
360
+ if (resolved.includes(primary)) {
361
+ conflicts.forEach((conflict) => {
362
+ const index = resolved.indexOf(conflict);
363
+ if (index > -1) {
364
+ resolved.splice(index, 1);
365
+ }
366
+ });
367
+ }
368
+ }
369
+ return resolved;
370
+ }
371
+ /**
372
+ * Execute uninstall for a specific item
373
+ */
374
+ async executeUninstallItem(item) {
375
+ switch (item) {
376
+ case "config":
377
+ return await this.removeConfig();
378
+ case "auth":
379
+ return await this.removeAuth();
380
+ case "system-prompt":
381
+ return await this.removeSystemPrompt();
382
+ case "workflow":
383
+ return await this.removeWorkflow();
384
+ case "cli-package":
385
+ return await this.uninstallCliPackage();
386
+ case "api-config":
387
+ return await this.removeApiConfig();
388
+ case "mcp-config":
389
+ return await this.removeMcpConfig();
390
+ case "backups":
391
+ return await this.removeBackups();
392
+ default:
393
+ return {
394
+ success: false,
395
+ removed: [],
396
+ removedConfigs: [],
397
+ errors: [`Unknown uninstall item: ${item}`],
398
+ warnings: []
399
+ };
400
+ }
401
+ }
402
+ }
403
+
404
+ export { CodexUninstaller };
@@ -0,0 +1,120 @@
1
+ import { exec } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ import ansis from 'ansis';
4
+ import { co as ensureI18nInitialized, cj as i18n } from './simple-config.mjs';
5
+ import 'node:fs';
6
+ import 'node:process';
7
+ import 'inquirer';
8
+ import 'pathe';
9
+ import 'smol-toml';
10
+ import 'dayjs';
11
+ import 'node:os';
12
+ import 'node:url';
13
+ import 'inquirer-toggle';
14
+ import 'ora';
15
+ import 'tinyexec';
16
+ import 'semver';
17
+ import 'node:fs/promises';
18
+ import 'fs-extra';
19
+ import 'trash';
20
+ import 'i18next';
21
+ import 'i18next-fs-backend';
22
+
23
+ const execAsync = promisify(exec);
24
+ async function runCcrUi(apiKey) {
25
+ ensureI18nInitialized();
26
+ console.log(ansis.cyan(`
27
+ \u{1F5A5}\uFE0F ${i18n.t("ccr:startingCcrUi")}`));
28
+ if (apiKey) {
29
+ console.log(ansis.bold.green(`
30
+ \u{1F511} ${i18n.t("ccr:ccrUiApiKey") || "CCR UI API Key"}: ${apiKey}`));
31
+ console.log(ansis.gray(` ${i18n.t("ccr:ccrUiApiKeyHint") || "Use this API key to login to CCR UI"}
32
+ `));
33
+ }
34
+ try {
35
+ const { stdout, stderr } = await execAsync("ccr ui");
36
+ if (stdout)
37
+ console.log(stdout);
38
+ if (stderr)
39
+ console.error(ansis.yellow(stderr));
40
+ console.log(ansis.green(`\u2714 ${i18n.t("ccr:ccrUiStarted")}`));
41
+ } catch (error) {
42
+ console.error(ansis.red(`\u2716 ${i18n.t("ccr:ccrCommandFailed")}: ${error instanceof Error ? error.message : String(error)}`));
43
+ throw error;
44
+ }
45
+ }
46
+ async function runCcrStatus() {
47
+ ensureI18nInitialized();
48
+ console.log(ansis.cyan(`
49
+ \u{1F4CA} ${i18n.t("ccr:checkingCcrStatus")}`));
50
+ try {
51
+ const { stdout, stderr } = await execAsync("ccr status");
52
+ if (stdout) {
53
+ console.log(`
54
+ ${ansis.bold(i18n.t("ccr:ccrStatusTitle"))}`);
55
+ console.log(stdout);
56
+ }
57
+ if (stderr)
58
+ console.error(ansis.yellow(stderr));
59
+ } catch (error) {
60
+ console.error(ansis.red(`\u2716 ${i18n.t("ccr:ccrCommandFailed")}: ${error instanceof Error ? error.message : String(error)}`));
61
+ throw error;
62
+ }
63
+ }
64
+ async function runCcrRestart() {
65
+ ensureI18nInitialized();
66
+ console.log(ansis.cyan(`
67
+ \u{1F504} ${i18n.t("ccr:restartingCcr")}`));
68
+ try {
69
+ const { stdout, stderr } = await execAsync("ccr restart");
70
+ if (stdout)
71
+ console.log(stdout);
72
+ if (stderr)
73
+ console.error(ansis.yellow(stderr));
74
+ console.log(ansis.green(`\u2714 ${i18n.t("ccr:ccrRestarted")}`));
75
+ } catch (error) {
76
+ console.error(ansis.red(`\u2716 ${i18n.t("ccr:ccrCommandFailed")}: ${error instanceof Error ? error.message : String(error)}`));
77
+ throw error;
78
+ }
79
+ }
80
+ async function runCcrStart() {
81
+ ensureI18nInitialized();
82
+ console.log(ansis.cyan(`
83
+ \u25B6\uFE0F ${i18n.t("ccr:startingCcr")}`));
84
+ try {
85
+ const { stdout, stderr } = await execAsync("ccr start");
86
+ if (stdout)
87
+ console.log(stdout);
88
+ if (stderr)
89
+ console.error(ansis.yellow(stderr));
90
+ console.log(ansis.green(`\u2714 ${i18n.t("ccr:ccrStarted")}`));
91
+ } catch (error) {
92
+ if (error.stdout && error.stdout.includes("Loaded JSON config from:")) {
93
+ console.log(error.stdout);
94
+ if (error.stderr)
95
+ console.error(ansis.yellow(error.stderr));
96
+ console.log(ansis.green(`\u2714 ${i18n.t("ccr:ccrStarted")}`));
97
+ } else {
98
+ console.error(ansis.red(`\u2716 ${i18n.t("ccr:ccrCommandFailed")}: ${error instanceof Error ? error.message : String(error)}`));
99
+ throw error;
100
+ }
101
+ }
102
+ }
103
+ async function runCcrStop() {
104
+ ensureI18nInitialized();
105
+ console.log(ansis.cyan(`
106
+ \u23F9\uFE0F ${i18n.t("ccr:stoppingCcr")}`));
107
+ try {
108
+ const { stdout, stderr } = await execAsync("ccr stop");
109
+ if (stdout)
110
+ console.log(stdout);
111
+ if (stderr)
112
+ console.error(ansis.yellow(stderr));
113
+ console.log(ansis.green(`\u2714 ${i18n.t("ccr:ccrStopped")}`));
114
+ } catch (error) {
115
+ console.error(ansis.red(`\u2716 ${i18n.t("ccr:ccrCommandFailed")}: ${error instanceof Error ? error.message : String(error)}`));
116
+ throw error;
117
+ }
118
+ }
119
+
120
+ export { runCcrRestart, runCcrStart, runCcrStatus, runCcrStop, runCcrUi };