feat: migrate from inquirer to @inquirer/prompts for interactive prompts
- Replaced inquirer with @inquirer/prompts in various command files for improved prompt handling. - Updated confirmation and input prompts in commands such as app, config, deploy, login, and others. - Added a new command 'cc' for switching between Claude code models with appropriate configurations. - Enhanced user experience by ensuring prompts are more streamlined and consistent across the application.
This commit is contained in:
13
package.json
13
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@kevisual/cli",
|
"name": "@kevisual/cli",
|
||||||
"version": "0.0.78",
|
"version": "0.0.80",
|
||||||
"description": "envision 命令行工具",
|
"description": "envision 命令行工具",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"basename": "/root/cli",
|
"basename": "/root/cli",
|
||||||
@@ -41,9 +41,11 @@
|
|||||||
],
|
],
|
||||||
"author": "abearxiong",
|
"author": "abearxiong",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@inquirer/prompts": "^8.2.0",
|
||||||
"@kevisual/app": "^0.0.2",
|
"@kevisual/app": "^0.0.2",
|
||||||
"@kevisual/context": "^0.0.4",
|
"@kevisual/context": "^0.0.4",
|
||||||
"@kevisual/hot-api": "^0.0.3",
|
"@kevisual/hot-api": "^0.0.3",
|
||||||
|
"@kevisual/use-config": "^1.0.26",
|
||||||
"@nut-tree-fork/nut-js": "^4.2.6",
|
"@nut-tree-fork/nut-js": "^4.2.6",
|
||||||
"eventemitter3": "^5.0.1",
|
"eventemitter3": "^5.0.1",
|
||||||
"lowdb": "^7.0.1",
|
"lowdb": "^7.0.1",
|
||||||
@@ -57,13 +59,13 @@
|
|||||||
"@kevisual/dts": "^0.0.3",
|
"@kevisual/dts": "^0.0.3",
|
||||||
"@kevisual/load": "^0.0.6",
|
"@kevisual/load": "^0.0.6",
|
||||||
"@kevisual/logger": "^0.0.4",
|
"@kevisual/logger": "^0.0.4",
|
||||||
"@kevisual/query": "0.0.33",
|
"@kevisual/query": "0.0.35",
|
||||||
"@kevisual/query-login": "0.0.7",
|
"@kevisual/query-login": "0.0.7",
|
||||||
"@types/bun": "^1.3.5",
|
"@types/bun": "^1.3.6",
|
||||||
"@types/crypto-js": "^4.2.2",
|
"@types/crypto-js": "^4.2.2",
|
||||||
"@types/jsonwebtoken": "^9.0.10",
|
"@types/jsonwebtoken": "^9.0.10",
|
||||||
"@types/micromatch": "^4.0.10",
|
"@types/micromatch": "^4.0.10",
|
||||||
"@types/node": "^25.0.3",
|
"@types/node": "^25.0.8",
|
||||||
"@types/semver": "^7.7.1",
|
"@types/semver": "^7.7.1",
|
||||||
"chalk": "^5.6.2",
|
"chalk": "^5.6.2",
|
||||||
"commander": "^14.0.2",
|
"commander": "^14.0.2",
|
||||||
@@ -72,10 +74,9 @@
|
|||||||
"filesize": "^11.0.13",
|
"filesize": "^11.0.13",
|
||||||
"form-data": "^4.0.5",
|
"form-data": "^4.0.5",
|
||||||
"ignore": "^7.0.5",
|
"ignore": "^7.0.5",
|
||||||
"inquirer": "^13.1.0",
|
|
||||||
"jsonwebtoken": "^9.0.3",
|
"jsonwebtoken": "^9.0.3",
|
||||||
"tar": "^7.5.2",
|
"tar": "^7.5.2",
|
||||||
"zustand": "^5.0.9"
|
"zustand": "^5.0.10"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=22.0.0"
|
"node": ">=22.0.0"
|
||||||
|
|||||||
521
pnpm-lock.yaml
generated
521
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -10,7 +10,7 @@ import { fileIsExist } from '@/uitls/file.ts';
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import { getConfig } from '@/module/get-config.ts';
|
import { getConfig } from '@/module/get-config.ts';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import inquirer from 'inquirer';
|
import { confirm } from '@inquirer/prompts';
|
||||||
import { baseURL, getUrl } from '@/module/query.ts';
|
import { baseURL, getUrl } from '@/module/query.ts';
|
||||||
export const appCommand = new Command('app').description('app 命令').action(() => {
|
export const appCommand = new Command('app').description('app 命令').action(() => {
|
||||||
console.log('app');
|
console.log('app');
|
||||||
@@ -99,15 +99,11 @@ const uninstallAppCommand = new Command('uninstall')
|
|||||||
if (!checkPath) {
|
if (!checkPath) {
|
||||||
console.error(chalk.red('path is error, 请输入正确的路径'));
|
console.error(chalk.red('path is error, 请输入正确的路径'));
|
||||||
} else {
|
} else {
|
||||||
const answer = await inquirer.prompt([
|
const confirmed = await confirm({
|
||||||
{
|
|
||||||
type: 'confirm',
|
|
||||||
name: 'confirm',
|
|
||||||
message: `确定要删除 ${_path} 吗?`,
|
message: `确定要删除 ${_path} 吗?`,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
});
|
||||||
]);
|
if (confirmed) {
|
||||||
if (answer.confirm) {
|
|
||||||
fs.rmSync(_path, { recursive: true });
|
fs.rmSync(_path, { recursive: true });
|
||||||
console.log(chalk.green('删除成功', _path));
|
console.log(chalk.green('删除成功', _path));
|
||||||
}
|
}
|
||||||
|
|||||||
120
src/command/cc.ts
Normal file
120
src/command/cc.ts
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
import { program, Command } from '@/program.ts';
|
||||||
|
import { chalk } from '../module/chalk.ts';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { spawn } from 'node:child_process';
|
||||||
|
import { useKey } from '@kevisual/use-config';
|
||||||
|
import os from 'node:os'
|
||||||
|
import fs from 'node:fs';
|
||||||
|
import { select } from '@inquirer/prompts';
|
||||||
|
|
||||||
|
const MODELS = ['minimax', 'glm'] as const;
|
||||||
|
type Model = typeof MODELS[number];
|
||||||
|
|
||||||
|
const changeMinimax = (token?: string) => {
|
||||||
|
const auth_token = token || useKey("MINIMAX_API_KEY")
|
||||||
|
return {
|
||||||
|
"env": {
|
||||||
|
"ANTHROPIC_AUTH_TOKEN": auth_token,
|
||||||
|
"ANTHROPIC_BASE_URL": "https://api.minimaxi.com/anthropic",
|
||||||
|
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "MiniMax-M2.1",
|
||||||
|
"ANTHROPIC_DEFAULT_OPUS_MODEL": "MiniMax-M2.1",
|
||||||
|
"ANTHROPIC_DEFAULT_SONNET_MODEL": "MiniMax-M2.1",
|
||||||
|
"ANTHROPIC_MODEL": "MiniMax-M2.1",
|
||||||
|
"API_TIMEOUT_MS": "3000000",
|
||||||
|
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const changeGLM = (token?: string) => {
|
||||||
|
const auth_token = token || useKey('ZHIPU_API_KEY')
|
||||||
|
return {
|
||||||
|
"env": {
|
||||||
|
"ANTHROPIC_AUTH_TOKEN": auth_token,
|
||||||
|
"ANTHROPIC_BASE_URL": "https://open.bigmodel.cn/api/anthropic",
|
||||||
|
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "glm-4.7",
|
||||||
|
"ANTHROPIC_DEFAULT_OPUS_MODEL": "glm-4.7",
|
||||||
|
"ANTHROPIC_DEFAULT_SONNET_MODEL": "glm-4.7",
|
||||||
|
"ANTHROPIC_MODEL": "glm-4.7"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 跳过登录检查,在~/.claude.json的配置中添加字段 "hasCompletedOnboarding": true
|
||||||
|
*/
|
||||||
|
const changeNoCheck = () => {
|
||||||
|
const homeDir = os.homedir();
|
||||||
|
const claudeConfigPath = path.join(homeDir, '.claude.json');
|
||||||
|
|
||||||
|
let claudeConfig = {};
|
||||||
|
if (fs.existsSync(claudeConfigPath)) {
|
||||||
|
const content = fs.readFileSync(claudeConfigPath, 'utf-8');
|
||||||
|
try {
|
||||||
|
claudeConfig = JSON.parse(content);
|
||||||
|
} catch {
|
||||||
|
claudeConfig = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
claudeConfig = {
|
||||||
|
...claudeConfig,
|
||||||
|
hasCompletedOnboarding: true
|
||||||
|
};
|
||||||
|
|
||||||
|
fs.writeFileSync(claudeConfigPath, JSON.stringify(claudeConfig, null, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
const modelConfig: Record<Model, (token?: string) => object> = {
|
||||||
|
minimax: changeMinimax,
|
||||||
|
glm: changeGLM,
|
||||||
|
};
|
||||||
|
|
||||||
|
const readOrCreateConfig = (configPath: string): Record<string, unknown> => {
|
||||||
|
if (fs.existsSync(configPath)) {
|
||||||
|
const content = fs.readFileSync(configPath, 'utf-8');
|
||||||
|
try {
|
||||||
|
return JSON.parse(content);
|
||||||
|
} catch {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveConfig = (configPath: string, config: Record<string, unknown>) => {
|
||||||
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const command = new Command('cc')
|
||||||
|
.description('切换claude code模型,支持GLM4.7和Minimax')
|
||||||
|
.option('-m, --models <model:string>', `选择模型: ${MODELS.join(' | ')}`)
|
||||||
|
.action(async (options) => {
|
||||||
|
const configPath = path.join(os.homedir(), '.claude/settings.json');
|
||||||
|
|
||||||
|
// 读取或创建配置
|
||||||
|
const config = readOrCreateConfig(configPath);
|
||||||
|
|
||||||
|
// 如果没有指定模型,使用 inquire 选择
|
||||||
|
let selectedModel: Model;
|
||||||
|
if (options.models && MODELS.includes(options.models as Model)) {
|
||||||
|
selectedModel = options.models as Model;
|
||||||
|
} else {
|
||||||
|
selectedModel = await select({
|
||||||
|
message: '请选择模型:',
|
||||||
|
choices: MODELS,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新配置
|
||||||
|
const updateConfig = modelConfig[selectedModel]();
|
||||||
|
Object.assign(config, updateConfig);
|
||||||
|
|
||||||
|
// 保存配置
|
||||||
|
saveConfig(configPath, config);
|
||||||
|
changeNoCheck();
|
||||||
|
|
||||||
|
console.log(`已切换到模型: ${chalk.green(selectedModel)}`);
|
||||||
|
console.log(`配置已保存到: ${configPath}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
program.addCommand(command)
|
||||||
@@ -3,7 +3,7 @@ import { checkFileExists, getConfig, writeConfig } from '@/module/index.ts';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import { chalk } from '@/module/chalk.ts';
|
import { chalk } from '@/module/chalk.ts';
|
||||||
import inquirer from 'inquirer';
|
import { confirm, input } from '@inquirer/prompts';
|
||||||
|
|
||||||
// 设置工作目录
|
// 设置工作目录
|
||||||
const setWorkdir = async (options: { workdir: string }) => {
|
const setWorkdir = async (options: { workdir: string }) => {
|
||||||
@@ -24,15 +24,11 @@ const setWorkdir = async (options: { workdir: string }) => {
|
|||||||
console.log('路径不存在');
|
console.log('路径不存在');
|
||||||
fs.mkdirSync(finalPath, { recursive: true });
|
fs.mkdirSync(finalPath, { recursive: true });
|
||||||
}
|
}
|
||||||
const answers = await inquirer.prompt([
|
const confirmed = await confirm({
|
||||||
{
|
|
||||||
type: 'confirm',
|
|
||||||
name: 'confirm',
|
|
||||||
message: `Are you sure you want to set the workdir to: ${finalPath}?`,
|
message: `Are you sure you want to set the workdir to: ${finalPath}?`,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
});
|
||||||
]);
|
if (confirmed) {
|
||||||
if (answers.confirm) {
|
|
||||||
flag = true;
|
flag = true;
|
||||||
config.workdir = finalPath;
|
config.workdir = finalPath;
|
||||||
console.log(chalk.green(`set workdir success:`, finalPath));
|
console.log(chalk.green(`set workdir success:`, finalPath));
|
||||||
@@ -81,15 +77,11 @@ const command = new Command('config')
|
|||||||
console.log('路径不存在');
|
console.log('路径不存在');
|
||||||
fs.mkdirSync(finalPath, { recursive: true });
|
fs.mkdirSync(finalPath, { recursive: true });
|
||||||
}
|
}
|
||||||
const answers = await inquirer.prompt([
|
const confirmed = await confirm({
|
||||||
{
|
|
||||||
type: 'confirm',
|
|
||||||
name: 'confirm',
|
|
||||||
message: `Are you sure you want to set the workdir to: ${finalPath}?`,
|
message: `Are you sure you want to set the workdir to: ${finalPath}?`,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
});
|
||||||
]);
|
if (confirmed) {
|
||||||
if (answers.confirm) {
|
|
||||||
flag = true;
|
flag = true;
|
||||||
config.workdir = finalPath;
|
config.workdir = finalPath;
|
||||||
console.log(chalk.green(`set workdir success:`, finalPath));
|
console.log(chalk.green(`set workdir success:`, finalPath));
|
||||||
@@ -100,15 +92,11 @@ const command = new Command('config')
|
|||||||
if (options.set) {
|
if (options.set) {
|
||||||
const key = options.set;
|
const key = options.set;
|
||||||
let value = options.value;
|
let value = options.value;
|
||||||
const answer = await inquirer.prompt([
|
if (!value) {
|
||||||
{
|
value = await input({
|
||||||
type: 'input',
|
|
||||||
name: 'value',
|
|
||||||
message: `Enter your ${key}:(current: ${config[key]})`,
|
message: `Enter your ${key}:(current: ${config[key]})`,
|
||||||
when: () => !value,
|
});
|
||||||
},
|
}
|
||||||
]);
|
|
||||||
value = answer.value || value;
|
|
||||||
if (key && value) {
|
if (key && value) {
|
||||||
flag = true;
|
flag = true;
|
||||||
config[key] = value;
|
config[key] = value;
|
||||||
@@ -138,16 +126,10 @@ const setCommand = new Command('set')
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let flag = false;
|
let flag = false;
|
||||||
const answer = await inquirer.prompt([
|
if (value === 'not_input') {
|
||||||
{
|
value = await input({
|
||||||
type: 'input',
|
|
||||||
name: 'value',
|
|
||||||
message: `Enter your ${key}:(current: ${config[key]})`,
|
message: `Enter your ${key}:(current: ${config[key]})`,
|
||||||
when: () => value === 'not_input',
|
});
|
||||||
},
|
|
||||||
]);
|
|
||||||
if (value === 'not_input' && !answer.value) {
|
|
||||||
value = '';
|
|
||||||
}
|
}
|
||||||
if (key === 'workdir') {
|
if (key === 'workdir') {
|
||||||
await setWorkdir({ workdir: value });
|
await setWorkdir({ workdir: value });
|
||||||
@@ -192,15 +174,11 @@ const getCommand = new Command('get')
|
|||||||
.action(async (key) => {
|
.action(async (key) => {
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
const keys = Object.keys(config);
|
const keys = Object.keys(config);
|
||||||
const answer = await inquirer.prompt([
|
if (!key) {
|
||||||
{
|
key = await input({
|
||||||
type: 'input',
|
|
||||||
name: 'key',
|
|
||||||
message: `Enter your key:(keys: ${JSON.stringify(keys)})`,
|
message: `Enter your key:(keys: ${JSON.stringify(keys)})`,
|
||||||
when: () => !key,
|
});
|
||||||
},
|
}
|
||||||
]);
|
|
||||||
key = answer.key || key;
|
|
||||||
|
|
||||||
if (config[key]) {
|
if (config[key]) {
|
||||||
console.log(chalk.green(`get ${key}:`));
|
console.log(chalk.green(`get ${key}:`));
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import path from 'path';
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import FormData from 'form-data';
|
import FormData from 'form-data';
|
||||||
import { getBaseURL, query, storage } from '@/module/query.ts';
|
import { getBaseURL, query, storage } from '@/module/query.ts';
|
||||||
import inquirer from 'inquirer';
|
import { input, confirm } from '@inquirer/prompts';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import { upload } from '@/module/download/upload.ts';
|
import { upload } from '@/module/download/upload.ts';
|
||||||
import { getHash } from '@/uitls/hash.ts';
|
import { getHash } from '@/uitls/hash.ts';
|
||||||
@@ -60,23 +60,15 @@ const command = new Command('deploy')
|
|||||||
key = pkgInfo?.appKey || '';
|
key = pkgInfo?.appKey || '';
|
||||||
}
|
}
|
||||||
logger.debug('start deploy');
|
logger.debug('start deploy');
|
||||||
if (!version || !key) {
|
if (!version) {
|
||||||
const answers = await inquirer.prompt([
|
version = await input({
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
name: 'version',
|
|
||||||
message: 'Enter your version:',
|
message: 'Enter your version:',
|
||||||
when: () => !version,
|
});
|
||||||
},
|
}
|
||||||
{
|
if (!key) {
|
||||||
type: 'input',
|
key = await input({
|
||||||
name: 'key',
|
|
||||||
message: 'Enter your key:',
|
message: 'Enter your key:',
|
||||||
when: () => !key,
|
});
|
||||||
},
|
|
||||||
]);
|
|
||||||
version = answers.version || version;
|
|
||||||
key = answers.key || key;
|
|
||||||
}
|
}
|
||||||
const pwd = process.cwd();
|
const pwd = process.cwd();
|
||||||
const directory = path.join(pwd, filePath);
|
const directory = path.join(pwd, filePath);
|
||||||
@@ -110,14 +102,10 @@ const command = new Command('deploy')
|
|||||||
logger.debug('upload Files Key', key, version);
|
logger.debug('upload Files Key', key, version);
|
||||||
if (!yes) {
|
if (!yes) {
|
||||||
// 确认是否上传
|
// 确认是否上传
|
||||||
const confirm = await inquirer.prompt([
|
const confirmed = await confirm({
|
||||||
{
|
|
||||||
type: 'confirm',
|
|
||||||
name: 'confirm',
|
|
||||||
message: 'Do you want to upload these files?',
|
message: 'Do you want to upload these files?',
|
||||||
},
|
});
|
||||||
]);
|
if (!confirmed) {
|
||||||
if (!confirm.confirm) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { program, Command } from '@/program.ts';
|
import { program, Command } from '@/program.ts';
|
||||||
import { getConfig, getEnvToken } from '@/module/get-config.ts';
|
import { getConfig, getEnvToken } from '@/module/get-config.ts';
|
||||||
import inquirer from 'inquirer';
|
import { input, password } from '@inquirer/prompts';
|
||||||
import { loginInCommand } from '@/module/login/login-by-web.ts';
|
import { loginInCommand } from '@/module/login/login-by-web.ts';
|
||||||
import { queryLogin, storage } from '@/module/query.ts';
|
import { queryLogin, storage } from '@/module/query.ts';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
@@ -28,24 +28,15 @@ const loginCommand = new Command('login')
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 如果没有传递参数,则通过交互式输入
|
// 如果没有传递参数,则通过交互式输入
|
||||||
if (!username || !password) {
|
if (!username) {
|
||||||
const answers = await inquirer.prompt([
|
username = await input({
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
name: 'username',
|
|
||||||
message: 'Enter your username:',
|
message: 'Enter your username:',
|
||||||
when: () => !username, // 当 username 为空时,提示用户输入
|
});
|
||||||
},
|
}
|
||||||
{
|
if (!password) {
|
||||||
type: 'password',
|
password = await password({
|
||||||
name: 'password',
|
|
||||||
message: 'Enter your password:',
|
message: 'Enter your password:',
|
||||||
mask: '*', // 隐藏输入的字符
|
});
|
||||||
when: () => !password, // 当 password 为空时,提示用户输入
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
username = answers.username || username;
|
|
||||||
password = answers.password || password;
|
|
||||||
}
|
}
|
||||||
const token = storage.getItem('token');
|
const token = storage.getItem('token');
|
||||||
if (token) {
|
if (token) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { program as app, Command } from '@/program.ts';
|
import { program as app, Command } from '@/program.ts';
|
||||||
import { getConfig, getEnvToken, writeConfig } from '@/module/index.ts';
|
import { getConfig, getEnvToken, writeConfig } from '@/module/index.ts';
|
||||||
import { queryLogin, storage } from '@/module/query.ts';
|
import { queryLogin, storage } from '@/module/query.ts';
|
||||||
import inquirer from 'inquirer';
|
import { input } from '@inquirer/prompts';
|
||||||
import util from 'util';
|
import util from 'util';
|
||||||
function isNumeric(str: string) {
|
function isNumeric(str: string) {
|
||||||
return /^-?\d+\.?\d*$/.test(str);
|
return /^-?\d+\.?\d*$/.test(str);
|
||||||
@@ -136,14 +136,9 @@ const setBaseURL = new Command('set')
|
|||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
let baseURL = opt.baseURL;
|
let baseURL = opt.baseURL;
|
||||||
if (!baseURL) {
|
if (!baseURL) {
|
||||||
const answers = await inquirer.prompt([
|
baseURL = await input({
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
name: 'baseURL',
|
|
||||||
message: `Enter your baseURL:(current: ${config.baseURL})`,
|
message: `Enter your baseURL:(current: ${config.baseURL})`,
|
||||||
},
|
});
|
||||||
]);
|
|
||||||
baseURL = answers.baseURL;
|
|
||||||
if (!baseURL) {
|
if (!baseURL) {
|
||||||
console.log('baseURL is required');
|
console.log('baseURL is required');
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { spawn } from 'child_process';
|
|||||||
import { fileIsExist } from '@/uitls/file.ts';
|
import { fileIsExist } from '@/uitls/file.ts';
|
||||||
import { getConfig } from '@/module/get-config.ts';
|
import { getConfig } from '@/module/get-config.ts';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import inquirer from 'inquirer';
|
import { select, confirm } from '@inquirer/prompts';
|
||||||
import { checkPnpm } from '@/uitls/npm.ts';
|
import { checkPnpm } from '@/uitls/npm.ts';
|
||||||
const parseIfJson = (str: string) => {
|
const parseIfJson = (str: string) => {
|
||||||
try {
|
try {
|
||||||
@@ -21,10 +21,8 @@ const publish = new Command('publish')
|
|||||||
.option('-t, --tag', 'tag')
|
.option('-t, --tag', 'tag')
|
||||||
.description('publish npm')
|
.description('publish npm')
|
||||||
.action(async (registry, options) => {
|
.action(async (registry, options) => {
|
||||||
const answer = await inquirer.prompt([
|
if (!registry) {
|
||||||
{
|
registry = await select({
|
||||||
type: 'list',
|
|
||||||
name: 'publish',
|
|
||||||
message: 'Select the registry to publish',
|
message: 'Select the registry to publish',
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
@@ -36,10 +34,8 @@ const publish = new Command('publish')
|
|||||||
value: 'npm',
|
value: 'npm',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
when: !registry,
|
});
|
||||||
},
|
}
|
||||||
]);
|
|
||||||
registry = registry || answer.publish;
|
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
let cmd = '';
|
let cmd = '';
|
||||||
const execPath = process.cwd();
|
const execPath = process.cwd();
|
||||||
@@ -149,15 +145,11 @@ const npmrc = new Command('set')
|
|||||||
if (options.force) {
|
if (options.force) {
|
||||||
writeFlag = true;
|
writeFlag = true;
|
||||||
} else {
|
} else {
|
||||||
const answer = await inquirer.prompt([
|
const confirmed = await confirm({
|
||||||
{
|
|
||||||
type: 'confirm',
|
|
||||||
name: 'confirm',
|
|
||||||
message: `Are you sure you want to overwrite the .npmrc file?`,
|
message: `Are you sure you want to overwrite the .npmrc file?`,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
});
|
||||||
]);
|
if (confirmed) {
|
||||||
if (answer.confirm) {
|
|
||||||
writeFlag = true;
|
writeFlag = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { program, Command } from '@/program.ts';
|
import { program, Command } from '@/program.ts';
|
||||||
import { chalk } from '@/module/chalk.ts';
|
import { chalk } from '@/module/chalk.ts';
|
||||||
import inquirer from 'inquirer';
|
|
||||||
|
|
||||||
const command = new Command('proxy')
|
const command = new Command('proxy')
|
||||||
.description('执行代理相关的命令')
|
.description('执行代理相关的命令')
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { getConfig, query } from '@/module/index.ts';
|
|||||||
import { fileIsExist } from '@/uitls/file.ts';
|
import { fileIsExist } from '@/uitls/file.ts';
|
||||||
import { chalk } from '@/module/chalk.ts';
|
import { chalk } from '@/module/chalk.ts';
|
||||||
import * as backServices from '@/query/services/index.ts';
|
import * as backServices from '@/query/services/index.ts';
|
||||||
import inquirer from 'inquirer';
|
import { select, input } from '@inquirer/prompts';
|
||||||
import { logger } from '@/module/logger.ts';
|
import { logger } from '@/module/logger.ts';
|
||||||
// 查找文件(忽略大小写)
|
// 查找文件(忽略大小写)
|
||||||
async function findFileInsensitive(targetFile: string): Promise<string | null> {
|
async function findFileInsensitive(targetFile: string): Promise<string | null> {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { program, Command } from '@/program.ts';
|
import { program, Command } from '@/program.ts';
|
||||||
import inquirer from 'inquirer';
|
import { input } from '@inquirer/prompts';
|
||||||
import { query } from '../module/index.ts';
|
import { query } from '../module/index.ts';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import util from 'util';
|
import util from 'util';
|
||||||
@@ -15,27 +15,14 @@ const command = new Command('service')
|
|||||||
let { path, key } = options;
|
let { path, key } = options;
|
||||||
// 如果没有传递参数,则通过交互式输入
|
// 如果没有传递参数,则通过交互式输入
|
||||||
if (!path) {
|
if (!path) {
|
||||||
const answers = await inquirer.prompt([
|
path = await input({
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
name: 'path',
|
|
||||||
required: true,
|
|
||||||
message: 'Enter your path:',
|
message: 'Enter your path:',
|
||||||
when: () => !path, // 当 username 为空时,提示用户输入
|
});
|
||||||
},
|
|
||||||
]);
|
|
||||||
path = answers.path || path;
|
|
||||||
}
|
}
|
||||||
if (!key) {
|
if (!key) {
|
||||||
const answers = await inquirer.prompt([
|
key = await input({
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
required: false,
|
|
||||||
name: 'key',
|
|
||||||
message: 'Enter your key:',
|
message: 'Enter your key:',
|
||||||
},
|
});
|
||||||
]);
|
|
||||||
key = answers.key || key;
|
|
||||||
}
|
}
|
||||||
const res = await query.post({ path, key });
|
const res = await query.post({ path, key });
|
||||||
if (res?.code === 200) {
|
if (res?.code === 200) {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import './command/gist/index.ts';
|
|||||||
import './command/config-remote.ts';
|
import './command/config-remote.ts';
|
||||||
import './command/config-secret-remote.ts';
|
import './command/config-secret-remote.ts';
|
||||||
import './command/ai.ts';
|
import './command/ai.ts';
|
||||||
|
import './command/cc.ts'
|
||||||
// program.parse(process.argv);
|
// program.parse(process.argv);
|
||||||
|
|
||||||
export const runParser = async (argv: string[]) => {
|
export const runParser = async (argv: string[]) => {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { chalk } from '../chalk.ts';
|
|||||||
import { Result } from '@kevisual/query';
|
import { Result } from '@kevisual/query';
|
||||||
import { fileIsExist } from '@/uitls/file.ts';
|
import { fileIsExist } from '@/uitls/file.ts';
|
||||||
import { glob } from 'fast-glob';
|
import { glob } from 'fast-glob';
|
||||||
import inquirer from 'inquirer';
|
import { confirm } from '@inquirer/prompts';
|
||||||
import { getEnvToken } from '../get-config.ts';
|
import { getEnvToken } from '../get-config.ts';
|
||||||
|
|
||||||
type DownloadTask = {
|
type DownloadTask = {
|
||||||
@@ -80,15 +80,11 @@ const checkDelete = async (opts?: { force?: boolean; dir?: string; yes?: boolean
|
|||||||
try {
|
try {
|
||||||
if (fileIsExist(dir)) {
|
if (fileIsExist(dir)) {
|
||||||
const files = await glob(`${dir}/**/*`, { onlyFiles: true });
|
const files = await glob(`${dir}/**/*`, { onlyFiles: true });
|
||||||
const answers = await inquirer.prompt([
|
const shouldConfirm = files.length > 0 && !yes;
|
||||||
{
|
const confirmed = shouldConfirm ? await confirm({
|
||||||
type: 'confirm',
|
|
||||||
name: 'confirm',
|
|
||||||
message: `是否你需要删除 【${opts?.dir}】 目录下的文件. [${files.length}] 个?`,
|
message: `是否你需要删除 【${opts?.dir}】 目录下的文件. [${files.length}] 个?`,
|
||||||
when: () => files.length > 0 && !yes, // 当 username 为空时,提示用户输入
|
}) : false;
|
||||||
},
|
if (confirmed || yes) {
|
||||||
]);
|
|
||||||
if (answers?.confirm || yes) {
|
|
||||||
fs.rmSync(dir, { recursive: true });
|
fs.rmSync(dir, { recursive: true });
|
||||||
console.log(chalk.green('删除成功', dir));
|
console.log(chalk.green('删除成功', dir));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { program, Command } from 'commander';
|
import { program, Command } from 'commander';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import { useContextKey } from '@kevisual/context'
|
import { useContextKey } from '@kevisual/context'
|
||||||
|
|
||||||
// 将多个子命令加入主程序中
|
// 将多个子命令加入主程序中
|
||||||
const version = useContextKey('version', () => {
|
const version = useContextKey('version', () => {
|
||||||
let version = '0.0.64';
|
let version = '0.0.64';
|
||||||
|
|||||||
Reference in New Issue
Block a user