diff --git a/apps/cli/package.json b/apps/cli/package.json index 285e546b..263601ef 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -1,6 +1,6 @@ { "name": "tailchat-cli", - "version": "1.5.4", + "version": "1.5.5", "description": "A Command line interface of tailchat", "bin": { "tailchat": "./bin/cli" diff --git a/apps/cli/src/app/App.tsx b/apps/cli/src/app/App.tsx index 9b09e275..451c6062 100644 --- a/apps/cli/src/app/App.tsx +++ b/apps/cli/src/app/App.tsx @@ -31,7 +31,7 @@ export const App: React.FC = React.memo(() => { {}}> - {/* 因为react版本问题暂时注释 */} + {/* Temporary comments due to react version issues */} {/* Foo diff --git a/apps/cli/src/commands/app.ts b/apps/cli/src/commands/app.ts index 8c50004a..9616ab5f 100644 --- a/apps/cli/src/commands/app.ts +++ b/apps/cli/src/commands/app.ts @@ -4,7 +4,7 @@ import { isDev } from '../utils'; export const appCommand: CommandModule = { command: 'app', - describe: isDev() ? false : 'Tailchat cli 版本(WIP)', + describe: isDev() ? false : 'Tailchat cli(WIP)', builder: undefined, async handler() { await run(); diff --git a/apps/cli/src/commands/bench.ts b/apps/cli/src/commands/bench.ts index 3ae7cdc7..617f46eb 100644 --- a/apps/cli/src/commands/bench.ts +++ b/apps/cli/src/commands/bench.ts @@ -12,41 +12,41 @@ import filesize from 'filesize'; export const benchCommand: CommandModule = { command: 'bench', - describe: '压力测试', + describe: 'Benchmark', builder: (yargs) => yargs .command( 'message', - '通过Tailchat网络请求进行压力测试(适用于纯业务测试)', + 'Stress testing through Tailchat network requests (suitable for pure business testing)', (yargs) => yargs .option('groupId', { - describe: '群组ID', + describe: 'Group ID', demandOption: true, type: 'string', }) .option('converseId', { - describe: '会话ID', + describe: 'Converse ID', demandOption: true, type: 'string', }) .option('userId', { - describe: '用户ID', + describe: 'User ID', demandOption: true, type: 'string', }) .option('num', { - describe: '测试次数', + describe: 'Test Num', type: 'number', default: 100, }) .option('parallel', { - describe: '是否并发', + describe: 'Is Parallel', type: 'boolean', default: false, }) .option('parallelLimit', { - describe: '并发上限', + describe: 'Parallel Limit', type: 'number', default: Infinity, }), @@ -89,10 +89,10 @@ export const benchCommand: CommandModule = { return usage; }, onCompleted: (res) => { - console.log(`测试数量: \t${res.length}`); - console.log(`最大用时: \t${prettyMs(Math.max(...res, 0))}`); - console.log(`最小用时: \t${prettyMs(Math.min(...res, 0))}`); - console.log(`平均用时: \t${prettyMs(_.mean(res))}`); + console.log(`Test Num: \t${res.length}`); + console.log(`Max Usage: \t${prettyMs(Math.max(...res, 0))}`); + console.log(`Min Usage: \t${prettyMs(Math.min(...res, 0))}`); + console.log(`Average time: \t${prettyMs(_.mean(res))}`); }, }); @@ -107,11 +107,11 @@ export const benchCommand: CommandModule = { * 打印系统信息 */ function printSystemInfo() { - console.log(`主机: \t${os.hostname()}`); - console.log(`系统: \t${os.type()} - ${os.release()}`); - console.log(`架构: \t${os.arch()} - ${os.version()}`); + console.log(`Host: \t${os.hostname()}`); + console.log(`System: \t${os.type()} - ${os.release()}`); + console.log(`Architecture: \t${os.arch()} - ${os.version()}`); console.log(`CPU: \t${os.cpus().length}`); - console.log(`内存: \t${filesize(os.totalmem(), { base: 2 })}`); + console.log(`Memory: \t${filesize(os.totalmem(), { base: 2 })}`); } function calcUsage(startTime: [number, number]) { @@ -143,10 +143,12 @@ async function startBenchmark(options: BenchmarkOptions) { const spinner = ora(); spinner.info( - `测试方式: ${parallel ? `并行, 并行上限 ${parallelLimit}` : `串行`}` + `Test mode: ${ + parallel ? `parallel, parallel limit ${parallelLimit}` : `serial` + }` ); - spinner.info(`执行任务数: ${number}`); - spinner.start('正在执行基准测试...'); + spinner.info(`Number of tasks to execute: ${number}`); + spinner.start('Benchmark in progress...'); try { const startTime = process.hrtime(); let res: (T | false)[] = []; @@ -172,13 +174,13 @@ async function startBenchmark(options: BenchmarkOptions) { const allUsage = calcUsage(startTime); const succeed = res.filter((i): i is T => Boolean(i)); const failed = res.filter((i) => !Boolean(i)); - spinner.succeed(`基准测试完毕, 用时: ${prettyMs(allUsage)}`); - console.log(`成功/失败: ${succeed.length}/${failed.length}`); + spinner.succeed(`Benchmarking is complete, usage: ${prettyMs(allUsage)}`); + console.log(`Success/Failed: ${succeed.length}/${failed.length}`); console.log(`TPS: ${res.length / (allUsage / 1000)}`); onCompleted(succeed); } catch (err) { console.error(err); - spinner.fail(`基准测试出现问题`).stop(); + spinner.fail(`A problem with benchmarking`).stop(); } } diff --git a/apps/cli/src/commands/connect.ts b/apps/cli/src/commands/connect.ts index 761b1bda..94ac4c99 100644 --- a/apps/cli/src/commands/connect.ts +++ b/apps/cli/src/commands/connect.ts @@ -5,7 +5,7 @@ import { config } from 'dotenv'; export const connectCommand: CommandModule = { command: 'connect', - describe: '连接到 Tailchat 节点网络', + describe: 'Connect to Tailchat network', builder: undefined, async handler(args) { config(); diff --git a/apps/cli/src/commands/create.ts b/apps/cli/src/commands/create.ts index 4a35deac..41adfbe9 100644 --- a/apps/cli/src/commands/create.ts +++ b/apps/cli/src/commands/create.ts @@ -7,11 +7,11 @@ const plop = nodePlop(path.resolve(__dirname, '../../templates/plopfile.js')); export const createCommand: CommandModule = { command: 'create [template]', - describe: '创建 Tailchat 项目代码', + describe: 'Create Tailchat repo code', builder: (yargs) => yargs.positional('template', { demandOption: true, - description: '代码模板名', + description: 'Template Name', type: 'string', choices: plop.getGeneratorList().map((v) => v.name), }), @@ -23,7 +23,7 @@ export const createCommand: CommandModule = { { type: 'list', name: 'template', - message: '选择代码模板', + message: 'Choose Template', choices: plop.getGeneratorList().map((v) => ({ name: `${v.name} (${v.description})`, value: v.name, @@ -40,11 +40,11 @@ export const createCommand: CommandModule = { const answers = await basic.runPrompts(); const results = await basic.runActions(answers); - console.log('操作变更:'); + console.log('Changes:'); console.log(results.changes.map((change) => change.path).join('\n')); if (results.failures.length > 0) { - console.log('操作失败:'); + console.log('Operation failed:'); console.log(results.failures); } }, diff --git a/apps/cli/src/commands/declaration.ts b/apps/cli/src/commands/declaration.ts index 38a705f9..3d7f59e9 100644 --- a/apps/cli/src/commands/declaration.ts +++ b/apps/cli/src/commands/declaration.ts @@ -12,11 +12,11 @@ const onlineDeclarationUrl = withGhProxy( export const declarationCommand: CommandModule = { command: 'declaration ', - describe: 'Tailchat 插件类型声明', + describe: 'Tailchat plugin type declaration', builder: (yargs) => yargs.positional('source', { demandOption: true, - description: '声明类型来源', + description: 'Declaration Type Source', type: 'string', choices: ['empty', 'github'], }), @@ -28,14 +28,14 @@ export const declarationCommand: CommandModule = { { type: 'list', name: 'source', - message: '选择类型来源', + message: 'Select type source', choices: [ { - name: '空', + name: 'Empty', value: 'empty', }, { - name: '从 Github 下载完整声明', + name: 'Download the full statement from Github', value: 'github', }, ], @@ -51,18 +51,20 @@ export const declarationCommand: CommandModule = { } else if (source === 'github') { const url = onlineDeclarationUrl; - const spinner = ora(`正在从 Github 下载插件类型声明: ${url}`).start(); + const spinner = ora( + `Downloading plugin type declarations from Github: ${url}` + ).start(); content = await got.get(url).then((res) => res.body); - spinner.succeed('声明文件下载完毕'); + spinner.succeed('The declaration file has been downloaded'); } if (content !== '') { const target = path.resolve(process.cwd(), './types/tailchat.d.ts'); await mkdirp(path.dirname(target)); await fs.writeFile(target, content); - console.log('写入类型文件完毕:', target); + console.log('Writing type file complete:', target); } }, }; diff --git a/apps/cli/src/commands/docker/doctor.ts b/apps/cli/src/commands/docker/doctor.ts index 9e5936ff..6c2f4fd6 100644 --- a/apps/cli/src/commands/docker/doctor.ts +++ b/apps/cli/src/commands/docker/doctor.ts @@ -5,7 +5,7 @@ import filesize from 'filesize'; export const dockerDoctorCommand: CommandModule = { command: 'doctor', - describe: 'docker 环境检查', + describe: 'docker environment check', builder: undefined, async handler(args) { const docker = new Docker(); @@ -15,7 +15,7 @@ export const dockerDoctorCommand: CommandModule = { (image.RepoTags ?? []).some((tag) => tag.includes('tailchat')) ); - console.log('Tailchat 镜像列表:'); + console.log('Tailchat image list:'); console.log( asTable.configure({ delimiter: ' | ' })( tailchatImages.map((image) => ({ diff --git a/apps/cli/src/commands/docker/index.ts b/apps/cli/src/commands/docker/index.ts index 65fddd56..7b46c3f8 100644 --- a/apps/cli/src/commands/docker/index.ts +++ b/apps/cli/src/commands/docker/index.ts @@ -7,7 +7,7 @@ import { dockerDoctorCommand } from './doctor'; export const dockerCommand: CommandModule = { command: 'docker', - describe: 'Tailchat 镜像管理', + describe: 'Tailchat image management', builder: (yargs) => yargs .command(dockerInitCommand) diff --git a/apps/cli/src/commands/docker/init.ts b/apps/cli/src/commands/docker/init.ts index 7ca1498a..8d6ed579 100644 --- a/apps/cli/src/commands/docker/init.ts +++ b/apps/cli/src/commands/docker/init.ts @@ -11,24 +11,28 @@ import { withGhProxy } from '../../utils'; // https://docs.docker.com/engine/api/v1.41/ const initWelcome = `================ -正在为您初始化 Tailchat 配置与环境变量 -完整的环境变量列表可以访问: ${chalk.underline( +Initializing Tailchat configuration and environment variables for you +A complete list of environment variables can be accessed at: ${chalk.underline( 'https://tailchat.msgbyte.com/docs/deployment/environment' -)} 以了解更多 +)} to learn more ================`; const initCompleted = (dir: string) => chalk.green(`================ -恭喜你已经成功完成了配置初始化, 你的配置文件已经准备就绪,距离成功成功部署就差一步了! +Congratulations, you have successfully completed the configuration initialization, your configuration file is ready, and you are one step away from a successful deployment! -你的tailchat配置文件都被存储在: ${chalk.underline( +Your tailchat configuration files are stored in: ${chalk.underline( path.join(process.cwd(), dir) )} -运行以下命令以完成镜像下载与启动: -- ${chalk.bold(`cd ${dir}`)} ${chalk.gray('# 移动到安装目录')} -- ${chalk.bold('tailchat docker update')} ${chalk.gray('# 下载/更新官方镜像')} -- ${chalk.bold('docker compose up -d')} ${chalk.gray('# 启动服务')} +Run the following command to complete the image download and start: +- ${chalk.bold(`cd ${dir}`)} ${chalk.gray( + '# Move to the installation directory' + )} +- ${chalk.bold('tailchat docker update')} ${chalk.gray( + '# Download/update the official mirror' + )} +- ${chalk.bold('docker compose up -d')} ${chalk.gray('# Start service')} ================`); const envUrl = withGhProxy( @@ -40,7 +44,7 @@ const configUrl = withGhProxy( export const dockerInitCommand: CommandModule = { command: 'init', - describe: '初始化Tailchat with docker配置', + describe: 'Initialize Tailchat with docker configuration', builder: undefined, async handler(args) { const spinner = ora(); @@ -51,36 +55,37 @@ export const dockerInitCommand: CommandModule = { name: 'dir', type: 'input', default: './tailchat', - message: '配置存放目录', + message: 'Configurate storage directory', }, { name: 'secret', type: 'input', default: randomString({ length: 16 }), message: - '(SECRET)请输入任意字符串,这将会作为Tailchat进行用户身份签名的秘钥,泄露该字符串则会产生身份伪造的风险, 默认随机生成一个16位字符串', + '(SECRET)Please enter any string, which will be used as the secret key for Tailchat to sign the user identity. Leaking this string will cause the risk of identity forgery. By default, a 16-digit string is randomly generated', }, { name: 'apiUrl', type: 'input', message: - '(API_URL)请配置外网能够访问的地址,这个会影响文件的存储路径与访问地址, 示例: https://tailchat.example.com', + '(API_URL)Please configure an address that can be accessed by the external network, which will affect the storage path and access address of the file, example: https://tailchat.example.com', }, { name: 'fileLimit', type: 'number', default: 1048576, - message: '(FILE_LIMIT)文件上传体积限制, 默认为 1048576(1m)', + message: + '(FILE_LIMIT)File upload volume limit, the default is 1048576(1m)', }, ]); - spinner.start('开始下载最新的配置文件'); + spinner.start('Start downloading the latest configuration file'); // eslint-disable-next-line prefer-const let [rawEnv, rawConfig] = await Promise.all([ got(envUrl).then((res) => res.body), got(configUrl).then((res) => res.body), ]); - spinner.info('配置文件下载完毕'); + spinner.info('The configuration file is downloaded'); if (secret) { rawEnv = setEnvValue(rawEnv, 'SECRET', secret); @@ -96,7 +101,7 @@ export const dockerInitCommand: CommandModule = { if ( await promptConfirm( - '需要配置邮件服务么?邮件服务可以用于密码找回以及邮件通知等功能。' + 'Do you need to configure the email service? The email service can be used for functions such as password retrieval and email notification.' ) ) { const { stmpURI, stmpSender } = await inquirer.prompt([ @@ -104,13 +109,13 @@ export const dockerInitCommand: CommandModule = { name: 'stmpURI', type: 'input', message: - '(SMTP_URI)请配置邮件服务SMTP的连接地址,示例: smtps://username:password@example.mailserver.com/?pool=true', + '(SMTP_URI) Please configure the SMTP connection address of the mail service, for example: smtps://username:password@example.mailserver.com/?pool=true', }, { name: 'stmpSender', type: 'input', message: - '(SMTP_SENDER)邮件发送人,示例: "Tailchat" tailchat@example.mailserver.com', + '(SMTP_SENDER) Email sender, example: "Tailchat" tailchat@example.mailserver.com', }, ]); @@ -124,7 +129,7 @@ export const dockerInitCommand: CommandModule = { if (stmpURI && stmpSender) { if ( await promptConfirm( - '是否需要开启邮箱校验? 开启后当用户注册时需要校验邮箱通过以后才能继续注册' + 'Do you need to enable email verification? After it is enabled, when the user registers, it is necessary to verify the email address and pass it before continuing to register' ) ) { rawEnv = setEnvValue(rawEnv, 'EMAIL_VERIFY', 'true'); @@ -132,20 +137,20 @@ export const dockerInitCommand: CommandModule = { } } - spinner.info(`正在创建目录 ${dir} ...`); + spinner.info(`Creating directory ${dir} ...`); await fs.mkdirp(dir); - spinner.info('正在写入配置文件 ...'); + spinner.info('Writing configuration file ...'); await Promise.all([ fs.writeFile(path.join(dir, 'docker-compose.env'), rawEnv), fs.writeFile(path.join(dir, 'docker-compose.yml'), rawConfig), ]); - spinner.succeed('配置初始化完毕'); + spinner.succeed('The configuration is initialized'); console.log(initCompleted(dir)); } catch (err) { - spinner.fail('Tailchat with docker 初始化出现意外'); + spinner.fail('Unexpected initialization of Tailchat with docker'); console.error(err); } }, diff --git a/apps/cli/src/commands/docker/update.ts b/apps/cli/src/commands/docker/update.ts index 3f308c99..fbf89f3e 100644 --- a/apps/cli/src/commands/docker/update.ts +++ b/apps/cli/src/commands/docker/update.ts @@ -12,12 +12,12 @@ const targetImageName = targetImage.repo + targetImage.tag; export const dockerUpdateCommand: CommandModule = { command: 'update', - describe: '更新Tailchat镜像版本', + describe: 'Update Tailchat image version', builder: undefined, async handler(args) { const docker = new Docker(); - const spinner = ora().start('开始更新镜像'); + const spinner = ora().start('Start updating the image'); try { const pullSpinnies = new Spinnies(); @@ -32,7 +32,7 @@ export const dockerUpdateCommand: CommandModule = { return; } - spinner.info('已找到远程镜像, 开始下载'); + spinner.info('The remote image has been found, start downloading'); docker.modem.followProgress( stream, @@ -82,22 +82,26 @@ export const dockerUpdateCommand: CommandModule = { }); }); - spinner.succeed('下载镜像完毕'); + spinner.succeed('Download image complete'); const image = docker.getImage(remoteImageName); if (!image) { - spinner.fail('出现异常,没有找到下载的镜像'); + spinner.fail( + 'An exception occurred, the downloaded image was not found' + ); return; } - spinner.info('正在更新镜像标签'); + spinner.info('Updating image tags'); await image.tag(targetImage); - spinner.succeed('镜像标签更新完毕'); + spinner.succeed('The image tag has been updated'); } catch (err) { - spinner.fail('更新出现错误, 请检查网络配置'); + spinner.fail( + 'An update error occurred, please check the network configuration' + ); console.error(err); } }, diff --git a/apps/cli/src/commands/usage.ts b/apps/cli/src/commands/usage.ts index 005e278d..df0dd96d 100644 --- a/apps/cli/src/commands/usage.ts +++ b/apps/cli/src/commands/usage.ts @@ -7,11 +7,11 @@ import _ from 'lodash'; export const usageCommand: CommandModule = { command: 'usage [pid]', - describe: '查看 Tailchat 进程用量', + describe: 'View Tailchat process usage', builder: (yargs) => yargs.positional('pid', { demandOption: false, - description: '进程ID', + description: 'process id', type: 'number', }), async handler(args) { @@ -26,7 +26,7 @@ export const usageCommand: CommandModule = { { type: 'checkbox', name: 'process', - message: '选择需要查看的进程', + message: 'Select the process to view', choices: processList.map((item) => ({ name: `(${item.pid})${item.cmd}`, value: item.pid, diff --git a/apps/cli/src/utils.ts b/apps/cli/src/utils.ts index cfc5b9e4..1ba32d78 100644 --- a/apps/cli/src/utils.ts +++ b/apps/cli/src/utils.ts @@ -1,12 +1,12 @@ /** - * 判断是否为开发环境 + * Determine whether it is a development environment */ export function isDev(): boolean { return process.env.NODE_ENV === 'development'; } /** - * 增加github资源代理以优化国内访问速度 + * Add github resource proxy to optimize chinese access speed */ export function withGhProxy(url: string): string { return `https://ghproxy.com/${url}`; diff --git a/website/docs/cli/_category_.json b/website/docs/cli/_category_.json index be233a0e..a3077684 100644 --- a/website/docs/cli/_category_.json +++ b/website/docs/cli/_category_.json @@ -1,4 +1,4 @@ { - "label": "命令行终端", + "label": "cli", "position": 40 } diff --git a/website/docs/cli/tailchat-cli.md b/website/docs/cli/tailchat-cli.md index 94d370ff..955f14b4 100644 --- a/website/docs/cli/tailchat-cli.md +++ b/website/docs/cli/tailchat-cli.md @@ -1,12 +1,12 @@ --- sidebar_position: 1 -title: 命令行工具 tailchat-cli +title: tailchat-cli --- ## 安装 ```bash -npm install -g tailchat-cli@latest # 安装与更新同一命令 +npm install -g tailchat-cli@latest # Install and update with the same command ``` 或直接使用 @@ -14,18 +14,18 @@ npm install -g tailchat-cli@latest # 安装与更新同一命令 npx tailchat-cli ``` -安装成功后输入`tailchat` 后返回如下 +After the installation is successful, enter `tailchat` and return as follows: ```bash tailchat Commands: - tailchat create [template] 创建 Tailchat 项目代码 - tailchat connect 连接到 Tailchat 节点网络 - tailchat app Tailchat cli 版本(WIP) - tailchat bench 压力测试 - tailchat declaration Tailchat 插件类型声明 - tailchat docker Tailchat 镜像管理 + tailchat create [template] Create Tailchat repo code + tailchat connect Connect to Tailchat network + tailchat bench Benchmark + tailchat declaration Tailchat plugin type declaration + tailchat docker Tailchat image management + tailchat usage [pid] View Tailchat process usage Options: --version Show version number [boolean] diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current.json b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current.json index 56ab5245..3668ba59 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current.json +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current.json @@ -11,10 +11,6 @@ "message": "插件列表", "description": "The label for category 插件列表 in sidebar tutorialSidebar" }, - "sidebar.tutorialSidebar.category.命令行终端": { - "message": "命令行终端", - "description": "The label for category 命令行终端 in sidebar tutorialSidebar" - }, "sidebar.tutorialSidebar.category.视频会议": { "message": "视频会议", "description": "The label for category 视频会议 in sidebar tutorialSidebar" @@ -42,5 +38,9 @@ "sidebar.tutorialSidebar.category.Advanced Usage": { "message": "进阶使用", "description": "The label for category Advanced Usage in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.cli": { + "message": "命令行终端", + "description": "The label for category cli in sidebar tutorialSidebar" } }