ccjk 2.4.3 → 2.5.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.
- package/dist/chunks/api-providers.mjs +73 -1
- package/dist/chunks/ccjk-config.mjs +13 -77
- package/dist/chunks/ccr.mjs +9 -4
- package/dist/chunks/check-updates.mjs +4 -2
- package/dist/chunks/claude-code-config-manager.mjs +9 -15
- package/dist/chunks/claude-code-incremental-manager.mjs +5 -8
- package/dist/chunks/codex.mjs +10 -569
- package/dist/chunks/config-switch.mjs +7 -5
- package/dist/chunks/config.mjs +573 -0
- package/dist/chunks/config2.mjs +451 -0
- package/dist/chunks/doctor.mjs +89 -1
- package/dist/chunks/features.mjs +13 -10
- package/dist/chunks/index.mjs +10 -1164
- package/dist/chunks/index2.mjs +8 -2
- package/dist/chunks/init.mjs +14 -11
- package/dist/chunks/json-config.mjs +59 -0
- package/dist/chunks/mcp-server.mjs +776 -0
- package/dist/chunks/mcp.mjs +10 -8
- package/dist/chunks/menu.mjs +5 -5
- package/dist/chunks/package.mjs +1 -1
- package/dist/chunks/permissions.mjs +420 -0
- package/dist/chunks/prompts.mjs +2 -1
- package/dist/chunks/providers.mjs +261 -0
- package/dist/chunks/session.mjs +484 -41
- package/dist/chunks/skills.mjs +553 -0
- package/dist/chunks/stats.mjs +411 -0
- package/dist/chunks/uninstall.mjs +4 -3
- package/dist/chunks/update.mjs +6 -3
- package/dist/chunks/workflows2.mjs +140 -0
- package/dist/cli.mjs +316 -10
- package/dist/i18n/locales/en/hooks.json +47 -0
- package/dist/i18n/locales/en/mcp.json +55 -0
- package/dist/i18n/locales/en/permissions.json +43 -0
- package/dist/i18n/locales/en/sandbox.json +44 -0
- package/dist/i18n/locales/en/skills.json +89 -129
- package/dist/i18n/locales/en/stats.json +20 -0
- package/dist/i18n/locales/zh-CN/hooks.json +47 -0
- package/dist/i18n/locales/zh-CN/mcp.json +55 -0
- package/dist/i18n/locales/zh-CN/permissions.json +43 -0
- package/dist/i18n/locales/zh-CN/sandbox.json +44 -0
- package/dist/i18n/locales/zh-CN/skills.json +88 -128
- package/dist/i18n/locales/zh-CN/stats.json +20 -0
- package/dist/index.mjs +12 -8
- package/dist/shared/ccjk.B-lZxV2u.mjs +1162 -0
- package/dist/shared/{ccjk.CURU8gbR.mjs → ccjk.CUdzQluX.mjs} +1 -1
- package/dist/shared/{ccjk.ByTIGCUC.mjs → ccjk.Dut3wyoP.mjs} +1 -1
- package/dist/shared/ccjk.J8YiPsOw.mjs +259 -0
- package/dist/shared/{ccjk.CGTmRqsu.mjs → ccjk.rLRHmcqD.mjs} +5 -134
- package/dist/shared/{ccjk.QbS8EAOd.mjs → ccjk.uVUeWAt8.mjs} +2 -1
- package/package.json +1 -1
- package/templates/common/skills/code-review.md +343 -0
- package/templates/common/skills/summarize.md +312 -0
- package/templates/common/skills/translate.md +202 -0
package/dist/chunks/codex.mjs
CHANGED
|
@@ -8,11 +8,13 @@ import { join, dirname } from 'pathe';
|
|
|
8
8
|
import semver from 'semver';
|
|
9
9
|
import { parse } from 'smol-toml';
|
|
10
10
|
import { x } from 'tinyexec';
|
|
11
|
-
import {
|
|
11
|
+
import { SUPPORTED_LANGS, CODEX_DIR, CODEX_AGENTS_FILE, CODEX_CONFIG_FILE, CODEX_PROMPTS_DIR, CODEX_AUTH_FILE, AI_OUTPUT_LANGUAGES, ZCF_CONFIG_FILE } from './constants.mjs';
|
|
12
12
|
import { ensureI18nInitialized, i18n, format } from './index2.mjs';
|
|
13
|
-
import {
|
|
13
|
+
import { updateZcfConfig, readZcfConfig, readDefaultTomlConfig, updateTomlConfig } from './ccjk-config.mjs';
|
|
14
|
+
import { y as applyAiLanguageDirective } from './config.mjs';
|
|
15
|
+
import { exists, readFile, ensureDir, writeFileAtomic, writeFile, copyFile, copyDir } from './fs-operations.mjs';
|
|
16
|
+
import { readJsonConfig, writeJsonConfig } from './json-config.mjs';
|
|
14
17
|
import { isWindows, getMcpCommand, getSystemRoot, wrapCommandWithSudo, normalizeTomlPath } from './platform.mjs';
|
|
15
|
-
import { ensureDir, exists, copyDir, writeFileAtomic, copyFile, readFile, writeFile } from './fs-operations.mjs';
|
|
16
18
|
import { p as promptBoolean, a as addNumbersToChoices } from '../shared/ccjk.DhBeLRzf.mjs';
|
|
17
19
|
import { resolveAiOutputLanguage } from './prompts.mjs';
|
|
18
20
|
import 'node:child_process';
|
|
@@ -197,567 +199,6 @@ async function getMcpService(id) {
|
|
|
197
199
|
return services.find((service) => service.id === id);
|
|
198
200
|
}
|
|
199
201
|
|
|
200
|
-
function mergeArraysUnique(arr1, arr2) {
|
|
201
|
-
const combined = [...arr1 || [], ...arr2 || []];
|
|
202
|
-
return [...new Set(combined)];
|
|
203
|
-
}
|
|
204
|
-
function isPlainObject(value) {
|
|
205
|
-
return value !== null && typeof value === "object" && value.constructor === Object && Object.prototype.toString.call(value) === "[object Object]";
|
|
206
|
-
}
|
|
207
|
-
function deepMerge(target, source, options = {}) {
|
|
208
|
-
const { mergeArrays = false, arrayMergeStrategy = "replace" } = options;
|
|
209
|
-
const result = { ...target };
|
|
210
|
-
for (const key in source) {
|
|
211
|
-
const sourceValue = source[key];
|
|
212
|
-
const targetValue = result[key];
|
|
213
|
-
if (sourceValue === void 0) {
|
|
214
|
-
continue;
|
|
215
|
-
}
|
|
216
|
-
if (isPlainObject(sourceValue) && isPlainObject(targetValue)) {
|
|
217
|
-
result[key] = deepMerge(targetValue, sourceValue, options);
|
|
218
|
-
} else if (Array.isArray(sourceValue)) {
|
|
219
|
-
if (!mergeArrays || !Array.isArray(targetValue)) {
|
|
220
|
-
result[key] = sourceValue;
|
|
221
|
-
} else {
|
|
222
|
-
switch (arrayMergeStrategy) {
|
|
223
|
-
case "concat":
|
|
224
|
-
result[key] = [...targetValue, ...sourceValue];
|
|
225
|
-
break;
|
|
226
|
-
case "unique":
|
|
227
|
-
result[key] = mergeArraysUnique(targetValue, sourceValue);
|
|
228
|
-
break;
|
|
229
|
-
case "replace":
|
|
230
|
-
default:
|
|
231
|
-
result[key] = sourceValue;
|
|
232
|
-
break;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
} else {
|
|
236
|
-
result[key] = sourceValue;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
return result;
|
|
240
|
-
}
|
|
241
|
-
function deepClone(obj) {
|
|
242
|
-
if (obj === null || typeof obj !== "object") {
|
|
243
|
-
return obj;
|
|
244
|
-
}
|
|
245
|
-
if (obj instanceof Date) {
|
|
246
|
-
return new Date(obj.getTime());
|
|
247
|
-
}
|
|
248
|
-
if (Array.isArray(obj)) {
|
|
249
|
-
return obj.map((item) => deepClone(item));
|
|
250
|
-
}
|
|
251
|
-
if (isPlainObject(obj)) {
|
|
252
|
-
const cloned = {};
|
|
253
|
-
for (const key in obj) {
|
|
254
|
-
cloned[key] = deepClone(obj[key]);
|
|
255
|
-
}
|
|
256
|
-
return cloned;
|
|
257
|
-
}
|
|
258
|
-
return obj;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
function getMcpConfigPath() {
|
|
262
|
-
return ClAUDE_CONFIG_FILE;
|
|
263
|
-
}
|
|
264
|
-
function readMcpConfig() {
|
|
265
|
-
return readJsonConfig(ClAUDE_CONFIG_FILE);
|
|
266
|
-
}
|
|
267
|
-
function writeMcpConfig(config) {
|
|
268
|
-
writeJsonConfig(ClAUDE_CONFIG_FILE, config);
|
|
269
|
-
}
|
|
270
|
-
function backupMcpConfig() {
|
|
271
|
-
const backupBaseDir = join(CLAUDE_DIR, "backup");
|
|
272
|
-
return backupJsonConfig(ClAUDE_CONFIG_FILE, backupBaseDir);
|
|
273
|
-
}
|
|
274
|
-
function mergeMcpServers(existing, newServers) {
|
|
275
|
-
const config = existing || { mcpServers: {} };
|
|
276
|
-
if (!config.mcpServers) {
|
|
277
|
-
config.mcpServers = {};
|
|
278
|
-
}
|
|
279
|
-
Object.assign(config.mcpServers, newServers);
|
|
280
|
-
return config;
|
|
281
|
-
}
|
|
282
|
-
function applyPlatformCommand(config) {
|
|
283
|
-
if (isWindows() && config.command) {
|
|
284
|
-
const mcpCmd = getMcpCommand(config.command);
|
|
285
|
-
if (mcpCmd[0] === "cmd") {
|
|
286
|
-
config.command = mcpCmd[0];
|
|
287
|
-
config.args = [...mcpCmd.slice(1), ...config.args || []];
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
function buildMcpServerConfig(baseConfig, apiKey, placeholder = "YOUR_EXA_API_KEY", envVarName) {
|
|
292
|
-
const config = deepClone(baseConfig);
|
|
293
|
-
applyPlatformCommand(config);
|
|
294
|
-
if (!apiKey) {
|
|
295
|
-
return config;
|
|
296
|
-
}
|
|
297
|
-
if (envVarName && config.env) {
|
|
298
|
-
config.env[envVarName] = apiKey;
|
|
299
|
-
return config;
|
|
300
|
-
}
|
|
301
|
-
if (config.args) {
|
|
302
|
-
config.args = config.args.map((arg) => arg.replace(placeholder, apiKey));
|
|
303
|
-
}
|
|
304
|
-
if (config.url) {
|
|
305
|
-
config.url = config.url.replace(placeholder, apiKey);
|
|
306
|
-
}
|
|
307
|
-
return config;
|
|
308
|
-
}
|
|
309
|
-
function fixWindowsMcpConfig(config) {
|
|
310
|
-
if (!isWindows() || !config.mcpServers) {
|
|
311
|
-
return config;
|
|
312
|
-
}
|
|
313
|
-
const fixed = { ...config };
|
|
314
|
-
for (const [, serverConfig] of Object.entries(fixed.mcpServers)) {
|
|
315
|
-
if (serverConfig && typeof serverConfig === "object" && "command" in serverConfig) {
|
|
316
|
-
applyPlatformCommand(serverConfig);
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
return fixed;
|
|
320
|
-
}
|
|
321
|
-
function addCompletedOnboarding() {
|
|
322
|
-
try {
|
|
323
|
-
let config = readMcpConfig();
|
|
324
|
-
if (!config) {
|
|
325
|
-
config = { mcpServers: {} };
|
|
326
|
-
}
|
|
327
|
-
if (config.hasCompletedOnboarding === true) {
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
config.hasCompletedOnboarding = true;
|
|
331
|
-
writeMcpConfig(config);
|
|
332
|
-
} catch (error) {
|
|
333
|
-
console.error("Failed to add onboarding flag", error);
|
|
334
|
-
throw error;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
function ensureApiKeyApproved(config, apiKey) {
|
|
338
|
-
if (!apiKey || typeof apiKey !== "string" || apiKey.trim() === "") {
|
|
339
|
-
return config;
|
|
340
|
-
}
|
|
341
|
-
const truncatedApiKey = apiKey.substring(0, 20);
|
|
342
|
-
const updatedConfig = { ...config };
|
|
343
|
-
if (!updatedConfig.customApiKeyResponses) {
|
|
344
|
-
updatedConfig.customApiKeyResponses = {
|
|
345
|
-
approved: [],
|
|
346
|
-
rejected: []
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
if (!Array.isArray(updatedConfig.customApiKeyResponses.approved)) {
|
|
350
|
-
updatedConfig.customApiKeyResponses.approved = [];
|
|
351
|
-
}
|
|
352
|
-
if (!Array.isArray(updatedConfig.customApiKeyResponses.rejected)) {
|
|
353
|
-
updatedConfig.customApiKeyResponses.rejected = [];
|
|
354
|
-
}
|
|
355
|
-
const rejectedIndex = updatedConfig.customApiKeyResponses.rejected.indexOf(truncatedApiKey);
|
|
356
|
-
if (rejectedIndex > -1) {
|
|
357
|
-
updatedConfig.customApiKeyResponses.rejected.splice(rejectedIndex, 1);
|
|
358
|
-
}
|
|
359
|
-
if (!updatedConfig.customApiKeyResponses.approved.includes(truncatedApiKey)) {
|
|
360
|
-
updatedConfig.customApiKeyResponses.approved.push(truncatedApiKey);
|
|
361
|
-
}
|
|
362
|
-
return updatedConfig;
|
|
363
|
-
}
|
|
364
|
-
function removeApiKeyFromRejected(config, apiKey) {
|
|
365
|
-
if (!config.customApiKeyResponses || !Array.isArray(config.customApiKeyResponses.rejected)) {
|
|
366
|
-
return config;
|
|
367
|
-
}
|
|
368
|
-
const truncatedApiKey = apiKey.substring(0, 20);
|
|
369
|
-
const updatedConfig = { ...config };
|
|
370
|
-
if (updatedConfig.customApiKeyResponses) {
|
|
371
|
-
const rejectedIndex = updatedConfig.customApiKeyResponses.rejected.indexOf(truncatedApiKey);
|
|
372
|
-
if (rejectedIndex > -1) {
|
|
373
|
-
updatedConfig.customApiKeyResponses.rejected.splice(rejectedIndex, 1);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
return updatedConfig;
|
|
377
|
-
}
|
|
378
|
-
function manageApiKeyApproval(apiKey) {
|
|
379
|
-
try {
|
|
380
|
-
let config = readMcpConfig();
|
|
381
|
-
if (!config) {
|
|
382
|
-
config = { mcpServers: {} };
|
|
383
|
-
}
|
|
384
|
-
const updatedConfig = ensureApiKeyApproved(config, apiKey);
|
|
385
|
-
writeMcpConfig(updatedConfig);
|
|
386
|
-
} catch (error) {
|
|
387
|
-
ensureI18nInitialized();
|
|
388
|
-
console.error(i18n.t("mcp:apiKeyApprovalFailed"), error);
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
function setPrimaryApiKey() {
|
|
392
|
-
try {
|
|
393
|
-
let config = readJsonConfig(CLAUDE_VSC_CONFIG_FILE);
|
|
394
|
-
if (!config) {
|
|
395
|
-
config = {};
|
|
396
|
-
}
|
|
397
|
-
config.primaryApiKey = "ccjk";
|
|
398
|
-
writeJsonConfig(CLAUDE_VSC_CONFIG_FILE, config);
|
|
399
|
-
} catch (error) {
|
|
400
|
-
ensureI18nInitialized();
|
|
401
|
-
console.error(i18n.t("mcp:primaryApiKeySetFailed"), error);
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
const claudeConfig = {
|
|
406
|
-
__proto__: null,
|
|
407
|
-
addCompletedOnboarding: addCompletedOnboarding,
|
|
408
|
-
backupMcpConfig: backupMcpConfig,
|
|
409
|
-
buildMcpServerConfig: buildMcpServerConfig,
|
|
410
|
-
ensureApiKeyApproved: ensureApiKeyApproved,
|
|
411
|
-
fixWindowsMcpConfig: fixWindowsMcpConfig,
|
|
412
|
-
getMcpConfigPath: getMcpConfigPath,
|
|
413
|
-
manageApiKeyApproval: manageApiKeyApproval,
|
|
414
|
-
mergeMcpServers: mergeMcpServers,
|
|
415
|
-
readMcpConfig: readMcpConfig,
|
|
416
|
-
removeApiKeyFromRejected: removeApiKeyFromRejected,
|
|
417
|
-
setPrimaryApiKey: setPrimaryApiKey,
|
|
418
|
-
writeMcpConfig: writeMcpConfig
|
|
419
|
-
};
|
|
420
|
-
|
|
421
|
-
const MODEL_ENV_KEYS = [
|
|
422
|
-
"ANTHROPIC_MODEL",
|
|
423
|
-
"ANTHROPIC_DEFAULT_HAIKU_MODEL",
|
|
424
|
-
"ANTHROPIC_DEFAULT_SONNET_MODEL",
|
|
425
|
-
"ANTHROPIC_DEFAULT_OPUS_MODEL",
|
|
426
|
-
// Deprecated but still cleaned to avoid stale values
|
|
427
|
-
"ANTHROPIC_SMALL_FAST_MODEL"
|
|
428
|
-
];
|
|
429
|
-
function clearModelEnv(env) {
|
|
430
|
-
for (const key of MODEL_ENV_KEYS) {
|
|
431
|
-
delete env[key];
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
function cleanupPermissions(templatePermissions, userPermissions) {
|
|
436
|
-
const templateSet = new Set(templatePermissions);
|
|
437
|
-
const cleanedPermissions = userPermissions.filter((permission) => {
|
|
438
|
-
if (["mcp__.*", "mcp__*", "mcp__(*)"].includes(permission)) {
|
|
439
|
-
return false;
|
|
440
|
-
}
|
|
441
|
-
for (const templatePerm of templatePermissions) {
|
|
442
|
-
if (permission === templatePerm) {
|
|
443
|
-
continue;
|
|
444
|
-
}
|
|
445
|
-
if (permission.startsWith(templatePerm)) {
|
|
446
|
-
return false;
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
return true;
|
|
450
|
-
});
|
|
451
|
-
const merged = [...templateSet];
|
|
452
|
-
for (const permission of cleanedPermissions) {
|
|
453
|
-
if (!templateSet.has(permission)) {
|
|
454
|
-
merged.push(permission);
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
return merged;
|
|
458
|
-
}
|
|
459
|
-
function mergeAndCleanPermissions(templatePermissions, userPermissions) {
|
|
460
|
-
const template = templatePermissions || [];
|
|
461
|
-
const user = userPermissions || [];
|
|
462
|
-
return cleanupPermissions(template, user);
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
function ensureClaudeDir() {
|
|
466
|
-
ensureDir(CLAUDE_DIR);
|
|
467
|
-
}
|
|
468
|
-
function backupExistingConfig() {
|
|
469
|
-
if (!exists(CLAUDE_DIR)) {
|
|
470
|
-
return null;
|
|
471
|
-
}
|
|
472
|
-
const timestamp = dayjs().format("YYYY-MM-DD_HH-mm-ss");
|
|
473
|
-
const backupBaseDir = join(CLAUDE_DIR, "backup");
|
|
474
|
-
const backupDir = join(backupBaseDir, `backup_${timestamp}`);
|
|
475
|
-
ensureDir(backupDir);
|
|
476
|
-
const filter = (path) => {
|
|
477
|
-
return !path.includes("/backup");
|
|
478
|
-
};
|
|
479
|
-
copyDir(CLAUDE_DIR, backupDir, { filter });
|
|
480
|
-
return backupDir;
|
|
481
|
-
}
|
|
482
|
-
function copyConfigFiles(onlyMd = false) {
|
|
483
|
-
const currentFilePath = fileURLToPath(import.meta.url);
|
|
484
|
-
const distDir = dirname(dirname(currentFilePath));
|
|
485
|
-
const rootDir = dirname(distDir);
|
|
486
|
-
const baseTemplateDir = join(rootDir, "templates", "claude-code");
|
|
487
|
-
if (!onlyMd) {
|
|
488
|
-
const baseSettingsPath = join(baseTemplateDir, "common", "settings.json");
|
|
489
|
-
const destSettingsPath = join(CLAUDE_DIR, "settings.json");
|
|
490
|
-
if (exists(baseSettingsPath)) {
|
|
491
|
-
mergeSettingsFile(baseSettingsPath, destSettingsPath);
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
function getDefaultSettings() {
|
|
496
|
-
try {
|
|
497
|
-
const currentFilePath = fileURLToPath(import.meta.url);
|
|
498
|
-
const distDir = dirname(dirname(currentFilePath));
|
|
499
|
-
const rootDir = dirname(distDir);
|
|
500
|
-
const templateSettingsPath = join(rootDir, "templates", "claude-code", "common", "settings.json");
|
|
501
|
-
return readJsonConfig(templateSettingsPath) || {};
|
|
502
|
-
} catch (error) {
|
|
503
|
-
console.error("Failed to read template settings", error);
|
|
504
|
-
return {};
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
function configureApi(apiConfig) {
|
|
508
|
-
if (!apiConfig)
|
|
509
|
-
return null;
|
|
510
|
-
let settings = getDefaultSettings();
|
|
511
|
-
const existingSettings = readJsonConfig(SETTINGS_FILE);
|
|
512
|
-
if (existingSettings) {
|
|
513
|
-
settings = deepMerge(settings, existingSettings);
|
|
514
|
-
}
|
|
515
|
-
if (!settings.env) {
|
|
516
|
-
settings.env = {};
|
|
517
|
-
}
|
|
518
|
-
if (apiConfig.authType === "api_key") {
|
|
519
|
-
settings.env.ANTHROPIC_API_KEY = apiConfig.key;
|
|
520
|
-
delete settings.env.ANTHROPIC_AUTH_TOKEN;
|
|
521
|
-
} else if (apiConfig.authType === "auth_token") {
|
|
522
|
-
settings.env.ANTHROPIC_AUTH_TOKEN = apiConfig.key;
|
|
523
|
-
delete settings.env.ANTHROPIC_API_KEY;
|
|
524
|
-
}
|
|
525
|
-
if (apiConfig.url) {
|
|
526
|
-
settings.env.ANTHROPIC_BASE_URL = apiConfig.url;
|
|
527
|
-
}
|
|
528
|
-
writeJsonConfig(SETTINGS_FILE, settings);
|
|
529
|
-
if (apiConfig.authType) {
|
|
530
|
-
try {
|
|
531
|
-
setPrimaryApiKey();
|
|
532
|
-
} catch (error) {
|
|
533
|
-
ensureI18nInitialized();
|
|
534
|
-
console.error(i18n.t("mcp:primaryApiKeySetFailed"), error);
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
try {
|
|
538
|
-
addCompletedOnboarding();
|
|
539
|
-
} catch (error) {
|
|
540
|
-
console.error("Failed to set onboarding flag", error);
|
|
541
|
-
}
|
|
542
|
-
return apiConfig;
|
|
543
|
-
}
|
|
544
|
-
function mergeConfigs(sourceFile, targetFile) {
|
|
545
|
-
if (!exists(sourceFile))
|
|
546
|
-
return;
|
|
547
|
-
const target = readJsonConfig(targetFile) || {};
|
|
548
|
-
const source = readJsonConfig(sourceFile) || {};
|
|
549
|
-
const merged = deepMerge(target, source);
|
|
550
|
-
writeJsonConfig(targetFile, merged);
|
|
551
|
-
}
|
|
552
|
-
function updateCustomModel(primaryModel, haikuModel, sonnetModel, opusModel) {
|
|
553
|
-
if (!primaryModel?.trim() && !haikuModel?.trim() && !sonnetModel?.trim() && !opusModel?.trim()) {
|
|
554
|
-
return;
|
|
555
|
-
}
|
|
556
|
-
let settings = getDefaultSettings();
|
|
557
|
-
const existingSettings = readJsonConfig(SETTINGS_FILE);
|
|
558
|
-
if (existingSettings) {
|
|
559
|
-
settings = existingSettings;
|
|
560
|
-
}
|
|
561
|
-
delete settings.model;
|
|
562
|
-
settings.env = settings.env || {};
|
|
563
|
-
clearModelEnv(settings.env);
|
|
564
|
-
if (primaryModel?.trim()) {
|
|
565
|
-
settings.env.ANTHROPIC_MODEL = primaryModel.trim();
|
|
566
|
-
}
|
|
567
|
-
if (haikuModel?.trim())
|
|
568
|
-
settings.env.ANTHROPIC_DEFAULT_HAIKU_MODEL = haikuModel.trim();
|
|
569
|
-
if (sonnetModel?.trim())
|
|
570
|
-
settings.env.ANTHROPIC_DEFAULT_SONNET_MODEL = sonnetModel.trim();
|
|
571
|
-
if (opusModel?.trim())
|
|
572
|
-
settings.env.ANTHROPIC_DEFAULT_OPUS_MODEL = opusModel.trim();
|
|
573
|
-
writeJsonConfig(SETTINGS_FILE, settings);
|
|
574
|
-
}
|
|
575
|
-
function updateDefaultModel(model) {
|
|
576
|
-
let settings = getDefaultSettings();
|
|
577
|
-
const existingSettings = readJsonConfig(SETTINGS_FILE);
|
|
578
|
-
if (existingSettings) {
|
|
579
|
-
settings = existingSettings;
|
|
580
|
-
}
|
|
581
|
-
if (!settings.env) {
|
|
582
|
-
settings.env = {};
|
|
583
|
-
}
|
|
584
|
-
if (model !== "custom") {
|
|
585
|
-
clearModelEnv(settings.env);
|
|
586
|
-
}
|
|
587
|
-
if (model === "default" || model === "custom") {
|
|
588
|
-
delete settings.model;
|
|
589
|
-
} else {
|
|
590
|
-
settings.model = model;
|
|
591
|
-
}
|
|
592
|
-
writeJsonConfig(SETTINGS_FILE, settings);
|
|
593
|
-
}
|
|
594
|
-
function mergeSettingsFile(templatePath, targetPath) {
|
|
595
|
-
try {
|
|
596
|
-
const templateSettings = readJsonConfig(templatePath);
|
|
597
|
-
if (!templateSettings) {
|
|
598
|
-
console.error("Failed to read template settings");
|
|
599
|
-
return;
|
|
600
|
-
}
|
|
601
|
-
if (!exists(targetPath)) {
|
|
602
|
-
writeJsonConfig(targetPath, templateSettings);
|
|
603
|
-
return;
|
|
604
|
-
}
|
|
605
|
-
const existingSettings = readJsonConfig(targetPath) || {};
|
|
606
|
-
const mergedEnv = {
|
|
607
|
-
...templateSettings.env || {},
|
|
608
|
-
// Template env vars first
|
|
609
|
-
...existingSettings.env || {}
|
|
610
|
-
// User's env vars override (preserving API keys, etc.)
|
|
611
|
-
};
|
|
612
|
-
const mergedSettings = deepMerge(templateSettings, existingSettings, {
|
|
613
|
-
mergeArrays: true,
|
|
614
|
-
arrayMergeStrategy: "unique"
|
|
615
|
-
});
|
|
616
|
-
mergedSettings.env = mergedEnv;
|
|
617
|
-
if (mergedSettings.permissions && mergedSettings.permissions.allow) {
|
|
618
|
-
mergedSettings.permissions.allow = mergeAndCleanPermissions(
|
|
619
|
-
templateSettings.permissions?.allow,
|
|
620
|
-
existingSettings.permissions?.allow
|
|
621
|
-
);
|
|
622
|
-
}
|
|
623
|
-
writeJsonConfig(targetPath, mergedSettings);
|
|
624
|
-
} catch (error) {
|
|
625
|
-
console.error("Failed to merge settings", error);
|
|
626
|
-
if (exists(targetPath)) {
|
|
627
|
-
console.log("Preserving existing settings");
|
|
628
|
-
} else {
|
|
629
|
-
copyFile(templatePath, targetPath);
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
function getExistingModelConfig() {
|
|
634
|
-
const settings = readJsonConfig(SETTINGS_FILE);
|
|
635
|
-
if (!settings) {
|
|
636
|
-
return null;
|
|
637
|
-
}
|
|
638
|
-
const hasModelEnv = MODEL_ENV_KEYS.some((key) => settings.env?.[key]);
|
|
639
|
-
if (hasModelEnv) {
|
|
640
|
-
return "custom";
|
|
641
|
-
}
|
|
642
|
-
if (!settings.model) {
|
|
643
|
-
return "default";
|
|
644
|
-
}
|
|
645
|
-
const validModels = ["opus", "sonnet", "sonnet[1m]"];
|
|
646
|
-
if (validModels.includes(settings.model)) {
|
|
647
|
-
return settings.model;
|
|
648
|
-
}
|
|
649
|
-
return "default";
|
|
650
|
-
}
|
|
651
|
-
function getExistingApiConfig() {
|
|
652
|
-
const settings = readJsonConfig(SETTINGS_FILE);
|
|
653
|
-
if (!settings || !settings.env) {
|
|
654
|
-
return null;
|
|
655
|
-
}
|
|
656
|
-
const { ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL } = settings.env;
|
|
657
|
-
if (!ANTHROPIC_BASE_URL && !ANTHROPIC_API_KEY && !ANTHROPIC_AUTH_TOKEN) {
|
|
658
|
-
return null;
|
|
659
|
-
}
|
|
660
|
-
let authType;
|
|
661
|
-
let key;
|
|
662
|
-
if (ANTHROPIC_AUTH_TOKEN) {
|
|
663
|
-
authType = "auth_token";
|
|
664
|
-
key = ANTHROPIC_AUTH_TOKEN;
|
|
665
|
-
} else if (ANTHROPIC_API_KEY) {
|
|
666
|
-
authType = "api_key";
|
|
667
|
-
key = ANTHROPIC_API_KEY;
|
|
668
|
-
}
|
|
669
|
-
return {
|
|
670
|
-
url: ANTHROPIC_BASE_URL || "",
|
|
671
|
-
key: key || "",
|
|
672
|
-
authType
|
|
673
|
-
};
|
|
674
|
-
}
|
|
675
|
-
function applyAiLanguageDirective(aiOutputLang) {
|
|
676
|
-
const claudeFile = join(CLAUDE_DIR, "CLAUDE.md");
|
|
677
|
-
let directive = "";
|
|
678
|
-
if (aiOutputLang === "custom") {
|
|
679
|
-
return;
|
|
680
|
-
} else if (AI_OUTPUT_LANGUAGES[aiOutputLang]) {
|
|
681
|
-
directive = AI_OUTPUT_LANGUAGES[aiOutputLang].directive;
|
|
682
|
-
} else {
|
|
683
|
-
directive = `Always respond in ${aiOutputLang}`;
|
|
684
|
-
}
|
|
685
|
-
writeFileAtomic(claudeFile, directive);
|
|
686
|
-
}
|
|
687
|
-
function switchToOfficialLogin$1() {
|
|
688
|
-
try {
|
|
689
|
-
ensureI18nInitialized();
|
|
690
|
-
const settings = readJsonConfig(SETTINGS_FILE) || {};
|
|
691
|
-
if (settings.env) {
|
|
692
|
-
delete settings.env.ANTHROPIC_BASE_URL;
|
|
693
|
-
delete settings.env.ANTHROPIC_AUTH_TOKEN;
|
|
694
|
-
delete settings.env.ANTHROPIC_API_KEY;
|
|
695
|
-
}
|
|
696
|
-
writeJsonConfig(SETTINGS_FILE, settings);
|
|
697
|
-
const vscConfig = readJsonConfig(CLAUDE_VSC_CONFIG_FILE);
|
|
698
|
-
if (vscConfig) {
|
|
699
|
-
delete vscConfig.primaryApiKey;
|
|
700
|
-
writeJsonConfig(CLAUDE_VSC_CONFIG_FILE, vscConfig);
|
|
701
|
-
}
|
|
702
|
-
console.log(i18n.t("api:officialLoginConfigured"));
|
|
703
|
-
return true;
|
|
704
|
-
} catch (error) {
|
|
705
|
-
ensureI18nInitialized();
|
|
706
|
-
console.error(i18n.t("api:officialLoginFailed"), error);
|
|
707
|
-
return false;
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
async function promptApiConfigurationAction() {
|
|
711
|
-
ensureI18nInitialized();
|
|
712
|
-
const existingConfig = getExistingApiConfig();
|
|
713
|
-
if (!existingConfig) {
|
|
714
|
-
return null;
|
|
715
|
-
}
|
|
716
|
-
console.log(`
|
|
717
|
-
${ansis.blue(`\u2139 ${i18n.t("api:existingApiConfig")}`)}`);
|
|
718
|
-
console.log(ansis.gray(` ${i18n.t("api:apiConfigUrl")}: ${existingConfig.url || "N/A"}`));
|
|
719
|
-
console.log(ansis.gray(` ${i18n.t("api:apiConfigKey")}: ${existingConfig.key ? `***${existingConfig.key.slice(-4)}` : "N/A"}`));
|
|
720
|
-
console.log(ansis.gray(` ${i18n.t("api:apiConfigAuthType")}: ${existingConfig.authType || "N/A"}
|
|
721
|
-
`));
|
|
722
|
-
const { choice } = await inquirer.prompt({
|
|
723
|
-
type: "list",
|
|
724
|
-
name: "choice",
|
|
725
|
-
message: i18n.t("api:selectCustomConfigAction"),
|
|
726
|
-
choices: [
|
|
727
|
-
{
|
|
728
|
-
name: i18n.t("api:modifyPartialConfig"),
|
|
729
|
-
value: "modify-partial"
|
|
730
|
-
},
|
|
731
|
-
{
|
|
732
|
-
name: i18n.t("api:modifyAllConfig"),
|
|
733
|
-
value: "modify-all"
|
|
734
|
-
},
|
|
735
|
-
{
|
|
736
|
-
name: i18n.t("api:keepExistingConfig"),
|
|
737
|
-
value: "keep-existing"
|
|
738
|
-
}
|
|
739
|
-
]
|
|
740
|
-
});
|
|
741
|
-
return choice || null;
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
const config = {
|
|
745
|
-
__proto__: null,
|
|
746
|
-
applyAiLanguageDirective: applyAiLanguageDirective,
|
|
747
|
-
backupExistingConfig: backupExistingConfig,
|
|
748
|
-
configureApi: configureApi,
|
|
749
|
-
copyConfigFiles: copyConfigFiles,
|
|
750
|
-
ensureClaudeDir: ensureClaudeDir,
|
|
751
|
-
getExistingApiConfig: getExistingApiConfig,
|
|
752
|
-
getExistingModelConfig: getExistingModelConfig,
|
|
753
|
-
mergeConfigs: mergeConfigs,
|
|
754
|
-
mergeSettingsFile: mergeSettingsFile,
|
|
755
|
-
promptApiConfigurationAction: promptApiConfigurationAction,
|
|
756
|
-
switchToOfficialLogin: switchToOfficialLogin$1,
|
|
757
|
-
updateCustomModel: updateCustomModel,
|
|
758
|
-
updateDefaultModel: updateDefaultModel
|
|
759
|
-
};
|
|
760
|
-
|
|
761
202
|
function detectConfigManagementMode() {
|
|
762
203
|
try {
|
|
763
204
|
const config = readCodexConfig();
|
|
@@ -1718,7 +1159,7 @@ async function runCodexSystemPromptSelection(skipPrompt = false) {
|
|
|
1718
1159
|
ensureI18nInitialized();
|
|
1719
1160
|
const rootDir = getRootDir();
|
|
1720
1161
|
const zcfConfig = readZcfConfig();
|
|
1721
|
-
const { readDefaultTomlConfig: readDefaultTomlConfig2 } = await import('./ccjk-config.mjs')
|
|
1162
|
+
const { readDefaultTomlConfig: readDefaultTomlConfig2 } = await import('./ccjk-config.mjs');
|
|
1722
1163
|
const tomlConfig = readDefaultTomlConfig2();
|
|
1723
1164
|
const { resolveTemplateLanguage } = await import('./prompts.mjs');
|
|
1724
1165
|
const preferredLang = await resolveTemplateLanguage(
|
|
@@ -1773,7 +1214,7 @@ async function runCodexSystemPromptSelection(skipPrompt = false) {
|
|
|
1773
1214
|
}
|
|
1774
1215
|
writeFileAtomic(CODEX_AGENTS_FILE, content);
|
|
1775
1216
|
try {
|
|
1776
|
-
const { updateTomlConfig: updateTomlConfig2 } = await import('./ccjk-config.mjs')
|
|
1217
|
+
const { updateTomlConfig: updateTomlConfig2 } = await import('./ccjk-config.mjs');
|
|
1777
1218
|
const { ZCF_CONFIG_FILE: ZCF_CONFIG_FILE2 } = await import('./constants.mjs');
|
|
1778
1219
|
updateTomlConfig2(ZCF_CONFIG_FILE2, {
|
|
1779
1220
|
codex: {
|
|
@@ -2037,7 +1478,7 @@ async function configureCodexApi(options) {
|
|
|
2037
1478
|
}
|
|
2038
1479
|
const managementMode = detectConfigManagementMode();
|
|
2039
1480
|
if (managementMode.mode === "management" && managementMode.hasProviders) {
|
|
2040
|
-
const { default: { configureIncrementalManagement } } = await import('./index.mjs').then(function (n) { return n.
|
|
1481
|
+
const { default: { configureIncrementalManagement } } = await import('./index.mjs').then(function (n) { return n.aq; });
|
|
2041
1482
|
await configureIncrementalManagement();
|
|
2042
1483
|
return;
|
|
2043
1484
|
}
|
|
@@ -2301,7 +1742,7 @@ async function runCodexUpdate(force = false, skipPrompt = false) {
|
|
|
2301
1742
|
}
|
|
2302
1743
|
async function runCodexUninstall() {
|
|
2303
1744
|
ensureI18nInitialized();
|
|
2304
|
-
const { CodexUninstaller } = await import('./index.mjs').then(function (n) { return n.
|
|
1745
|
+
const { CodexUninstaller } = await import('./index.mjs').then(function (n) { return n.ar; });
|
|
2305
1746
|
const zcfConfig = readZcfConfig();
|
|
2306
1747
|
const preferredLang = zcfConfig?.preferredLang;
|
|
2307
1748
|
const uninstallLang = preferredLang && SUPPORTED_LANGS.includes(preferredLang) ? preferredLang : "en";
|
|
@@ -2530,4 +1971,4 @@ const codex = {
|
|
|
2530
1971
|
writeCodexConfig: writeCodexConfig
|
|
2531
1972
|
};
|
|
2532
1973
|
|
|
2533
|
-
export {
|
|
1974
|
+
export { runCodexSystemPromptSelection as A, runCodexUninstall as B, runCodexUpdate as C, runCodexWorkflowImport as D, runCodexWorkflowImportWithLanguageSelection as E, runCodexWorkflowSelection as F, switchCodexProvider as G, switchToProvider as H, shouldShowManagementMode as I, getAvailableManagementActions as J, configureCodexMcp as K, applyCodexPlatformCommand as L, MCP_SERVICE_CONFIGS as M, selectMcpServices as N, getMcpServices as O, getMcpService as P, codex as Q, writeAuthFile as a, backupCodexComplete as b, backupCodexAgents as c, detectConfigManagementMode as d, backupCodexConfig as e, backupCodexFiles as f, backupCodexPrompts as g, checkCodexUpdate as h, configureCodexApi as i, createBackupDirectory as j, ensureEnvKeyMigration as k, getBackupMessage as l, getCodexVersion as m, getCurrentCodexProvider as n, installCodexCli as o, isCodexInstalled as p, listCodexProviders as q, readCodexConfig as r, switchToOfficialLogin as s, migrateEnvKeyInContent as t, migrateEnvKeyToTempEnvKey as u, needsEnvKeyMigration as v, writeCodexConfig as w, parseCodexConfig as x, renderCodexConfig as y, runCodexFullInit as z };
|
|
@@ -3,9 +3,9 @@ import ansis from 'ansis';
|
|
|
3
3
|
import inquirer from 'inquirer';
|
|
4
4
|
import { resolveCodeToolType, isCodeToolType, DEFAULT_CODE_TOOL_TYPE } from './constants.mjs';
|
|
5
5
|
import { ensureI18nInitialized, i18n } from './index2.mjs';
|
|
6
|
-
import {
|
|
6
|
+
import { readZcfConfig } from './ccjk-config.mjs';
|
|
7
7
|
import { ClaudeCodeConfigManager } from './claude-code-config-manager.mjs';
|
|
8
|
-
import {
|
|
8
|
+
import { G as switchCodexProvider, q as listCodexProviders, r as readCodexConfig, s as switchToOfficialLogin, H as switchToProvider } from './codex.mjs';
|
|
9
9
|
import { a as handleGeneralError } from '../shared/ccjk.tB4-Y4Qb.mjs';
|
|
10
10
|
import { a as addNumbersToChoices } from '../shared/ccjk.DhBeLRzf.mjs';
|
|
11
11
|
import 'node:os';
|
|
@@ -18,14 +18,16 @@ import 'smol-toml';
|
|
|
18
18
|
import './fs-operations.mjs';
|
|
19
19
|
import 'node:crypto';
|
|
20
20
|
import 'node:fs/promises';
|
|
21
|
+
import './json-config.mjs';
|
|
21
22
|
import 'dayjs';
|
|
23
|
+
import './config.mjs';
|
|
24
|
+
import './platform.mjs';
|
|
25
|
+
import 'tinyexec';
|
|
22
26
|
import 'ora';
|
|
23
27
|
import 'semver';
|
|
24
|
-
import 'tinyexec';
|
|
25
|
-
import './platform.mjs';
|
|
26
|
-
import 'inquirer-toggle';
|
|
27
28
|
import './prompts.mjs';
|
|
28
29
|
import './package.mjs';
|
|
30
|
+
import 'inquirer-toggle';
|
|
29
31
|
import 'node:child_process';
|
|
30
32
|
|
|
31
33
|
async function configSwitchCommand(options) {
|