ccjk 13.3.18 → 13.3.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/api-cli.mjs +1 -1
- package/dist/chunks/api.mjs +1 -1
- package/dist/chunks/auto-fix.mjs +4 -4
- package/dist/chunks/boost.mjs +1 -1
- package/dist/chunks/ccjk-mcp.mjs +2 -2
- package/dist/chunks/ccr.mjs +24 -20
- package/dist/chunks/check-updates.mjs +2 -1
- package/dist/chunks/claude-code-config-manager.mjs +4 -4
- package/dist/chunks/claude-code-incremental-manager.mjs +5 -5
- package/dist/chunks/claude-config.mjs +2 -2
- package/dist/chunks/claude-wrapper.mjs +1 -1
- package/dist/chunks/codex-config-switch.mjs +4 -3
- package/dist/chunks/codex-provider-manager.mjs +2 -1
- package/dist/chunks/codex.mjs +4 -332
- package/dist/chunks/config-switch.mjs +2 -1
- package/dist/chunks/config.mjs +424 -358
- package/dist/chunks/config2.mjs +358 -424
- package/dist/chunks/config3.mjs +6 -1
- package/dist/chunks/doctor.mjs +2 -2
- package/dist/chunks/features.mjs +812 -0
- package/dist/chunks/index.mjs +1 -1
- package/dist/chunks/init.mjs +43 -89
- package/dist/chunks/installer.mjs +1 -1
- package/dist/chunks/mcp-cli.mjs +18 -17
- package/dist/chunks/mcp.mjs +5 -4
- package/dist/chunks/menu-hierarchical.mjs +27 -23
- package/dist/chunks/menu.mjs +17 -791
- package/dist/chunks/onboarding-wizard.mjs +2 -2
- package/dist/chunks/package.mjs +1 -1
- package/dist/chunks/platform.mjs +1 -1
- package/dist/chunks/quick-setup.mjs +14 -11
- package/dist/chunks/slash-commands.mjs +1 -1
- package/dist/chunks/uninstall.mjs +1 -1
- package/dist/chunks/update.mjs +17 -15
- package/dist/cli.mjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/shared/ccjk.0aJQmVxS.mjs +336 -0
- package/dist/shared/ccjk.C3o4BXvM.mjs +444 -0
- package/dist/shared/{ccjk.DfZKjHvG.mjs → ccjk.Dgq22o6V.mjs} +2 -438
- package/dist/shared/{ccjk.KpFl2RDA.mjs → ccjk.LTONy3IS.mjs} +4 -3
- package/dist/shared/ccjk.Si-T_ccK.mjs +75 -0
- package/dist/shared/{ccjk.I6IuYdc_.mjs → ccjk.Xla_pE3y.mjs} +1 -1
- package/dist/shared/{ccjk.DZ4ehAHg.mjs → ccjk.byom1b8z.mjs} +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,812 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import process__default from 'node:process';
|
|
4
|
+
import a from './index2.mjs';
|
|
5
|
+
import { i as inquirer } from './index3.mjs';
|
|
6
|
+
import { s as selectMcpServices, g as getMcpServices } from '../shared/ccjk.0aJQmVxS.mjs';
|
|
7
|
+
import { SUPPORTED_LANGS, LANG_LABELS } from './constants.mjs';
|
|
8
|
+
import { ensureI18nInitialized, i18n, changeLanguage } from './index5.mjs';
|
|
9
|
+
import { updateZcfConfig, readZcfConfig } from './ccjk-config.mjs';
|
|
10
|
+
import { setupCcrConfiguration } from './config.mjs';
|
|
11
|
+
import { i as isCcrInstalled, a as installCcr } from '../shared/ccjk.Si-T_ccK.mjs';
|
|
12
|
+
import { r as readMcpConfig, f as fixWindowsMcpConfig, w as writeMcpConfig, b as backupMcpConfig, a as buildMcpServerConfig, m as mergeMcpServers } from './claude-config.mjs';
|
|
13
|
+
import { g as getExistingModelConfig, a as getExistingCustomModelConfig, u as updateCustomModel, d as updateDefaultModel, e as applyAiLanguageDirective, f as getExistingApiConfig, p as promptApiConfigurationAction, h as configureApi, s as switchToOfficialLogin } from './config2.mjs';
|
|
14
|
+
import { c as configureOutputStyle, m as modifyApiConfigPartially, v as validateApiKey, f as formatApiKeyDisplay } from '../shared/ccjk.Dgq22o6V.mjs';
|
|
15
|
+
import { i as isWindows } from './platform.mjs';
|
|
16
|
+
import { a as addNumbersToChoices } from '../shared/ccjk.BFQ7yr5S.mjs';
|
|
17
|
+
import { openSettingsJson, importRecommendedPermissions, importRecommendedEnv } from './simple-config.mjs';
|
|
18
|
+
import { p as promptBoolean } from '../shared/ccjk.BWFpnOr3.mjs';
|
|
19
|
+
import { j as join } from '../shared/ccjk.bQ7Dh1g4.mjs';
|
|
20
|
+
import '../shared/ccjk.BAGoDD49.mjs';
|
|
21
|
+
import 'node:readline';
|
|
22
|
+
import 'stream';
|
|
23
|
+
import 'node:tty';
|
|
24
|
+
import 'node:async_hooks';
|
|
25
|
+
import '../shared/ccjk.Cjgrln_h.mjs';
|
|
26
|
+
import 'node:util';
|
|
27
|
+
import 'tty';
|
|
28
|
+
import 'fs';
|
|
29
|
+
import 'child_process';
|
|
30
|
+
import 'node:path';
|
|
31
|
+
import 'node:crypto';
|
|
32
|
+
import 'buffer';
|
|
33
|
+
import 'string_decoder';
|
|
34
|
+
import 'node:child_process';
|
|
35
|
+
import 'node:url';
|
|
36
|
+
import '../shared/ccjk.BBtCGd_g.mjs';
|
|
37
|
+
import './index6.mjs';
|
|
38
|
+
import './fs-operations.mjs';
|
|
39
|
+
import 'node:fs/promises';
|
|
40
|
+
import './json-config.mjs';
|
|
41
|
+
import '../shared/ccjk.RyizuzOI.mjs';
|
|
42
|
+
import './auto-updater.mjs';
|
|
43
|
+
import './index7.mjs';
|
|
44
|
+
import '../shared/ccjk.DeWpAShp.mjs';
|
|
45
|
+
import './main.mjs';
|
|
46
|
+
import 'module';
|
|
47
|
+
import 'node:stream';
|
|
48
|
+
import './version-checker.mjs';
|
|
49
|
+
import '../shared/ccjk.CxpGa6MC.mjs';
|
|
50
|
+
import '../shared/ccjk.DScm_NnL.mjs';
|
|
51
|
+
|
|
52
|
+
const DEFAULT_MODEL_CHOICES = [
|
|
53
|
+
{
|
|
54
|
+
nameKey: "configuration:defaultModelOption",
|
|
55
|
+
fallback: "Default - Let Claude Code choose",
|
|
56
|
+
value: "default"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
nameKey: "configuration:opusModelOption",
|
|
60
|
+
fallback: "Opus - Only use opus, high token consumption, use with caution",
|
|
61
|
+
value: "opus"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
nameKey: "configuration:sonnetModelOption",
|
|
65
|
+
fallback: "Sonnet - Recommended balanced model for daily coding",
|
|
66
|
+
value: "sonnet"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
nameKey: "configuration:sonnet1mModelOption",
|
|
70
|
+
fallback: "Sonnet 1M - 1M context version",
|
|
71
|
+
value: "sonnet[1m]"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
nameKey: "configuration:customModelOption",
|
|
75
|
+
fallback: "Custom - Specify custom model names",
|
|
76
|
+
value: "custom"
|
|
77
|
+
}
|
|
78
|
+
];
|
|
79
|
+
async function handleCancellation() {
|
|
80
|
+
ensureI18nInitialized();
|
|
81
|
+
console.log(a.yellow(i18n.t("common:cancelled")));
|
|
82
|
+
}
|
|
83
|
+
async function ensureModelConfigPriority() {
|
|
84
|
+
const { readJsonConfig, writeJsonConfig } = await import('./json-config.mjs');
|
|
85
|
+
const { SETTINGS_FILE } = await import('./constants.mjs');
|
|
86
|
+
const settings = readJsonConfig(SETTINGS_FILE);
|
|
87
|
+
if (!settings)
|
|
88
|
+
return;
|
|
89
|
+
if (settings.env?.ANTHROPIC_DEFAULT_HAIKU_MODEL && settings.env.ANTHROPIC_SMALL_FAST_MODEL !== settings.env.ANTHROPIC_DEFAULT_HAIKU_MODEL) {
|
|
90
|
+
settings.env.ANTHROPIC_SMALL_FAST_MODEL = settings.env.ANTHROPIC_DEFAULT_HAIKU_MODEL;
|
|
91
|
+
writeJsonConfig(SETTINGS_FILE, settings);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async function handleOfficialLoginMode() {
|
|
95
|
+
ensureI18nInitialized();
|
|
96
|
+
const success = switchToOfficialLogin();
|
|
97
|
+
if (success) {
|
|
98
|
+
console.log(a.green(`\u2714 ${i18n.t("api:officialLoginConfigured")}`));
|
|
99
|
+
} else {
|
|
100
|
+
console.log(a.red(i18n.t("api:officialLoginFailed")));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async function handleCustomApiMode() {
|
|
104
|
+
ensureI18nInitialized();
|
|
105
|
+
const zcfConfig = readZcfConfig();
|
|
106
|
+
const codeToolType = zcfConfig?.codeToolType || "claude-code";
|
|
107
|
+
if (codeToolType === "claude-code") {
|
|
108
|
+
const { configureIncrementalManagement } = await import('./claude-code-incremental-manager.mjs');
|
|
109
|
+
await configureIncrementalManagement();
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const existingConfig = getExistingApiConfig();
|
|
113
|
+
if (existingConfig) {
|
|
114
|
+
const configAction = await promptApiConfigurationAction();
|
|
115
|
+
if (configAction === "keep-existing") {
|
|
116
|
+
console.log(a.green(`\u2714 ${i18n.t("api:keepExistingConfig")}`));
|
|
117
|
+
return;
|
|
118
|
+
} else if (configAction === "modify-partial") {
|
|
119
|
+
await modifyApiConfigPartially(existingConfig);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const { apiChoice } = await inquirer.prompt({
|
|
124
|
+
type: "list",
|
|
125
|
+
name: "apiChoice",
|
|
126
|
+
message: i18n.t("api:configureApi"),
|
|
127
|
+
choices: addNumbersToChoices([
|
|
128
|
+
{
|
|
129
|
+
name: `${i18n.t("api:useAuthToken")} - ${a.gray(i18n.t("api:authTokenDesc"))}`,
|
|
130
|
+
value: "auth_token",
|
|
131
|
+
short: i18n.t("api:useAuthToken")
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: `${i18n.t("api:useApiKey")} - ${a.gray(i18n.t("api:apiKeyDesc"))}`,
|
|
135
|
+
value: "api_key",
|
|
136
|
+
short: i18n.t("api:useApiKey")
|
|
137
|
+
},
|
|
138
|
+
{ name: i18n.t("api:skipApi"), value: "skip" }
|
|
139
|
+
])
|
|
140
|
+
});
|
|
141
|
+
if (!apiChoice || apiChoice === "skip") {
|
|
142
|
+
await handleCancellation();
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const { url } = await inquirer.prompt({
|
|
146
|
+
type: "input",
|
|
147
|
+
name: "url",
|
|
148
|
+
message: `${i18n.t("api:enterApiUrl")}${i18n.t("common:emptyToSkip")}`,
|
|
149
|
+
validate: (value) => {
|
|
150
|
+
if (!value) {
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
void new URL(value);
|
|
155
|
+
return true;
|
|
156
|
+
} catch {
|
|
157
|
+
return i18n.t("api:invalidUrl");
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
if (url === void 0 || !url) {
|
|
162
|
+
await handleCancellation();
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const keyMessage = apiChoice === "auth_token" ? `${i18n.t("api:enterAuthToken")}${i18n.t("common:emptyToSkip")}` : `${i18n.t("api:enterApiKey")}${i18n.t("common:emptyToSkip")}`;
|
|
166
|
+
const { key } = await inquirer.prompt({
|
|
167
|
+
type: "input",
|
|
168
|
+
name: "key",
|
|
169
|
+
message: keyMessage,
|
|
170
|
+
validate: (value) => {
|
|
171
|
+
if (!value) {
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
const validation = validateApiKey(value);
|
|
175
|
+
if (!validation.isValid) {
|
|
176
|
+
return validation.error || i18n.t("api:invalidKeyFormat");
|
|
177
|
+
}
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
if (key === void 0 || !key) {
|
|
182
|
+
await handleCancellation();
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const apiConfig = { url, key, authType: apiChoice };
|
|
186
|
+
const configuredApi = configureApi(apiConfig);
|
|
187
|
+
if (configuredApi) {
|
|
188
|
+
console.log(a.green(`\u2714 ${i18n.t("api:apiConfigSuccess")}`));
|
|
189
|
+
console.log(a.gray(` URL: ${configuredApi.url}`));
|
|
190
|
+
console.log(a.gray(` Key: ${formatApiKeyDisplay(configuredApi.key)}`));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
async function handleCcrProxyMode() {
|
|
194
|
+
ensureI18nInitialized();
|
|
195
|
+
const ccrStatus = await isCcrInstalled();
|
|
196
|
+
if (!ccrStatus.hasCorrectPackage) {
|
|
197
|
+
await installCcr();
|
|
198
|
+
} else {
|
|
199
|
+
console.log(a.green(`\u2714 ${i18n.t("ccr:ccrAlreadyInstalled")}`));
|
|
200
|
+
}
|
|
201
|
+
const ccrConfigured = await setupCcrConfiguration();
|
|
202
|
+
if (ccrConfigured) {
|
|
203
|
+
console.log(a.green(`\u2714 ${i18n.t("ccr:ccrSetupComplete")}`));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
async function handleSwitchConfigMode() {
|
|
207
|
+
ensureI18nInitialized();
|
|
208
|
+
const { configSwitchCommand } = await import('./config-switch.mjs');
|
|
209
|
+
await configSwitchCommand({ codeType: "claude-code" });
|
|
210
|
+
}
|
|
211
|
+
async function configureApiFeature() {
|
|
212
|
+
ensureI18nInitialized();
|
|
213
|
+
const { mode } = await inquirer.prompt({
|
|
214
|
+
type: "list",
|
|
215
|
+
name: "mode",
|
|
216
|
+
message: i18n.t("api:apiModePrompt"),
|
|
217
|
+
choices: addNumbersToChoices([
|
|
218
|
+
{ name: i18n.t("api:apiModeOfficial"), value: "official" },
|
|
219
|
+
{ name: i18n.t("api:apiModeCustom"), value: "custom" },
|
|
220
|
+
{ name: i18n.t("api:apiModeCcr"), value: "ccr" },
|
|
221
|
+
{ name: i18n.t("api:apiModeSwitch"), value: "switch" },
|
|
222
|
+
{ name: i18n.t("api:apiModeSkip"), value: "skip" }
|
|
223
|
+
])
|
|
224
|
+
});
|
|
225
|
+
if (!mode || mode === "skip") {
|
|
226
|
+
await ensureModelConfigPriority();
|
|
227
|
+
await handleCancellation();
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
switch (mode) {
|
|
231
|
+
case "official":
|
|
232
|
+
await handleOfficialLoginMode();
|
|
233
|
+
break;
|
|
234
|
+
case "custom":
|
|
235
|
+
await handleCustomApiMode();
|
|
236
|
+
break;
|
|
237
|
+
case "ccr":
|
|
238
|
+
await handleCcrProxyMode();
|
|
239
|
+
break;
|
|
240
|
+
case "switch":
|
|
241
|
+
await handleSwitchConfigMode();
|
|
242
|
+
break;
|
|
243
|
+
default:
|
|
244
|
+
await handleCancellation();
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
await ensureModelConfigPriority();
|
|
248
|
+
}
|
|
249
|
+
async function configureMcpFeature() {
|
|
250
|
+
ensureI18nInitialized();
|
|
251
|
+
if (isWindows()) {
|
|
252
|
+
const fixWindows = await promptBoolean({
|
|
253
|
+
message: i18n.t("configuration:fixWindowsMcp") || "Fix Windows MCP configuration?",
|
|
254
|
+
defaultValue: true
|
|
255
|
+
});
|
|
256
|
+
if (fixWindows) {
|
|
257
|
+
const existingConfig = readMcpConfig() || { mcpServers: {} };
|
|
258
|
+
const fixedConfig = fixWindowsMcpConfig(existingConfig);
|
|
259
|
+
writeMcpConfig(fixedConfig);
|
|
260
|
+
console.log(a.green(`\u2714 ${i18n.t("configuration:windowsMcpConfigFixed")}`));
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
const selectedServices = await selectMcpServices();
|
|
264
|
+
if (!selectedServices) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (selectedServices.length > 0) {
|
|
268
|
+
const mcpBackupPath = backupMcpConfig();
|
|
269
|
+
if (mcpBackupPath) {
|
|
270
|
+
console.log(a.gray(`\u2714 ${i18n.t("mcp:mcpBackupSuccess")}: ${mcpBackupPath}`));
|
|
271
|
+
}
|
|
272
|
+
const newServers = {};
|
|
273
|
+
for (const serviceId of selectedServices) {
|
|
274
|
+
const service = (await getMcpServices()).find((s) => s.id === serviceId);
|
|
275
|
+
if (!service)
|
|
276
|
+
continue;
|
|
277
|
+
let config = service.config;
|
|
278
|
+
if (service.requiresApiKey) {
|
|
279
|
+
const { apiKey } = await inquirer.prompt({
|
|
280
|
+
type: "input",
|
|
281
|
+
name: "apiKey",
|
|
282
|
+
message: service.apiKeyPrompt,
|
|
283
|
+
validate: async (value) => !!value || i18n.t("api:keyRequired")
|
|
284
|
+
});
|
|
285
|
+
if (apiKey) {
|
|
286
|
+
config = buildMcpServerConfig(service.config, apiKey, service.apiKeyPlaceholder, service.apiKeyEnvVar);
|
|
287
|
+
} else {
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
newServers[service.id] = config;
|
|
292
|
+
}
|
|
293
|
+
const existingConfig = readMcpConfig();
|
|
294
|
+
let mergedConfig = mergeMcpServers(existingConfig, newServers);
|
|
295
|
+
mergedConfig = fixWindowsMcpConfig(mergedConfig);
|
|
296
|
+
writeMcpConfig(mergedConfig);
|
|
297
|
+
console.log(a.green(`\u2714 ${i18n.t("mcp:mcpConfigSuccess")}`));
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
async function configureDefaultModelFeature() {
|
|
301
|
+
ensureI18nInitialized();
|
|
302
|
+
const existingModel = getExistingModelConfig();
|
|
303
|
+
if (existingModel) {
|
|
304
|
+
console.log(`
|
|
305
|
+
${a.green(`\u2139 ${i18n.t("configuration:existingModelConfig") || "Existing model configuration"}`)}`);
|
|
306
|
+
const modelDisplay = existingModel === "default" ? i18n.t("configuration:defaultModelOption") || "Default (Let Claude Code choose)" : existingModel.charAt(0).toUpperCase() + existingModel.slice(1);
|
|
307
|
+
console.log(a.gray(` ${i18n.t("configuration:currentModel") || "Current model"}: ${modelDisplay}
|
|
308
|
+
`));
|
|
309
|
+
const modify = await promptBoolean({
|
|
310
|
+
message: i18n.t("configuration:modifyModel") || "Modify model configuration?",
|
|
311
|
+
defaultValue: false
|
|
312
|
+
});
|
|
313
|
+
if (!modify) {
|
|
314
|
+
console.log(a.green(`\u2714 ${i18n.t("configuration:keepModel") || "Keeping existing model configuration"}`));
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
const { model } = await inquirer.prompt({
|
|
319
|
+
type: "rawlist",
|
|
320
|
+
name: "model",
|
|
321
|
+
message: i18n.t("configuration:selectDefaultModel") || "Select default model",
|
|
322
|
+
choices: addNumbersToChoices(
|
|
323
|
+
DEFAULT_MODEL_CHOICES.map((choice) => ({
|
|
324
|
+
name: i18n.t(choice.nameKey) || choice.fallback,
|
|
325
|
+
value: choice.value
|
|
326
|
+
}))
|
|
327
|
+
),
|
|
328
|
+
default: existingModel ? DEFAULT_MODEL_CHOICES.findIndex((choice) => choice.value === existingModel) : 0
|
|
329
|
+
});
|
|
330
|
+
if (!model) {
|
|
331
|
+
await handleCancellation();
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
if (model === "custom") {
|
|
335
|
+
const existingCustomConfig = getExistingCustomModelConfig();
|
|
336
|
+
const { primaryModel, haikuModel, sonnetModel, opusModel } = await promptCustomModels(
|
|
337
|
+
existingCustomConfig?.primaryModel,
|
|
338
|
+
existingCustomConfig?.haikuModel,
|
|
339
|
+
existingCustomConfig?.sonnetModel,
|
|
340
|
+
existingCustomConfig?.opusModel
|
|
341
|
+
);
|
|
342
|
+
if (!primaryModel.trim() && !haikuModel.trim() && !sonnetModel.trim() && !opusModel.trim()) {
|
|
343
|
+
console.log(a.yellow(`\u26A0 ${i18n.t("configuration:customModelSkipped") || "Custom model configuration skipped"}`));
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
updateCustomModel(primaryModel, haikuModel, sonnetModel, opusModel);
|
|
347
|
+
console.log(a.green(`\u2714 ${i18n.t("configuration:customModelConfigured") || "Custom model configuration completed"}`));
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
updateDefaultModel(model);
|
|
351
|
+
console.log(a.green(`\u2714 ${i18n.t("configuration:modelConfigured") || "Default model configured"}`));
|
|
352
|
+
}
|
|
353
|
+
async function promptCustomModels(defaultPrimaryModel, defaultHaikuModel, defaultSonnetModel, defaultOpusModel) {
|
|
354
|
+
const { primaryModel } = await inquirer.prompt({
|
|
355
|
+
type: "input",
|
|
356
|
+
name: "primaryModel",
|
|
357
|
+
message: `${i18n.t("configuration:enterPrimaryModel")}${i18n.t("common:emptyToSkip")}`,
|
|
358
|
+
default: defaultPrimaryModel || ""
|
|
359
|
+
});
|
|
360
|
+
const { haikuModel } = await inquirer.prompt({
|
|
361
|
+
type: "input",
|
|
362
|
+
name: "haikuModel",
|
|
363
|
+
message: `${i18n.t("configuration:enterHaikuModel")}${i18n.t("common:emptyToSkip")}`,
|
|
364
|
+
default: defaultHaikuModel || ""
|
|
365
|
+
});
|
|
366
|
+
const { sonnetModel } = await inquirer.prompt({
|
|
367
|
+
type: "input",
|
|
368
|
+
name: "sonnetModel",
|
|
369
|
+
message: `${i18n.t("configuration:enterSonnetModel")}${i18n.t("common:emptyToSkip")}`,
|
|
370
|
+
default: defaultSonnetModel || ""
|
|
371
|
+
});
|
|
372
|
+
const { opusModel } = await inquirer.prompt({
|
|
373
|
+
type: "input",
|
|
374
|
+
name: "opusModel",
|
|
375
|
+
message: `${i18n.t("configuration:enterOpusModel")}${i18n.t("common:emptyToSkip")}`,
|
|
376
|
+
default: defaultOpusModel || ""
|
|
377
|
+
});
|
|
378
|
+
return { primaryModel, haikuModel, sonnetModel, opusModel };
|
|
379
|
+
}
|
|
380
|
+
async function configureAiMemoryFeature() {
|
|
381
|
+
ensureI18nInitialized();
|
|
382
|
+
const isZh = i18n.language === "zh-CN";
|
|
383
|
+
const { option } = await inquirer.prompt({
|
|
384
|
+
type: "list",
|
|
385
|
+
name: "option",
|
|
386
|
+
message: isZh ? "\u9009\u62E9 AI \u8BB0\u5FC6\u7BA1\u7406\u9009\u9879" : "Select AI memory management option",
|
|
387
|
+
choices: addNumbersToChoices([
|
|
388
|
+
{
|
|
389
|
+
name: isZh ? "\u{1F4C4} \u67E5\u770B\u5168\u5C40 CLAUDE.md\uFF08\u7CFB\u7EDF\u63D0\u793A\uFF09" : "\u{1F4C4} View global CLAUDE.md (system prompt)",
|
|
390
|
+
value: "viewGlobalClaudeMd"
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
name: isZh ? "\u{1F4C1} \u67E5\u770B\u9879\u76EE CLAUDE.md" : "\u{1F4C1} View project CLAUDE.md",
|
|
394
|
+
value: "viewProjectClaudeMd"
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
name: isZh ? "\u{1F52C} \u67E5\u770B Postmortem\uFF08\u5386\u53F2 Bug \u7ECF\u9A8C\uFF09" : "\u{1F52C} View Postmortem (bug lessons learned)",
|
|
398
|
+
value: "viewPostmortem"
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
name: isZh ? "\u270F\uFE0F \u7F16\u8F91\u5168\u5C40 CLAUDE.md" : "\u270F\uFE0F Edit global CLAUDE.md",
|
|
402
|
+
value: "editGlobalClaudeMd"
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
name: isZh ? "\u{1F310} \u914D\u7F6E AI \u8F93\u51FA\u8BED\u8A00" : "\u{1F310} Configure AI output language",
|
|
406
|
+
value: "language"
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
name: isZh ? "\u{1F3A8} \u914D\u7F6E\u8F93\u51FA\u98CE\u683C" : "\u{1F3A8} Configure output style",
|
|
410
|
+
value: "outputStyle"
|
|
411
|
+
}
|
|
412
|
+
])
|
|
413
|
+
});
|
|
414
|
+
if (!option) {
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
const cwd = process__default.cwd();
|
|
418
|
+
const globalClaudeMdPath = join(homedir(), ".claude", "CLAUDE.md");
|
|
419
|
+
const projectClaudeMdPath = join(cwd, "CLAUDE.md");
|
|
420
|
+
const localClaudeMdPath = join(cwd, ".claude", "CLAUDE.md");
|
|
421
|
+
switch (option) {
|
|
422
|
+
case "viewGlobalClaudeMd": {
|
|
423
|
+
if (existsSync(globalClaudeMdPath)) {
|
|
424
|
+
console.log(a.green.bold(`
|
|
425
|
+
\u{1F4C4} ${isZh ? "\u5168\u5C40 CLAUDE.md \u5185\u5BB9" : "Global CLAUDE.md Content"}:`));
|
|
426
|
+
console.log(a.dim("\u2500".repeat(60)));
|
|
427
|
+
const content = readFileSync(globalClaudeMdPath, "utf-8");
|
|
428
|
+
console.log(content);
|
|
429
|
+
console.log(a.dim("\u2500".repeat(60)));
|
|
430
|
+
console.log(a.gray(`${isZh ? "\u8DEF\u5F84" : "Path"}: ${globalClaudeMdPath}`));
|
|
431
|
+
} else {
|
|
432
|
+
console.log(a.yellow(`
|
|
433
|
+
\u26A0\uFE0F ${isZh ? "\u5168\u5C40 CLAUDE.md \u4E0D\u5B58\u5728" : "Global CLAUDE.md does not exist"}`));
|
|
434
|
+
console.log(a.gray(`${isZh ? "\u9884\u671F\u8DEF\u5F84" : "Expected path"}: ${globalClaudeMdPath}`));
|
|
435
|
+
}
|
|
436
|
+
break;
|
|
437
|
+
}
|
|
438
|
+
case "viewProjectClaudeMd": {
|
|
439
|
+
let foundPath = null;
|
|
440
|
+
if (existsSync(projectClaudeMdPath)) {
|
|
441
|
+
foundPath = projectClaudeMdPath;
|
|
442
|
+
} else if (existsSync(localClaudeMdPath)) {
|
|
443
|
+
foundPath = localClaudeMdPath;
|
|
444
|
+
}
|
|
445
|
+
if (foundPath) {
|
|
446
|
+
console.log(a.green.bold(`
|
|
447
|
+
\u{1F4C1} ${isZh ? "\u9879\u76EE CLAUDE.md \u5185\u5BB9" : "Project CLAUDE.md Content"}:`));
|
|
448
|
+
console.log(a.dim("\u2500".repeat(60)));
|
|
449
|
+
const content = readFileSync(foundPath, "utf-8");
|
|
450
|
+
console.log(content);
|
|
451
|
+
console.log(a.dim("\u2500".repeat(60)));
|
|
452
|
+
console.log(a.gray(`${isZh ? "\u8DEF\u5F84" : "Path"}: ${foundPath}`));
|
|
453
|
+
} else {
|
|
454
|
+
console.log(a.yellow(`
|
|
455
|
+
\u26A0\uFE0F ${isZh ? "\u9879\u76EE CLAUDE.md \u4E0D\u5B58\u5728" : "Project CLAUDE.md does not exist"}`));
|
|
456
|
+
console.log(a.gray(`${isZh ? "\u5DF2\u68C0\u67E5\u8DEF\u5F84" : "Checked paths"}:`));
|
|
457
|
+
console.log(a.gray(` - ${projectClaudeMdPath}`));
|
|
458
|
+
console.log(a.gray(` - ${localClaudeMdPath}`));
|
|
459
|
+
}
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
case "viewPostmortem": {
|
|
463
|
+
const postmortemDir = join(cwd, ".postmortem");
|
|
464
|
+
if (existsSync(postmortemDir)) {
|
|
465
|
+
console.log(a.green.bold(`
|
|
466
|
+
\u{1F52C} ${isZh ? "Postmortem \u62A5\u544A" : "Postmortem Reports"}:`));
|
|
467
|
+
console.log(a.dim("\u2500".repeat(60)));
|
|
468
|
+
const { readdirSync } = await import('node:fs');
|
|
469
|
+
const files = readdirSync(postmortemDir).filter((f) => f.endsWith(".md"));
|
|
470
|
+
if (files.length === 0) {
|
|
471
|
+
console.log(a.yellow(isZh ? "\u6682\u65E0 Postmortem \u62A5\u544A" : "No postmortem reports yet"));
|
|
472
|
+
} else {
|
|
473
|
+
console.log(a.green(`${isZh ? "\u627E\u5230" : "Found"} ${files.length} ${isZh ? "\u4E2A\u62A5\u544A" : "reports"}:
|
|
474
|
+
`));
|
|
475
|
+
const { selectedFile } = await inquirer.prompt({
|
|
476
|
+
type: "list",
|
|
477
|
+
name: "selectedFile",
|
|
478
|
+
message: isZh ? "\u9009\u62E9\u8981\u67E5\u770B\u7684\u62A5\u544A" : "Select a report to view",
|
|
479
|
+
choices: [
|
|
480
|
+
...files.map((f) => ({ name: f, value: f })),
|
|
481
|
+
{ name: isZh ? "\u8FD4\u56DE" : "Back", value: "back" }
|
|
482
|
+
]
|
|
483
|
+
});
|
|
484
|
+
if (selectedFile !== "back") {
|
|
485
|
+
const reportPath = join(postmortemDir, selectedFile);
|
|
486
|
+
const content = readFileSync(reportPath, "utf-8");
|
|
487
|
+
console.log(a.dim("\u2500".repeat(60)));
|
|
488
|
+
console.log(content);
|
|
489
|
+
console.log(a.dim("\u2500".repeat(60)));
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
console.log(a.gray(`
|
|
493
|
+
${isZh ? "\u76EE\u5F55" : "Directory"}: ${postmortemDir}`));
|
|
494
|
+
console.log(a.gray(`\u{1F4A1} ${isZh ? "\u8FD0\u884C `ccjk postmortem init` \u4ECE\u5386\u53F2 fix commits \u751F\u6210\u62A5\u544A" : "Run `ccjk postmortem init` to generate reports from fix commits"}`));
|
|
495
|
+
} else {
|
|
496
|
+
console.log(a.yellow(`
|
|
497
|
+
\u26A0\uFE0F ${isZh ? "Postmortem \u76EE\u5F55\u4E0D\u5B58\u5728" : "Postmortem directory does not exist"}`));
|
|
498
|
+
console.log(a.gray(`\u{1F4A1} ${isZh ? "\u8FD0\u884C `ccjk postmortem init` \u521D\u59CB\u5316 Postmortem \u7CFB\u7EDF" : "Run `ccjk postmortem init` to initialize the Postmortem system"}`));
|
|
499
|
+
}
|
|
500
|
+
break;
|
|
501
|
+
}
|
|
502
|
+
case "editGlobalClaudeMd": {
|
|
503
|
+
const editor = process__default.env.EDITOR || process__default.env.VISUAL || "vi";
|
|
504
|
+
if (!existsSync(globalClaudeMdPath)) {
|
|
505
|
+
const claudeDir = join(homedir(), ".claude");
|
|
506
|
+
if (!existsSync(claudeDir)) {
|
|
507
|
+
mkdirSync(claudeDir, { recursive: true });
|
|
508
|
+
}
|
|
509
|
+
writeFileSync(globalClaudeMdPath, `# Claude Global Memory
|
|
510
|
+
|
|
511
|
+
<!-- Add your global instructions here -->
|
|
512
|
+
`);
|
|
513
|
+
console.log(a.green(`\u2705 ${isZh ? "\u5DF2\u521B\u5EFA\u5168\u5C40 CLAUDE.md" : "Created global CLAUDE.md"}`));
|
|
514
|
+
}
|
|
515
|
+
console.log(a.green(`
|
|
516
|
+
\u{1F4DD} ${isZh ? "\u6B63\u5728\u6253\u5F00\u7F16\u8F91\u5668..." : "Opening editor..."}`));
|
|
517
|
+
console.log(a.gray(`${isZh ? "\u7F16\u8F91\u5668" : "Editor"}: ${editor}`));
|
|
518
|
+
console.log(a.gray(`${isZh ? "\u6587\u4EF6" : "File"}: ${globalClaudeMdPath}`));
|
|
519
|
+
try {
|
|
520
|
+
const { execSync } = await import('node:child_process');
|
|
521
|
+
execSync(`${editor} "${globalClaudeMdPath}"`, { stdio: "inherit" });
|
|
522
|
+
console.log(a.green(`
|
|
523
|
+
\u2705 ${isZh ? "\u7F16\u8F91\u5B8C\u6210" : "Edit complete"}`));
|
|
524
|
+
} catch {
|
|
525
|
+
console.log(a.yellow(`
|
|
526
|
+
\u26A0\uFE0F ${isZh ? "\u7F16\u8F91\u5668\u9000\u51FA" : "Editor exited"}`));
|
|
527
|
+
}
|
|
528
|
+
break;
|
|
529
|
+
}
|
|
530
|
+
case "language": {
|
|
531
|
+
const zcfConfig = readZcfConfig();
|
|
532
|
+
const existingLang = zcfConfig?.aiOutputLang;
|
|
533
|
+
if (existingLang) {
|
|
534
|
+
console.log(
|
|
535
|
+
`
|
|
536
|
+
${a.green(`\u2139 ${i18n.t("configuration:existingLanguageConfig") || "Existing AI output language configuration"}`)}`
|
|
537
|
+
);
|
|
538
|
+
console.log(a.gray(` ${i18n.t("configuration:currentLanguage") || "Current language"}: ${existingLang}
|
|
539
|
+
`));
|
|
540
|
+
const modify = await promptBoolean({
|
|
541
|
+
message: i18n.t("configuration:modifyLanguage") || "Modify AI output language?",
|
|
542
|
+
defaultValue: false
|
|
543
|
+
});
|
|
544
|
+
if (!modify) {
|
|
545
|
+
console.log(a.green(`\u2714 ${i18n.t("configuration:keepLanguage") || "Keeping existing language configuration"}`));
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
const { selectAiOutputLanguage } = await import('./prompts.mjs');
|
|
550
|
+
const aiOutputLang = await selectAiOutputLanguage();
|
|
551
|
+
applyAiLanguageDirective(aiOutputLang);
|
|
552
|
+
updateZcfConfig({ aiOutputLang });
|
|
553
|
+
console.log(a.green(`\u2714 ${i18n.t("configuration:aiLanguageConfigured") || "AI output language configured"}`));
|
|
554
|
+
break;
|
|
555
|
+
}
|
|
556
|
+
case "outputStyle": {
|
|
557
|
+
await configureOutputStyle();
|
|
558
|
+
break;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
async function changeScriptLanguageFeature(currentLang) {
|
|
563
|
+
ensureI18nInitialized();
|
|
564
|
+
const { lang } = await inquirer.prompt({
|
|
565
|
+
type: "list",
|
|
566
|
+
name: "lang",
|
|
567
|
+
message: i18n.t("language:selectScriptLang"),
|
|
568
|
+
choices: addNumbersToChoices(
|
|
569
|
+
SUPPORTED_LANGS.map((l) => ({
|
|
570
|
+
name: LANG_LABELS[l],
|
|
571
|
+
value: l
|
|
572
|
+
}))
|
|
573
|
+
),
|
|
574
|
+
default: SUPPORTED_LANGS.indexOf(currentLang)
|
|
575
|
+
});
|
|
576
|
+
if (!lang) {
|
|
577
|
+
return currentLang;
|
|
578
|
+
}
|
|
579
|
+
updateZcfConfig({ preferredLang: lang });
|
|
580
|
+
await changeLanguage(lang);
|
|
581
|
+
console.log(a.green(`\u2714 ${i18n.t("language:languageChanged") || "Language changed"}`));
|
|
582
|
+
return lang;
|
|
583
|
+
}
|
|
584
|
+
async function mcpManagerFeature() {
|
|
585
|
+
ensureI18nInitialized();
|
|
586
|
+
const isZh = i18n.language === "zh-CN";
|
|
587
|
+
const { choice } = await inquirer.prompt({
|
|
588
|
+
type: "list",
|
|
589
|
+
name: "choice",
|
|
590
|
+
message: isZh ? "\u{1F527} MCP \u7BA1\u7406 \u2014 \u9009\u62E9\u64CD\u4F5C:" : "\u{1F527} MCP Manager \u2014 Select action:",
|
|
591
|
+
choices: addNumbersToChoices([
|
|
592
|
+
{
|
|
593
|
+
name: isZh ? `\u{1F4CA} \u67E5\u770B MCP \u72B6\u6001 ${a.gray("- \u5DF2\u5B89\u88C5\u670D\u52A1\u603B\u89C8 + \u6027\u80FD\u9884\u8B66")}` : `\u{1F4CA} MCP Status ${a.gray("- Installed services overview + performance warning")}`,
|
|
594
|
+
value: "status"
|
|
595
|
+
},
|
|
596
|
+
{
|
|
597
|
+
name: isZh ? `\u{1FA7A} MCP \u8BCA\u65AD ${a.gray("- \u5065\u5EB7\u68C0\u67E5\u3001\u51B2\u7A81\u68C0\u6D4B\u3001\u4F18\u5316\u5EFA\u8BAE")}` : `\u{1FA7A} MCP Doctor ${a.gray("- Health check, conflict detection, optimization tips")}`,
|
|
598
|
+
value: "doctor"
|
|
599
|
+
},
|
|
600
|
+
{
|
|
601
|
+
name: isZh ? `\u{1F4CB} \u5217\u51FA\u5DF2\u5B89\u88C5\u670D\u52A1 ${a.gray("- \u67E5\u770B\u5DF2\u914D\u7F6E\u7684 MCP \u670D\u52A1\u8BE6\u60C5")}` : `\u{1F4CB} List installed services ${a.gray("- View details of configured MCP services")}`,
|
|
602
|
+
value: "list"
|
|
603
|
+
},
|
|
604
|
+
{
|
|
605
|
+
name: isZh ? `\u{1F504} \u5207\u6362\u914D\u7F6E\u9884\u8BBE ${a.gray("- minimal\uFF08\u8F7B\u91CF\uFF09/ dev\uFF08\u5F00\u53D1\uFF09/ full\uFF08\u5B8C\u6574\uFF09")}` : `\u{1F504} Switch profile ${a.gray("- minimal / dev / full preset")}`,
|
|
606
|
+
value: "profile"
|
|
607
|
+
},
|
|
608
|
+
{
|
|
609
|
+
name: isZh ? `\u{1F5D1}\uFE0F \u91CA\u653E\u95F2\u7F6E\u670D\u52A1 ${a.gray("- \u505C\u7528\u957F\u671F\u672A\u4F7F\u7528\u7684\u670D\u52A1\u4EE5\u8282\u7701\u8D44\u6E90")}` : `\u{1F5D1}\uFE0F Release idle services ${a.gray("- Disable unused services to free resources")}`,
|
|
610
|
+
value: "release"
|
|
611
|
+
},
|
|
612
|
+
{
|
|
613
|
+
name: isZh ? `\u{1F4E6} \u5B89\u88C5/\u66F4\u65B0 MCP \u670D\u52A1 ${a.gray("- \u8FDB\u5165\u670D\u52A1\u9009\u62E9\u5411\u5BFC\uFF08\u540C\u83DC\u5355\u9009\u9879 4\uFF09")}` : `\u{1F4E6} Install / Update services ${a.gray("- Open install wizard (same as menu option 4)")}`,
|
|
614
|
+
value: "install"
|
|
615
|
+
}
|
|
616
|
+
])
|
|
617
|
+
});
|
|
618
|
+
if (!choice) {
|
|
619
|
+
await handleCancellation();
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
try {
|
|
623
|
+
switch (choice) {
|
|
624
|
+
case "status": {
|
|
625
|
+
const { mcpStatus } = await import('./mcp.mjs');
|
|
626
|
+
await mcpStatus();
|
|
627
|
+
break;
|
|
628
|
+
}
|
|
629
|
+
case "doctor": {
|
|
630
|
+
const { mcpDoctor } = await import('./mcp.mjs');
|
|
631
|
+
await mcpDoctor();
|
|
632
|
+
break;
|
|
633
|
+
}
|
|
634
|
+
case "list": {
|
|
635
|
+
const { mcpList } = await import('./mcp.mjs');
|
|
636
|
+
await mcpList();
|
|
637
|
+
break;
|
|
638
|
+
}
|
|
639
|
+
case "profile": {
|
|
640
|
+
const { listProfiles, useProfile } = await import('./mcp.mjs');
|
|
641
|
+
await listProfiles();
|
|
642
|
+
const { profileId } = await inquirer.prompt({
|
|
643
|
+
type: "list",
|
|
644
|
+
name: "profileId",
|
|
645
|
+
message: isZh ? "\u9009\u62E9\u8981\u5207\u6362\u7684\u9884\u8BBE:" : "Select profile to switch:",
|
|
646
|
+
choices: [
|
|
647
|
+
{ name: isZh ? "minimal \u2014 \u4EC5\u6838\u5FC3\u670D\u52A1\uFF08\u6700\u4F4E\u8D44\u6E90\u5360\u7528\uFF09" : "minimal \u2014 Core services only (least resources)", value: "minimal" },
|
|
648
|
+
{ name: isZh ? "dev \u2014 \u5F00\u53D1\u5E38\u7528\u670D\u52A1\u5957\u88C5" : "dev \u2014 Dev-oriented service bundle", value: "dev" },
|
|
649
|
+
{ name: isZh ? "full \u2014 \u5B8C\u6574\u670D\u52A1\uFF08\u9AD8\u6027\u80FD\u673A\u5668\u63A8\u8350\uFF09" : "full \u2014 Full services (high-end machines)", value: "full" }
|
|
650
|
+
]
|
|
651
|
+
});
|
|
652
|
+
await useProfile(profileId);
|
|
653
|
+
break;
|
|
654
|
+
}
|
|
655
|
+
case "release": {
|
|
656
|
+
const { mcpRelease } = await import('./mcp.mjs');
|
|
657
|
+
await mcpRelease();
|
|
658
|
+
break;
|
|
659
|
+
}
|
|
660
|
+
case "install": {
|
|
661
|
+
await configureMcpFeature();
|
|
662
|
+
break;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
} catch (error) {
|
|
666
|
+
console.error(a.red(`${i18n.t("common:error")}: ${error.message}`));
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
async function configureMergedPermissionsFeature() {
|
|
670
|
+
ensureI18nInitialized();
|
|
671
|
+
const isZh = i18n.language === "zh-CN";
|
|
672
|
+
const { choice } = await inquirer.prompt({
|
|
673
|
+
type: "list",
|
|
674
|
+
name: "choice",
|
|
675
|
+
message: isZh ? "\u6743\u9650 & \u73AF\u5883\u914D\u7F6E \u2014 \u9009\u62E9\u64CD\u4F5C:" : "Permissions & Env Setup \u2014 Select action:",
|
|
676
|
+
choices: addNumbersToChoices([
|
|
677
|
+
{
|
|
678
|
+
name: isZh ? `\u5BFC\u5165\u63A8\u8350\u73AF\u5883\u53D8\u91CF ${a.gray("- \u5199\u5165\u9690\u79C1\u4FDD\u62A4 env \u5230 settings.json")}` : `Import recommended env vars ${a.gray("- Write privacy env to settings.json")}`,
|
|
679
|
+
value: "env"
|
|
680
|
+
},
|
|
681
|
+
{
|
|
682
|
+
name: isZh ? `\u5BFC\u5165\u63A8\u8350\u6743\u9650\u914D\u7F6E ${a.gray("- \u8FFD\u52A0\u63A8\u8350 allow \u89C4\u5219\u5230 settings.json")}` : `Import recommended permissions ${a.gray("- Append recommended allow rules")}`,
|
|
683
|
+
value: "permissions"
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
name: isZh ? `\u4E00\u952E\u6743\u9650\u9884\u8BBE ${a.gray("- \u6700\u5927(max) / \u5F00\u53D1\u8005(dev) / \u5B89\u5168(safe) \u9884\u8BBE")}` : `Zero-config permission preset ${a.gray("- max / dev / safe preset")}`,
|
|
687
|
+
value: "preset"
|
|
688
|
+
},
|
|
689
|
+
{
|
|
690
|
+
name: isZh ? `\u6253\u5F00 settings.json ${a.gray("- \u5728\u7F16\u8F91\u5668\u4E2D\u67E5\u770B\u5F53\u524D\u914D\u7F6E")}` : `Open settings.json ${a.gray("- View current config in editor")}`,
|
|
691
|
+
value: "open"
|
|
692
|
+
}
|
|
693
|
+
])
|
|
694
|
+
});
|
|
695
|
+
if (!choice) {
|
|
696
|
+
await handleCancellation();
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
try {
|
|
700
|
+
switch (choice) {
|
|
701
|
+
case "env":
|
|
702
|
+
await importRecommendedEnv();
|
|
703
|
+
console.log(a.green(`\u2705 ${i18n.t("configuration:envImportSuccess")}`));
|
|
704
|
+
break;
|
|
705
|
+
case "permissions":
|
|
706
|
+
await importRecommendedPermissions();
|
|
707
|
+
console.log(a.green(`\u2705 ${i18n.t("configuration:permissionsImportSuccess") || "Permissions imported"}`));
|
|
708
|
+
break;
|
|
709
|
+
case "preset": {
|
|
710
|
+
const { zeroConfig } = await import('./zero-config.mjs');
|
|
711
|
+
await zeroConfig();
|
|
712
|
+
break;
|
|
713
|
+
}
|
|
714
|
+
case "open":
|
|
715
|
+
console.log(a.green(i18n.t("configuration:openingSettingsJson") || "Opening settings.json..."));
|
|
716
|
+
await openSettingsJson();
|
|
717
|
+
break;
|
|
718
|
+
}
|
|
719
|
+
} catch (error) {
|
|
720
|
+
console.error(a.red(`${i18n.t("common:error")}: ${error.message}`));
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
async function configureMemoryFeature() {
|
|
724
|
+
const { AutoMemoryBridge } = await import('./auto-memory-bridge.mjs');
|
|
725
|
+
const inquirer2 = (await import('./index3.mjs').then(function (n) { return n.c; })).default;
|
|
726
|
+
const ansis2 = (await import('./index2.mjs')).default;
|
|
727
|
+
const { execSync } = await import('node:child_process');
|
|
728
|
+
const fs = await import('node:fs/promises');
|
|
729
|
+
const path = await import('node:path');
|
|
730
|
+
const os = await import('node:os');
|
|
731
|
+
console.log(ansis2.cyan(`
|
|
732
|
+
${i18n.t("memory:title")}`));
|
|
733
|
+
const bridge = new AutoMemoryBridge();
|
|
734
|
+
const claudeMemoryPath = path.join(os.homedir(), ".claude", "projects", "-Users-lu-ccjk-public", "memory", "MEMORY.md");
|
|
735
|
+
const ccjkMemoryPath = path.join(os.homedir(), ".ccjk", "memory", "MEMORY.md");
|
|
736
|
+
let claudeMemoryExists = false;
|
|
737
|
+
let ccjkMemoryExists = false;
|
|
738
|
+
try {
|
|
739
|
+
await fs.access(claudeMemoryPath);
|
|
740
|
+
claudeMemoryExists = true;
|
|
741
|
+
} catch {
|
|
742
|
+
}
|
|
743
|
+
try {
|
|
744
|
+
await fs.access(ccjkMemoryPath);
|
|
745
|
+
ccjkMemoryExists = true;
|
|
746
|
+
} catch {
|
|
747
|
+
}
|
|
748
|
+
console.log(`
|
|
749
|
+
${ansis2.bold(i18n.t("memory:currentStatus"))}`);
|
|
750
|
+
console.log(ansis2.gray("\u2500".repeat(50)));
|
|
751
|
+
console.log(`${ansis2.yellow(i18n.t("memory:claudeMemory"))}: ${claudeMemoryExists ? ansis2.green("\u2713") : ansis2.red("\u2717")}`);
|
|
752
|
+
console.log(`${ansis2.yellow(i18n.t("memory:ccjkMemory"))}: ${ccjkMemoryExists ? ansis2.green("\u2713") : ansis2.red("\u2717")}`);
|
|
753
|
+
console.log(ansis2.gray("\u2500".repeat(50)));
|
|
754
|
+
const { action } = await inquirer2.prompt([
|
|
755
|
+
{
|
|
756
|
+
type: "list",
|
|
757
|
+
name: "action",
|
|
758
|
+
message: i18n.t("memory:selectAction"),
|
|
759
|
+
choices: [
|
|
760
|
+
{ name: i18n.t("memory:viewMemory"), value: "view" },
|
|
761
|
+
{ name: i18n.t("memory:editMemory"), value: "edit" },
|
|
762
|
+
{ name: i18n.t("memory:syncNow"), value: "sync" },
|
|
763
|
+
{ name: i18n.t("memory:configureRules"), value: "rules" },
|
|
764
|
+
{ name: i18n.t("memory:back"), value: "back" }
|
|
765
|
+
]
|
|
766
|
+
}
|
|
767
|
+
]);
|
|
768
|
+
switch (action) {
|
|
769
|
+
case "view": {
|
|
770
|
+
const memoryPath = path.join(os.homedir(), ".claude", "projects", "-Users-lu-ccjk-public", "memory", "MEMORY.md");
|
|
771
|
+
try {
|
|
772
|
+
const content = await fs.readFile(memoryPath, "utf-8");
|
|
773
|
+
console.log(`
|
|
774
|
+
${ansis2.bold(i18n.t("memory:memoryContent"))}`);
|
|
775
|
+
console.log(ansis2.gray("\u2500".repeat(50)));
|
|
776
|
+
console.log(content);
|
|
777
|
+
console.log(ansis2.gray("\u2500".repeat(50)));
|
|
778
|
+
} catch (error) {
|
|
779
|
+
console.log(ansis2.red(i18n.t("memory:readError")));
|
|
780
|
+
}
|
|
781
|
+
break;
|
|
782
|
+
}
|
|
783
|
+
case "edit": {
|
|
784
|
+
const memoryPath = path.join(os.homedir(), ".claude", "projects", "-Users-lu-ccjk-public", "memory", "MEMORY.md");
|
|
785
|
+
const editor = process__default.env.EDITOR || "nano";
|
|
786
|
+
try {
|
|
787
|
+
execSync(`${editor} "${memoryPath}"`, { stdio: "inherit" });
|
|
788
|
+
console.log(ansis2.green(i18n.t("memory:editComplete")));
|
|
789
|
+
} catch (error) {
|
|
790
|
+
console.log(ansis2.red(i18n.t("memory:editError")));
|
|
791
|
+
}
|
|
792
|
+
break;
|
|
793
|
+
}
|
|
794
|
+
case "sync": {
|
|
795
|
+
console.log(ansis2.cyan(i18n.t("memory:syncing")));
|
|
796
|
+
try {
|
|
797
|
+
await bridge.syncToClaude();
|
|
798
|
+
console.log(ansis2.green(i18n.t("memory:syncComplete")));
|
|
799
|
+
} catch (error) {
|
|
800
|
+
console.log(ansis2.red(i18n.t("memory:syncError")));
|
|
801
|
+
}
|
|
802
|
+
break;
|
|
803
|
+
}
|
|
804
|
+
case "rules": {
|
|
805
|
+
console.log(ansis2.yellow(i18n.t("memory:rulesInfo")));
|
|
806
|
+
console.log(i18n.t("memory:rulesDescription"));
|
|
807
|
+
break;
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
export { DEFAULT_MODEL_CHOICES, changeScriptLanguageFeature, configureAiMemoryFeature, configureApiFeature, configureDefaultModelFeature, configureMcpFeature, configureMemoryFeature, configureMergedPermissionsFeature, handleCustomApiMode, mcpManagerFeature, promptCustomModels };
|