ccjk 16.0.1 → 16.0.2

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.
@@ -9,7 +9,6 @@ import { promisify } from 'node:util';
9
9
  import dayjs from 'dayjs';
10
10
  import { dirname, join } from 'pathe';
11
11
  import { fileURLToPath } from 'node:url';
12
- import { edit, stringify, parse, initSync } from '@rainbowatcher/toml-edit-js';
13
12
  import toggleModule from 'inquirer-toggle';
14
13
  import ora from 'ora';
15
14
  import { exec, x } from 'tinyexec';
@@ -17,8 +16,9 @@ import semver from 'semver';
17
16
  import { rm, mkdir, copyFile as copyFile$1 } from 'node:fs/promises';
18
17
  import i18next from 'i18next';
19
18
  import Backend from 'i18next-fs-backend';
19
+ import { edit, stringify, parse, initSync } from '@rainbowatcher/toml-edit-js';
20
20
 
21
- const version = "16.0.1";
21
+ const version = "16.0.2";
22
22
  const homepage = "https://github.com/miounet11/ccjk#readme";
23
23
 
24
24
  const i18n = i18next.createInstance();
@@ -384,6 +384,8 @@ const CLAUDE_DIR = join(homedir(), ".claude");
384
384
  const SETTINGS_FILE = join(CLAUDE_DIR, "settings.json");
385
385
  const CLAVUE_DIR = join(homedir(), ".clavue");
386
386
  const CLAVUE_SETTINGS_FILE = join(CLAVUE_DIR, "settings.json");
387
+ const CLAVUE_CONFIG_FILE = join(CLAVUE_DIR, ".clavue.json");
388
+ const CLAVUE_MD_FILE = join(CLAVUE_DIR, "clavue.md");
387
389
  const CLAUDE_MD_FILE = join(CLAUDE_DIR, "CLAUDE.md");
388
390
  const ClAUDE_CONFIG_FILE = join(homedir(), ".claude.json");
389
391
  const CLAUDE_VSC_CONFIG_FILE = join(CLAUDE_DIR, "config.json");
@@ -399,12 +401,13 @@ const LEGACY_CCJK_CONFIG_FILES = [
399
401
  join(homedir(), ".ccjk.json"),
400
402
  join(homedir(), ".ufomiao", "ccjk", "config.toml")
401
403
  ];
402
- const CODE_TOOL_TYPES = ["clavue", "claude-code", "codex"];
404
+ const CODE_TOOL_TYPES = ["clavue", "claude-code", "codex", "grok"];
403
405
  const DEFAULT_CODE_TOOL_TYPE = "clavue";
404
406
  const CODE_TOOL_BANNERS = {
405
407
  "clavue": "for Clavue",
406
408
  "claude-code": "for Claude Code",
407
- "codex": "for Codex"
409
+ "codex": "for Codex",
410
+ "grok": "for Grok CLI"
408
411
  };
409
412
  function settingsFileForTool(tool) {
410
413
  if (tool === "clavue") return CLAVUE_SETTINGS_FILE;
@@ -414,7 +417,8 @@ function settingsFileForTool(tool) {
414
417
  const CODE_TOOL_ALIASES = {
415
418
  cv: "clavue",
416
419
  cc: "claude-code",
417
- cx: "codex"
420
+ cx: "codex",
421
+ gk: "grok"
418
422
  };
419
423
  function isCodeToolType(value) {
420
424
  return CODE_TOOL_TYPES.includes(value);
@@ -463,7 +467,9 @@ const constants = {
463
467
  CLAUDE_DIR: CLAUDE_DIR,
464
468
  CLAUDE_MD_FILE: CLAUDE_MD_FILE,
465
469
  CLAUDE_VSC_CONFIG_FILE: CLAUDE_VSC_CONFIG_FILE,
470
+ CLAVUE_CONFIG_FILE: CLAVUE_CONFIG_FILE,
466
471
  CLAVUE_DIR: CLAVUE_DIR,
472
+ CLAVUE_MD_FILE: CLAVUE_MD_FILE,
467
473
  CLAVUE_SETTINGS_FILE: CLAVUE_SETTINGS_FILE,
468
474
  CODEX_AGENTS_FILE: CODEX_AGENTS_FILE,
469
475
  CODEX_AUTH_FILE: CODEX_AUTH_FILE,
@@ -506,19 +512,19 @@ function displayBanner(subtitle) {
506
512
  const defaultSubtitle = i18n.t("cli:banner.subtitle");
507
513
  const subtitleText = subtitle || defaultSubtitle;
508
514
  const paddedSubtitle = padToDisplayWidth(subtitleText, 30);
509
- const paddedTitle = padToDisplayWidth("Zero-Config Code Flow", 60);
515
+ const paddedTitle = padToDisplayWidth("CCJK", 60);
510
516
  console.log(
511
517
  ansis.cyan.bold(`
512
518
  \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
513
519
  \u2551 \u2551
514
- \u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2551
515
- \u2551 \u2588\u2588\u2554\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2551
516
- \u2551 \u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2551
517
- \u2551 \u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D \u2551
518
- \u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2551
519
- \u2551 \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D ${ansis.gray(paddedSubtitle)} \u2551
520
+ \u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2551
521
+ \u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2554\u255D \u2551
522
+ \u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2551
523
+ \u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2588\u2588\u2557 \u2551
524
+ \u2551 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2557 \u2551
525
+ \u2551 \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D ${ansis.gray(paddedSubtitle)} \u2551
520
526
  \u2551 \u2551
521
- \u2551 ${ansis.white.bold(paddedTitle)} \u2551
527
+ \u2551 ${ansis.white.bold(paddedTitle)} \u2014 Clavue / Claude / Codex / Grok \u7EDF\u4E00\u914D\u7F6E \u2551
522
528
  \u2551 \u2551
523
529
  \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
524
530
  `)
@@ -1172,241 +1178,6 @@ const jsonConfig = {
1172
1178
  writeJsonConfig: writeJsonConfig
1173
1179
  };
1174
1180
 
1175
- function mergeArraysUnique(arr1, arr2) {
1176
- const combined = [...arr1 || [], ...arr2 || []];
1177
- return [...new Set(combined)];
1178
- }
1179
- function isPlainObject(value) {
1180
- return value !== null && typeof value === "object" && value.constructor === Object && Object.prototype.toString.call(value) === "[object Object]";
1181
- }
1182
- function deepMerge(target, source, options = {}) {
1183
- const { mergeArrays = false, arrayMergeStrategy = "replace" } = options;
1184
- const result = { ...target };
1185
- for (const key in source) {
1186
- const sourceValue = source[key];
1187
- const targetValue = result[key];
1188
- if (sourceValue === void 0) {
1189
- continue;
1190
- }
1191
- if (isPlainObject(sourceValue) && isPlainObject(targetValue)) {
1192
- result[key] = deepMerge(targetValue, sourceValue, options);
1193
- } else if (Array.isArray(sourceValue)) {
1194
- if (!mergeArrays || !Array.isArray(targetValue)) {
1195
- result[key] = sourceValue;
1196
- } else {
1197
- switch (arrayMergeStrategy) {
1198
- case "concat":
1199
- result[key] = [...targetValue, ...sourceValue];
1200
- break;
1201
- case "unique":
1202
- result[key] = mergeArraysUnique(targetValue, sourceValue);
1203
- break;
1204
- case "replace":
1205
- default:
1206
- result[key] = sourceValue;
1207
- break;
1208
- }
1209
- }
1210
- } else {
1211
- result[key] = sourceValue;
1212
- }
1213
- }
1214
- return result;
1215
- }
1216
- function deepClone(obj) {
1217
- if (obj === null || typeof obj !== "object") {
1218
- return obj;
1219
- }
1220
- if (obj instanceof Date) {
1221
- return new Date(obj.getTime());
1222
- }
1223
- if (Array.isArray(obj)) {
1224
- return obj.map((item) => deepClone(item));
1225
- }
1226
- if (isPlainObject(obj)) {
1227
- const cloned = {};
1228
- for (const key in obj) {
1229
- cloned[key] = deepClone(obj[key]);
1230
- }
1231
- return cloned;
1232
- }
1233
- return obj;
1234
- }
1235
-
1236
- function getMcpConfigPath() {
1237
- return ClAUDE_CONFIG_FILE;
1238
- }
1239
- function readMcpConfig() {
1240
- return readJsonConfig(ClAUDE_CONFIG_FILE);
1241
- }
1242
- function writeMcpConfig(config) {
1243
- writeJsonConfig(ClAUDE_CONFIG_FILE, config);
1244
- }
1245
- function backupMcpConfig() {
1246
- const backupBaseDir = join(CLAUDE_DIR, "backup");
1247
- return backupJsonConfig(ClAUDE_CONFIG_FILE, backupBaseDir);
1248
- }
1249
- function mergeMcpServers(existing, newServers) {
1250
- const config = existing || { mcpServers: {} };
1251
- if (!config.mcpServers) {
1252
- config.mcpServers = {};
1253
- }
1254
- Object.assign(config.mcpServers, newServers);
1255
- return config;
1256
- }
1257
- function applyPlatformCommand(config) {
1258
- if (isWindows() && config.command) {
1259
- const mcpCmd = getMcpCommand(config.command);
1260
- if (mcpCmd[0] === "cmd") {
1261
- config.command = mcpCmd[0];
1262
- config.args = [...mcpCmd.slice(1), ...config.args || []];
1263
- }
1264
- }
1265
- }
1266
- function buildMcpServerConfig(baseConfig, apiKey, placeholder = "YOUR_EXA_API_KEY", envVarName) {
1267
- const config = deepClone(baseConfig);
1268
- applyPlatformCommand(config);
1269
- if (!apiKey) {
1270
- return config;
1271
- }
1272
- if (envVarName && config.env) {
1273
- config.env[envVarName] = apiKey;
1274
- return config;
1275
- }
1276
- if (config.args) {
1277
- config.args = config.args.map((arg) => arg.replace(placeholder, apiKey));
1278
- }
1279
- if (config.url) {
1280
- config.url = config.url.replace(placeholder, apiKey);
1281
- }
1282
- return config;
1283
- }
1284
- function fixWindowsMcpConfig(config) {
1285
- if (!isWindows() || !config.mcpServers) {
1286
- return config;
1287
- }
1288
- const fixed = { ...config };
1289
- for (const [, serverConfig] of Object.entries(fixed.mcpServers)) {
1290
- if (serverConfig && typeof serverConfig === "object" && "command" in serverConfig) {
1291
- applyPlatformCommand(serverConfig);
1292
- }
1293
- }
1294
- return fixed;
1295
- }
1296
- function addCompletedOnboarding() {
1297
- try {
1298
- let config = readMcpConfig();
1299
- if (!config) {
1300
- config = { mcpServers: {} };
1301
- }
1302
- if (config.hasCompletedOnboarding === true) {
1303
- return;
1304
- }
1305
- config.hasCompletedOnboarding = true;
1306
- writeMcpConfig(config);
1307
- } catch (error) {
1308
- console.error("Failed to add onboarding flag", error);
1309
- throw error;
1310
- }
1311
- }
1312
- function ensureApiKeyApproved(config, apiKey) {
1313
- if (!apiKey || typeof apiKey !== "string" || apiKey.trim() === "") {
1314
- return config;
1315
- }
1316
- const truncatedApiKey = apiKey.substring(0, 20);
1317
- const updatedConfig = { ...config };
1318
- if (!updatedConfig.customApiKeyResponses) {
1319
- updatedConfig.customApiKeyResponses = {
1320
- approved: [],
1321
- rejected: []
1322
- };
1323
- }
1324
- if (!Array.isArray(updatedConfig.customApiKeyResponses.approved)) {
1325
- updatedConfig.customApiKeyResponses.approved = [];
1326
- }
1327
- if (!Array.isArray(updatedConfig.customApiKeyResponses.rejected)) {
1328
- updatedConfig.customApiKeyResponses.rejected = [];
1329
- }
1330
- const rejectedIndex = updatedConfig.customApiKeyResponses.rejected.indexOf(truncatedApiKey);
1331
- if (rejectedIndex > -1) {
1332
- updatedConfig.customApiKeyResponses.rejected.splice(rejectedIndex, 1);
1333
- }
1334
- if (!updatedConfig.customApiKeyResponses.approved.includes(truncatedApiKey)) {
1335
- updatedConfig.customApiKeyResponses.approved.push(truncatedApiKey);
1336
- }
1337
- return updatedConfig;
1338
- }
1339
- function removeApiKeyFromRejected(config, apiKey) {
1340
- if (!config.customApiKeyResponses || !Array.isArray(config.customApiKeyResponses.rejected)) {
1341
- return config;
1342
- }
1343
- const truncatedApiKey = apiKey.substring(0, 20);
1344
- const updatedConfig = { ...config };
1345
- if (updatedConfig.customApiKeyResponses) {
1346
- const rejectedIndex = updatedConfig.customApiKeyResponses.rejected.indexOf(truncatedApiKey);
1347
- if (rejectedIndex > -1) {
1348
- updatedConfig.customApiKeyResponses.rejected.splice(rejectedIndex, 1);
1349
- }
1350
- }
1351
- return updatedConfig;
1352
- }
1353
- function manageApiKeyApproval(apiKey) {
1354
- try {
1355
- let config = readMcpConfig();
1356
- if (!config) {
1357
- config = { mcpServers: {} };
1358
- }
1359
- const updatedConfig = ensureApiKeyApproved(config, apiKey);
1360
- writeMcpConfig(updatedConfig);
1361
- } catch (error) {
1362
- ensureI18nInitialized();
1363
- console.error(i18n.t("mcp:apiKeyApprovalFailed"), error);
1364
- }
1365
- }
1366
- function setPrimaryApiKey() {
1367
- try {
1368
- let config = readJsonConfig(CLAUDE_VSC_CONFIG_FILE);
1369
- if (!config) {
1370
- config = {};
1371
- }
1372
- config.primaryApiKey = "ccjk";
1373
- writeJsonConfig(CLAUDE_VSC_CONFIG_FILE, config);
1374
- } catch (error) {
1375
- ensureI18nInitialized();
1376
- console.error(i18n.t("mcp:primaryApiKeySetFailed"), error);
1377
- }
1378
- }
1379
-
1380
- const claudeConfig = {
1381
- __proto__: null,
1382
- addCompletedOnboarding: addCompletedOnboarding,
1383
- backupMcpConfig: backupMcpConfig,
1384
- buildMcpServerConfig: buildMcpServerConfig,
1385
- ensureApiKeyApproved: ensureApiKeyApproved,
1386
- fixWindowsMcpConfig: fixWindowsMcpConfig,
1387
- getMcpConfigPath: getMcpConfigPath,
1388
- manageApiKeyApproval: manageApiKeyApproval,
1389
- mergeMcpServers: mergeMcpServers,
1390
- readMcpConfig: readMcpConfig,
1391
- removeApiKeyFromRejected: removeApiKeyFromRejected,
1392
- setPrimaryApiKey: setPrimaryApiKey,
1393
- writeMcpConfig: writeMcpConfig
1394
- };
1395
-
1396
- const MODEL_ENV_KEYS = [
1397
- "ANTHROPIC_MODEL",
1398
- "ANTHROPIC_DEFAULT_HAIKU_MODEL",
1399
- "ANTHROPIC_DEFAULT_SONNET_MODEL",
1400
- "ANTHROPIC_DEFAULT_OPUS_MODEL",
1401
- // Deprecated but still cleaned to avoid stale values
1402
- "ANTHROPIC_SMALL_FAST_MODEL"
1403
- ];
1404
- function clearModelEnv(env) {
1405
- for (const key of MODEL_ENV_KEYS) {
1406
- delete env[key];
1407
- }
1408
- }
1409
-
1410
1181
  let initialized = false;
1411
1182
  function ensureTomlInitSync() {
1412
1183
  if (!initialized) {
@@ -1819,6 +1590,347 @@ const ccjkConfig = {
1819
1590
  writeTomlConfig: writeTomlConfig
1820
1591
  };
1821
1592
 
1593
+ function getActiveCodeTool() {
1594
+ const configured = readCcjkConfig()?.codeToolType;
1595
+ return isCodeToolType(configured) ? configured : DEFAULT_CODE_TOOL_TYPE;
1596
+ }
1597
+ function resolveClaudeFamilySettingsTarget(codeTool) {
1598
+ const configuredTool = readCcjkConfig()?.codeToolType;
1599
+ const resolvedTool = codeTool || (isCodeToolType(configuredTool) && (configuredTool === "clavue" || configuredTool === "claude-code") ? configuredTool : "clavue" );
1600
+ if (resolvedTool === "clavue") {
1601
+ return {
1602
+ codeTool: "clavue",
1603
+ configDir: CLAVUE_DIR,
1604
+ settingsFile: CLAVUE_SETTINGS_FILE,
1605
+ instructionsFile: join(CLAVUE_DIR, "clavue.md"),
1606
+ runtimeConfigFile: CLAVUE_CONFIG_FILE,
1607
+ runtimeBackupDirName: "backups",
1608
+ displayName: "Clavue",
1609
+ runtimeCommand: "clavue",
1610
+ configDirDisplay: "~/.clavue"
1611
+ };
1612
+ }
1613
+ return {
1614
+ codeTool: "claude-code",
1615
+ configDir: CLAUDE_DIR,
1616
+ settingsFile: SETTINGS_FILE,
1617
+ instructionsFile: join(CLAUDE_DIR, "CLAUDE.md"),
1618
+ runtimeConfigFile: ClAUDE_CONFIG_FILE,
1619
+ runtimeBackupDirName: "backup",
1620
+ displayName: "Claude Code",
1621
+ runtimeCommand: "claude",
1622
+ configDirDisplay: "~/.claude"
1623
+ };
1624
+ }
1625
+ function activeSettingsFile(codeTool) {
1626
+ return resolveClaudeFamilySettingsTarget(codeTool).settingsFile;
1627
+ }
1628
+ function isClaudeFamilyCodeTool(tool) {
1629
+ return tool === "clavue" || tool === "claude-code";
1630
+ }
1631
+
1632
+ function mergeArraysUnique(arr1, arr2) {
1633
+ const combined = [...arr1 || [], ...arr2 || []];
1634
+ return [...new Set(combined)];
1635
+ }
1636
+ function isPlainObject(value) {
1637
+ return value !== null && typeof value === "object" && value.constructor === Object && Object.prototype.toString.call(value) === "[object Object]";
1638
+ }
1639
+ function deepMerge(target, source, options = {}) {
1640
+ const { mergeArrays = false, arrayMergeStrategy = "replace" } = options;
1641
+ const result = { ...target };
1642
+ for (const key in source) {
1643
+ const sourceValue = source[key];
1644
+ const targetValue = result[key];
1645
+ if (sourceValue === void 0) {
1646
+ continue;
1647
+ }
1648
+ if (isPlainObject(sourceValue) && isPlainObject(targetValue)) {
1649
+ result[key] = deepMerge(targetValue, sourceValue, options);
1650
+ } else if (Array.isArray(sourceValue)) {
1651
+ if (!mergeArrays || !Array.isArray(targetValue)) {
1652
+ result[key] = sourceValue;
1653
+ } else {
1654
+ switch (arrayMergeStrategy) {
1655
+ case "concat":
1656
+ result[key] = [...targetValue, ...sourceValue];
1657
+ break;
1658
+ case "unique":
1659
+ result[key] = mergeArraysUnique(targetValue, sourceValue);
1660
+ break;
1661
+ case "replace":
1662
+ default:
1663
+ result[key] = sourceValue;
1664
+ break;
1665
+ }
1666
+ }
1667
+ } else {
1668
+ result[key] = sourceValue;
1669
+ }
1670
+ }
1671
+ return result;
1672
+ }
1673
+ function deepClone(obj) {
1674
+ if (obj === null || typeof obj !== "object") {
1675
+ return obj;
1676
+ }
1677
+ if (obj instanceof Date) {
1678
+ return new Date(obj.getTime());
1679
+ }
1680
+ if (Array.isArray(obj)) {
1681
+ return obj.map((item) => deepClone(item));
1682
+ }
1683
+ if (isPlainObject(obj)) {
1684
+ const cloned = {};
1685
+ for (const key in obj) {
1686
+ cloned[key] = deepClone(obj[key]);
1687
+ }
1688
+ return cloned;
1689
+ }
1690
+ return obj;
1691
+ }
1692
+
1693
+ function getMcpConfigPath(codeTool) {
1694
+ return resolveClaudeFamilySettingsTarget(codeTool).runtimeConfigFile;
1695
+ }
1696
+ function readMcpConfig(codeTool) {
1697
+ return readJsonConfig(resolveClaudeFamilySettingsTarget(codeTool).runtimeConfigFile);
1698
+ }
1699
+ function writeMcpConfig(config, codeTool) {
1700
+ writeJsonConfig(resolveClaudeFamilySettingsTarget(codeTool).runtimeConfigFile, config);
1701
+ }
1702
+ function backupMcpConfig(codeTool) {
1703
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
1704
+ const backupBaseDir = join(target.configDir, target.runtimeBackupDirName);
1705
+ return backupJsonConfig(target.runtimeConfigFile, backupBaseDir);
1706
+ }
1707
+ function mergeMcpServers(existing, newServers) {
1708
+ const config = existing || { mcpServers: {} };
1709
+ if (!config.mcpServers) {
1710
+ config.mcpServers = {};
1711
+ }
1712
+ Object.assign(config.mcpServers, newServers);
1713
+ return config;
1714
+ }
1715
+ function applyPlatformCommand(config) {
1716
+ if (isWindows() && config.command) {
1717
+ const mcpCmd = getMcpCommand(config.command);
1718
+ if (mcpCmd[0] === "cmd") {
1719
+ config.command = mcpCmd[0];
1720
+ config.args = [...mcpCmd.slice(1), ...config.args || []];
1721
+ }
1722
+ }
1723
+ }
1724
+ function buildMcpServerConfig(baseConfig, apiKey, placeholder = "YOUR_EXA_API_KEY", envVarName) {
1725
+ const config = deepClone(baseConfig);
1726
+ applyPlatformCommand(config);
1727
+ if (!apiKey) {
1728
+ return config;
1729
+ }
1730
+ if (envVarName && config.env) {
1731
+ config.env[envVarName] = apiKey;
1732
+ return config;
1733
+ }
1734
+ if (config.args) {
1735
+ config.args = config.args.map((arg) => arg.replace(placeholder, apiKey));
1736
+ }
1737
+ if (config.url) {
1738
+ config.url = config.url.replace(placeholder, apiKey);
1739
+ }
1740
+ return config;
1741
+ }
1742
+ function fixWindowsMcpConfig(config) {
1743
+ if (!isWindows() || !config.mcpServers) {
1744
+ return config;
1745
+ }
1746
+ const fixed = { ...config };
1747
+ for (const [, serverConfig] of Object.entries(fixed.mcpServers)) {
1748
+ if (serverConfig && typeof serverConfig === "object" && "command" in serverConfig) {
1749
+ applyPlatformCommand(serverConfig);
1750
+ }
1751
+ }
1752
+ return fixed;
1753
+ }
1754
+ function addCompletedOnboarding(codeTool) {
1755
+ try {
1756
+ let config = readMcpConfig(codeTool);
1757
+ if (!config) {
1758
+ config = { mcpServers: {} };
1759
+ }
1760
+ if (config.hasCompletedOnboarding === true) {
1761
+ return;
1762
+ }
1763
+ config.hasCompletedOnboarding = true;
1764
+ writeMcpConfig(config, codeTool);
1765
+ } catch (error) {
1766
+ console.error("Failed to add onboarding flag", error);
1767
+ throw error;
1768
+ }
1769
+ }
1770
+ function ensureApiKeyApproved(config, apiKey) {
1771
+ if (!apiKey || typeof apiKey !== "string" || apiKey.trim() === "") {
1772
+ return config;
1773
+ }
1774
+ const truncatedApiKey = apiKey.substring(0, 20);
1775
+ const updatedConfig = { ...config };
1776
+ if (!updatedConfig.customApiKeyResponses) {
1777
+ updatedConfig.customApiKeyResponses = {
1778
+ approved: [],
1779
+ rejected: []
1780
+ };
1781
+ }
1782
+ if (!Array.isArray(updatedConfig.customApiKeyResponses.approved)) {
1783
+ updatedConfig.customApiKeyResponses.approved = [];
1784
+ }
1785
+ if (!Array.isArray(updatedConfig.customApiKeyResponses.rejected)) {
1786
+ updatedConfig.customApiKeyResponses.rejected = [];
1787
+ }
1788
+ const rejectedIndex = updatedConfig.customApiKeyResponses.rejected.indexOf(truncatedApiKey);
1789
+ if (rejectedIndex > -1) {
1790
+ updatedConfig.customApiKeyResponses.rejected.splice(rejectedIndex, 1);
1791
+ }
1792
+ if (!updatedConfig.customApiKeyResponses.approved.includes(truncatedApiKey)) {
1793
+ updatedConfig.customApiKeyResponses.approved.push(truncatedApiKey);
1794
+ }
1795
+ return updatedConfig;
1796
+ }
1797
+ function removeApiKeyFromRejected(config, apiKey) {
1798
+ if (!config.customApiKeyResponses || !Array.isArray(config.customApiKeyResponses.rejected)) {
1799
+ return config;
1800
+ }
1801
+ const truncatedApiKey = apiKey.substring(0, 20);
1802
+ const updatedConfig = { ...config };
1803
+ if (updatedConfig.customApiKeyResponses) {
1804
+ const rejectedIndex = updatedConfig.customApiKeyResponses.rejected.indexOf(truncatedApiKey);
1805
+ if (rejectedIndex > -1) {
1806
+ updatedConfig.customApiKeyResponses.rejected.splice(rejectedIndex, 1);
1807
+ }
1808
+ }
1809
+ return updatedConfig;
1810
+ }
1811
+ function manageApiKeyApproval(apiKey, codeTool) {
1812
+ try {
1813
+ let config = readMcpConfig(codeTool);
1814
+ if (!config) {
1815
+ config = { mcpServers: {} };
1816
+ }
1817
+ const updatedConfig = ensureApiKeyApproved(config, apiKey);
1818
+ writeMcpConfig(updatedConfig, codeTool);
1819
+ } catch (error) {
1820
+ ensureI18nInitialized();
1821
+ console.error(i18n.t("mcp:apiKeyApprovalFailed"), error);
1822
+ }
1823
+ }
1824
+ function setPrimaryApiKey(codeTool) {
1825
+ try {
1826
+ if (resolveClaudeFamilySettingsTarget(codeTool).codeTool !== "claude-code") {
1827
+ return;
1828
+ }
1829
+ let config = readJsonConfig(CLAUDE_VSC_CONFIG_FILE);
1830
+ if (!config) {
1831
+ config = {};
1832
+ }
1833
+ config.primaryApiKey = "ccjk";
1834
+ writeJsonConfig(CLAUDE_VSC_CONFIG_FILE, config);
1835
+ } catch (error) {
1836
+ ensureI18nInitialized();
1837
+ console.error(i18n.t("mcp:primaryApiKeySetFailed"), error);
1838
+ }
1839
+ }
1840
+
1841
+ const claudeConfig = {
1842
+ __proto__: null,
1843
+ addCompletedOnboarding: addCompletedOnboarding,
1844
+ backupMcpConfig: backupMcpConfig,
1845
+ buildMcpServerConfig: buildMcpServerConfig,
1846
+ ensureApiKeyApproved: ensureApiKeyApproved,
1847
+ fixWindowsMcpConfig: fixWindowsMcpConfig,
1848
+ getMcpConfigPath: getMcpConfigPath,
1849
+ manageApiKeyApproval: manageApiKeyApproval,
1850
+ mergeMcpServers: mergeMcpServers,
1851
+ readMcpConfig: readMcpConfig,
1852
+ removeApiKeyFromRejected: removeApiKeyFromRejected,
1853
+ setPrimaryApiKey: setPrimaryApiKey,
1854
+ writeMcpConfig: writeMcpConfig
1855
+ };
1856
+
1857
+ const TRUSTED_OPERATOR_ASK_RULES = [
1858
+ "Bash(git push:*)",
1859
+ "Bash(rm:*)",
1860
+ "Bash(rm -rf:*)",
1861
+ "Bash(git push --force:*)",
1862
+ "Bash(git reset --hard:*)",
1863
+ "Bash(npm publish:*)",
1864
+ "Bash(npm login:*)",
1865
+ "Bash(docker:*)",
1866
+ "Bash(kubectl:*)",
1867
+ "Bash(terraform apply:*)",
1868
+ "Bash(gh release:*)",
1869
+ "Bash(git tag:*)",
1870
+ "Bash(gh pr merge:*)"
1871
+ ];
1872
+ function hasOwn(object, key) {
1873
+ return Object.prototype.hasOwnProperty.call(object, key);
1874
+ }
1875
+ function stringArray(value) {
1876
+ return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
1877
+ }
1878
+ function mergeStringArray(existing, additions) {
1879
+ const merged = stringArray(existing);
1880
+ for (const item of additions) {
1881
+ if (!merged.includes(item)) {
1882
+ merged.push(item);
1883
+ }
1884
+ }
1885
+ return merged;
1886
+ }
1887
+ function normalizeClaudeFamilySettings(settings, options = {}) {
1888
+ if (!settings || typeof settings !== "object" || Array.isArray(settings)) {
1889
+ return settings;
1890
+ }
1891
+ const mutableSettings = settings;
1892
+ if (options.codeTool === "clavue" && mutableSettings.plansDirectory === ".claude/plans") {
1893
+ mutableSettings.plansDirectory = ".clavue/plans";
1894
+ }
1895
+ if (hasOwn(mutableSettings, "statusLine")) {
1896
+ const statusLine = mutableSettings.statusLine;
1897
+ if (statusLine && typeof statusLine === "object" && !Array.isArray(statusLine) && typeof statusLine.command === "string") {
1898
+ mutableSettings.statusLine = {
1899
+ ...statusLine,
1900
+ type: "command"
1901
+ };
1902
+ } else {
1903
+ delete mutableSettings.statusLine;
1904
+ }
1905
+ }
1906
+ return settings;
1907
+ }
1908
+ function applyTrustedOperatorPermissions(settings) {
1909
+ if (!settings || typeof settings !== "object" || Array.isArray(settings)) {
1910
+ return settings;
1911
+ }
1912
+ const mutableSettings = settings;
1913
+ mutableSettings.permissions = mutableSettings.permissions && typeof mutableSettings.permissions === "object" && !Array.isArray(mutableSettings.permissions) ? mutableSettings.permissions : {};
1914
+ mutableSettings.permissions.defaultMode = "bypassPermissions";
1915
+ mutableSettings.permissions.trustedOperatorMode = true;
1916
+ mutableSettings.permissions.ask = mergeStringArray(mutableSettings.permissions.ask, TRUSTED_OPERATOR_ASK_RULES);
1917
+ return settings;
1918
+ }
1919
+
1920
+ const MODEL_ENV_KEYS = [
1921
+ "ANTHROPIC_MODEL",
1922
+ "ANTHROPIC_DEFAULT_HAIKU_MODEL",
1923
+ "ANTHROPIC_DEFAULT_SONNET_MODEL",
1924
+ "ANTHROPIC_DEFAULT_OPUS_MODEL",
1925
+ // Deprecated but still cleaned to avoid stale values
1926
+ "ANTHROPIC_SMALL_FAST_MODEL"
1927
+ ];
1928
+ function clearModelEnv(env) {
1929
+ for (const key of MODEL_ENV_KEYS) {
1930
+ delete env[key];
1931
+ }
1932
+ }
1933
+
1822
1934
  function cleanupPermissions(templatePermissions, userPermissions) {
1823
1935
  const templateSet = new Set(templatePermissions);
1824
1936
  const cleanedPermissions = userPermissions.filter((permission) => {
@@ -1849,37 +1961,34 @@ function mergeAndCleanPermissions(templatePermissions, userPermissions) {
1849
1961
  return cleanupPermissions(template, user);
1850
1962
  }
1851
1963
 
1852
- function activeSettingsFile() {
1853
- const tool = readCcjkConfig()?.codeToolType ?? "clavue";
1854
- return settingsFileForTool(tool === "codex" ? "claude-code" : tool);
1855
- }
1856
- function ensureClaudeDir() {
1857
- ensureDir(CLAUDE_DIR);
1964
+ function ensureClaudeDir(codeTool) {
1965
+ ensureDir(resolveClaudeFamilySettingsTarget(codeTool).configDir);
1858
1966
  }
1859
- function backupExistingConfig() {
1860
- if (!exists(CLAUDE_DIR)) {
1967
+ function backupExistingConfig(codeTool) {
1968
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
1969
+ if (!exists(target.configDir)) {
1861
1970
  return null;
1862
1971
  }
1863
1972
  const timestamp = dayjs().format("YYYY-MM-DD_HH-mm-ss");
1864
- const backupBaseDir = join(CLAUDE_DIR, "backup");
1973
+ const backupBaseDir = join(target.configDir, target.runtimeBackupDirName);
1865
1974
  const backupDir = join(backupBaseDir, `backup_${timestamp}`);
1866
1975
  ensureDir(backupDir);
1867
1976
  const filter = (path) => {
1868
- return !path.includes("/backup");
1977
+ return !path.includes("/backup") && !path.includes("/backups");
1869
1978
  };
1870
- copyDir(CLAUDE_DIR, backupDir, { filter });
1979
+ copyDir(target.configDir, backupDir, { filter });
1871
1980
  return backupDir;
1872
1981
  }
1873
- function copyConfigFiles(onlyMd = false) {
1982
+ function copyConfigFiles(onlyMd = false, codeTool) {
1983
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
1874
1984
  const currentFilePath = fileURLToPath(import.meta.url);
1875
1985
  const distDir = dirname(dirname(currentFilePath));
1876
1986
  const rootDir = dirname(distDir);
1877
1987
  const baseTemplateDir = join(rootDir, "templates", "claude-code");
1878
1988
  if (!onlyMd) {
1879
1989
  const baseSettingsPath = join(baseTemplateDir, "common", "settings.json");
1880
- const destSettingsPath = join(CLAUDE_DIR, "settings.json");
1881
1990
  if (exists(baseSettingsPath)) {
1882
- mergeSettingsFile(baseSettingsPath, destSettingsPath);
1991
+ mergeSettingsFile(baseSettingsPath, target.settingsFile, target.codeTool);
1883
1992
  }
1884
1993
  }
1885
1994
  }
@@ -1895,11 +2004,12 @@ function getDefaultSettings() {
1895
2004
  return {};
1896
2005
  }
1897
2006
  }
1898
- function configureApi(apiConfig) {
2007
+ function configureApi(apiConfig, codeTool) {
1899
2008
  if (!apiConfig)
1900
2009
  return null;
2010
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
1901
2011
  let settings = getDefaultSettings();
1902
- const existingSettings = readJsonConfig(activeSettingsFile());
2012
+ const existingSettings = readJsonConfig(target.settingsFile);
1903
2013
  if (existingSettings) {
1904
2014
  settings = deepMerge(settings, existingSettings);
1905
2015
  }
@@ -1916,17 +2026,18 @@ function configureApi(apiConfig) {
1916
2026
  if (apiConfig.url) {
1917
2027
  settings.env.ANTHROPIC_BASE_URL = apiConfig.url;
1918
2028
  }
1919
- writeJsonConfig(activeSettingsFile(), settings);
2029
+ normalizeClaudeFamilySettings(settings, { codeTool: target.codeTool });
2030
+ writeJsonConfig(target.settingsFile, settings);
1920
2031
  if (apiConfig.authType) {
1921
2032
  try {
1922
- setPrimaryApiKey();
2033
+ setPrimaryApiKey(target.codeTool);
1923
2034
  } catch (error) {
1924
2035
  ensureI18nInitialized();
1925
2036
  console.error(i18n.t("mcp:primaryApiKeySetFailed"), error);
1926
2037
  }
1927
2038
  }
1928
2039
  try {
1929
- addCompletedOnboarding();
2040
+ addCompletedOnboarding(target.codeTool);
1930
2041
  } catch (error) {
1931
2042
  console.error("Failed to set onboarding flag", error);
1932
2043
  }
@@ -1940,12 +2051,13 @@ function mergeConfigs(sourceFile, targetFile) {
1940
2051
  const merged = deepMerge(target, source);
1941
2052
  writeJsonConfig(targetFile, merged);
1942
2053
  }
1943
- function updateCustomModel(primaryModel, haikuModel, sonnetModel, opusModel) {
2054
+ function updateCustomModel(primaryModel, haikuModel, sonnetModel, opusModel, codeTool) {
2055
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
1944
2056
  if (!primaryModel?.trim() && !haikuModel?.trim() && !sonnetModel?.trim() && !opusModel?.trim()) {
1945
2057
  return;
1946
2058
  }
1947
2059
  let settings = getDefaultSettings();
1948
- const existingSettings = readJsonConfig(activeSettingsFile());
2060
+ const existingSettings = readJsonConfig(target.settingsFile);
1949
2061
  if (existingSettings) {
1950
2062
  settings = existingSettings;
1951
2063
  }
@@ -1961,11 +2073,13 @@ function updateCustomModel(primaryModel, haikuModel, sonnetModel, opusModel) {
1961
2073
  settings.env.ANTHROPIC_DEFAULT_SONNET_MODEL = sonnetModel.trim();
1962
2074
  if (opusModel?.trim())
1963
2075
  settings.env.ANTHROPIC_DEFAULT_OPUS_MODEL = opusModel.trim();
1964
- writeJsonConfig(activeSettingsFile(), settings);
2076
+ normalizeClaudeFamilySettings(settings, { codeTool: target.codeTool });
2077
+ writeJsonConfig(target.settingsFile, settings);
1965
2078
  }
1966
- function updateDefaultModel(model) {
2079
+ function updateDefaultModel(model, codeTool) {
2080
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
1967
2081
  let settings = getDefaultSettings();
1968
- const existingSettings = readJsonConfig(activeSettingsFile());
2082
+ const existingSettings = readJsonConfig(target.settingsFile);
1969
2083
  if (existingSettings) {
1970
2084
  settings = existingSettings;
1971
2085
  }
@@ -1980,9 +2094,10 @@ function updateDefaultModel(model) {
1980
2094
  } else {
1981
2095
  settings.model = model;
1982
2096
  }
1983
- writeJsonConfig(activeSettingsFile(), settings);
2097
+ normalizeClaudeFamilySettings(settings, { codeTool: target.codeTool });
2098
+ writeJsonConfig(target.settingsFile, settings);
1984
2099
  }
1985
- function mergeSettingsFile(templatePath, targetPath) {
2100
+ function mergeSettingsFile(templatePath, targetPath, codeTool) {
1986
2101
  try {
1987
2102
  const templateSettings = readJsonConfig(templatePath);
1988
2103
  if (!templateSettings) {
@@ -2011,6 +2126,7 @@ function mergeSettingsFile(templatePath, targetPath) {
2011
2126
  existingSettings.permissions?.allow
2012
2127
  );
2013
2128
  }
2129
+ normalizeClaudeFamilySettings(mergedSettings, { codeTool });
2014
2130
  writeJsonConfig(targetPath, mergedSettings);
2015
2131
  } catch (error) {
2016
2132
  console.error("Failed to merge settings", error);
@@ -2021,8 +2137,8 @@ function mergeSettingsFile(templatePath, targetPath) {
2021
2137
  }
2022
2138
  }
2023
2139
  }
2024
- function getExistingModelConfig() {
2025
- const settings = readJsonConfig(activeSettingsFile());
2140
+ function getExistingModelConfig(codeTool) {
2141
+ const settings = readJsonConfig(activeSettingsFile(codeTool));
2026
2142
  if (!settings) {
2027
2143
  return null;
2028
2144
  }
@@ -2039,8 +2155,8 @@ function getExistingModelConfig() {
2039
2155
  }
2040
2156
  return "default";
2041
2157
  }
2042
- function getExistingApiConfig() {
2043
- const settings = readJsonConfig(activeSettingsFile());
2158
+ function getExistingApiConfig(codeTool) {
2159
+ const settings = readJsonConfig(activeSettingsFile(codeTool));
2044
2160
  if (!settings || !settings.env) {
2045
2161
  return null;
2046
2162
  }
@@ -2063,8 +2179,9 @@ function getExistingApiConfig() {
2063
2179
  authType
2064
2180
  };
2065
2181
  }
2066
- function applyAiLanguageDirective(aiOutputLang) {
2067
- const claudeFile = join(CLAUDE_DIR, "CLAUDE.md");
2182
+ function applyAiLanguageDirective(aiOutputLang, codeTool) {
2183
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
2184
+ const instructionsFile = target.instructionsFile;
2068
2185
  let directive = "";
2069
2186
  if (aiOutputLang === "custom") {
2070
2187
  return;
@@ -2073,22 +2190,27 @@ function applyAiLanguageDirective(aiOutputLang) {
2073
2190
  } else {
2074
2191
  directive = `Always respond in ${aiOutputLang}`;
2075
2192
  }
2076
- writeFile(claudeFile, directive);
2193
+ ensureDir(target.configDir);
2194
+ writeFile(instructionsFile, directive);
2077
2195
  }
2078
- function switchToOfficialLogin$1() {
2196
+ function switchToOfficialLogin$1(codeTool) {
2079
2197
  try {
2080
2198
  ensureI18nInitialized();
2081
- const settings = readJsonConfig(activeSettingsFile()) || {};
2199
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
2200
+ const settings = readJsonConfig(target.settingsFile) || {};
2082
2201
  if (settings.env) {
2083
2202
  delete settings.env.ANTHROPIC_BASE_URL;
2084
2203
  delete settings.env.ANTHROPIC_AUTH_TOKEN;
2085
2204
  delete settings.env.ANTHROPIC_API_KEY;
2086
2205
  }
2087
- writeJsonConfig(activeSettingsFile(), settings);
2088
- const vscConfig = readJsonConfig(CLAUDE_VSC_CONFIG_FILE);
2089
- if (vscConfig) {
2090
- delete vscConfig.primaryApiKey;
2091
- writeJsonConfig(CLAUDE_VSC_CONFIG_FILE, vscConfig);
2206
+ normalizeClaudeFamilySettings(settings, { codeTool: target.codeTool });
2207
+ writeJsonConfig(target.settingsFile, settings);
2208
+ if (target.codeTool === "claude-code") {
2209
+ const vscConfig = readJsonConfig(CLAUDE_VSC_CONFIG_FILE);
2210
+ if (vscConfig) {
2211
+ delete vscConfig.primaryApiKey;
2212
+ writeJsonConfig(CLAUDE_VSC_CONFIG_FILE, vscConfig);
2213
+ }
2092
2214
  }
2093
2215
  console.log(i18n.t("api:officialLoginConfigured"));
2094
2216
  return true;
@@ -2134,6 +2256,7 @@ ${ansis.blue(`\u2139 ${i18n.t("api:existingApiConfig")}`)}`);
2134
2256
 
2135
2257
  const config$1 = {
2136
2258
  __proto__: null,
2259
+ activeSettingsFile: activeSettingsFile,
2137
2260
  applyAiLanguageDirective: applyAiLanguageDirective,
2138
2261
  backupExistingConfig: backupExistingConfig,
2139
2262
  configureApi: configureApi,
@@ -5505,10 +5628,12 @@ const codex = {
5505
5628
  writeAuthFile: writeAuthFile
5506
5629
  };
5507
5630
 
5631
+ const STARTUP_CODE_TOOL_CHOICES = CODE_TOOL_TYPES;
5508
5632
  const CODE_TYPE_ABBREVIATIONS = {
5509
5633
  cv: "clavue",
5510
5634
  cc: "claude-code",
5511
- cx: "codex"
5635
+ cx: "codex",
5636
+ gk: "grok"
5512
5637
  };
5513
5638
  async function resolveCodeType(codeTypeParam) {
5514
5639
  if (codeTypeParam) {
@@ -5544,7 +5669,7 @@ async function resolveCodeType(codeTypeParam) {
5544
5669
  return DEFAULT_CODE_TOOL_TYPE;
5545
5670
  }
5546
5671
  function isValidCodeType(value) {
5547
- return ["clavue", "claude-code", "codex"].includes(value);
5672
+ return CODE_TOOL_TYPES.includes(value);
5548
5673
  }
5549
5674
 
5550
5675
  function getPlatformStatusLineConfig() {
@@ -5700,8 +5825,9 @@ const LEGACY_FILES = ["personality.md", "rules.md", "technical-guides.md", "mcp.
5700
5825
  function getAvailableOutputStyles() {
5701
5826
  return OUTPUT_STYLES;
5702
5827
  }
5703
- async function copyOutputStyles(selectedStyles, lang) {
5704
- const outputStylesDir = join(CLAUDE_DIR, "output-styles");
5828
+ async function copyOutputStyles(selectedStyles, lang, codeTool) {
5829
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
5830
+ const outputStylesDir = join(target.configDir, "output-styles");
5705
5831
  ensureDir(outputStylesDir);
5706
5832
  const currentFilePath = fileURLToPath(import.meta.url);
5707
5833
  const distDir = dirname(dirname(currentFilePath));
@@ -5719,32 +5845,39 @@ async function copyOutputStyles(selectedStyles, lang) {
5719
5845
  }
5720
5846
  }
5721
5847
  }
5722
- function setGlobalDefaultOutputStyle(styleId) {
5723
- const existingSettings = readJsonConfig(SETTINGS_FILE) || {};
5848
+ function setGlobalDefaultOutputStyle(styleId, codeTool) {
5849
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
5850
+ const existingSettings = readJsonConfig(target.settingsFile) || {};
5724
5851
  const updatedSettings = {
5725
5852
  ...existingSettings,
5726
5853
  outputStyle: styleId
5727
5854
  };
5728
- writeJsonConfig(SETTINGS_FILE, updatedSettings);
5855
+ normalizeClaudeFamilySettings(updatedSettings, { codeTool: target.codeTool });
5856
+ writeJsonConfig(target.settingsFile, updatedSettings);
5729
5857
  }
5730
- function clearGlobalOutputStyle() {
5731
- const existingSettings = readJsonConfig(SETTINGS_FILE) || {};
5858
+ function clearGlobalOutputStyle(codeTool) {
5859
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
5860
+ const existingSettings = readJsonConfig(target.settingsFile) || {};
5732
5861
  const { outputStyle: _, ...rest } = existingSettings;
5733
- writeJsonConfig(SETTINGS_FILE, rest);
5862
+ normalizeClaudeFamilySettings(rest, { codeTool: target.codeTool });
5863
+ writeJsonConfig(target.settingsFile, rest);
5734
5864
  }
5735
- function hasLegacyPersonalityFiles() {
5736
- return LEGACY_FILES.some((filename) => exists(join(CLAUDE_DIR, filename)));
5865
+ function hasLegacyPersonalityFiles(codeTool) {
5866
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
5867
+ return LEGACY_FILES.some((filename) => exists(join(target.configDir, filename)));
5737
5868
  }
5738
- function cleanupLegacyPersonalityFiles() {
5869
+ function cleanupLegacyPersonalityFiles(codeTool) {
5870
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
5739
5871
  LEGACY_FILES.forEach((filename) => {
5740
- const filePath = join(CLAUDE_DIR, filename);
5872
+ const filePath = join(target.configDir, filename);
5741
5873
  if (exists(filePath)) {
5742
5874
  removeFile(filePath);
5743
5875
  }
5744
5876
  });
5745
5877
  }
5746
- async function configureOutputStyle(preselectedStyles, preselectedDefault) {
5878
+ async function configureOutputStyle(preselectedStyles, preselectedDefault, codeTool) {
5747
5879
  ensureI18nInitialized();
5880
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
5748
5881
  const outputStyleList = [
5749
5882
  {
5750
5883
  id: "default",
@@ -5793,18 +5926,18 @@ async function configureOutputStyle(preselectedStyles, preselectedDefault) {
5793
5926
  }
5794
5927
  ];
5795
5928
  const availableStyles = getAvailableOutputStyles();
5796
- if (hasLegacyPersonalityFiles() && !preselectedStyles) {
5929
+ if (hasLegacyPersonalityFiles(target.codeTool) && !preselectedStyles) {
5797
5930
  console.log(ansis.yellow(`\u26A0\uFE0F ${i18n.t("configuration:legacyFilesDetected")}`));
5798
5931
  const cleanupLegacy = await promptBoolean({
5799
5932
  message: i18n.t("configuration:cleanupLegacyFiles"),
5800
5933
  defaultValue: true
5801
5934
  });
5802
5935
  if (cleanupLegacy) {
5803
- cleanupLegacyPersonalityFiles();
5936
+ cleanupLegacyPersonalityFiles(target.codeTool);
5804
5937
  console.log(ansis.green(`\u2714 ${i18n.t("configuration:legacyFilesRemoved")}`));
5805
5938
  }
5806
- } else if (hasLegacyPersonalityFiles() && preselectedStyles) {
5807
- cleanupLegacyPersonalityFiles();
5939
+ } else if (hasLegacyPersonalityFiles(target.codeTool) && preselectedStyles) {
5940
+ cleanupLegacyPersonalityFiles(target.codeTool);
5808
5941
  }
5809
5942
  let selectedStyles;
5810
5943
  let defaultStyle;
@@ -5860,7 +5993,7 @@ async function configureOutputStyle(preselectedStyles, preselectedDefault) {
5860
5993
  return;
5861
5994
  }
5862
5995
  if (promptedDefault2 === "__none__") {
5863
- clearGlobalOutputStyle();
5996
+ clearGlobalOutputStyle(target.codeTool);
5864
5997
  updateCcjkConfig({
5865
5998
  outputStyles: [],
5866
5999
  defaultOutputStyle: "none"
@@ -5869,7 +6002,7 @@ async function configureOutputStyle(preselectedStyles, preselectedDefault) {
5869
6002
  return;
5870
6003
  }
5871
6004
  defaultStyle = promptedDefault2;
5872
- setGlobalDefaultOutputStyle(defaultStyle);
6005
+ setGlobalDefaultOutputStyle(defaultStyle, target.codeTool);
5873
6006
  updateCcjkConfig({
5874
6007
  outputStyles: [],
5875
6008
  defaultOutputStyle: defaultStyle
@@ -5910,8 +6043,8 @@ async function configureOutputStyle(preselectedStyles, preselectedDefault) {
5910
6043
  }
5911
6044
  defaultStyle = promptedDefault;
5912
6045
  }
5913
- await copyOutputStyles(selectedStyles, "zh-CN");
5914
- setGlobalDefaultOutputStyle(defaultStyle);
6046
+ await copyOutputStyles(selectedStyles, "zh-CN", target.codeTool);
6047
+ setGlobalDefaultOutputStyle(defaultStyle, target.codeTool);
5915
6048
  updateCcjkConfig({
5916
6049
  outputStyles: selectedStyles,
5917
6050
  defaultOutputStyle: defaultStyle
@@ -6123,17 +6256,20 @@ async function modifyApiConfigPartially(existingConfig) {
6123
6256
  }
6124
6257
  async function updatePromptOnly(aiOutputLang) {
6125
6258
  ensureI18nInitialized();
6126
- const backupDir = backupExistingConfig();
6259
+ const activeTool = getActiveCodeTool();
6260
+ const settingsTool = isClaudeFamilyCodeTool(activeTool) ? activeTool : "claude-code";
6261
+ const target = resolveClaudeFamilySettingsTarget(settingsTool);
6262
+ const backupDir = backupExistingConfig(settingsTool);
6127
6263
  if (backupDir) {
6128
6264
  console.log(ansis.gray(`\u2714 ${i18n.t("configuration:backupSuccess")}: ${backupDir}`));
6129
6265
  }
6130
6266
  if (aiOutputLang) {
6131
- applyAiLanguageDirective(aiOutputLang);
6267
+ applyAiLanguageDirective(aiOutputLang, settingsTool);
6132
6268
  }
6133
- await configureOutputStyle();
6134
- console.log(ansis.green(`\u2714 ${i18n.t("configuration:configSuccess")} ${CLAUDE_DIR}`));
6269
+ await configureOutputStyle(void 0, void 0, settingsTool);
6270
+ console.log(ansis.green(`\u2714 ${i18n.t("configuration:configSuccess")} ${target.configDirDisplay}`));
6135
6271
  console.log(`
6136
- ${ansis.cyan(i18n.t("common:complete"))}`);
6272
+ ${ansis.cyan(i18n.t("common:complete", { runtime: target.runtimeCommand }))}`);
6137
6273
  }
6138
6274
 
6139
6275
  function handleExitPromptError(error) {
@@ -6915,8 +7051,9 @@ function getRootDir() {
6915
7051
  }
6916
7052
  const DEFAULT_CODE_TOOL_TEMPLATE = "claude-code";
6917
7053
  const COMMON_TEMPLATE_CATEGORIES = ["git", "sixStep"];
6918
- async function selectAndInstallWorkflows(configLang, preselectedWorkflows) {
7054
+ async function selectAndInstallWorkflows(configLang, preselectedWorkflows, options = {}) {
6919
7055
  ensureI18nInitialized();
7056
+ const target = resolveClaudeFamilySettingsTarget(options.codeToolType);
6920
7057
  const workflows = getOrderedWorkflows();
6921
7058
  const choices = workflows.map((workflow) => {
6922
7059
  return {
@@ -6941,15 +7078,15 @@ async function selectAndInstallWorkflows(configLang, preselectedWorkflows) {
6941
7078
  console.log(ansis.yellow(i18n.t("common:cancelled")));
6942
7079
  return;
6943
7080
  }
6944
- await cleanupOldVersionFiles();
7081
+ await cleanupOldVersionFiles(target);
6945
7082
  for (const workflowId of selectedWorkflows) {
6946
7083
  const config = getWorkflowConfig(workflowId);
6947
7084
  if (config) {
6948
- await installWorkflowWithDependencies(config, configLang);
7085
+ await installWorkflowWithDependencies(config, configLang, target);
6949
7086
  }
6950
7087
  }
6951
7088
  }
6952
- async function installWorkflowWithDependencies(config, configLang) {
7089
+ async function installWorkflowWithDependencies(config, configLang, target) {
6953
7090
  const rootDir = getRootDir();
6954
7091
  ensureI18nInitialized();
6955
7092
  const result = {
@@ -6969,7 +7106,7 @@ async function installWorkflowWithDependencies(config, configLang) {
6969
7106
  const workflowName = WORKFLOW_OPTION_KEYS[config.id] || config.id;
6970
7107
  console.log(ansis.cyan(`
6971
7108
  \u{1F4E6} ${i18n.t("workflow:installingWorkflow")}: ${workflowName}...`));
6972
- const commandsDir = join(CLAUDE_DIR, "commands", "ccjk");
7109
+ const commandsDir = join(target.configDir, "commands", "ccjk");
6973
7110
  if (!existsSync(commandsDir)) {
6974
7111
  await mkdir(commandsDir, { recursive: true });
6975
7112
  }
@@ -7009,7 +7146,7 @@ async function installWorkflowWithDependencies(config, configLang) {
7009
7146
  }
7010
7147
  }
7011
7148
  if (config.autoInstallAgents && config.agents.length > 0) {
7012
- const agentsCategoryDir = join(CLAUDE_DIR, "agents", "ccjk", config.category);
7149
+ const agentsCategoryDir = join(target.configDir, "agents", "ccjk", config.category);
7013
7150
  if (!existsSync(agentsCategoryDir)) {
7014
7151
  await mkdir(agentsCategoryDir, { recursive: true });
7015
7152
  }
@@ -7052,25 +7189,25 @@ ${i18n.t("workflow:bmadInitPrompt")}`));
7052
7189
  }
7053
7190
  return result;
7054
7191
  }
7055
- async function cleanupOldVersionFiles() {
7192
+ async function cleanupOldVersionFiles(target) {
7056
7193
  ensureI18nInitialized();
7057
7194
  console.log(ansis.cyan(`
7058
7195
  \u{1F9F9} ${i18n.t("workflow:cleaningOldFiles")}...`));
7059
7196
  const oldCommandFiles = [
7060
- join(CLAUDE_DIR, "commands", "workflow.md"),
7061
- join(CLAUDE_DIR, "commands", "feat.md")
7197
+ join(target.configDir, "commands", "workflow.md"),
7198
+ join(target.configDir, "commands", "feat.md")
7062
7199
  ];
7063
7200
  const oldAgentFiles = [
7064
- join(CLAUDE_DIR, "agents", "planner.md"),
7065
- join(CLAUDE_DIR, "agents", "ui-ux-designer.md")
7201
+ join(target.configDir, "agents", "planner.md"),
7202
+ join(target.configDir, "agents", "ui-ux-designer.md")
7066
7203
  ];
7067
7204
  for (const file of oldCommandFiles) {
7068
7205
  if (existsSync(file)) {
7069
7206
  try {
7070
7207
  await rm(file, { force: true });
7071
- console.log(ansis.gray(` \u2714 ${i18n.t("workflow:removedOldFile")}: ${file.replace(CLAUDE_DIR, "~/.claude")}`));
7208
+ console.log(ansis.gray(` \u2714 ${i18n.t("workflow:removedOldFile")}: ${file.replace(target.configDir, target.configDirDisplay)}`));
7072
7209
  } catch {
7073
- console.error(ansis.yellow(` \u26A0 ${i18n.t("errors:failedToRemoveFile")}: ${file.replace(CLAUDE_DIR, "~/.claude")}`));
7210
+ console.error(ansis.yellow(` \u26A0 ${i18n.t("errors:failedToRemoveFile")}: ${file.replace(target.configDir, target.configDirDisplay)}`));
7074
7211
  }
7075
7212
  }
7076
7213
  }
@@ -7078,9 +7215,9 @@ async function cleanupOldVersionFiles() {
7078
7215
  if (existsSync(file)) {
7079
7216
  try {
7080
7217
  await rm(file, { force: true });
7081
- console.log(ansis.gray(` \u2714 ${i18n.t("workflow:removedOldFile")}: ${file.replace(CLAUDE_DIR, "~/.claude")}`));
7218
+ console.log(ansis.gray(` \u2714 ${i18n.t("workflow:removedOldFile")}: ${file.replace(target.configDir, target.configDirDisplay)}`));
7082
7219
  } catch {
7083
- console.error(ansis.yellow(` \u26A0 ${i18n.t("errors:failedToRemoveFile")}: ${file.replace(CLAUDE_DIR, "~/.claude")}`));
7220
+ console.error(ansis.yellow(` \u26A0 ${i18n.t("errors:failedToRemoveFile")}: ${file.replace(target.configDir, target.configDirDisplay)}`));
7084
7221
  }
7085
7222
  }
7086
7223
  }
@@ -7243,6 +7380,8 @@ async function init(options = {}) {
7243
7380
  const targetSettingsFile = settingsFileForTool(
7244
7381
  codeToolType === "codex" ? "claude-code" : codeToolType
7245
7382
  );
7383
+ const runtimeTarget = isClaudeFamilyCodeTool(codeToolType) ? resolveClaudeFamilySettingsTarget(codeToolType) : null;
7384
+ const claudeFamilyTool = codeToolType === "clavue" ? "clavue" : "claude-code";
7246
7385
  async function selectApiConfigurationMode() {
7247
7386
  const { apiMode } = await inquirer.prompt({
7248
7387
  type: "list",
@@ -7325,6 +7464,14 @@ async function init(options = {}) {
7325
7464
  if (!options.skipBanner) {
7326
7465
  displayBannerWithInfo(CODE_TOOL_BANNERS[codeToolType] || "CCJK");
7327
7466
  }
7467
+ if (codeToolType === "grok") {
7468
+ const { configureIncrementalManagement } = await import('./claude-code-incremental-manager.mjs');
7469
+ await configureIncrementalManagement();
7470
+ console.log(ansis.dim(`
7471
+ ${i18n.t("menu:menuDescriptions.grokInitHint")}
7472
+ `));
7473
+ return;
7474
+ }
7328
7475
  if (isTermux()) {
7329
7476
  console.log(ansis.yellow(`
7330
7477
  \u2139 ${i18n.t("installation:termuxDetected")}`));
@@ -7395,56 +7542,81 @@ async function init(options = {}) {
7395
7542
  return;
7396
7543
  }
7397
7544
  const aiOutputLang = await resolveAiOutputLanguage(i18n.language, options.aiOutputLang, ccjkConfig, options.skipPrompt);
7398
- const installationStatus = await getInstallationStatus();
7399
- if (installationStatus.hasGlobal || installationStatus.hasLocal) {
7400
- if (!options.skipPrompt) {
7401
- await handleMultipleInstallations(installationStatus);
7402
- } else {
7403
- if (installationStatus.hasLocal) {
7404
- if (!installationStatus.hasGlobal) {
7405
- console.log(ansis.blue(`${i18n.t("installation:installingGlobalClaudeCode")}...`));
7406
- await installClaudeCode(true);
7407
- console.log(ansis.green(`\u2714 ${i18n.t("installation:globalInstallationCompleted")}`));
7408
- }
7409
- if (installationStatus.hasGlobal && installationStatus.hasLocal) {
7410
- console.log(ansis.yellow(`\u26A0\uFE0F ${i18n.t("installation:multipleInstallationsDetected")}`));
7545
+ if (codeToolType === "clavue") {
7546
+ const clavueInstalled = await commandExists("clavue");
7547
+ if (!clavueInstalled) {
7548
+ if (options.skipPrompt) {
7549
+ console.log(ansis.yellow(i18n.t("installation:clavueNotInstalledHint")));
7550
+ } else {
7551
+ const shouldInstall = await promptBoolean({
7552
+ message: i18n.t("installation:clavueInstallPrompt"),
7553
+ defaultValue: true
7554
+ });
7555
+ if (shouldInstall) {
7556
+ const { exec } = await import('tinyexec');
7557
+ console.log(ansis.cyan(i18n.t("installation:installingClavue")));
7558
+ await exec("npm", ["install", "-g", "clavue"]);
7559
+ console.log(ansis.green(`\u2714 ${i18n.t("installation:clavueInstallSuccess")}`));
7560
+ } else {
7561
+ console.log(ansis.yellow(i18n.t("common:skip")));
7411
7562
  }
7412
- console.log(ansis.blue(`${i18n.t("installation:removingLocalInstallation")}...`));
7413
- const { removeLocalClaudeCode } = await Promise.resolve().then(function () { return installer; });
7414
- await removeLocalClaudeCode();
7415
- console.log(ansis.green(`\u2714 ${i18n.t("installation:localInstallationRemoved")}`));
7416
7563
  }
7417
7564
  }
7418
- const { verifyInstallation, displayVerificationResult } = await Promise.resolve().then(function () { return installer; });
7419
- const verification = await verifyInstallation("claude-code");
7420
- if (verification.symlinkCreated) {
7421
- console.log(ansis.green(`\u2714 ${i18n.t("installation:alreadyInstalled")}`));
7422
- displayVerificationResult(verification, "claude-code");
7423
- } else if (!verification.success) {
7424
- console.log(ansis.yellow(`\u26A0 ${i18n.t("installation:verificationFailed")}`));
7425
- if (verification.error) {
7426
- console.log(ansis.gray(` ${verification.error}`));
7565
+ } else if (codeToolType === "claude-code") {
7566
+ const installationStatus = await getInstallationStatus();
7567
+ if (installationStatus.hasGlobal || installationStatus.hasLocal) {
7568
+ if (!options.skipPrompt) {
7569
+ await handleMultipleInstallations(installationStatus);
7570
+ } else {
7571
+ if (installationStatus.hasLocal) {
7572
+ if (!installationStatus.hasGlobal) {
7573
+ console.log(ansis.blue(`${i18n.t("installation:installingGlobalClaudeCode")}...`));
7574
+ await installClaudeCode(true);
7575
+ console.log(ansis.green(`\u2714 ${i18n.t("installation:globalInstallationCompleted")}`));
7576
+ }
7577
+ if (installationStatus.hasGlobal && installationStatus.hasLocal) {
7578
+ console.log(ansis.yellow(`\u26A0\uFE0F ${i18n.t("installation:multipleInstallationsDetected")}`));
7579
+ }
7580
+ console.log(ansis.blue(`${i18n.t("installation:removingLocalInstallation")}...`));
7581
+ const { removeLocalClaudeCode } = await Promise.resolve().then(function () { return installer; });
7582
+ await removeLocalClaudeCode();
7583
+ console.log(ansis.green(`\u2714 ${i18n.t("installation:localInstallationRemoved")}`));
7584
+ }
7585
+ }
7586
+ const { verifyInstallation, displayVerificationResult } = await Promise.resolve().then(function () { return installer; });
7587
+ const verification = await verifyInstallation("claude-code");
7588
+ if (verification.symlinkCreated) {
7589
+ console.log(ansis.green(`\u2714 ${i18n.t("installation:alreadyInstalled")}`));
7590
+ displayVerificationResult(verification, "claude-code");
7591
+ } else if (!verification.success) {
7592
+ console.log(ansis.yellow(`\u26A0 ${i18n.t("installation:verificationFailed")}`));
7593
+ if (verification.error) {
7594
+ console.log(ansis.gray(` ${verification.error}`));
7595
+ }
7427
7596
  }
7428
- }
7429
- } else {
7430
- if (options.skipPrompt) {
7431
- await installClaudeCode(true);
7432
7597
  } else {
7433
- const shouldInstall = await promptBoolean({
7434
- message: i18n.t("installation:installPrompt"),
7435
- defaultValue: true
7436
- });
7437
- if (shouldInstall) {
7438
- await installClaudeCode(false);
7598
+ if (options.skipPrompt) {
7599
+ await installClaudeCode(true);
7439
7600
  } else {
7440
- console.log(ansis.yellow(i18n.t("common:skip")));
7601
+ const shouldInstall = await promptBoolean({
7602
+ message: i18n.t("installation:installPrompt"),
7603
+ defaultValue: true
7604
+ });
7605
+ if (shouldInstall) {
7606
+ await installClaudeCode(false);
7607
+ } else {
7608
+ console.log(ansis.yellow(i18n.t("common:skip")));
7609
+ }
7441
7610
  }
7442
7611
  }
7612
+ if (installationStatus.hasGlobal || installationStatus.hasLocal) {
7613
+ await checkClaudeCodeVersionAndPrompt(options.skipPrompt);
7614
+ }
7443
7615
  }
7444
- if (installationStatus.hasGlobal || installationStatus.hasLocal) {
7445
- await checkClaudeCodeVersionAndPrompt(options.skipPrompt);
7616
+ if (!runtimeTarget) {
7617
+ return;
7446
7618
  }
7447
- ensureClaudeDir();
7619
+ ensureClaudeDir(codeToolType);
7448
7620
  let action = "new";
7449
7621
  if (existsSync(targetSettingsFile) && !options.force) {
7450
7622
  if (options.skipPrompt) {
@@ -7582,43 +7754,44 @@ async function init(options = {}) {
7582
7754
  }
7583
7755
  }
7584
7756
  if (["backup", "docs-only", "merge"].includes(action)) {
7585
- const backupDir = backupExistingConfig();
7757
+ const backupDir = backupExistingConfig(codeToolType);
7586
7758
  if (backupDir) {
7587
7759
  console.log(ansis.gray(`\u2714 ${i18n.t("configuration:backupSuccess")}: ${backupDir}`));
7588
7760
  }
7589
7761
  }
7590
7762
  if (action === "docs-only") {
7591
- copyConfigFiles(true);
7763
+ copyConfigFiles(true, codeToolType);
7592
7764
  if (options.skipPrompt) {
7593
7765
  if (options.workflows !== false) {
7594
- await selectAndInstallWorkflows(configLang, options.workflows);
7766
+ await selectAndInstallWorkflows(configLang, options.workflows, { codeToolType });
7595
7767
  }
7596
7768
  } else {
7597
- await selectAndInstallWorkflows(configLang);
7769
+ await selectAndInstallWorkflows(configLang, void 0, { codeToolType });
7598
7770
  }
7599
7771
  } else if (["backup", "merge", "new"].includes(action)) {
7600
- copyConfigFiles(false);
7772
+ copyConfigFiles(false, codeToolType);
7601
7773
  if (options.skipPrompt) {
7602
7774
  if (options.workflows !== false) {
7603
- await selectAndInstallWorkflows(configLang, options.workflows);
7775
+ await selectAndInstallWorkflows(configLang, options.workflows, { codeToolType });
7604
7776
  }
7605
7777
  } else {
7606
- await selectAndInstallWorkflows(configLang);
7778
+ await selectAndInstallWorkflows(configLang, void 0, { codeToolType });
7607
7779
  }
7608
7780
  }
7609
- applyAiLanguageDirective(aiOutputLang);
7781
+ applyAiLanguageDirective(aiOutputLang, codeToolType);
7610
7782
  if (options.skipPrompt) {
7611
7783
  if (options.outputStyles !== false) {
7612
7784
  await configureOutputStyle(
7613
7785
  options.outputStyles,
7614
- options.defaultOutputStyle
7786
+ options.defaultOutputStyle,
7787
+ codeToolType
7615
7788
  );
7616
7789
  }
7617
7790
  } else {
7618
- await configureOutputStyle();
7791
+ await configureOutputStyle(void 0, void 0, codeToolType);
7619
7792
  }
7620
7793
  if (apiConfig && action !== "docs-only") {
7621
- const configuredApi = configureApi(apiConfig);
7794
+ const configuredApi = configureApi(apiConfig, codeToolType);
7622
7795
  if (configuredApi) {
7623
7796
  console.log(ansis.green(`\u2714 ${i18n.t("api:apiConfigSuccess")}`));
7624
7797
  console.log(ansis.gray(` URL: ${configuredApi.url}`));
@@ -7626,14 +7799,15 @@ async function init(options = {}) {
7626
7799
  }
7627
7800
  }
7628
7801
  const hasModelParams = options.apiModel || options.apiHaikuModel || options.apiSonnetModel || options.apiOpusModel;
7629
- if (hasModelParams && action !== "docs-only" && codeToolType === "claude-code") {
7802
+ if (hasModelParams && action !== "docs-only" && isClaudeFamilyCodeTool(codeToolType)) {
7630
7803
  if (options.skipPrompt) {
7631
7804
  const { updateCustomModel } = await Promise.resolve().then(function () { return config$1; });
7632
7805
  updateCustomModel(
7633
7806
  options.apiModel || void 0,
7634
7807
  options.apiHaikuModel || void 0,
7635
7808
  options.apiSonnetModel || void 0,
7636
- options.apiOpusModel || void 0
7809
+ options.apiOpusModel || void 0,
7810
+ codeToolType
7637
7811
  );
7638
7812
  console.log(ansis.green(`\u2714 ${i18n.t("api:modelConfigSuccess")}`));
7639
7813
  if (options.apiModel) {
@@ -7672,7 +7846,7 @@ async function init(options = {}) {
7672
7846
  }
7673
7847
  }
7674
7848
  if (selectedServices.length > 0) {
7675
- const mcpBackupPath = backupMcpConfig();
7849
+ const mcpBackupPath = backupMcpConfig(claudeFamilyTool);
7676
7850
  if (mcpBackupPath) {
7677
7851
  console.log(ansis.gray(`\u2714 ${i18n.t("mcp:mcpBackupSuccess")}: ${mcpBackupPath}`));
7678
7852
  }
@@ -7713,11 +7887,11 @@ async function init(options = {}) {
7713
7887
  }
7714
7888
  newServers[service.id] = config;
7715
7889
  }
7716
- const existingConfig = readMcpConfig();
7890
+ const existingConfig = readMcpConfig(claudeFamilyTool);
7717
7891
  let mergedConfig = mergeMcpServers(existingConfig, newServers);
7718
7892
  mergedConfig = fixWindowsMcpConfig(mergedConfig);
7719
7893
  try {
7720
- writeMcpConfig(mergedConfig);
7894
+ writeMcpConfig(mergedConfig, claudeFamilyTool);
7721
7895
  console.log(ansis.green(`\u2714 ${i18n.t("mcp:mcpConfigSuccess")}`));
7722
7896
  } catch (error) {
7723
7897
  console.error(ansis.red(`${i18n.t("errors:failedToWriteMcpConfig")} ${error}`));
@@ -7754,9 +7928,9 @@ async function init(options = {}) {
7754
7928
  aiOutputLang,
7755
7929
  codeToolType
7756
7930
  });
7757
- console.log(ansis.green(`\u2714 ${i18n.t("configuration:configSuccess")} ${CLAUDE_DIR}`));
7931
+ console.log(ansis.green(`\u2714 ${i18n.t("configuration:configSuccess")} ${runtimeTarget.configDirDisplay}`));
7758
7932
  console.log(`
7759
- ${ansis.cyan(i18n.t("common:complete"))}`);
7933
+ ${ansis.cyan(i18n.t("common:complete", { runtime: runtimeTarget.runtimeCommand }))}`);
7760
7934
  } catch (error) {
7761
7935
  if (!handleExitPromptError(error)) {
7762
7936
  handleGeneralError(error);
@@ -7785,7 +7959,7 @@ async function handleMultiConfigurations(options, codeToolType) {
7785
7959
  }
7786
7960
  }
7787
7961
  await validateApiConfigs(configs);
7788
- if (codeToolType === "claude-code") {
7962
+ if (codeToolType === "claude-code" || codeToolType === "clavue") {
7789
7963
  await handleClaudeCodeConfigs(configs);
7790
7964
  } else if (codeToolType === "codex") {
7791
7965
  await handleCodexConfigs(configs);
@@ -8022,33 +8196,39 @@ function getTemplateSettings() {
8022
8196
  const content = readFileSync(templatePath, "utf-8");
8023
8197
  return JSON.parse(content);
8024
8198
  }
8025
- function loadCurrentSettings() {
8026
- if (!existsSync(SETTINGS_FILE)) {
8199
+ function loadCurrentSettings(codeTool) {
8200
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
8201
+ if (!existsSync(target.settingsFile)) {
8027
8202
  return {};
8028
8203
  }
8029
8204
  try {
8030
- const content = readFileSync(SETTINGS_FILE, "utf-8");
8205
+ const content = readFileSync(target.settingsFile, "utf-8");
8031
8206
  return JSON.parse(content);
8032
8207
  } catch {
8033
8208
  return {};
8034
8209
  }
8035
8210
  }
8036
- function saveSettings(settings) {
8037
- ensureDir(CLAUDE_DIR);
8038
- writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2));
8211
+ function saveSettings(settings, codeTool) {
8212
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
8213
+ ensureDir(target.configDir);
8214
+ normalizeClaudeFamilySettings(settings, { codeTool: target.codeTool });
8215
+ writeSettingsFile(target.settingsFile, settings);
8216
+ }
8217
+ function writeSettingsFile(path, settings) {
8218
+ writeFileSync(path, JSON.stringify(settings, null, 2));
8039
8219
  }
8040
- async function importRecommendedEnv() {
8220
+ async function importRecommendedEnv(codeTool) {
8041
8221
  const templateSettings = getTemplateSettings();
8042
- const currentSettings = loadCurrentSettings();
8222
+ const currentSettings = loadCurrentSettings(codeTool);
8043
8223
  currentSettings.env = {
8044
8224
  ...currentSettings.env,
8045
8225
  ...templateSettings.env
8046
8226
  };
8047
- saveSettings(currentSettings);
8227
+ saveSettings(currentSettings, codeTool);
8048
8228
  }
8049
- async function importRecommendedPermissions() {
8229
+ async function importRecommendedPermissions(codeTool) {
8050
8230
  const templateSettings = getTemplateSettings();
8051
- const currentSettings = loadCurrentSettings();
8231
+ const currentSettings = loadCurrentSettings(codeTool);
8052
8232
  if (templateSettings.permissions && templateSettings.permissions.allow) {
8053
8233
  currentSettings.permissions = {
8054
8234
  ...templateSettings.permissions,
@@ -8060,12 +8240,14 @@ async function importRecommendedPermissions() {
8060
8240
  } else {
8061
8241
  currentSettings.permissions = templateSettings.permissions;
8062
8242
  }
8063
- saveSettings(currentSettings);
8243
+ applyTrustedOperatorPermissions(currentSettings);
8244
+ saveSettings(currentSettings, codeTool);
8064
8245
  }
8065
- async function openSettingsJson() {
8066
- ensureDir(CLAUDE_DIR);
8067
- if (!existsSync(SETTINGS_FILE)) {
8068
- saveSettings({});
8246
+ async function openSettingsJson(codeTool) {
8247
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
8248
+ ensureDir(target.configDir);
8249
+ if (!existsSync(target.settingsFile)) {
8250
+ saveSettings({}, codeTool);
8069
8251
  }
8070
8252
  const platform = getPlatform();
8071
8253
  let command;
@@ -8080,18 +8262,18 @@ async function openSettingsJson() {
8080
8262
  command = "xdg-open";
8081
8263
  }
8082
8264
  try {
8083
- await exec(command, [SETTINGS_FILE]);
8265
+ await exec(command, [target.settingsFile]);
8084
8266
  } catch {
8085
8267
  try {
8086
- await exec("code", [SETTINGS_FILE]);
8268
+ await exec("code", [target.settingsFile]);
8087
8269
  } catch {
8088
8270
  try {
8089
- await exec("vim", [SETTINGS_FILE]);
8271
+ await exec("vim", [target.settingsFile]);
8090
8272
  } catch {
8091
- await exec("nano", [SETTINGS_FILE]);
8273
+ await exec("nano", [target.settingsFile]);
8092
8274
  }
8093
8275
  }
8094
8276
  }
8095
8277
  }
8096
8278
 
8097
- export { isCodeToolType as $, AI_OUTPUT_LANGUAGES as A, configureApi as B, CCJK_CONFIG_DIR as C, DEFAULT_CODE_TOOL_TYPE as D, copyConfigFiles as E, createHomebrewSymlink as F, detectInstalledVersion as G, displayVerificationResult as H, ensureApiKeyApproved as I, ensureClaudeDir as J, executeInstallMethod as K, LANG_LABELS as L, fixWindowsMcpConfig as M, getAiOutputLanguageLabel as N, getExistingApiConfig as O, getExistingModelConfig as P, getInstallationStatus as Q, getMcpConfigPath as R, SETTINGS_FILE as S, getPlatform as T, handleInstallFailure as U, importRecommendedEnv as V, importRecommendedPermissions as W, init as X, installClaudeCode as Y, installCodex as Z, isClaudeCodeInstalled as _, API_DEFAULT_URL as a, displayBanner as a$, isCodexInstalled as a0, isLocalClaudeCodeInstalled as a1, manageApiKeyApproval as a2, mergeAndCleanPermissions as a3, mergeConfigs as a4, mergeMcpServers as a5, mergeSettingsFile as a6, openSettingsJson as a7, promptApiConfigurationAction as a8, readMcpConfig as a9, detectConfigManagementMode as aA, readCodexConfig as aB, backupCodexComplete as aC, writeAuthFile as aD, updateCcjkConfig as aE, changeLanguage as aF, readCcjkConfig as aG, configureOutputStyle as aH, isWindows as aI, selectMcpServices as aJ, getMcpServices as aK, isCcrInstalled as aL, installCcr as aM, setupCcrConfiguration as aN, modifyApiConfigPartially as aO, formatApiKeyDisplay as aP, readCcrConfig as aQ, configureCcrFeature as aR, handleExitPromptError as aS, handleGeneralError as aT, COMETIX_COMMAND_NAME as aU, COMETIX_COMMANDS as aV, installCometixLine as aW, checkAndUpdateTools as aX, runCodexUpdate as aY, resolveCodeType as aZ, writeJsonConfig as a_, removeApiKeyFromRejected as aa, removeLocalClaudeCode as ab, resolveCodeToolType as ac, selectInstallMethod as ad, setInstallMethod as ae, setPrimaryApiKey as af, settingsFileForTool as ag, switchToOfficialLogin$1 as ah, uninstallCodeTool as ai, updateCustomModel as aj, updateDefaultModel as ak, verifyInstallation as al, writeMcpConfig as am, ensureI18nInitialized as an, i18n as ao, addNumbersToChoices as ap, validateApiKey as aq, promptBoolean as ar, ensureDir as as, readDefaultTomlConfig as at, createDefaultTomlConfig as au, exists as av, readJsonConfig as aw, writeTomlConfig as ax, clearModelEnv as ay, copyFile as az, API_ENV_KEY as b, version as b0, resolveAiOutputLanguage as b1, updatePromptOnly as b2, selectAndInstallWorkflows as b3, checkClaudeCodeVersionAndPrompt as b4, displayBannerWithInfo as b5, runCodexUninstall as b6, configureCodexMcp as b7, configureCodexApi as b8, runCodexWorkflowImportWithLanguageSelection as b9, runCodexFullInit as ba, switchCodexProvider as bb, listCodexProviders as bc, switchToOfficialLogin as bd, switchToProvider as be, readCcjkConfigAsync as bf, initI18n as bg, selectScriptLanguage as bh, index as bi, fsOperations as bj, jsonConfig as bk, claudeConfig as bl, config$1 as bm, config as bn, prompts as bo, codexProfileV2 as bp, codexTomlUpdater as bq, codex as br, installer as bs, CCJK_CONFIG_FILE as c, CLAUDE_DIR as d, CLAUDE_MD_FILE as e, CLAUDE_VSC_CONFIG_FILE as f, CLAVUE_DIR as g, CLAVUE_SETTINGS_FILE as h, CODEX_AGENTS_FILE as i, CODEX_AUTH_FILE as j, CODEX_CONFIG_FILE as k, CODEX_DIR as l, CODEX_PROMPTS_DIR as m, CODE_TOOL_ALIASES as n, CODE_TOOL_BANNERS as o, CODE_TOOL_TYPES as p, ClAUDE_CONFIG_FILE as q, LEGACY_CCJK_CONFIG_FILES as r, SUPPORTED_LANGS as s, addCompletedOnboarding as t, applyAiLanguageDirective as u, backupExistingConfig as v, backupMcpConfig as w, buildMcpServerConfig as x, cleanupPermissions as y, commandExists as z };
8279
+ export { installClaudeCode as $, AI_OUTPUT_LANGUAGES as A, buildMcpServerConfig as B, CCJK_CONFIG_DIR as C, DEFAULT_CODE_TOOL_TYPE as D, cleanupPermissions as E, commandExists as F, configureApi as G, copyConfigFiles as H, createHomebrewSymlink as I, detectInstalledVersion as J, displayVerificationResult as K, LANG_LABELS as L, ensureApiKeyApproved as M, ensureClaudeDir as N, executeInstallMethod as O, fixWindowsMcpConfig as P, getAiOutputLanguageLabel as Q, getExistingApiConfig as R, SETTINGS_FILE as S, getExistingModelConfig as T, getInstallationStatus as U, getMcpConfigPath as V, getPlatform as W, handleInstallFailure as X, importRecommendedEnv as Y, importRecommendedPermissions as Z, init as _, API_DEFAULT_URL as a, COMETIX_COMMAND_NAME as a$, installCodex as a0, isClaudeCodeInstalled as a1, isCodeToolType as a2, isCodexInstalled as a3, isLocalClaudeCodeInstalled as a4, manageApiKeyApproval as a5, mergeAndCleanPermissions as a6, mergeConfigs as a7, mergeMcpServers as a8, mergeSettingsFile as a9, exists as aA, readJsonConfig as aB, writeTomlConfig as aC, clearModelEnv as aD, normalizeClaudeFamilySettings as aE, copyFile as aF, detectConfigManagementMode as aG, readCodexConfig as aH, backupCodexComplete as aI, writeAuthFile as aJ, updateCcjkConfig as aK, changeLanguage as aL, readCcjkConfig as aM, configureOutputStyle as aN, isClaudeFamilyCodeTool as aO, isWindows as aP, selectMcpServices as aQ, getMcpServices as aR, isCcrInstalled as aS, installCcr as aT, setupCcrConfiguration as aU, modifyApiConfigPartially as aV, formatApiKeyDisplay as aW, readCcrConfig as aX, configureCcrFeature as aY, handleExitPromptError as aZ, handleGeneralError as a_, openSettingsJson as aa, promptApiConfigurationAction as ab, readMcpConfig as ac, removeApiKeyFromRejected as ad, removeLocalClaudeCode as ae, resolveCodeToolType as af, selectInstallMethod as ag, setInstallMethod as ah, setPrimaryApiKey as ai, settingsFileForTool as aj, switchToOfficialLogin$1 as ak, uninstallCodeTool as al, updateCustomModel as am, updateDefaultModel as an, verifyInstallation as ao, writeMcpConfig as ap, ensureI18nInitialized as aq, getActiveCodeTool as ar, i18n as as, addNumbersToChoices as at, validateApiKey as au, promptBoolean as av, resolveClaudeFamilySettingsTarget as aw, ensureDir as ax, readDefaultTomlConfig as ay, createDefaultTomlConfig as az, API_ENV_KEY as b, COMETIX_COMMANDS as b0, installCometixLine as b1, checkAndUpdateTools as b2, runCodexUpdate as b3, resolveCodeType as b4, writeJsonConfig as b5, displayBanner as b6, version as b7, resolveAiOutputLanguage as b8, updatePromptOnly as b9, installer as bA, selectAndInstallWorkflows as ba, checkClaudeCodeVersionAndPrompt as bb, STARTUP_CODE_TOOL_CHOICES as bc, displayBannerWithInfo as bd, runCodexUninstall as be, configureCodexMcp as bf, configureCodexApi as bg, runCodexWorkflowImportWithLanguageSelection as bh, runCodexFullInit as bi, switchCodexProvider as bj, listCodexProviders as bk, switchToOfficialLogin as bl, switchToProvider as bm, readCcjkConfigAsync as bn, initI18n as bo, selectScriptLanguage as bp, index as bq, fsOperations as br, jsonConfig as bs, claudeConfig as bt, config$1 as bu, config as bv, prompts as bw, codexProfileV2 as bx, codexTomlUpdater as by, codex as bz, CCJK_CONFIG_FILE as c, CLAUDE_DIR as d, CLAUDE_MD_FILE as e, CLAUDE_VSC_CONFIG_FILE as f, CLAVUE_CONFIG_FILE as g, CLAVUE_DIR as h, CLAVUE_MD_FILE as i, CLAVUE_SETTINGS_FILE as j, CODEX_AGENTS_FILE as k, CODEX_AUTH_FILE as l, CODEX_CONFIG_FILE as m, CODEX_DIR as n, CODEX_PROMPTS_DIR as o, CODE_TOOL_ALIASES as p, CODE_TOOL_BANNERS as q, CODE_TOOL_TYPES as r, ClAUDE_CONFIG_FILE as s, LEGACY_CCJK_CONFIG_FILES as t, SUPPORTED_LANGS as u, activeSettingsFile as v, addCompletedOnboarding as w, applyAiLanguageDirective as x, backupExistingConfig as y, backupMcpConfig as z };