ccjk 16.0.0-alpha.3 → 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.0-alpha.3";
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");
@@ -397,16 +399,15 @@ const CCJK_CONFIG_FILE = join(CCJK_CONFIG_DIR, "config.toml");
397
399
  const LEGACY_CCJK_CONFIG_FILES = [
398
400
  join(CLAUDE_DIR, ".ccjk-config.json"),
399
401
  join(homedir(), ".ccjk.json"),
400
- join(homedir(), ".ufomiao", "zcf", "config.toml"),
401
- join(homedir(), ".ufomiao", "ccjk", "config.toml"),
402
- join(homedir(), ".zcf", "config.toml")
402
+ join(homedir(), ".ufomiao", "ccjk", "config.toml")
403
403
  ];
404
- const CODE_TOOL_TYPES = ["clavue", "claude-code", "codex"];
404
+ const CODE_TOOL_TYPES = ["clavue", "claude-code", "codex", "grok"];
405
405
  const DEFAULT_CODE_TOOL_TYPE = "clavue";
406
406
  const CODE_TOOL_BANNERS = {
407
407
  "clavue": "for Clavue",
408
408
  "claude-code": "for Claude Code",
409
- "codex": "for Codex"
409
+ "codex": "for Codex",
410
+ "grok": "for Grok CLI"
410
411
  };
411
412
  function settingsFileForTool(tool) {
412
413
  if (tool === "clavue") return CLAVUE_SETTINGS_FILE;
@@ -416,7 +417,8 @@ function settingsFileForTool(tool) {
416
417
  const CODE_TOOL_ALIASES = {
417
418
  cv: "clavue",
418
419
  cc: "claude-code",
419
- cx: "codex"
420
+ cx: "codex",
421
+ gk: "grok"
420
422
  };
421
423
  function isCodeToolType(value) {
422
424
  return CODE_TOOL_TYPES.includes(value);
@@ -465,7 +467,9 @@ const constants = {
465
467
  CLAUDE_DIR: CLAUDE_DIR,
466
468
  CLAUDE_MD_FILE: CLAUDE_MD_FILE,
467
469
  CLAUDE_VSC_CONFIG_FILE: CLAUDE_VSC_CONFIG_FILE,
470
+ CLAVUE_CONFIG_FILE: CLAVUE_CONFIG_FILE,
468
471
  CLAVUE_DIR: CLAVUE_DIR,
472
+ CLAVUE_MD_FILE: CLAVUE_MD_FILE,
469
473
  CLAVUE_SETTINGS_FILE: CLAVUE_SETTINGS_FILE,
470
474
  CODEX_AGENTS_FILE: CODEX_AGENTS_FILE,
471
475
  CODEX_AUTH_FILE: CODEX_AUTH_FILE,
@@ -508,19 +512,19 @@ function displayBanner(subtitle) {
508
512
  const defaultSubtitle = i18n.t("cli:banner.subtitle");
509
513
  const subtitleText = subtitle || defaultSubtitle;
510
514
  const paddedSubtitle = padToDisplayWidth(subtitleText, 30);
511
- const paddedTitle = padToDisplayWidth("Zero-Config Code Flow", 60);
515
+ const paddedTitle = padToDisplayWidth("CCJK", 60);
512
516
  console.log(
513
517
  ansis.cyan.bold(`
514
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
515
519
  \u2551 \u2551
516
- \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
517
- \u2551 \u2588\u2588\u2554\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2551
518
- \u2551 \u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2551
519
- \u2551 \u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D \u2551
520
- \u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2551
521
- \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
522
526
  \u2551 \u2551
523
- \u2551 ${ansis.white.bold(paddedTitle)} \u2551
527
+ \u2551 ${ansis.white.bold(paddedTitle)} \u2014 Clavue / Claude / Codex / Grok \u7EDF\u4E00\u914D\u7F6E \u2551
524
528
  \u2551 \u2551
525
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
526
530
  `)
@@ -1174,241 +1178,6 @@ const jsonConfig = {
1174
1178
  writeJsonConfig: writeJsonConfig
1175
1179
  };
1176
1180
 
1177
- function mergeArraysUnique(arr1, arr2) {
1178
- const combined = [...arr1 || [], ...arr2 || []];
1179
- return [...new Set(combined)];
1180
- }
1181
- function isPlainObject(value) {
1182
- return value !== null && typeof value === "object" && value.constructor === Object && Object.prototype.toString.call(value) === "[object Object]";
1183
- }
1184
- function deepMerge(target, source, options = {}) {
1185
- const { mergeArrays = false, arrayMergeStrategy = "replace" } = options;
1186
- const result = { ...target };
1187
- for (const key in source) {
1188
- const sourceValue = source[key];
1189
- const targetValue = result[key];
1190
- if (sourceValue === void 0) {
1191
- continue;
1192
- }
1193
- if (isPlainObject(sourceValue) && isPlainObject(targetValue)) {
1194
- result[key] = deepMerge(targetValue, sourceValue, options);
1195
- } else if (Array.isArray(sourceValue)) {
1196
- if (!mergeArrays || !Array.isArray(targetValue)) {
1197
- result[key] = sourceValue;
1198
- } else {
1199
- switch (arrayMergeStrategy) {
1200
- case "concat":
1201
- result[key] = [...targetValue, ...sourceValue];
1202
- break;
1203
- case "unique":
1204
- result[key] = mergeArraysUnique(targetValue, sourceValue);
1205
- break;
1206
- case "replace":
1207
- default:
1208
- result[key] = sourceValue;
1209
- break;
1210
- }
1211
- }
1212
- } else {
1213
- result[key] = sourceValue;
1214
- }
1215
- }
1216
- return result;
1217
- }
1218
- function deepClone(obj) {
1219
- if (obj === null || typeof obj !== "object") {
1220
- return obj;
1221
- }
1222
- if (obj instanceof Date) {
1223
- return new Date(obj.getTime());
1224
- }
1225
- if (Array.isArray(obj)) {
1226
- return obj.map((item) => deepClone(item));
1227
- }
1228
- if (isPlainObject(obj)) {
1229
- const cloned = {};
1230
- for (const key in obj) {
1231
- cloned[key] = deepClone(obj[key]);
1232
- }
1233
- return cloned;
1234
- }
1235
- return obj;
1236
- }
1237
-
1238
- function getMcpConfigPath() {
1239
- return ClAUDE_CONFIG_FILE;
1240
- }
1241
- function readMcpConfig() {
1242
- return readJsonConfig(ClAUDE_CONFIG_FILE);
1243
- }
1244
- function writeMcpConfig(config) {
1245
- writeJsonConfig(ClAUDE_CONFIG_FILE, config);
1246
- }
1247
- function backupMcpConfig() {
1248
- const backupBaseDir = join(CLAUDE_DIR, "backup");
1249
- return backupJsonConfig(ClAUDE_CONFIG_FILE, backupBaseDir);
1250
- }
1251
- function mergeMcpServers(existing, newServers) {
1252
- const config = existing || { mcpServers: {} };
1253
- if (!config.mcpServers) {
1254
- config.mcpServers = {};
1255
- }
1256
- Object.assign(config.mcpServers, newServers);
1257
- return config;
1258
- }
1259
- function applyPlatformCommand(config) {
1260
- if (isWindows() && config.command) {
1261
- const mcpCmd = getMcpCommand(config.command);
1262
- if (mcpCmd[0] === "cmd") {
1263
- config.command = mcpCmd[0];
1264
- config.args = [...mcpCmd.slice(1), ...config.args || []];
1265
- }
1266
- }
1267
- }
1268
- function buildMcpServerConfig(baseConfig, apiKey, placeholder = "YOUR_EXA_API_KEY", envVarName) {
1269
- const config = deepClone(baseConfig);
1270
- applyPlatformCommand(config);
1271
- if (!apiKey) {
1272
- return config;
1273
- }
1274
- if (envVarName && config.env) {
1275
- config.env[envVarName] = apiKey;
1276
- return config;
1277
- }
1278
- if (config.args) {
1279
- config.args = config.args.map((arg) => arg.replace(placeholder, apiKey));
1280
- }
1281
- if (config.url) {
1282
- config.url = config.url.replace(placeholder, apiKey);
1283
- }
1284
- return config;
1285
- }
1286
- function fixWindowsMcpConfig(config) {
1287
- if (!isWindows() || !config.mcpServers) {
1288
- return config;
1289
- }
1290
- const fixed = { ...config };
1291
- for (const [, serverConfig] of Object.entries(fixed.mcpServers)) {
1292
- if (serverConfig && typeof serverConfig === "object" && "command" in serverConfig) {
1293
- applyPlatformCommand(serverConfig);
1294
- }
1295
- }
1296
- return fixed;
1297
- }
1298
- function addCompletedOnboarding() {
1299
- try {
1300
- let config = readMcpConfig();
1301
- if (!config) {
1302
- config = { mcpServers: {} };
1303
- }
1304
- if (config.hasCompletedOnboarding === true) {
1305
- return;
1306
- }
1307
- config.hasCompletedOnboarding = true;
1308
- writeMcpConfig(config);
1309
- } catch (error) {
1310
- console.error("Failed to add onboarding flag", error);
1311
- throw error;
1312
- }
1313
- }
1314
- function ensureApiKeyApproved(config, apiKey) {
1315
- if (!apiKey || typeof apiKey !== "string" || apiKey.trim() === "") {
1316
- return config;
1317
- }
1318
- const truncatedApiKey = apiKey.substring(0, 20);
1319
- const updatedConfig = { ...config };
1320
- if (!updatedConfig.customApiKeyResponses) {
1321
- updatedConfig.customApiKeyResponses = {
1322
- approved: [],
1323
- rejected: []
1324
- };
1325
- }
1326
- if (!Array.isArray(updatedConfig.customApiKeyResponses.approved)) {
1327
- updatedConfig.customApiKeyResponses.approved = [];
1328
- }
1329
- if (!Array.isArray(updatedConfig.customApiKeyResponses.rejected)) {
1330
- updatedConfig.customApiKeyResponses.rejected = [];
1331
- }
1332
- const rejectedIndex = updatedConfig.customApiKeyResponses.rejected.indexOf(truncatedApiKey);
1333
- if (rejectedIndex > -1) {
1334
- updatedConfig.customApiKeyResponses.rejected.splice(rejectedIndex, 1);
1335
- }
1336
- if (!updatedConfig.customApiKeyResponses.approved.includes(truncatedApiKey)) {
1337
- updatedConfig.customApiKeyResponses.approved.push(truncatedApiKey);
1338
- }
1339
- return updatedConfig;
1340
- }
1341
- function removeApiKeyFromRejected(config, apiKey) {
1342
- if (!config.customApiKeyResponses || !Array.isArray(config.customApiKeyResponses.rejected)) {
1343
- return config;
1344
- }
1345
- const truncatedApiKey = apiKey.substring(0, 20);
1346
- const updatedConfig = { ...config };
1347
- if (updatedConfig.customApiKeyResponses) {
1348
- const rejectedIndex = updatedConfig.customApiKeyResponses.rejected.indexOf(truncatedApiKey);
1349
- if (rejectedIndex > -1) {
1350
- updatedConfig.customApiKeyResponses.rejected.splice(rejectedIndex, 1);
1351
- }
1352
- }
1353
- return updatedConfig;
1354
- }
1355
- function manageApiKeyApproval(apiKey) {
1356
- try {
1357
- let config = readMcpConfig();
1358
- if (!config) {
1359
- config = { mcpServers: {} };
1360
- }
1361
- const updatedConfig = ensureApiKeyApproved(config, apiKey);
1362
- writeMcpConfig(updatedConfig);
1363
- } catch (error) {
1364
- ensureI18nInitialized();
1365
- console.error(i18n.t("mcp:apiKeyApprovalFailed"), error);
1366
- }
1367
- }
1368
- function setPrimaryApiKey() {
1369
- try {
1370
- let config = readJsonConfig(CLAUDE_VSC_CONFIG_FILE);
1371
- if (!config) {
1372
- config = {};
1373
- }
1374
- config.primaryApiKey = "ccjk";
1375
- writeJsonConfig(CLAUDE_VSC_CONFIG_FILE, config);
1376
- } catch (error) {
1377
- ensureI18nInitialized();
1378
- console.error(i18n.t("mcp:primaryApiKeySetFailed"), error);
1379
- }
1380
- }
1381
-
1382
- const claudeConfig = {
1383
- __proto__: null,
1384
- addCompletedOnboarding: addCompletedOnboarding,
1385
- backupMcpConfig: backupMcpConfig,
1386
- buildMcpServerConfig: buildMcpServerConfig,
1387
- ensureApiKeyApproved: ensureApiKeyApproved,
1388
- fixWindowsMcpConfig: fixWindowsMcpConfig,
1389
- getMcpConfigPath: getMcpConfigPath,
1390
- manageApiKeyApproval: manageApiKeyApproval,
1391
- mergeMcpServers: mergeMcpServers,
1392
- readMcpConfig: readMcpConfig,
1393
- removeApiKeyFromRejected: removeApiKeyFromRejected,
1394
- setPrimaryApiKey: setPrimaryApiKey,
1395
- writeMcpConfig: writeMcpConfig
1396
- };
1397
-
1398
- const MODEL_ENV_KEYS = [
1399
- "ANTHROPIC_MODEL",
1400
- "ANTHROPIC_DEFAULT_HAIKU_MODEL",
1401
- "ANTHROPIC_DEFAULT_SONNET_MODEL",
1402
- "ANTHROPIC_DEFAULT_OPUS_MODEL",
1403
- // Deprecated but still cleaned to avoid stale values
1404
- "ANTHROPIC_SMALL_FAST_MODEL"
1405
- ];
1406
- function clearModelEnv(env) {
1407
- for (const key of MODEL_ENV_KEYS) {
1408
- delete env[key];
1409
- }
1410
- }
1411
-
1412
1181
  let initialized = false;
1413
1182
  function ensureTomlInitSync() {
1414
1183
  if (!initialized) {
@@ -1821,6 +1590,347 @@ const ccjkConfig = {
1821
1590
  writeTomlConfig: writeTomlConfig
1822
1591
  };
1823
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
+
1824
1934
  function cleanupPermissions(templatePermissions, userPermissions) {
1825
1935
  const templateSet = new Set(templatePermissions);
1826
1936
  const cleanedPermissions = userPermissions.filter((permission) => {
@@ -1851,37 +1961,34 @@ function mergeAndCleanPermissions(templatePermissions, userPermissions) {
1851
1961
  return cleanupPermissions(template, user);
1852
1962
  }
1853
1963
 
1854
- function activeSettingsFile() {
1855
- const tool = readCcjkConfig()?.codeToolType ?? "clavue";
1856
- return settingsFileForTool(tool === "codex" ? "claude-code" : tool);
1857
- }
1858
- function ensureClaudeDir() {
1859
- ensureDir(CLAUDE_DIR);
1964
+ function ensureClaudeDir(codeTool) {
1965
+ ensureDir(resolveClaudeFamilySettingsTarget(codeTool).configDir);
1860
1966
  }
1861
- function backupExistingConfig() {
1862
- if (!exists(CLAUDE_DIR)) {
1967
+ function backupExistingConfig(codeTool) {
1968
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
1969
+ if (!exists(target.configDir)) {
1863
1970
  return null;
1864
1971
  }
1865
1972
  const timestamp = dayjs().format("YYYY-MM-DD_HH-mm-ss");
1866
- const backupBaseDir = join(CLAUDE_DIR, "backup");
1973
+ const backupBaseDir = join(target.configDir, target.runtimeBackupDirName);
1867
1974
  const backupDir = join(backupBaseDir, `backup_${timestamp}`);
1868
1975
  ensureDir(backupDir);
1869
1976
  const filter = (path) => {
1870
- return !path.includes("/backup");
1977
+ return !path.includes("/backup") && !path.includes("/backups");
1871
1978
  };
1872
- copyDir(CLAUDE_DIR, backupDir, { filter });
1979
+ copyDir(target.configDir, backupDir, { filter });
1873
1980
  return backupDir;
1874
1981
  }
1875
- function copyConfigFiles(onlyMd = false) {
1982
+ function copyConfigFiles(onlyMd = false, codeTool) {
1983
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
1876
1984
  const currentFilePath = fileURLToPath(import.meta.url);
1877
1985
  const distDir = dirname(dirname(currentFilePath));
1878
1986
  const rootDir = dirname(distDir);
1879
1987
  const baseTemplateDir = join(rootDir, "templates", "claude-code");
1880
1988
  if (!onlyMd) {
1881
1989
  const baseSettingsPath = join(baseTemplateDir, "common", "settings.json");
1882
- const destSettingsPath = join(CLAUDE_DIR, "settings.json");
1883
1990
  if (exists(baseSettingsPath)) {
1884
- mergeSettingsFile(baseSettingsPath, destSettingsPath);
1991
+ mergeSettingsFile(baseSettingsPath, target.settingsFile, target.codeTool);
1885
1992
  }
1886
1993
  }
1887
1994
  }
@@ -1897,11 +2004,12 @@ function getDefaultSettings() {
1897
2004
  return {};
1898
2005
  }
1899
2006
  }
1900
- function configureApi(apiConfig) {
2007
+ function configureApi(apiConfig, codeTool) {
1901
2008
  if (!apiConfig)
1902
2009
  return null;
2010
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
1903
2011
  let settings = getDefaultSettings();
1904
- const existingSettings = readJsonConfig(activeSettingsFile());
2012
+ const existingSettings = readJsonConfig(target.settingsFile);
1905
2013
  if (existingSettings) {
1906
2014
  settings = deepMerge(settings, existingSettings);
1907
2015
  }
@@ -1918,17 +2026,18 @@ function configureApi(apiConfig) {
1918
2026
  if (apiConfig.url) {
1919
2027
  settings.env.ANTHROPIC_BASE_URL = apiConfig.url;
1920
2028
  }
1921
- writeJsonConfig(activeSettingsFile(), settings);
2029
+ normalizeClaudeFamilySettings(settings, { codeTool: target.codeTool });
2030
+ writeJsonConfig(target.settingsFile, settings);
1922
2031
  if (apiConfig.authType) {
1923
2032
  try {
1924
- setPrimaryApiKey();
2033
+ setPrimaryApiKey(target.codeTool);
1925
2034
  } catch (error) {
1926
2035
  ensureI18nInitialized();
1927
2036
  console.error(i18n.t("mcp:primaryApiKeySetFailed"), error);
1928
2037
  }
1929
2038
  }
1930
2039
  try {
1931
- addCompletedOnboarding();
2040
+ addCompletedOnboarding(target.codeTool);
1932
2041
  } catch (error) {
1933
2042
  console.error("Failed to set onboarding flag", error);
1934
2043
  }
@@ -1942,12 +2051,13 @@ function mergeConfigs(sourceFile, targetFile) {
1942
2051
  const merged = deepMerge(target, source);
1943
2052
  writeJsonConfig(targetFile, merged);
1944
2053
  }
1945
- function updateCustomModel(primaryModel, haikuModel, sonnetModel, opusModel) {
2054
+ function updateCustomModel(primaryModel, haikuModel, sonnetModel, opusModel, codeTool) {
2055
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
1946
2056
  if (!primaryModel?.trim() && !haikuModel?.trim() && !sonnetModel?.trim() && !opusModel?.trim()) {
1947
2057
  return;
1948
2058
  }
1949
2059
  let settings = getDefaultSettings();
1950
- const existingSettings = readJsonConfig(activeSettingsFile());
2060
+ const existingSettings = readJsonConfig(target.settingsFile);
1951
2061
  if (existingSettings) {
1952
2062
  settings = existingSettings;
1953
2063
  }
@@ -1963,11 +2073,13 @@ function updateCustomModel(primaryModel, haikuModel, sonnetModel, opusModel) {
1963
2073
  settings.env.ANTHROPIC_DEFAULT_SONNET_MODEL = sonnetModel.trim();
1964
2074
  if (opusModel?.trim())
1965
2075
  settings.env.ANTHROPIC_DEFAULT_OPUS_MODEL = opusModel.trim();
1966
- writeJsonConfig(activeSettingsFile(), settings);
2076
+ normalizeClaudeFamilySettings(settings, { codeTool: target.codeTool });
2077
+ writeJsonConfig(target.settingsFile, settings);
1967
2078
  }
1968
- function updateDefaultModel(model) {
2079
+ function updateDefaultModel(model, codeTool) {
2080
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
1969
2081
  let settings = getDefaultSettings();
1970
- const existingSettings = readJsonConfig(activeSettingsFile());
2082
+ const existingSettings = readJsonConfig(target.settingsFile);
1971
2083
  if (existingSettings) {
1972
2084
  settings = existingSettings;
1973
2085
  }
@@ -1982,9 +2094,10 @@ function updateDefaultModel(model) {
1982
2094
  } else {
1983
2095
  settings.model = model;
1984
2096
  }
1985
- writeJsonConfig(activeSettingsFile(), settings);
2097
+ normalizeClaudeFamilySettings(settings, { codeTool: target.codeTool });
2098
+ writeJsonConfig(target.settingsFile, settings);
1986
2099
  }
1987
- function mergeSettingsFile(templatePath, targetPath) {
2100
+ function mergeSettingsFile(templatePath, targetPath, codeTool) {
1988
2101
  try {
1989
2102
  const templateSettings = readJsonConfig(templatePath);
1990
2103
  if (!templateSettings) {
@@ -2013,6 +2126,7 @@ function mergeSettingsFile(templatePath, targetPath) {
2013
2126
  existingSettings.permissions?.allow
2014
2127
  );
2015
2128
  }
2129
+ normalizeClaudeFamilySettings(mergedSettings, { codeTool });
2016
2130
  writeJsonConfig(targetPath, mergedSettings);
2017
2131
  } catch (error) {
2018
2132
  console.error("Failed to merge settings", error);
@@ -2023,8 +2137,8 @@ function mergeSettingsFile(templatePath, targetPath) {
2023
2137
  }
2024
2138
  }
2025
2139
  }
2026
- function getExistingModelConfig() {
2027
- const settings = readJsonConfig(activeSettingsFile());
2140
+ function getExistingModelConfig(codeTool) {
2141
+ const settings = readJsonConfig(activeSettingsFile(codeTool));
2028
2142
  if (!settings) {
2029
2143
  return null;
2030
2144
  }
@@ -2041,8 +2155,8 @@ function getExistingModelConfig() {
2041
2155
  }
2042
2156
  return "default";
2043
2157
  }
2044
- function getExistingApiConfig() {
2045
- const settings = readJsonConfig(activeSettingsFile());
2158
+ function getExistingApiConfig(codeTool) {
2159
+ const settings = readJsonConfig(activeSettingsFile(codeTool));
2046
2160
  if (!settings || !settings.env) {
2047
2161
  return null;
2048
2162
  }
@@ -2065,8 +2179,9 @@ function getExistingApiConfig() {
2065
2179
  authType
2066
2180
  };
2067
2181
  }
2068
- function applyAiLanguageDirective(aiOutputLang) {
2069
- const claudeFile = join(CLAUDE_DIR, "CLAUDE.md");
2182
+ function applyAiLanguageDirective(aiOutputLang, codeTool) {
2183
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
2184
+ const instructionsFile = target.instructionsFile;
2070
2185
  let directive = "";
2071
2186
  if (aiOutputLang === "custom") {
2072
2187
  return;
@@ -2075,22 +2190,27 @@ function applyAiLanguageDirective(aiOutputLang) {
2075
2190
  } else {
2076
2191
  directive = `Always respond in ${aiOutputLang}`;
2077
2192
  }
2078
- writeFile(claudeFile, directive);
2193
+ ensureDir(target.configDir);
2194
+ writeFile(instructionsFile, directive);
2079
2195
  }
2080
- function switchToOfficialLogin$1() {
2196
+ function switchToOfficialLogin$1(codeTool) {
2081
2197
  try {
2082
2198
  ensureI18nInitialized();
2083
- const settings = readJsonConfig(activeSettingsFile()) || {};
2199
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
2200
+ const settings = readJsonConfig(target.settingsFile) || {};
2084
2201
  if (settings.env) {
2085
2202
  delete settings.env.ANTHROPIC_BASE_URL;
2086
2203
  delete settings.env.ANTHROPIC_AUTH_TOKEN;
2087
2204
  delete settings.env.ANTHROPIC_API_KEY;
2088
2205
  }
2089
- writeJsonConfig(activeSettingsFile(), settings);
2090
- const vscConfig = readJsonConfig(CLAUDE_VSC_CONFIG_FILE);
2091
- if (vscConfig) {
2092
- delete vscConfig.primaryApiKey;
2093
- 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
+ }
2094
2214
  }
2095
2215
  console.log(i18n.t("api:officialLoginConfigured"));
2096
2216
  return true;
@@ -2136,6 +2256,7 @@ ${ansis.blue(`\u2139 ${i18n.t("api:existingApiConfig")}`)}`);
2136
2256
 
2137
2257
  const config$1 = {
2138
2258
  __proto__: null,
2259
+ activeSettingsFile: activeSettingsFile,
2139
2260
  applyAiLanguageDirective: applyAiLanguageDirective,
2140
2261
  backupExistingConfig: backupExistingConfig,
2141
2262
  configureApi: configureApi,
@@ -5507,10 +5628,12 @@ const codex = {
5507
5628
  writeAuthFile: writeAuthFile
5508
5629
  };
5509
5630
 
5631
+ const STARTUP_CODE_TOOL_CHOICES = CODE_TOOL_TYPES;
5510
5632
  const CODE_TYPE_ABBREVIATIONS = {
5511
5633
  cv: "clavue",
5512
5634
  cc: "claude-code",
5513
- cx: "codex"
5635
+ cx: "codex",
5636
+ gk: "grok"
5514
5637
  };
5515
5638
  async function resolveCodeType(codeTypeParam) {
5516
5639
  if (codeTypeParam) {
@@ -5546,7 +5669,7 @@ async function resolveCodeType(codeTypeParam) {
5546
5669
  return DEFAULT_CODE_TOOL_TYPE;
5547
5670
  }
5548
5671
  function isValidCodeType(value) {
5549
- return ["clavue", "claude-code", "codex"].includes(value);
5672
+ return CODE_TOOL_TYPES.includes(value);
5550
5673
  }
5551
5674
 
5552
5675
  function getPlatformStatusLineConfig() {
@@ -5702,8 +5825,9 @@ const LEGACY_FILES = ["personality.md", "rules.md", "technical-guides.md", "mcp.
5702
5825
  function getAvailableOutputStyles() {
5703
5826
  return OUTPUT_STYLES;
5704
5827
  }
5705
- async function copyOutputStyles(selectedStyles, lang) {
5706
- 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");
5707
5831
  ensureDir(outputStylesDir);
5708
5832
  const currentFilePath = fileURLToPath(import.meta.url);
5709
5833
  const distDir = dirname(dirname(currentFilePath));
@@ -5721,32 +5845,39 @@ async function copyOutputStyles(selectedStyles, lang) {
5721
5845
  }
5722
5846
  }
5723
5847
  }
5724
- function setGlobalDefaultOutputStyle(styleId) {
5725
- const existingSettings = readJsonConfig(SETTINGS_FILE) || {};
5848
+ function setGlobalDefaultOutputStyle(styleId, codeTool) {
5849
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
5850
+ const existingSettings = readJsonConfig(target.settingsFile) || {};
5726
5851
  const updatedSettings = {
5727
5852
  ...existingSettings,
5728
5853
  outputStyle: styleId
5729
5854
  };
5730
- writeJsonConfig(SETTINGS_FILE, updatedSettings);
5855
+ normalizeClaudeFamilySettings(updatedSettings, { codeTool: target.codeTool });
5856
+ writeJsonConfig(target.settingsFile, updatedSettings);
5731
5857
  }
5732
- function clearGlobalOutputStyle() {
5733
- const existingSettings = readJsonConfig(SETTINGS_FILE) || {};
5858
+ function clearGlobalOutputStyle(codeTool) {
5859
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
5860
+ const existingSettings = readJsonConfig(target.settingsFile) || {};
5734
5861
  const { outputStyle: _, ...rest } = existingSettings;
5735
- writeJsonConfig(SETTINGS_FILE, rest);
5862
+ normalizeClaudeFamilySettings(rest, { codeTool: target.codeTool });
5863
+ writeJsonConfig(target.settingsFile, rest);
5736
5864
  }
5737
- function hasLegacyPersonalityFiles() {
5738
- 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)));
5739
5868
  }
5740
- function cleanupLegacyPersonalityFiles() {
5869
+ function cleanupLegacyPersonalityFiles(codeTool) {
5870
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
5741
5871
  LEGACY_FILES.forEach((filename) => {
5742
- const filePath = join(CLAUDE_DIR, filename);
5872
+ const filePath = join(target.configDir, filename);
5743
5873
  if (exists(filePath)) {
5744
5874
  removeFile(filePath);
5745
5875
  }
5746
5876
  });
5747
5877
  }
5748
- async function configureOutputStyle(preselectedStyles, preselectedDefault) {
5878
+ async function configureOutputStyle(preselectedStyles, preselectedDefault, codeTool) {
5749
5879
  ensureI18nInitialized();
5880
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
5750
5881
  const outputStyleList = [
5751
5882
  {
5752
5883
  id: "default",
@@ -5795,18 +5926,18 @@ async function configureOutputStyle(preselectedStyles, preselectedDefault) {
5795
5926
  }
5796
5927
  ];
5797
5928
  const availableStyles = getAvailableOutputStyles();
5798
- if (hasLegacyPersonalityFiles() && !preselectedStyles) {
5929
+ if (hasLegacyPersonalityFiles(target.codeTool) && !preselectedStyles) {
5799
5930
  console.log(ansis.yellow(`\u26A0\uFE0F ${i18n.t("configuration:legacyFilesDetected")}`));
5800
5931
  const cleanupLegacy = await promptBoolean({
5801
5932
  message: i18n.t("configuration:cleanupLegacyFiles"),
5802
5933
  defaultValue: true
5803
5934
  });
5804
5935
  if (cleanupLegacy) {
5805
- cleanupLegacyPersonalityFiles();
5936
+ cleanupLegacyPersonalityFiles(target.codeTool);
5806
5937
  console.log(ansis.green(`\u2714 ${i18n.t("configuration:legacyFilesRemoved")}`));
5807
5938
  }
5808
- } else if (hasLegacyPersonalityFiles() && preselectedStyles) {
5809
- cleanupLegacyPersonalityFiles();
5939
+ } else if (hasLegacyPersonalityFiles(target.codeTool) && preselectedStyles) {
5940
+ cleanupLegacyPersonalityFiles(target.codeTool);
5810
5941
  }
5811
5942
  let selectedStyles;
5812
5943
  let defaultStyle;
@@ -5862,7 +5993,7 @@ async function configureOutputStyle(preselectedStyles, preselectedDefault) {
5862
5993
  return;
5863
5994
  }
5864
5995
  if (promptedDefault2 === "__none__") {
5865
- clearGlobalOutputStyle();
5996
+ clearGlobalOutputStyle(target.codeTool);
5866
5997
  updateCcjkConfig({
5867
5998
  outputStyles: [],
5868
5999
  defaultOutputStyle: "none"
@@ -5871,7 +6002,7 @@ async function configureOutputStyle(preselectedStyles, preselectedDefault) {
5871
6002
  return;
5872
6003
  }
5873
6004
  defaultStyle = promptedDefault2;
5874
- setGlobalDefaultOutputStyle(defaultStyle);
6005
+ setGlobalDefaultOutputStyle(defaultStyle, target.codeTool);
5875
6006
  updateCcjkConfig({
5876
6007
  outputStyles: [],
5877
6008
  defaultOutputStyle: defaultStyle
@@ -5912,8 +6043,8 @@ async function configureOutputStyle(preselectedStyles, preselectedDefault) {
5912
6043
  }
5913
6044
  defaultStyle = promptedDefault;
5914
6045
  }
5915
- await copyOutputStyles(selectedStyles, "zh-CN");
5916
- setGlobalDefaultOutputStyle(defaultStyle);
6046
+ await copyOutputStyles(selectedStyles, "zh-CN", target.codeTool);
6047
+ setGlobalDefaultOutputStyle(defaultStyle, target.codeTool);
5917
6048
  updateCcjkConfig({
5918
6049
  outputStyles: selectedStyles,
5919
6050
  defaultOutputStyle: defaultStyle
@@ -6125,17 +6256,20 @@ async function modifyApiConfigPartially(existingConfig) {
6125
6256
  }
6126
6257
  async function updatePromptOnly(aiOutputLang) {
6127
6258
  ensureI18nInitialized();
6128
- 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);
6129
6263
  if (backupDir) {
6130
6264
  console.log(ansis.gray(`\u2714 ${i18n.t("configuration:backupSuccess")}: ${backupDir}`));
6131
6265
  }
6132
6266
  if (aiOutputLang) {
6133
- applyAiLanguageDirective(aiOutputLang);
6267
+ applyAiLanguageDirective(aiOutputLang, settingsTool);
6134
6268
  }
6135
- await configureOutputStyle();
6136
- 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}`));
6137
6271
  console.log(`
6138
- ${ansis.cyan(i18n.t("common:complete"))}`);
6272
+ ${ansis.cyan(i18n.t("common:complete", { runtime: target.runtimeCommand }))}`);
6139
6273
  }
6140
6274
 
6141
6275
  function handleExitPromptError(error) {
@@ -6917,8 +7051,9 @@ function getRootDir() {
6917
7051
  }
6918
7052
  const DEFAULT_CODE_TOOL_TEMPLATE = "claude-code";
6919
7053
  const COMMON_TEMPLATE_CATEGORIES = ["git", "sixStep"];
6920
- async function selectAndInstallWorkflows(configLang, preselectedWorkflows) {
7054
+ async function selectAndInstallWorkflows(configLang, preselectedWorkflows, options = {}) {
6921
7055
  ensureI18nInitialized();
7056
+ const target = resolveClaudeFamilySettingsTarget(options.codeToolType);
6922
7057
  const workflows = getOrderedWorkflows();
6923
7058
  const choices = workflows.map((workflow) => {
6924
7059
  return {
@@ -6943,15 +7078,15 @@ async function selectAndInstallWorkflows(configLang, preselectedWorkflows) {
6943
7078
  console.log(ansis.yellow(i18n.t("common:cancelled")));
6944
7079
  return;
6945
7080
  }
6946
- await cleanupOldVersionFiles();
7081
+ await cleanupOldVersionFiles(target);
6947
7082
  for (const workflowId of selectedWorkflows) {
6948
7083
  const config = getWorkflowConfig(workflowId);
6949
7084
  if (config) {
6950
- await installWorkflowWithDependencies(config, configLang);
7085
+ await installWorkflowWithDependencies(config, configLang, target);
6951
7086
  }
6952
7087
  }
6953
7088
  }
6954
- async function installWorkflowWithDependencies(config, configLang) {
7089
+ async function installWorkflowWithDependencies(config, configLang, target) {
6955
7090
  const rootDir = getRootDir();
6956
7091
  ensureI18nInitialized();
6957
7092
  const result = {
@@ -6971,7 +7106,7 @@ async function installWorkflowWithDependencies(config, configLang) {
6971
7106
  const workflowName = WORKFLOW_OPTION_KEYS[config.id] || config.id;
6972
7107
  console.log(ansis.cyan(`
6973
7108
  \u{1F4E6} ${i18n.t("workflow:installingWorkflow")}: ${workflowName}...`));
6974
- const commandsDir = join(CLAUDE_DIR, "commands", "ccjk");
7109
+ const commandsDir = join(target.configDir, "commands", "ccjk");
6975
7110
  if (!existsSync(commandsDir)) {
6976
7111
  await mkdir(commandsDir, { recursive: true });
6977
7112
  }
@@ -7011,7 +7146,7 @@ async function installWorkflowWithDependencies(config, configLang) {
7011
7146
  }
7012
7147
  }
7013
7148
  if (config.autoInstallAgents && config.agents.length > 0) {
7014
- const agentsCategoryDir = join(CLAUDE_DIR, "agents", "ccjk", config.category);
7149
+ const agentsCategoryDir = join(target.configDir, "agents", "ccjk", config.category);
7015
7150
  if (!existsSync(agentsCategoryDir)) {
7016
7151
  await mkdir(agentsCategoryDir, { recursive: true });
7017
7152
  }
@@ -7054,25 +7189,25 @@ ${i18n.t("workflow:bmadInitPrompt")}`));
7054
7189
  }
7055
7190
  return result;
7056
7191
  }
7057
- async function cleanupOldVersionFiles() {
7192
+ async function cleanupOldVersionFiles(target) {
7058
7193
  ensureI18nInitialized();
7059
7194
  console.log(ansis.cyan(`
7060
7195
  \u{1F9F9} ${i18n.t("workflow:cleaningOldFiles")}...`));
7061
7196
  const oldCommandFiles = [
7062
- join(CLAUDE_DIR, "commands", "workflow.md"),
7063
- join(CLAUDE_DIR, "commands", "feat.md")
7197
+ join(target.configDir, "commands", "workflow.md"),
7198
+ join(target.configDir, "commands", "feat.md")
7064
7199
  ];
7065
7200
  const oldAgentFiles = [
7066
- join(CLAUDE_DIR, "agents", "planner.md"),
7067
- join(CLAUDE_DIR, "agents", "ui-ux-designer.md")
7201
+ join(target.configDir, "agents", "planner.md"),
7202
+ join(target.configDir, "agents", "ui-ux-designer.md")
7068
7203
  ];
7069
7204
  for (const file of oldCommandFiles) {
7070
7205
  if (existsSync(file)) {
7071
7206
  try {
7072
7207
  await rm(file, { force: true });
7073
- 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)}`));
7074
7209
  } catch {
7075
- 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)}`));
7076
7211
  }
7077
7212
  }
7078
7213
  }
@@ -7080,9 +7215,9 @@ async function cleanupOldVersionFiles() {
7080
7215
  if (existsSync(file)) {
7081
7216
  try {
7082
7217
  await rm(file, { force: true });
7083
- 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)}`));
7084
7219
  } catch {
7085
- 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)}`));
7086
7221
  }
7087
7222
  }
7088
7223
  }
@@ -7245,6 +7380,8 @@ async function init(options = {}) {
7245
7380
  const targetSettingsFile = settingsFileForTool(
7246
7381
  codeToolType === "codex" ? "claude-code" : codeToolType
7247
7382
  );
7383
+ const runtimeTarget = isClaudeFamilyCodeTool(codeToolType) ? resolveClaudeFamilySettingsTarget(codeToolType) : null;
7384
+ const claudeFamilyTool = codeToolType === "clavue" ? "clavue" : "claude-code";
7248
7385
  async function selectApiConfigurationMode() {
7249
7386
  const { apiMode } = await inquirer.prompt({
7250
7387
  type: "list",
@@ -7327,6 +7464,14 @@ async function init(options = {}) {
7327
7464
  if (!options.skipBanner) {
7328
7465
  displayBannerWithInfo(CODE_TOOL_BANNERS[codeToolType] || "CCJK");
7329
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
+ }
7330
7475
  if (isTermux()) {
7331
7476
  console.log(ansis.yellow(`
7332
7477
  \u2139 ${i18n.t("installation:termuxDetected")}`));
@@ -7397,56 +7542,81 @@ async function init(options = {}) {
7397
7542
  return;
7398
7543
  }
7399
7544
  const aiOutputLang = await resolveAiOutputLanguage(i18n.language, options.aiOutputLang, ccjkConfig, options.skipPrompt);
7400
- const installationStatus = await getInstallationStatus();
7401
- if (installationStatus.hasGlobal || installationStatus.hasLocal) {
7402
- if (!options.skipPrompt) {
7403
- await handleMultipleInstallations(installationStatus);
7404
- } else {
7405
- if (installationStatus.hasLocal) {
7406
- if (!installationStatus.hasGlobal) {
7407
- console.log(ansis.blue(`${i18n.t("installation:installingGlobalClaudeCode")}...`));
7408
- await installClaudeCode(true);
7409
- console.log(ansis.green(`\u2714 ${i18n.t("installation:globalInstallationCompleted")}`));
7410
- }
7411
- if (installationStatus.hasGlobal && installationStatus.hasLocal) {
7412
- 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")));
7413
7562
  }
7414
- console.log(ansis.blue(`${i18n.t("installation:removingLocalInstallation")}...`));
7415
- const { removeLocalClaudeCode } = await Promise.resolve().then(function () { return installer; });
7416
- await removeLocalClaudeCode();
7417
- console.log(ansis.green(`\u2714 ${i18n.t("installation:localInstallationRemoved")}`));
7418
7563
  }
7419
7564
  }
7420
- const { verifyInstallation, displayVerificationResult } = await Promise.resolve().then(function () { return installer; });
7421
- const verification = await verifyInstallation("claude-code");
7422
- if (verification.symlinkCreated) {
7423
- console.log(ansis.green(`\u2714 ${i18n.t("installation:alreadyInstalled")}`));
7424
- displayVerificationResult(verification, "claude-code");
7425
- } else if (!verification.success) {
7426
- console.log(ansis.yellow(`\u26A0 ${i18n.t("installation:verificationFailed")}`));
7427
- if (verification.error) {
7428
- 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
+ }
7429
7596
  }
7430
- }
7431
- } else {
7432
- if (options.skipPrompt) {
7433
- await installClaudeCode(true);
7434
7597
  } else {
7435
- const shouldInstall = await promptBoolean({
7436
- message: i18n.t("installation:installPrompt"),
7437
- defaultValue: true
7438
- });
7439
- if (shouldInstall) {
7440
- await installClaudeCode(false);
7598
+ if (options.skipPrompt) {
7599
+ await installClaudeCode(true);
7441
7600
  } else {
7442
- 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
+ }
7443
7610
  }
7444
7611
  }
7612
+ if (installationStatus.hasGlobal || installationStatus.hasLocal) {
7613
+ await checkClaudeCodeVersionAndPrompt(options.skipPrompt);
7614
+ }
7445
7615
  }
7446
- if (installationStatus.hasGlobal || installationStatus.hasLocal) {
7447
- await checkClaudeCodeVersionAndPrompt(options.skipPrompt);
7616
+ if (!runtimeTarget) {
7617
+ return;
7448
7618
  }
7449
- ensureClaudeDir();
7619
+ ensureClaudeDir(codeToolType);
7450
7620
  let action = "new";
7451
7621
  if (existsSync(targetSettingsFile) && !options.force) {
7452
7622
  if (options.skipPrompt) {
@@ -7584,43 +7754,44 @@ async function init(options = {}) {
7584
7754
  }
7585
7755
  }
7586
7756
  if (["backup", "docs-only", "merge"].includes(action)) {
7587
- const backupDir = backupExistingConfig();
7757
+ const backupDir = backupExistingConfig(codeToolType);
7588
7758
  if (backupDir) {
7589
7759
  console.log(ansis.gray(`\u2714 ${i18n.t("configuration:backupSuccess")}: ${backupDir}`));
7590
7760
  }
7591
7761
  }
7592
7762
  if (action === "docs-only") {
7593
- copyConfigFiles(true);
7763
+ copyConfigFiles(true, codeToolType);
7594
7764
  if (options.skipPrompt) {
7595
7765
  if (options.workflows !== false) {
7596
- await selectAndInstallWorkflows(configLang, options.workflows);
7766
+ await selectAndInstallWorkflows(configLang, options.workflows, { codeToolType });
7597
7767
  }
7598
7768
  } else {
7599
- await selectAndInstallWorkflows(configLang);
7769
+ await selectAndInstallWorkflows(configLang, void 0, { codeToolType });
7600
7770
  }
7601
7771
  } else if (["backup", "merge", "new"].includes(action)) {
7602
- copyConfigFiles(false);
7772
+ copyConfigFiles(false, codeToolType);
7603
7773
  if (options.skipPrompt) {
7604
7774
  if (options.workflows !== false) {
7605
- await selectAndInstallWorkflows(configLang, options.workflows);
7775
+ await selectAndInstallWorkflows(configLang, options.workflows, { codeToolType });
7606
7776
  }
7607
7777
  } else {
7608
- await selectAndInstallWorkflows(configLang);
7778
+ await selectAndInstallWorkflows(configLang, void 0, { codeToolType });
7609
7779
  }
7610
7780
  }
7611
- applyAiLanguageDirective(aiOutputLang);
7781
+ applyAiLanguageDirective(aiOutputLang, codeToolType);
7612
7782
  if (options.skipPrompt) {
7613
7783
  if (options.outputStyles !== false) {
7614
7784
  await configureOutputStyle(
7615
7785
  options.outputStyles,
7616
- options.defaultOutputStyle
7786
+ options.defaultOutputStyle,
7787
+ codeToolType
7617
7788
  );
7618
7789
  }
7619
7790
  } else {
7620
- await configureOutputStyle();
7791
+ await configureOutputStyle(void 0, void 0, codeToolType);
7621
7792
  }
7622
7793
  if (apiConfig && action !== "docs-only") {
7623
- const configuredApi = configureApi(apiConfig);
7794
+ const configuredApi = configureApi(apiConfig, codeToolType);
7624
7795
  if (configuredApi) {
7625
7796
  console.log(ansis.green(`\u2714 ${i18n.t("api:apiConfigSuccess")}`));
7626
7797
  console.log(ansis.gray(` URL: ${configuredApi.url}`));
@@ -7628,14 +7799,15 @@ async function init(options = {}) {
7628
7799
  }
7629
7800
  }
7630
7801
  const hasModelParams = options.apiModel || options.apiHaikuModel || options.apiSonnetModel || options.apiOpusModel;
7631
- if (hasModelParams && action !== "docs-only" && codeToolType === "claude-code") {
7802
+ if (hasModelParams && action !== "docs-only" && isClaudeFamilyCodeTool(codeToolType)) {
7632
7803
  if (options.skipPrompt) {
7633
7804
  const { updateCustomModel } = await Promise.resolve().then(function () { return config$1; });
7634
7805
  updateCustomModel(
7635
7806
  options.apiModel || void 0,
7636
7807
  options.apiHaikuModel || void 0,
7637
7808
  options.apiSonnetModel || void 0,
7638
- options.apiOpusModel || void 0
7809
+ options.apiOpusModel || void 0,
7810
+ codeToolType
7639
7811
  );
7640
7812
  console.log(ansis.green(`\u2714 ${i18n.t("api:modelConfigSuccess")}`));
7641
7813
  if (options.apiModel) {
@@ -7674,7 +7846,7 @@ async function init(options = {}) {
7674
7846
  }
7675
7847
  }
7676
7848
  if (selectedServices.length > 0) {
7677
- const mcpBackupPath = backupMcpConfig();
7849
+ const mcpBackupPath = backupMcpConfig(claudeFamilyTool);
7678
7850
  if (mcpBackupPath) {
7679
7851
  console.log(ansis.gray(`\u2714 ${i18n.t("mcp:mcpBackupSuccess")}: ${mcpBackupPath}`));
7680
7852
  }
@@ -7715,11 +7887,11 @@ async function init(options = {}) {
7715
7887
  }
7716
7888
  newServers[service.id] = config;
7717
7889
  }
7718
- const existingConfig = readMcpConfig();
7890
+ const existingConfig = readMcpConfig(claudeFamilyTool);
7719
7891
  let mergedConfig = mergeMcpServers(existingConfig, newServers);
7720
7892
  mergedConfig = fixWindowsMcpConfig(mergedConfig);
7721
7893
  try {
7722
- writeMcpConfig(mergedConfig);
7894
+ writeMcpConfig(mergedConfig, claudeFamilyTool);
7723
7895
  console.log(ansis.green(`\u2714 ${i18n.t("mcp:mcpConfigSuccess")}`));
7724
7896
  } catch (error) {
7725
7897
  console.error(ansis.red(`${i18n.t("errors:failedToWriteMcpConfig")} ${error}`));
@@ -7756,9 +7928,9 @@ async function init(options = {}) {
7756
7928
  aiOutputLang,
7757
7929
  codeToolType
7758
7930
  });
7759
- console.log(ansis.green(`\u2714 ${i18n.t("configuration:configSuccess")} ${CLAUDE_DIR}`));
7931
+ console.log(ansis.green(`\u2714 ${i18n.t("configuration:configSuccess")} ${runtimeTarget.configDirDisplay}`));
7760
7932
  console.log(`
7761
- ${ansis.cyan(i18n.t("common:complete"))}`);
7933
+ ${ansis.cyan(i18n.t("common:complete", { runtime: runtimeTarget.runtimeCommand }))}`);
7762
7934
  } catch (error) {
7763
7935
  if (!handleExitPromptError(error)) {
7764
7936
  handleGeneralError(error);
@@ -7787,7 +7959,7 @@ async function handleMultiConfigurations(options, codeToolType) {
7787
7959
  }
7788
7960
  }
7789
7961
  await validateApiConfigs(configs);
7790
- if (codeToolType === "claude-code") {
7962
+ if (codeToolType === "claude-code" || codeToolType === "clavue") {
7791
7963
  await handleClaudeCodeConfigs(configs);
7792
7964
  } else if (codeToolType === "codex") {
7793
7965
  await handleCodexConfigs(configs);
@@ -8024,33 +8196,39 @@ function getTemplateSettings() {
8024
8196
  const content = readFileSync(templatePath, "utf-8");
8025
8197
  return JSON.parse(content);
8026
8198
  }
8027
- function loadCurrentSettings() {
8028
- if (!existsSync(SETTINGS_FILE)) {
8199
+ function loadCurrentSettings(codeTool) {
8200
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
8201
+ if (!existsSync(target.settingsFile)) {
8029
8202
  return {};
8030
8203
  }
8031
8204
  try {
8032
- const content = readFileSync(SETTINGS_FILE, "utf-8");
8205
+ const content = readFileSync(target.settingsFile, "utf-8");
8033
8206
  return JSON.parse(content);
8034
8207
  } catch {
8035
8208
  return {};
8036
8209
  }
8037
8210
  }
8038
- function saveSettings(settings) {
8039
- ensureDir(CLAUDE_DIR);
8040
- 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));
8041
8219
  }
8042
- async function importRecommendedEnv() {
8220
+ async function importRecommendedEnv(codeTool) {
8043
8221
  const templateSettings = getTemplateSettings();
8044
- const currentSettings = loadCurrentSettings();
8222
+ const currentSettings = loadCurrentSettings(codeTool);
8045
8223
  currentSettings.env = {
8046
8224
  ...currentSettings.env,
8047
8225
  ...templateSettings.env
8048
8226
  };
8049
- saveSettings(currentSettings);
8227
+ saveSettings(currentSettings, codeTool);
8050
8228
  }
8051
- async function importRecommendedPermissions() {
8229
+ async function importRecommendedPermissions(codeTool) {
8052
8230
  const templateSettings = getTemplateSettings();
8053
- const currentSettings = loadCurrentSettings();
8231
+ const currentSettings = loadCurrentSettings(codeTool);
8054
8232
  if (templateSettings.permissions && templateSettings.permissions.allow) {
8055
8233
  currentSettings.permissions = {
8056
8234
  ...templateSettings.permissions,
@@ -8062,12 +8240,14 @@ async function importRecommendedPermissions() {
8062
8240
  } else {
8063
8241
  currentSettings.permissions = templateSettings.permissions;
8064
8242
  }
8065
- saveSettings(currentSettings);
8243
+ applyTrustedOperatorPermissions(currentSettings);
8244
+ saveSettings(currentSettings, codeTool);
8066
8245
  }
8067
- async function openSettingsJson() {
8068
- ensureDir(CLAUDE_DIR);
8069
- if (!existsSync(SETTINGS_FILE)) {
8070
- saveSettings({});
8246
+ async function openSettingsJson(codeTool) {
8247
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
8248
+ ensureDir(target.configDir);
8249
+ if (!existsSync(target.settingsFile)) {
8250
+ saveSettings({}, codeTool);
8071
8251
  }
8072
8252
  const platform = getPlatform();
8073
8253
  let command;
@@ -8082,18 +8262,18 @@ async function openSettingsJson() {
8082
8262
  command = "xdg-open";
8083
8263
  }
8084
8264
  try {
8085
- await exec(command, [SETTINGS_FILE]);
8265
+ await exec(command, [target.settingsFile]);
8086
8266
  } catch {
8087
8267
  try {
8088
- await exec("code", [SETTINGS_FILE]);
8268
+ await exec("code", [target.settingsFile]);
8089
8269
  } catch {
8090
8270
  try {
8091
- await exec("vim", [SETTINGS_FILE]);
8271
+ await exec("vim", [target.settingsFile]);
8092
8272
  } catch {
8093
- await exec("nano", [SETTINGS_FILE]);
8273
+ await exec("nano", [target.settingsFile]);
8094
8274
  }
8095
8275
  }
8096
8276
  }
8097
8277
  }
8098
8278
 
8099
- 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 };