aico-cli 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import cac from 'cac';
|
|
3
3
|
import ansis from 'ansis';
|
|
4
|
-
import { J as readAicoConfig, K as updateAicoConfig, N as getTranslation, k as AI_OUTPUT_LANGUAGES, O as inquirer, P as addNumbersToChoices, Q as version, q as backupExistingConfig, r as copyConfigFiles, x as applyAiLanguageDirective, R as configureAiPersonality, C as CLAUDE_DIR, I as I18N, T as isWindows, U as readCcrConfig, V as isCcrInstalled, W as installCcr, X as configureCcrFeature, Y as handleExitPromptError, Z as handleGeneralError, _ as readAicoConfigAsync, $ as COMETIX_COMMANDS, a0 as COMETIX_COMMAND_NAME, a1 as installCometixLine, o as openSettingsJson, b as importRecommendedPermissions, a as importRecommendedEnv, z as readMcpConfig, G as fixWindowsMcpConfig, B as writeMcpConfig, a2 as selectMcpServices, D as backupMcpConfig, M as MCP_SERVICES, F as buildMcpServerConfig, a3 as EscapeKeyPressed, E as mergeMcpServers, a4 as displayBanner, a5 as selectAndInstallWorkflows, a6 as displayBannerWithInfo, i as init, a7 as executeWithEscapeSupport, a8 as checkAndUpdateTools } from './shared/aico-cli.
|
|
4
|
+
import { J as readAicoConfig, K as updateAicoConfig, N as getTranslation, k as AI_OUTPUT_LANGUAGES, O as inquirer, P as addNumbersToChoices, Q as version, q as backupExistingConfig, r as copyConfigFiles, x as applyAiLanguageDirective, R as configureAiPersonality, C as CLAUDE_DIR, I as I18N, T as isWindows, U as readCcrConfig, V as isCcrInstalled, W as installCcr, X as configureCcrFeature, Y as handleExitPromptError, Z as handleGeneralError, _ as readAicoConfigAsync, $ as COMETIX_COMMANDS, a0 as COMETIX_COMMAND_NAME, a1 as installCometixLine, o as openSettingsJson, b as importRecommendedPermissions, a as importRecommendedEnv, z as readMcpConfig, G as fixWindowsMcpConfig, B as writeMcpConfig, a2 as selectMcpServices, D as backupMcpConfig, M as MCP_SERVICES, F as buildMcpServerConfig, a3 as EscapeKeyPressed, E as mergeMcpServers, a4 as displayBanner, a5 as selectAndInstallWorkflows, a6 as displayBannerWithInfo, i as init, a7 as executeWithEscapeSupport, a8 as checkAndUpdateTools } from './shared/aico-cli.CSeKe20G.mjs';
|
|
5
5
|
import inquirer$1 from 'inquirer';
|
|
6
6
|
import { existsSync } from 'node:fs';
|
|
7
7
|
import { x } from 'tinyexec';
|
|
@@ -1125,7 +1125,6 @@ async function handleInitCommand(options) {
|
|
|
1125
1125
|
force: options.force,
|
|
1126
1126
|
skipPrompt: options.skipPrompt,
|
|
1127
1127
|
configAction: options.configAction,
|
|
1128
|
-
apiType: options.apiType,
|
|
1129
1128
|
apiKey: options.apiKey,
|
|
1130
1129
|
apiUrl: options.apiUrl,
|
|
1131
1130
|
mcpServices: options.mcpServices,
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as AICO_CONFIG_FILE, k as AI_OUTPUT_LANGUAGES, C as CLAUDE_DIR, e as CLAUDE_MD_FILE, f as ClAUDE_CONFIG_FILE, I as I18N, j as LANG_LABELS, L as LEGACY_AICO_CONFIG_FILE, M as MCP_SERVICES, S as SETTINGS_FILE, h as SUPPORTED_LANGS, H as addCompletedOnboarding, x as applyAiLanguageDirective, q as backupExistingConfig, D as backupMcpConfig, F as buildMcpServerConfig, d as cleanupPermissions, c as commandExists, s as configureApi, r as copyConfigFiles, p as ensureClaudeDir, G as fixWindowsMcpConfig, w as getExistingApiConfig, y as getMcpConfigPath, g as getPlatform, a as importRecommendedEnv, b as importRecommendedPermissions, i as init, n as installClaudeCode, l as isClaudeCodeInstalled, m as mergeAndCleanPermissions, t as mergeConfigs, E as mergeMcpServers, v as mergeSettingsFile, o as openSettingsJson, z as readMcpConfig, u as updateDefaultModel, B as writeMcpConfig } from './shared/aico-cli.
|
|
1
|
+
export { A as AICO_CONFIG_FILE, k as AI_OUTPUT_LANGUAGES, C as CLAUDE_DIR, e as CLAUDE_MD_FILE, f as ClAUDE_CONFIG_FILE, I as I18N, j as LANG_LABELS, L as LEGACY_AICO_CONFIG_FILE, M as MCP_SERVICES, S as SETTINGS_FILE, h as SUPPORTED_LANGS, H as addCompletedOnboarding, x as applyAiLanguageDirective, q as backupExistingConfig, D as backupMcpConfig, F as buildMcpServerConfig, d as cleanupPermissions, c as commandExists, s as configureApi, r as copyConfigFiles, p as ensureClaudeDir, G as fixWindowsMcpConfig, w as getExistingApiConfig, y as getMcpConfigPath, g as getPlatform, a as importRecommendedEnv, b as importRecommendedPermissions, i as init, n as installClaudeCode, l as isClaudeCodeInstalled, m as mergeAndCleanPermissions, t as mergeConfigs, E as mergeMcpServers, v as mergeSettingsFile, o as openSettingsJson, z as readMcpConfig, u as updateDefaultModel, B as writeMcpConfig } from './shared/aico-cli.CSeKe20G.mjs';
|
|
2
2
|
import 'ansis';
|
|
3
3
|
import 'inquirer';
|
|
4
4
|
import 'node:fs';
|
|
@@ -3,18 +3,18 @@ import inquirer$1 from 'inquirer';
|
|
|
3
3
|
import { existsSync, mkdirSync, copyFileSync, writeFileSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
4
4
|
import { join, dirname } from 'pathe';
|
|
5
5
|
import dayjs from 'dayjs';
|
|
6
|
-
import { exec as exec$
|
|
6
|
+
import { exec as exec$2 } from 'node:child_process';
|
|
7
7
|
import { homedir, platform } from 'node:os';
|
|
8
8
|
import { join as join$1 } from 'node:path';
|
|
9
|
-
import { promisify } from 'node:util';
|
|
9
|
+
import { promisify as promisify$1 } from 'node:util';
|
|
10
10
|
import { fileURLToPath } from 'node:url';
|
|
11
|
-
import { exec as exec$
|
|
12
|
-
import { promisify
|
|
11
|
+
import { exec as exec$1 } from 'child_process';
|
|
12
|
+
import { promisify } from 'util';
|
|
13
13
|
import ora from 'ora';
|
|
14
14
|
import { exec } from 'tinyexec';
|
|
15
15
|
import { rm, mkdir, copyFile as copyFile$1 } from 'node:fs/promises';
|
|
16
16
|
|
|
17
|
-
const version = "0.1.
|
|
17
|
+
const version = "0.1.4";
|
|
18
18
|
|
|
19
19
|
const common$1 = {
|
|
20
20
|
// Basic
|
|
@@ -358,6 +358,14 @@ const ccrMessages$1 = {
|
|
|
358
358
|
ccrInstallSuccess: "Claude Code Router \u5B89\u88C5\u6210\u529F",
|
|
359
359
|
ccrInstallFailed: "\u5B89\u88C5 Claude Code Router \u5931\u8D25",
|
|
360
360
|
ccrAlreadyInstalled: "Claude Code Router \u5DF2\u5B89\u88C5",
|
|
361
|
+
// Additional status messages
|
|
362
|
+
checkingInstallation: "\u6B63\u5728\u68C0\u67E5 CCR \u5B89\u88C5...",
|
|
363
|
+
ccrNotInstalled: "CCR \u672A\u5B89\u88C5",
|
|
364
|
+
ccrInstalledWrongPackage: "CCR \u5DF2\u5B89\u88C5\u4F46\u5305/\u7248\u672C\u4E0D\u5339\u914D",
|
|
365
|
+
installationStarting: "\u6B63\u5728\u5F00\u59CB CCR \u5B89\u88C5...",
|
|
366
|
+
installationSuccess: "CCR \u5B89\u88C5\u5B8C\u6210",
|
|
367
|
+
startingCcrService: "\u6B63\u5728\u542F\u52A8 CCR \u670D\u52A1...",
|
|
368
|
+
ccrServiceStarted: "CCR \u670D\u52A1\u5DF2\u542F\u52A8",
|
|
361
369
|
// Configuration
|
|
362
370
|
configureCcr: "\u542F\u52A8\u672C\u5730\u4E2A\u4EBA\u914D\u7F6E",
|
|
363
371
|
useCcrProxy: "\u4F7F\u7528 CCR \u4EE3\u7406",
|
|
@@ -482,6 +490,7 @@ const zhCN = {
|
|
|
482
490
|
errors: errors$1,
|
|
483
491
|
tools: tools$1,
|
|
484
492
|
ccr: ccrMessages$1,
|
|
493
|
+
updater: {},
|
|
485
494
|
cometix: cometixMessages$1
|
|
486
495
|
};
|
|
487
496
|
|
|
@@ -827,6 +836,14 @@ const ccrMessages = {
|
|
|
827
836
|
ccrInstallSuccess: "Claude Code Router installed successfully",
|
|
828
837
|
ccrInstallFailed: "Failed to install Claude Code Router",
|
|
829
838
|
ccrAlreadyInstalled: "Claude Code Router is already installed",
|
|
839
|
+
// Additional status messages
|
|
840
|
+
checkingInstallation: "Checking CCR installation...",
|
|
841
|
+
ccrNotInstalled: "CCR is not installed",
|
|
842
|
+
ccrInstalledWrongPackage: "CCR is installed but has an unexpected package/version",
|
|
843
|
+
installationStarting: "Starting CCR installation...",
|
|
844
|
+
installationSuccess: "CCR installation completed",
|
|
845
|
+
startingCcrService: "Starting CCR service...",
|
|
846
|
+
ccrServiceStarted: "CCR service started",
|
|
830
847
|
// Configuration
|
|
831
848
|
configureCcr: "Configure Model Proxy (CCR)",
|
|
832
849
|
useCcrProxy: "Use CCR Proxy",
|
|
@@ -951,6 +968,7 @@ const en = {
|
|
|
951
968
|
errors,
|
|
952
969
|
tools,
|
|
953
970
|
ccr: ccrMessages,
|
|
971
|
+
updater: {},
|
|
954
972
|
cometix: cometixMessages
|
|
955
973
|
};
|
|
956
974
|
|
|
@@ -1976,277 +1994,6 @@ function getFallbackPresets() {
|
|
|
1976
1994
|
];
|
|
1977
1995
|
}
|
|
1978
1996
|
|
|
1979
|
-
const execAsync$4 = promisify(exec$1);
|
|
1980
|
-
const CCR_CONFIG_DIR = join$1(homedir(), ".claude-code-router");
|
|
1981
|
-
const CCR_CONFIG_FILE = join$1(CCR_CONFIG_DIR, "config.json");
|
|
1982
|
-
const CCR_BACKUP_DIR = CCR_CONFIG_DIR;
|
|
1983
|
-
function ensureCcrConfigDir() {
|
|
1984
|
-
if (!existsSync(CCR_CONFIG_DIR)) {
|
|
1985
|
-
mkdirSync(CCR_CONFIG_DIR, { recursive: true });
|
|
1986
|
-
}
|
|
1987
|
-
}
|
|
1988
|
-
function backupCcrConfig(scriptLang) {
|
|
1989
|
-
const i18n = getTranslation(scriptLang);
|
|
1990
|
-
try {
|
|
1991
|
-
if (!existsSync(CCR_CONFIG_FILE)) {
|
|
1992
|
-
return null;
|
|
1993
|
-
}
|
|
1994
|
-
const timestamp = dayjs().format("YYYY-MM-DDTHH-mm-ss-SSS") + "Z";
|
|
1995
|
-
const backupFileName = `config.json.${timestamp}.bak`;
|
|
1996
|
-
const backupPath = join$1(CCR_BACKUP_DIR, backupFileName);
|
|
1997
|
-
console.log(ansis.cyan(`${i18n.ccr.backupCcrConfig}`));
|
|
1998
|
-
copyFileSync(CCR_CONFIG_FILE, backupPath);
|
|
1999
|
-
console.log(ansis.green(`\u2714 ${i18n.ccr.ccrBackupSuccess.replace("{path}", backupPath)}`));
|
|
2000
|
-
return backupPath;
|
|
2001
|
-
} catch (error) {
|
|
2002
|
-
console.error(ansis.red(`${i18n.ccr.ccrBackupFailed}:`), error.message);
|
|
2003
|
-
return null;
|
|
2004
|
-
}
|
|
2005
|
-
}
|
|
2006
|
-
function readCcrConfig() {
|
|
2007
|
-
if (!existsSync(CCR_CONFIG_FILE)) {
|
|
2008
|
-
return null;
|
|
2009
|
-
}
|
|
2010
|
-
return readJsonConfig(CCR_CONFIG_FILE);
|
|
2011
|
-
}
|
|
2012
|
-
function writeCcrConfig(config) {
|
|
2013
|
-
ensureCcrConfigDir();
|
|
2014
|
-
writeJsonConfig(CCR_CONFIG_FILE, config);
|
|
2015
|
-
}
|
|
2016
|
-
async function configureCcrProxy(ccrConfig) {
|
|
2017
|
-
const settings = readJsonConfig(SETTINGS_FILE) || {};
|
|
2018
|
-
const host = ccrConfig.HOST || "127.0.0.1";
|
|
2019
|
-
const port = ccrConfig.PORT || 3456;
|
|
2020
|
-
const apiKey = ccrConfig.APIKEY || "sk-aico-x-ccr";
|
|
2021
|
-
if (!settings.env) {
|
|
2022
|
-
settings.env = {};
|
|
2023
|
-
}
|
|
2024
|
-
settings.env.ANTHROPIC_BASE_URL = `http://${host}:${port}`;
|
|
2025
|
-
settings.env.ANTHROPIC_AUTH_TOKEN = apiKey;
|
|
2026
|
-
writeJsonConfig(SETTINGS_FILE, settings);
|
|
2027
|
-
}
|
|
2028
|
-
async function selectCcrPreset(scriptLang) {
|
|
2029
|
-
const i18n = getTranslation(scriptLang);
|
|
2030
|
-
console.log(ansis.cyan(`${i18n.ccr.fetchingPresets}`));
|
|
2031
|
-
const presets = await fetchProviderPresets();
|
|
2032
|
-
if (!presets || presets.length === 0) {
|
|
2033
|
-
console.log(ansis.yellow(`${i18n.ccr.noPresetsAvailable}`));
|
|
2034
|
-
return null;
|
|
2035
|
-
}
|
|
2036
|
-
try {
|
|
2037
|
-
const choices = [
|
|
2038
|
-
{
|
|
2039
|
-
name: `1. ${i18n.ccr.skipOption}`,
|
|
2040
|
-
value: "skip"
|
|
2041
|
-
},
|
|
2042
|
-
...presets.map((p, index) => ({
|
|
2043
|
-
name: `${index + 2}. ${p.name}`,
|
|
2044
|
-
value: p
|
|
2045
|
-
}))
|
|
2046
|
-
];
|
|
2047
|
-
const { preset } = await inquirer$1.prompt({
|
|
2048
|
-
type: "list",
|
|
2049
|
-
name: "preset",
|
|
2050
|
-
message: i18n.ccr.selectCcrPreset,
|
|
2051
|
-
choices
|
|
2052
|
-
});
|
|
2053
|
-
return preset;
|
|
2054
|
-
} catch (error) {
|
|
2055
|
-
if (error.name === "ExitPromptError") {
|
|
2056
|
-
console.log(ansis.yellow(i18n.common.cancelled));
|
|
2057
|
-
return null;
|
|
2058
|
-
}
|
|
2059
|
-
throw error;
|
|
2060
|
-
}
|
|
2061
|
-
}
|
|
2062
|
-
async function configureCcrWithPreset(preset, scriptLang) {
|
|
2063
|
-
const i18n = getTranslation(scriptLang);
|
|
2064
|
-
const provider = {
|
|
2065
|
-
name: preset.name,
|
|
2066
|
-
// Use the original name from JSON
|
|
2067
|
-
api_base_url: preset.baseURL || "",
|
|
2068
|
-
api_key: "",
|
|
2069
|
-
models: preset.models
|
|
2070
|
-
};
|
|
2071
|
-
if (preset.transformer) {
|
|
2072
|
-
provider.transformer = preset.transformer;
|
|
2073
|
-
}
|
|
2074
|
-
if (preset.requiresApiKey) {
|
|
2075
|
-
try {
|
|
2076
|
-
const { apiKey } = await inquirer$1.prompt({
|
|
2077
|
-
type: "input",
|
|
2078
|
-
name: "apiKey",
|
|
2079
|
-
message: i18n.ccr.enterApiKeyForProvider.replace("{provider}", preset.name),
|
|
2080
|
-
validate: (value) => !!value || i18n.api.keyRequired
|
|
2081
|
-
});
|
|
2082
|
-
provider.api_key = apiKey;
|
|
2083
|
-
} catch (error) {
|
|
2084
|
-
if (error.name === "ExitPromptError") {
|
|
2085
|
-
throw error;
|
|
2086
|
-
}
|
|
2087
|
-
throw error;
|
|
2088
|
-
}
|
|
2089
|
-
} else {
|
|
2090
|
-
provider.api_key = "sk-free";
|
|
2091
|
-
}
|
|
2092
|
-
let defaultModel = preset.models[0];
|
|
2093
|
-
if (preset.models.length > 1) {
|
|
2094
|
-
try {
|
|
2095
|
-
const { model } = await inquirer$1.prompt({
|
|
2096
|
-
type: "list",
|
|
2097
|
-
name: "model",
|
|
2098
|
-
message: i18n.ccr.selectDefaultModelForProvider.replace("{provider}", preset.name),
|
|
2099
|
-
choices: preset.models.map((m, index) => ({
|
|
2100
|
-
name: `${index + 1}. ${m}`,
|
|
2101
|
-
value: m
|
|
2102
|
-
}))
|
|
2103
|
-
});
|
|
2104
|
-
defaultModel = model;
|
|
2105
|
-
} catch (error) {
|
|
2106
|
-
if (error.name === "ExitPromptError") {
|
|
2107
|
-
throw error;
|
|
2108
|
-
}
|
|
2109
|
-
throw error;
|
|
2110
|
-
}
|
|
2111
|
-
}
|
|
2112
|
-
const router = {
|
|
2113
|
-
default: `${preset.name},${defaultModel}`,
|
|
2114
|
-
// Use the original name
|
|
2115
|
-
background: `${preset.name},${defaultModel}`,
|
|
2116
|
-
think: `${preset.name},${defaultModel}`,
|
|
2117
|
-
longContext: `${preset.name},${defaultModel}`,
|
|
2118
|
-
longContextThreshold: 6e4,
|
|
2119
|
-
webSearch: `${preset.name},${defaultModel}`
|
|
2120
|
-
};
|
|
2121
|
-
const config = {
|
|
2122
|
-
LOG: true,
|
|
2123
|
-
CLAUDE_PATH: "",
|
|
2124
|
-
HOST: "127.0.0.1",
|
|
2125
|
-
PORT: 3456,
|
|
2126
|
-
APIKEY: "sk-aico-x-ccr",
|
|
2127
|
-
API_TIMEOUT_MS: "600000",
|
|
2128
|
-
PROXY_URL: "",
|
|
2129
|
-
transformers: [],
|
|
2130
|
-
Providers: [provider],
|
|
2131
|
-
Router: router
|
|
2132
|
-
};
|
|
2133
|
-
return config;
|
|
2134
|
-
}
|
|
2135
|
-
async function restartAndCheckCcrStatus(scriptLang) {
|
|
2136
|
-
const i18n = getTranslation(scriptLang);
|
|
2137
|
-
try {
|
|
2138
|
-
console.log(ansis.cyan(`${i18n.ccr.restartingCcr}`));
|
|
2139
|
-
await execAsync$4("ccr restart");
|
|
2140
|
-
console.log(ansis.green(`\u2714 ${i18n.ccr.ccrRestartSuccess}`));
|
|
2141
|
-
console.log(ansis.cyan(`${i18n.ccr.checkingCcrStatus}`));
|
|
2142
|
-
const { stdout } = await execAsync$4("ccr status");
|
|
2143
|
-
console.log(ansis.gray(stdout));
|
|
2144
|
-
} catch (error) {
|
|
2145
|
-
console.error(ansis.red(`${i18n.ccr.ccrRestartFailed}:`), error.message || error);
|
|
2146
|
-
if (process.env.DEBUG) {
|
|
2147
|
-
console.error("Full error:", error);
|
|
2148
|
-
}
|
|
2149
|
-
}
|
|
2150
|
-
}
|
|
2151
|
-
function showConfigurationTips(scriptLang, apiKey) {
|
|
2152
|
-
const i18n = getTranslation(scriptLang);
|
|
2153
|
-
console.log(ansis.bold.cyan(`
|
|
2154
|
-
\u{1F4CC} ${i18n.ccr.configTips}:`));
|
|
2155
|
-
console.log(ansis.blue(` \u2022 ${i18n.ccr.advancedConfigTip}`));
|
|
2156
|
-
console.log(ansis.blue(` \u2022 ${i18n.ccr.manualConfigTip}`));
|
|
2157
|
-
console.log(ansis.bold.yellow(` \u2022 ${i18n.ccr.useClaudeCommand}`));
|
|
2158
|
-
if (apiKey) {
|
|
2159
|
-
console.log(ansis.bold.green(` \u2022 ${i18n.ccr.ccrUiApiKey || "CCR UI API Key"}: ${apiKey}`));
|
|
2160
|
-
console.log(ansis.gray(` ${i18n.ccr.ccrUiApiKeyHint || "Use this API key to login to CCR UI"}`));
|
|
2161
|
-
}
|
|
2162
|
-
console.log("");
|
|
2163
|
-
}
|
|
2164
|
-
function createDefaultCcrConfig() {
|
|
2165
|
-
return {
|
|
2166
|
-
LOG: false,
|
|
2167
|
-
CLAUDE_PATH: "",
|
|
2168
|
-
HOST: "127.0.0.1",
|
|
2169
|
-
PORT: 3456,
|
|
2170
|
-
APIKEY: "sk-aico-x-ccr",
|
|
2171
|
-
API_TIMEOUT_MS: "600000",
|
|
2172
|
-
PROXY_URL: "",
|
|
2173
|
-
transformers: [],
|
|
2174
|
-
Providers: [],
|
|
2175
|
-
// Empty providers array - user configures in UI
|
|
2176
|
-
Router: {}
|
|
2177
|
-
// Empty router configuration - user configures in UI
|
|
2178
|
-
};
|
|
2179
|
-
}
|
|
2180
|
-
async function setupCcrConfiguration(scriptLang) {
|
|
2181
|
-
const i18n = getTranslation(scriptLang);
|
|
2182
|
-
try {
|
|
2183
|
-
const existingConfig = readCcrConfig();
|
|
2184
|
-
if (existingConfig) {
|
|
2185
|
-
console.log(ansis.blue(`\u2139 ${i18n.ccr.existingCcrConfig}`));
|
|
2186
|
-
let shouldBackupAndReconfigure = false;
|
|
2187
|
-
try {
|
|
2188
|
-
const result = await inquirer$1.prompt({
|
|
2189
|
-
type: "confirm",
|
|
2190
|
-
name: "overwrite",
|
|
2191
|
-
message: i18n.ccr.overwriteCcrConfig,
|
|
2192
|
-
default: false
|
|
2193
|
-
});
|
|
2194
|
-
shouldBackupAndReconfigure = result.overwrite;
|
|
2195
|
-
} catch (error) {
|
|
2196
|
-
if (error.name === "ExitPromptError") {
|
|
2197
|
-
console.log(ansis.yellow(i18n.common.cancelled));
|
|
2198
|
-
return false;
|
|
2199
|
-
}
|
|
2200
|
-
throw error;
|
|
2201
|
-
}
|
|
2202
|
-
if (!shouldBackupAndReconfigure) {
|
|
2203
|
-
console.log(ansis.yellow(`${i18n.ccr.keepingExistingConfig}`));
|
|
2204
|
-
await configureCcrProxy(existingConfig);
|
|
2205
|
-
return true;
|
|
2206
|
-
}
|
|
2207
|
-
backupCcrConfig(scriptLang);
|
|
2208
|
-
}
|
|
2209
|
-
const preset = await selectCcrPreset(scriptLang);
|
|
2210
|
-
if (!preset) {
|
|
2211
|
-
return false;
|
|
2212
|
-
}
|
|
2213
|
-
let config;
|
|
2214
|
-
if (preset === "skip") {
|
|
2215
|
-
console.log(ansis.yellow(`${i18n.ccr.skipConfiguring}`));
|
|
2216
|
-
config = createDefaultCcrConfig();
|
|
2217
|
-
} else {
|
|
2218
|
-
config = await configureCcrWithPreset(preset, scriptLang);
|
|
2219
|
-
}
|
|
2220
|
-
writeCcrConfig(config);
|
|
2221
|
-
console.log(ansis.green(`\u2714 ${i18n.ccr.ccrConfigSuccess}`));
|
|
2222
|
-
await configureCcrProxy(config);
|
|
2223
|
-
console.log(ansis.green(`\u2714 ${i18n.ccr.proxyConfigSuccess}`));
|
|
2224
|
-
await restartAndCheckCcrStatus(scriptLang);
|
|
2225
|
-
showConfigurationTips(scriptLang, config.APIKEY);
|
|
2226
|
-
try {
|
|
2227
|
-
addCompletedOnboarding();
|
|
2228
|
-
} catch (error) {
|
|
2229
|
-
console.error(ansis.red(i18n.configuration.failedToSetOnboarding), error);
|
|
2230
|
-
}
|
|
2231
|
-
return true;
|
|
2232
|
-
} catch (error) {
|
|
2233
|
-
if (error.name === "ExitPromptError") {
|
|
2234
|
-
console.log(ansis.yellow(i18n.common.cancelled));
|
|
2235
|
-
return false;
|
|
2236
|
-
}
|
|
2237
|
-
console.error(ansis.red(`${i18n.ccr.ccrConfigFailed}:`), error);
|
|
2238
|
-
return false;
|
|
2239
|
-
}
|
|
2240
|
-
}
|
|
2241
|
-
async function configureCcrFeature(scriptLang) {
|
|
2242
|
-
const i18n = getTranslation(scriptLang);
|
|
2243
|
-
const backupDir = backupExistingConfig();
|
|
2244
|
-
if (backupDir) {
|
|
2245
|
-
console.log(ansis.gray(`\u2714 ${i18n.configuration.backupSuccess}: ${backupDir}`));
|
|
2246
|
-
}
|
|
2247
|
-
await setupCcrConfiguration(scriptLang);
|
|
2248
|
-
}
|
|
2249
|
-
|
|
2250
1997
|
function format(template, replacements) {
|
|
2251
1998
|
return template.replace(/\{(\w+)\}/g, (match, key) => {
|
|
2252
1999
|
return replacements[key] || match;
|
|
@@ -4959,15 +4706,15 @@ function requireSemver () {
|
|
|
4959
4706
|
var semverExports = requireSemver();
|
|
4960
4707
|
const semver = /*@__PURE__*/getDefaultExportFromCjs(semverExports);
|
|
4961
4708
|
|
|
4962
|
-
const execAsync$
|
|
4709
|
+
const execAsync$4 = promisify(exec$1);
|
|
4963
4710
|
async function getInstalledVersion(command) {
|
|
4964
4711
|
try {
|
|
4965
4712
|
let stdout;
|
|
4966
4713
|
try {
|
|
4967
|
-
const result = await execAsync$
|
|
4714
|
+
const result = await execAsync$4(`${command} -v`);
|
|
4968
4715
|
stdout = result.stdout;
|
|
4969
4716
|
} catch {
|
|
4970
|
-
const result = await execAsync$
|
|
4717
|
+
const result = await execAsync$4(`${command} --version`);
|
|
4971
4718
|
stdout = result.stdout;
|
|
4972
4719
|
}
|
|
4973
4720
|
const versionMatch = stdout.match(/(\d+\.\d+\.\d+(?:-[\w.]+)?)/);
|
|
@@ -4978,7 +4725,7 @@ async function getInstalledVersion(command) {
|
|
|
4978
4725
|
}
|
|
4979
4726
|
async function getLatestVersion(packageName) {
|
|
4980
4727
|
try {
|
|
4981
|
-
const { stdout } = await execAsync$
|
|
4728
|
+
const { stdout } = await execAsync$4(`npm view ${packageName} version`);
|
|
4982
4729
|
return stdout.trim();
|
|
4983
4730
|
} catch {
|
|
4984
4731
|
return null;
|
|
@@ -5024,7 +4771,7 @@ async function checkCometixLineVersion() {
|
|
|
5024
4771
|
};
|
|
5025
4772
|
}
|
|
5026
4773
|
|
|
5027
|
-
const execAsync$
|
|
4774
|
+
const execAsync$3 = promisify(exec$1);
|
|
5028
4775
|
async function updateCcr(scriptLang, force = false) {
|
|
5029
4776
|
const i18n = getTranslation(scriptLang);
|
|
5030
4777
|
const spinner = ora(i18n.updater.checkingVersion).start();
|
|
@@ -5057,7 +4804,7 @@ async function updateCcr(scriptLang, force = false) {
|
|
|
5057
4804
|
}
|
|
5058
4805
|
const updateSpinner = ora(format(i18n.updater.updating, { tool: "CCR" })).start();
|
|
5059
4806
|
try {
|
|
5060
|
-
await execAsync$
|
|
4807
|
+
await execAsync$3("npm update -g @musistudio/claude-code-router");
|
|
5061
4808
|
updateSpinner.succeed(format(i18n.updater.updateSuccess, { tool: "CCR" }));
|
|
5062
4809
|
return true;
|
|
5063
4810
|
} catch (error) {
|
|
@@ -5101,143 +4848,455 @@ async function updateClaudeCode(scriptLang, force = false) {
|
|
|
5101
4848
|
console.log(ansis.gray(i18n.updater.updateSkipped));
|
|
5102
4849
|
return true;
|
|
5103
4850
|
}
|
|
5104
|
-
const updateSpinner = ora(format(i18n.updater.updating, { tool: "Claude Code" })).start();
|
|
4851
|
+
const updateSpinner = ora(format(i18n.updater.updating, { tool: "Claude Code" })).start();
|
|
4852
|
+
try {
|
|
4853
|
+
await execAsync$3("npm update -g @anthropic-ai/claude-code");
|
|
4854
|
+
updateSpinner.succeed(format(i18n.updater.updateSuccess, { tool: "Claude Code" }));
|
|
4855
|
+
return true;
|
|
4856
|
+
} catch (error) {
|
|
4857
|
+
updateSpinner.fail(format(i18n.updater.updateFailed, { tool: "Claude Code" }));
|
|
4858
|
+
console.error(ansis.red(error instanceof Error ? error.message : String(error)));
|
|
4859
|
+
return false;
|
|
4860
|
+
}
|
|
4861
|
+
} catch (error) {
|
|
4862
|
+
spinner.fail(i18n.updater.checkFailed);
|
|
4863
|
+
console.error(ansis.red(error instanceof Error ? error.message : String(error)));
|
|
4864
|
+
return false;
|
|
4865
|
+
}
|
|
4866
|
+
}
|
|
4867
|
+
async function updateCometixLine(scriptLang, force = false) {
|
|
4868
|
+
const i18n = getTranslation(scriptLang);
|
|
4869
|
+
const spinner = ora(i18n.updater.checkingVersion).start();
|
|
4870
|
+
try {
|
|
4871
|
+
const { installed, currentVersion, latestVersion, needsUpdate } = await checkCometixLineVersion();
|
|
4872
|
+
spinner.stop();
|
|
4873
|
+
if (!installed) {
|
|
4874
|
+
console.log(ansis.yellow(i18n.updater.cometixLineNotInstalled));
|
|
4875
|
+
return false;
|
|
4876
|
+
}
|
|
4877
|
+
if (!needsUpdate && !force) {
|
|
4878
|
+
console.log(ansis.green(format(i18n.updater.cometixLineUpToDate, { version: currentVersion || "" })));
|
|
4879
|
+
return true;
|
|
4880
|
+
}
|
|
4881
|
+
if (!latestVersion) {
|
|
4882
|
+
console.log(ansis.yellow(i18n.updater.cannotCheckVersion));
|
|
4883
|
+
return false;
|
|
4884
|
+
}
|
|
4885
|
+
console.log(ansis.cyan(format(i18n.updater.currentVersion, { version: currentVersion || "" })));
|
|
4886
|
+
console.log(ansis.cyan(format(i18n.updater.latestVersion, { version: latestVersion })));
|
|
4887
|
+
const { confirm } = await inquirer$1.prompt({
|
|
4888
|
+
type: "confirm",
|
|
4889
|
+
name: "confirm",
|
|
4890
|
+
message: format(i18n.updater.confirmUpdate, { tool: "CCometixLine" }),
|
|
4891
|
+
default: true
|
|
4892
|
+
});
|
|
4893
|
+
if (!confirm) {
|
|
4894
|
+
console.log(ansis.gray(i18n.updater.updateSkipped));
|
|
4895
|
+
return true;
|
|
4896
|
+
}
|
|
4897
|
+
const updateSpinner = ora(format(i18n.updater.updating, { tool: "CCometixLine" })).start();
|
|
4898
|
+
try {
|
|
4899
|
+
await execAsync$3("cargo install ccometix");
|
|
4900
|
+
updateSpinner.succeed(format(i18n.updater.updateSuccess, { tool: "CCometixLine" }));
|
|
4901
|
+
return true;
|
|
4902
|
+
} catch (error) {
|
|
4903
|
+
updateSpinner.fail(format(i18n.updater.updateFailed, { tool: "CCometixLine" }));
|
|
4904
|
+
console.error(ansis.red(error instanceof Error ? error.message : String(error)));
|
|
4905
|
+
return false;
|
|
4906
|
+
}
|
|
4907
|
+
} catch (error) {
|
|
4908
|
+
spinner.fail(i18n.updater.checkFailed);
|
|
4909
|
+
console.error(ansis.red(error instanceof Error ? error.message : String(error)));
|
|
4910
|
+
return false;
|
|
4911
|
+
}
|
|
4912
|
+
}
|
|
4913
|
+
async function checkAndUpdateTools(scriptLang) {
|
|
4914
|
+
const i18n = getTranslation(scriptLang);
|
|
4915
|
+
console.log(ansis.bold.cyan(`
|
|
4916
|
+
\u{1F50D} ${i18n.updater.checkingTools}
|
|
4917
|
+
`));
|
|
4918
|
+
await updateCcr(scriptLang);
|
|
4919
|
+
console.log();
|
|
4920
|
+
await updateClaudeCode(scriptLang);
|
|
4921
|
+
console.log();
|
|
4922
|
+
await updateCometixLine(scriptLang);
|
|
4923
|
+
}
|
|
4924
|
+
|
|
4925
|
+
const execAsync$2 = promisify$1(exec$2);
|
|
4926
|
+
async function isCcrInstalled() {
|
|
4927
|
+
let commandExists = false;
|
|
4928
|
+
try {
|
|
4929
|
+
const ccrCommand = isWindows() ? "npx ccr version" : "ccr version";
|
|
4930
|
+
await execAsync$2(ccrCommand);
|
|
4931
|
+
commandExists = true;
|
|
4932
|
+
} catch {
|
|
4933
|
+
try {
|
|
4934
|
+
const whichCommand = isWindows() ? "where ccr" : "which ccr";
|
|
4935
|
+
await execAsync$2(whichCommand);
|
|
4936
|
+
commandExists = true;
|
|
4937
|
+
} catch {
|
|
4938
|
+
commandExists = false;
|
|
4939
|
+
}
|
|
4940
|
+
}
|
|
4941
|
+
let hasCorrectPackage = false;
|
|
4942
|
+
try {
|
|
4943
|
+
await execAsync$2("npm list -g @musistudio/claude-code-router");
|
|
4944
|
+
hasCorrectPackage = true;
|
|
4945
|
+
} catch {
|
|
4946
|
+
hasCorrectPackage = false;
|
|
4947
|
+
}
|
|
4948
|
+
return {
|
|
4949
|
+
isInstalled: commandExists,
|
|
4950
|
+
hasCorrectPackage
|
|
4951
|
+
};
|
|
4952
|
+
}
|
|
4953
|
+
async function installCcr(scriptLang) {
|
|
4954
|
+
const i18n = getTranslation(scriptLang);
|
|
4955
|
+
const { isInstalled, hasCorrectPackage } = await isCcrInstalled();
|
|
4956
|
+
if (hasCorrectPackage) {
|
|
4957
|
+
console.log(ansis.green(`\u2714 ${i18n.ccr.ccrAlreadyInstalled}`));
|
|
4958
|
+
await updateCcr(scriptLang);
|
|
4959
|
+
return;
|
|
4960
|
+
}
|
|
4961
|
+
if (isInstalled && !hasCorrectPackage) {
|
|
4962
|
+
try {
|
|
4963
|
+
await execAsync$2("npm list -g claude-code-router");
|
|
4964
|
+
console.log(ansis.yellow(`\u26A0 ${i18n.ccr.detectedIncorrectPackage}`));
|
|
4965
|
+
try {
|
|
4966
|
+
await execAsync$2("npm uninstall -g claude-code-router");
|
|
4967
|
+
console.log(ansis.green(`\u2714 ${i18n.ccr.uninstalledIncorrectPackage}`));
|
|
4968
|
+
} catch (uninstallError) {
|
|
4969
|
+
console.log(ansis.yellow(`\u26A0 ${i18n.ccr.failedToUninstallIncorrectPackage}`));
|
|
4970
|
+
}
|
|
4971
|
+
} catch {
|
|
4972
|
+
}
|
|
4973
|
+
}
|
|
4974
|
+
console.log(ansis.cyan(`\u{1F4E6} ${i18n.ccr.installingCcr}`));
|
|
4975
|
+
try {
|
|
4976
|
+
await execAsync$2("npm install -g @musistudio/claude-code-router --force");
|
|
4977
|
+
console.log(ansis.green(`\u2714 ${i18n.ccr.ccrInstallSuccess}`));
|
|
4978
|
+
} catch (error) {
|
|
4979
|
+
if (error.message?.includes("EEXIST")) {
|
|
4980
|
+
console.log(ansis.yellow(`\u26A0 ${i18n.ccr.ccrAlreadyInstalled}`));
|
|
4981
|
+
await updateCcr(scriptLang);
|
|
4982
|
+
return;
|
|
4983
|
+
}
|
|
4984
|
+
console.error(ansis.red(`\u2716 ${i18n.ccr.ccrInstallFailed}`));
|
|
4985
|
+
throw error;
|
|
4986
|
+
}
|
|
4987
|
+
}
|
|
4988
|
+
async function startCcrService(scriptLang) {
|
|
4989
|
+
const lang = scriptLang || "zh-CN";
|
|
4990
|
+
const i18n = getTranslation(lang);
|
|
4991
|
+
try {
|
|
4992
|
+
const ccrCommand = isWindows() ? "npx ccr" : "ccr";
|
|
4993
|
+
exec$2(ccrCommand, (error) => {
|
|
4994
|
+
if (error) {
|
|
4995
|
+
console.error(ansis.red(`${i18n.ccr.failedToStartCcrService}:`), error);
|
|
4996
|
+
}
|
|
4997
|
+
});
|
|
4998
|
+
await new Promise((resolve) => setTimeout(resolve, 2e3));
|
|
4999
|
+
} catch (error) {
|
|
5000
|
+
console.error(ansis.red(`${i18n.ccr.errorStartingCcrService}:`), error);
|
|
5001
|
+
}
|
|
5002
|
+
}
|
|
5003
|
+
|
|
5004
|
+
const execAsync$1 = promisify$1(exec$2);
|
|
5005
|
+
const CCR_CONFIG_DIR = join$1(homedir(), ".claude-code-router");
|
|
5006
|
+
const CCR_CONFIG_FILE = join$1(CCR_CONFIG_DIR, "config.json");
|
|
5007
|
+
const CCR_BACKUP_DIR = CCR_CONFIG_DIR;
|
|
5008
|
+
function ensureCcrConfigDir() {
|
|
5009
|
+
if (!existsSync(CCR_CONFIG_DIR)) {
|
|
5010
|
+
mkdirSync(CCR_CONFIG_DIR, { recursive: true });
|
|
5011
|
+
}
|
|
5012
|
+
}
|
|
5013
|
+
function backupCcrConfig(scriptLang) {
|
|
5014
|
+
const i18n = getTranslation(scriptLang);
|
|
5015
|
+
try {
|
|
5016
|
+
if (!existsSync(CCR_CONFIG_FILE)) {
|
|
5017
|
+
return null;
|
|
5018
|
+
}
|
|
5019
|
+
const timestamp = dayjs().format("YYYY-MM-DDTHH-mm-ss-SSS") + "Z";
|
|
5020
|
+
const backupFileName = `config.json.${timestamp}.bak`;
|
|
5021
|
+
const backupPath = join$1(CCR_BACKUP_DIR, backupFileName);
|
|
5022
|
+
console.log(ansis.cyan(`${i18n.ccr.backupCcrConfig}`));
|
|
5023
|
+
copyFileSync(CCR_CONFIG_FILE, backupPath);
|
|
5024
|
+
console.log(ansis.green(`\u2714 ${i18n.ccr.ccrBackupSuccess.replace("{path}", backupPath)}`));
|
|
5025
|
+
return backupPath;
|
|
5026
|
+
} catch (error) {
|
|
5027
|
+
console.error(ansis.red(`${i18n.ccr.ccrBackupFailed}:`), error.message);
|
|
5028
|
+
return null;
|
|
5029
|
+
}
|
|
5030
|
+
}
|
|
5031
|
+
function readCcrConfig() {
|
|
5032
|
+
if (!existsSync(CCR_CONFIG_FILE)) {
|
|
5033
|
+
return null;
|
|
5034
|
+
}
|
|
5035
|
+
return readJsonConfig(CCR_CONFIG_FILE);
|
|
5036
|
+
}
|
|
5037
|
+
function writeCcrConfig(config) {
|
|
5038
|
+
ensureCcrConfigDir();
|
|
5039
|
+
writeJsonConfig(CCR_CONFIG_FILE, config);
|
|
5040
|
+
}
|
|
5041
|
+
async function configureCcrProxy(ccrConfig) {
|
|
5042
|
+
const settings = readJsonConfig(SETTINGS_FILE) || {};
|
|
5043
|
+
const host = ccrConfig.HOST || "127.0.0.1";
|
|
5044
|
+
const port = ccrConfig.PORT || 3456;
|
|
5045
|
+
const apiKey = ccrConfig.APIKEY || "sk-aico-x-ccr";
|
|
5046
|
+
if (!settings.env) {
|
|
5047
|
+
settings.env = {};
|
|
5048
|
+
}
|
|
5049
|
+
settings.env.ANTHROPIC_BASE_URL = `http://${host}:${port}`;
|
|
5050
|
+
settings.env.ANTHROPIC_AUTH_TOKEN = apiKey;
|
|
5051
|
+
writeJsonConfig(SETTINGS_FILE, settings);
|
|
5052
|
+
}
|
|
5053
|
+
async function selectCcrPreset(scriptLang) {
|
|
5054
|
+
const i18n = getTranslation(scriptLang);
|
|
5055
|
+
console.log(ansis.cyan(`${i18n.ccr.fetchingPresets}`));
|
|
5056
|
+
const presets = await fetchProviderPresets();
|
|
5057
|
+
if (!presets || presets.length === 0) {
|
|
5058
|
+
console.log(ansis.yellow(`${i18n.ccr.noPresetsAvailable}`));
|
|
5059
|
+
return null;
|
|
5060
|
+
}
|
|
5061
|
+
try {
|
|
5062
|
+
const choices = [
|
|
5063
|
+
{
|
|
5064
|
+
name: `1. ${i18n.ccr.skipOption}`,
|
|
5065
|
+
value: "skip"
|
|
5066
|
+
},
|
|
5067
|
+
...presets.map((p, index) => ({
|
|
5068
|
+
name: `${index + 2}. ${p.name}`,
|
|
5069
|
+
value: p
|
|
5070
|
+
}))
|
|
5071
|
+
];
|
|
5072
|
+
const { preset } = await inquirer$1.prompt({
|
|
5073
|
+
type: "list",
|
|
5074
|
+
name: "preset",
|
|
5075
|
+
message: i18n.ccr.selectCcrPreset,
|
|
5076
|
+
choices
|
|
5077
|
+
});
|
|
5078
|
+
return preset;
|
|
5079
|
+
} catch (error) {
|
|
5080
|
+
if (error.name === "ExitPromptError") {
|
|
5081
|
+
console.log(ansis.yellow(i18n.common.cancelled));
|
|
5082
|
+
return null;
|
|
5083
|
+
}
|
|
5084
|
+
throw error;
|
|
5085
|
+
}
|
|
5086
|
+
}
|
|
5087
|
+
async function configureCcrWithPreset(preset, scriptLang) {
|
|
5088
|
+
const i18n = getTranslation(scriptLang);
|
|
5089
|
+
const provider = {
|
|
5090
|
+
name: preset.name,
|
|
5091
|
+
// Use the original name from JSON
|
|
5092
|
+
api_base_url: preset.baseURL || "",
|
|
5093
|
+
api_key: "",
|
|
5094
|
+
models: preset.models
|
|
5095
|
+
};
|
|
5096
|
+
if (preset.transformer) {
|
|
5097
|
+
provider.transformer = preset.transformer;
|
|
5098
|
+
}
|
|
5099
|
+
if (preset.requiresApiKey) {
|
|
5100
|
+
try {
|
|
5101
|
+
const { apiKey } = await inquirer$1.prompt({
|
|
5102
|
+
type: "input",
|
|
5103
|
+
name: "apiKey",
|
|
5104
|
+
message: i18n.ccr.enterApiKeyForProvider.replace("{provider}", preset.name),
|
|
5105
|
+
validate: (value) => !!value || i18n.api.keyRequired
|
|
5106
|
+
});
|
|
5107
|
+
provider.api_key = apiKey;
|
|
5108
|
+
} catch (error) {
|
|
5109
|
+
if (error.name === "ExitPromptError") {
|
|
5110
|
+
throw error;
|
|
5111
|
+
}
|
|
5112
|
+
throw error;
|
|
5113
|
+
}
|
|
5114
|
+
} else {
|
|
5115
|
+
provider.api_key = "sk-free";
|
|
5116
|
+
}
|
|
5117
|
+
let defaultModel = preset.models[0];
|
|
5118
|
+
if (preset.models.length > 1) {
|
|
5105
5119
|
try {
|
|
5106
|
-
await
|
|
5107
|
-
|
|
5108
|
-
|
|
5120
|
+
const { model } = await inquirer$1.prompt({
|
|
5121
|
+
type: "list",
|
|
5122
|
+
name: "model",
|
|
5123
|
+
message: i18n.ccr.selectDefaultModelForProvider.replace("{provider}", preset.name),
|
|
5124
|
+
choices: preset.models.map((m, index) => ({
|
|
5125
|
+
name: `${index + 1}. ${m}`,
|
|
5126
|
+
value: m
|
|
5127
|
+
}))
|
|
5128
|
+
});
|
|
5129
|
+
defaultModel = model;
|
|
5109
5130
|
} catch (error) {
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5131
|
+
if (error.name === "ExitPromptError") {
|
|
5132
|
+
throw error;
|
|
5133
|
+
}
|
|
5134
|
+
throw error;
|
|
5113
5135
|
}
|
|
5114
|
-
} catch (error) {
|
|
5115
|
-
spinner.fail(i18n.updater.checkFailed);
|
|
5116
|
-
console.error(ansis.red(error instanceof Error ? error.message : String(error)));
|
|
5117
|
-
return false;
|
|
5118
5136
|
}
|
|
5137
|
+
const router = {
|
|
5138
|
+
default: `${preset.name},${defaultModel}`,
|
|
5139
|
+
// Use the original name
|
|
5140
|
+
background: `${preset.name},${defaultModel}`,
|
|
5141
|
+
think: `${preset.name},${defaultModel}`,
|
|
5142
|
+
longContext: `${preset.name},${defaultModel}`,
|
|
5143
|
+
longContextThreshold: 6e4,
|
|
5144
|
+
webSearch: `${preset.name},${defaultModel}`
|
|
5145
|
+
};
|
|
5146
|
+
const config = {
|
|
5147
|
+
LOG: true,
|
|
5148
|
+
CLAUDE_PATH: "",
|
|
5149
|
+
HOST: "127.0.0.1",
|
|
5150
|
+
PORT: 3456,
|
|
5151
|
+
APIKEY: "sk-aico-x-ccr",
|
|
5152
|
+
API_TIMEOUT_MS: "600000",
|
|
5153
|
+
PROXY_URL: "",
|
|
5154
|
+
transformers: [],
|
|
5155
|
+
Providers: [provider],
|
|
5156
|
+
Router: router
|
|
5157
|
+
};
|
|
5158
|
+
return config;
|
|
5119
5159
|
}
|
|
5120
|
-
async function
|
|
5160
|
+
async function restartAndCheckCcrStatus(scriptLang) {
|
|
5121
5161
|
const i18n = getTranslation(scriptLang);
|
|
5122
|
-
const spinner = ora(i18n.updater.checkingVersion).start();
|
|
5123
5162
|
try {
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
console.log(ansis.green(format(i18n.updater.cometixLineUpToDate, { version: currentVersion || "" })));
|
|
5132
|
-
return true;
|
|
5133
|
-
}
|
|
5134
|
-
if (!latestVersion) {
|
|
5135
|
-
console.log(ansis.yellow(i18n.updater.cannotCheckVersion));
|
|
5136
|
-
return false;
|
|
5137
|
-
}
|
|
5138
|
-
console.log(ansis.cyan(format(i18n.updater.currentVersion, { version: currentVersion || "" })));
|
|
5139
|
-
console.log(ansis.cyan(format(i18n.updater.latestVersion, { version: latestVersion })));
|
|
5140
|
-
const { confirm } = await inquirer$1.prompt({
|
|
5141
|
-
type: "confirm",
|
|
5142
|
-
name: "confirm",
|
|
5143
|
-
message: format(i18n.updater.confirmUpdate, { tool: "CCometixLine" }),
|
|
5144
|
-
default: true
|
|
5145
|
-
});
|
|
5146
|
-
if (!confirm) {
|
|
5147
|
-
console.log(ansis.gray(i18n.updater.updateSkipped));
|
|
5148
|
-
return true;
|
|
5149
|
-
}
|
|
5150
|
-
const updateSpinner = ora(format(i18n.updater.updating, { tool: "CCometixLine" })).start();
|
|
5151
|
-
try {
|
|
5152
|
-
await execAsync$2("cargo install ccometix");
|
|
5153
|
-
updateSpinner.succeed(format(i18n.updater.updateSuccess, { tool: "CCometixLine" }));
|
|
5154
|
-
return true;
|
|
5155
|
-
} catch (error) {
|
|
5156
|
-
updateSpinner.fail(format(i18n.updater.updateFailed, { tool: "CCometixLine" }));
|
|
5157
|
-
console.error(ansis.red(error instanceof Error ? error.message : String(error)));
|
|
5158
|
-
return false;
|
|
5159
|
-
}
|
|
5163
|
+
console.log(ansis.cyan(`${i18n.ccr.restartingCcr}`));
|
|
5164
|
+
await execAsync$1("ccr restart", { encoding: "buffer", maxBuffer: 10 * 1024 * 1024 });
|
|
5165
|
+
console.log(ansis.green(`\u2714 ${i18n.ccr.ccrRestartSuccess}`));
|
|
5166
|
+
console.log(ansis.cyan(`${i18n.ccr.checkingCcrStatus}`));
|
|
5167
|
+
const { stdout } = await execAsync$1("ccr status", { encoding: "buffer", maxBuffer: 10 * 1024 * 1024 });
|
|
5168
|
+
const statusOut = Buffer.isBuffer(stdout) ? stdout.toString("utf8").replace(/\0/g, "") : String(stdout);
|
|
5169
|
+
console.log(ansis.gray(statusOut));
|
|
5160
5170
|
} catch (error) {
|
|
5161
|
-
|
|
5162
|
-
console.error(ansis.red(error instanceof Error ? error.message : String(error)));
|
|
5163
|
-
return false;
|
|
5171
|
+
console.error(ansis.red(`${i18n.ccr.ccrRestartFailed}:`), error);
|
|
5164
5172
|
}
|
|
5165
5173
|
}
|
|
5166
|
-
|
|
5174
|
+
function showConfigurationTips(scriptLang, apiKey) {
|
|
5167
5175
|
const i18n = getTranslation(scriptLang);
|
|
5168
5176
|
console.log(ansis.bold.cyan(`
|
|
5169
|
-
\u{
|
|
5170
|
-
`));
|
|
5171
|
-
|
|
5172
|
-
console.log();
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
}
|
|
5177
|
-
|
|
5178
|
-
const execAsync$1 = promisify(exec$1);
|
|
5179
|
-
async function isCcrInstalled() {
|
|
5180
|
-
let commandExists = false;
|
|
5181
|
-
try {
|
|
5182
|
-
const ccrCommand = isWindows() ? "npx ccr version" : "ccr version";
|
|
5183
|
-
await execAsync$1(ccrCommand);
|
|
5184
|
-
commandExists = true;
|
|
5185
|
-
} catch {
|
|
5186
|
-
try {
|
|
5187
|
-
const whichCommand = isWindows() ? "where ccr" : "which ccr";
|
|
5188
|
-
await execAsync$1(whichCommand);
|
|
5189
|
-
commandExists = true;
|
|
5190
|
-
} catch {
|
|
5191
|
-
commandExists = false;
|
|
5192
|
-
}
|
|
5193
|
-
}
|
|
5194
|
-
let hasCorrectPackage = false;
|
|
5195
|
-
try {
|
|
5196
|
-
await execAsync$1("npm list -g @musistudio/claude-code-router");
|
|
5197
|
-
hasCorrectPackage = true;
|
|
5198
|
-
} catch {
|
|
5199
|
-
hasCorrectPackage = false;
|
|
5177
|
+
\u{1F4CC} ${i18n.ccr.configTips}:`));
|
|
5178
|
+
console.log(ansis.blue(` \u2022 ${i18n.ccr.advancedConfigTip}`));
|
|
5179
|
+
console.log(ansis.blue(` \u2022 ${i18n.ccr.manualConfigTip}`));
|
|
5180
|
+
console.log(ansis.bold.yellow(` \u2022 ${i18n.ccr.useClaudeCommand}`));
|
|
5181
|
+
if (apiKey) {
|
|
5182
|
+
console.log(ansis.bold.green(` \u2022 ${i18n.ccr.ccrUiApiKey || "CCR UI API Key"}: ${apiKey}`));
|
|
5183
|
+
console.log(ansis.gray(` ${i18n.ccr.ccrUiApiKeyHint || "Use this API key to login to CCR UI"}`));
|
|
5200
5184
|
}
|
|
5185
|
+
console.log("");
|
|
5186
|
+
}
|
|
5187
|
+
function createDefaultCcrConfig() {
|
|
5201
5188
|
return {
|
|
5202
|
-
|
|
5203
|
-
|
|
5189
|
+
LOG: false,
|
|
5190
|
+
CLAUDE_PATH: "",
|
|
5191
|
+
HOST: "127.0.0.1",
|
|
5192
|
+
PORT: 3456,
|
|
5193
|
+
APIKEY: "sk-aico-x-ccr",
|
|
5194
|
+
API_TIMEOUT_MS: "600000",
|
|
5195
|
+
PROXY_URL: "",
|
|
5196
|
+
transformers: [],
|
|
5197
|
+
Providers: [],
|
|
5198
|
+
// Empty providers array - user configures in UI
|
|
5199
|
+
Router: {}
|
|
5200
|
+
// Empty router configuration - user configures in UI
|
|
5204
5201
|
};
|
|
5205
5202
|
}
|
|
5206
|
-
async function
|
|
5203
|
+
async function setupCcrConfiguration(scriptLang) {
|
|
5207
5204
|
const i18n = getTranslation(scriptLang);
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
}
|
|
5214
|
-
if (isInstalled && !hasCorrectPackage) {
|
|
5215
|
-
try {
|
|
5216
|
-
await execAsync$1("npm list -g claude-code-router");
|
|
5217
|
-
console.log(ansis.yellow(`\u26A0 ${i18n.ccr.detectedIncorrectPackage}`));
|
|
5205
|
+
try {
|
|
5206
|
+
const existingConfig = readCcrConfig();
|
|
5207
|
+
if (existingConfig) {
|
|
5208
|
+
console.log(ansis.blue(`\u2139 ${i18n.ccr.existingCcrConfig}`));
|
|
5209
|
+
let shouldBackupAndReconfigure = false;
|
|
5218
5210
|
try {
|
|
5219
|
-
await
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5211
|
+
const result = await inquirer$1.prompt({
|
|
5212
|
+
type: "confirm",
|
|
5213
|
+
name: "overwrite",
|
|
5214
|
+
message: i18n.ccr.overwriteCcrConfig,
|
|
5215
|
+
default: false
|
|
5216
|
+
});
|
|
5217
|
+
shouldBackupAndReconfigure = result.overwrite;
|
|
5218
|
+
} catch (error) {
|
|
5219
|
+
if (error.name === "ExitPromptError") {
|
|
5220
|
+
console.log(ansis.yellow(i18n.common.cancelled));
|
|
5221
|
+
return false;
|
|
5222
|
+
}
|
|
5223
|
+
throw error;
|
|
5223
5224
|
}
|
|
5224
|
-
|
|
5225
|
+
if (!shouldBackupAndReconfigure) {
|
|
5226
|
+
console.log(ansis.yellow(`${i18n.ccr.keepingExistingConfig}`));
|
|
5227
|
+
await configureCcrProxy(existingConfig);
|
|
5228
|
+
return true;
|
|
5229
|
+
}
|
|
5230
|
+
backupCcrConfig(scriptLang);
|
|
5225
5231
|
}
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5232
|
+
const preset = await selectCcrPreset(scriptLang);
|
|
5233
|
+
if (!preset) {
|
|
5234
|
+
return false;
|
|
5235
|
+
}
|
|
5236
|
+
let config;
|
|
5237
|
+
if (preset === "skip") {
|
|
5238
|
+
console.log(ansis.yellow(`${i18n.ccr.skipConfiguring}`));
|
|
5239
|
+
config = createDefaultCcrConfig();
|
|
5240
|
+
} else {
|
|
5241
|
+
config = await configureCcrWithPreset(preset, scriptLang);
|
|
5242
|
+
}
|
|
5243
|
+
writeCcrConfig(config);
|
|
5244
|
+
console.log(ansis.green(`\u2714 ${i18n.ccr.ccrConfigSuccess}`));
|
|
5245
|
+
await configureCcrProxy(config);
|
|
5246
|
+
console.log(ansis.green(`\u2714 ${i18n.ccr.proxyConfigSuccess}`));
|
|
5247
|
+
try {
|
|
5248
|
+
console.log(ansis.cyan(i18n.ccr.checkingInstallation || "Checking CCR installation..."));
|
|
5249
|
+
const { isInstalled, hasCorrectPackage } = await isCcrInstalled();
|
|
5250
|
+
if (isInstalled && hasCorrectPackage) {
|
|
5251
|
+
console.log(ansis.green(i18n.ccr.ccrAlreadyInstalled || "\u2714 CCR is already installed and up to date."));
|
|
5252
|
+
} else if (isInstalled && !hasCorrectPackage) {
|
|
5253
|
+
console.log(ansis.yellow(i18n.ccr.ccrInstalledWrongPackage || "\u26A0 CCR is installed but has an unexpected package/version. Will reinstall."));
|
|
5254
|
+
} else {
|
|
5255
|
+
console.log(ansis.yellow(i18n.ccr.ccrNotInstalled || "\u2716 CCR is not installed."));
|
|
5256
|
+
}
|
|
5257
|
+
if (!isInstalled || !hasCorrectPackage) {
|
|
5258
|
+
console.log(ansis.cyan(i18n.ccr.installingCcr || "Installing CCR..."));
|
|
5259
|
+
try {
|
|
5260
|
+
console.log(ansis.cyan(i18n.ccr.installationStarting || "Starting CCR installation..."));
|
|
5261
|
+
await installCcr(scriptLang);
|
|
5262
|
+
console.log(ansis.green(i18n.ccr.installationSuccess || "\u2714 CCR installation completed."));
|
|
5263
|
+
console.log(ansis.cyan(i18n.ccr.startingCcrService || "Starting CCR service..."));
|
|
5264
|
+
await startCcrService(scriptLang);
|
|
5265
|
+
console.log(ansis.green(i18n.ccr.ccrServiceStarted || "\u2714 CCR service started."));
|
|
5266
|
+
} catch (installError) {
|
|
5267
|
+
console.error(ansis.red(`${i18n.ccr.ccrInstallFailed}:`), installError);
|
|
5268
|
+
return false;
|
|
5269
|
+
}
|
|
5270
|
+
}
|
|
5271
|
+
} catch (checkError) {
|
|
5272
|
+
console.error(ansis.red(`${i18n.ccr.ccrInstallCheckFailed || i18n.ccr.ccrInstallFailed}:`), checkError);
|
|
5273
|
+
return false;
|
|
5274
|
+
}
|
|
5275
|
+
await restartAndCheckCcrStatus(scriptLang);
|
|
5276
|
+
showConfigurationTips(scriptLang, config.APIKEY);
|
|
5277
|
+
try {
|
|
5278
|
+
addCompletedOnboarding();
|
|
5279
|
+
} catch (error) {
|
|
5280
|
+
console.error(ansis.red(i18n.configuration.failedToSetOnboarding), error);
|
|
5281
|
+
}
|
|
5282
|
+
return true;
|
|
5231
5283
|
} catch (error) {
|
|
5232
|
-
if (error.
|
|
5233
|
-
console.log(ansis.yellow(
|
|
5234
|
-
|
|
5235
|
-
return;
|
|
5284
|
+
if (error.name === "ExitPromptError") {
|
|
5285
|
+
console.log(ansis.yellow(i18n.common.cancelled));
|
|
5286
|
+
return false;
|
|
5236
5287
|
}
|
|
5237
|
-
console.error(ansis.red(
|
|
5238
|
-
|
|
5288
|
+
console.error(ansis.red(`${i18n.ccr.ccrConfigFailed}:`), error);
|
|
5289
|
+
return false;
|
|
5239
5290
|
}
|
|
5240
5291
|
}
|
|
5292
|
+
async function configureCcrFeature(scriptLang) {
|
|
5293
|
+
const i18n = getTranslation(scriptLang);
|
|
5294
|
+
const backupDir = backupExistingConfig();
|
|
5295
|
+
if (backupDir) {
|
|
5296
|
+
console.log(ansis.gray(`\u2714 ${i18n.configuration.backupSuccess}: ${backupDir}`));
|
|
5297
|
+
}
|
|
5298
|
+
await setupCcrConfiguration(scriptLang);
|
|
5299
|
+
}
|
|
5241
5300
|
|
|
5242
5301
|
const COMETIX_PACKAGE_NAME = "@cometix/ccline";
|
|
5243
5302
|
const COMETIX_COMMAND_NAME = "ccline";
|
|
@@ -5283,7 +5342,7 @@ function hasCCometixLineConfig() {
|
|
|
5283
5342
|
}
|
|
5284
5343
|
}
|
|
5285
5344
|
|
|
5286
|
-
const execAsync = promisify(exec$
|
|
5345
|
+
const execAsync = promisify$1(exec$2);
|
|
5287
5346
|
async function isCometixLineInstalled() {
|
|
5288
5347
|
try {
|
|
5289
5348
|
await execAsync(COMETIX_COMMANDS.CHECK_INSTALL);
|