diff --git a/bin/envision.js b/bin/envision.js deleted file mode 100755 index e38566b..0000000 --- a/bin/envision.js +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env node -import { runParser } from '../dist/envision.js'; - -runParser(process.argv); diff --git a/bun.config.ts b/bun.config.ts index 458b8fe..a8fcb2e 100644 --- a/bun.config.ts +++ b/bun.config.ts @@ -1,5 +1,4 @@ import { buildWithBun } from '@kevisual/code-builder'; -await buildWithBun({ naming: 'envision', entry: 'src/oldindex.ts',}); await buildWithBun({ naming: 'cli', entry: 'src/cli.ts' }); diff --git a/package.json b/package.json index 7975491..b853847 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,8 @@ ] }, "bin": { - "envision": "bin/envision.js", - "ev": "bin/envision.js", - "ev-next": "bin/cli.js", + "envision": "bin/cli.js", + "ev": "bin/cli.js", "assistant": "bin/assistant.js", "assistant-server": "bin/assistant-server.js", "asst": "bin/assistant.js", diff --git a/src/cli.ts b/src/cli.ts index 161bfdf..960aa40 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,4 +1,5 @@ import { app } from './index.ts'; +import { program } from './oldindex.ts'; import { parse } from "@kevisual/router/commander" -parse({ app }); \ No newline at end of file +parse({ app, program }); \ No newline at end of file diff --git a/src/command/ai.ts b/src/command/ai.ts deleted file mode 100644 index 6ac11ba..0000000 --- a/src/command/ai.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { program, Command } from '@/program.ts'; -import { app } from '../ai/index.ts'; -import util from 'util'; -import { chalk } from '@/module/chalk.ts'; -import { logger } from '@/module/logger.ts'; -const aiCmd = new Command('ai') - .description('AI 相关命令') - .action(async (opts) => { - }); - -const runCmd = async (cmd: string) => { - const res = await app.router.call({ path: 'cmd-run', payload: { cmd } }); - const { body } = res; - const steps = body?.steps || []; - for (const step of steps) { - logger.debug(chalk.blue(`\n==== 步骤: ${step.cmd || '结束'} ====`)); - logger.debug(step.result || 'No result'); - } -} -const aiRun = new Command('run') - .description('执行 AI 命令') - .option('-c, --cmd ', '要执行的 CMD 命令') - .action(async (opts) => { - if (opts.cmd) { - await runCmd(opts.cmd); - } else { - console.log('请提供要执行的 CMD 命令'); - } - }); - -const aiRunDeploy = new Command('deploy') - .description('部署 AI 后端应用') - .action(async (opts) => { - const cmd = 'ev pack -p -u'; - const res = await runCmd(cmd); - }); - -aiCmd.addCommand(aiRun); -aiCmd.addCommand(aiRunDeploy); - -program.addCommand(aiCmd); \ No newline at end of file diff --git a/src/command/cnb/index.ts b/src/command/cnb/index.ts deleted file mode 100644 index a3d23ec..0000000 --- a/src/command/cnb/index.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { createKeepAlive } from '@kevisual/cnb/keep' -import { readFileSync } from 'node:fs' -import path from 'node:path' - -import { program, Command } from '@/program.ts'; - -const cnbCmd = new Command('cnb') - .description('CNB 相关命令') - .action(async (opts) => { - console.log('CNB 命令'); - }); - -// cnb live -j '{"wss":"wss://...","cookie":"...","url":"..."}' -// # 或 -// cnb live --json '{"wss":"wss://...","cookie":"...","url":"..."}' - -const liveCmd = new Command('live') - .description('启动 CNB Keep Alive 服务') - .option('-j, --json ', 'JSON数据') - .option('-c, --config ', '配置文件路径 (优先级高于 JSON 参数), 默认keep.json') - .action(async (opts) => { - let config: { wss: string; cookie: string; url?: string }; - let configPath = opts.config || 'keep.json' - if (configPath.startsWith('/')) { - configPath = path.resolve(configPath) - } else { - configPath = path.join(process.cwd(), configPath) - } - - try { - let jsonString = opts.json; - - if (!jsonString) { - jsonString = readFileSync(configPath, 'utf-8').trim(); - } - - config = JSON.parse(jsonString); - } catch (error) { - console.error('JSON 解析错误: 请检查输入的 JSON 格式是否正确'); - process.exit(1); - } - if (!config.wss || !config.cookie) { - console.error('配置错误: 必须包含 wss 和 cookie 字段'); - process.exit(1); - } - - createKeepAlive({ - wsUrl: config.wss, - cookie: config.cookie, - onDisconnect: (code) => { - console.log(`与 CNB 服务器断开连接,代码: ${code}`); - }, - debug: true - }); - }); - -cnbCmd.addCommand(liveCmd); - -const workspaceCmd = new Command('workspace') - .alias('w') - .description('工作区live保活,默认执行 ev cnb live -c /workspace/live/keep.json') - .action(() => { - try { - - const configPath = path.join('/workspace/live/keep.json') - const json = readFileSync(configPath, 'utf-8').trim(); - let config = JSON.parse(json); - if (!config.wss || !config.cookie) { - console.error('配置错误: 必须包含 wss 和 cookie 字段'); - process.exit(1); - } - createKeepAlive({ - wsUrl: config.wss, - cookie: config.cookie, - onDisconnect: (code) => { - console.log(`与 CNB 服务器断开连接,代码: ${code}`); - }, - debug: true - }); - } catch (e) { - console.error('error', e) - } - }) -program.addCommand(workspaceCmd) -program.addCommand(cnbCmd); \ No newline at end of file diff --git a/src/command/coding-plan/cc.ts b/src/command/coding-plan/cc.ts index 48f2b61..a083595 100644 --- a/src/command/coding-plan/cc.ts +++ b/src/command/coding-plan/cc.ts @@ -1,7 +1,6 @@ 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'; diff --git a/src/command/config-remote.ts b/src/command/config-remote.ts deleted file mode 100644 index b3b9414..0000000 --- a/src/command/config-remote.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { program, Command } from '@/program.ts'; -import { query } from '@/module/query.ts'; -import { QueryConfig } from '@kevisual/api/query-config'; -import { showMore } from '@/uitls/show-more.ts'; -import fs from 'node:fs'; -import path from 'node:path'; - -const queryConfig = new QueryConfig({ query: query as any }); -const command = new Command('remote-config') - .alias('rc').description('获取或设置远程配置'); - - -const getCommand = new Command('get') - .option('-k, --key ', '配置键名') - .action(async (options) => { - const { key } = options || {}; - if (!key) { - console.log('Please provide a key using -k or --key option.'); - return; - } - const res = await queryConfig.getConfigByKey(key); - console.log('res Config Result:', showMore(res.data)); - }) - -const listCommand = new Command('list') - .description('列出所有配置') - .action(async () => { - const res = await queryConfig.listConfig(); - console.log('Remote Configs:', res); - if (res.code === 200) { - const list = res.data?.list || []; - list.forEach(item => { - console.log(item.id, item.key, item.data); - }); - } - - }); - -const updateCommand = new Command('update') - .description('更新远程配置') - .option('-k, --key ', '配置键名') - .option('-v, --value ', '配置值') - .option('-f, --file ', '从文件读取配置值') - .action(async (options) => { - const { key, value, file } = options || {}; - if (!key) { - console.log('请提供配置键名,使用 -k 或 --key 选项。', options); - return; - } - try { - let data: any = {} - const filePath = path.resolve(process.cwd(), file); - const hasFile = fs.existsSync(filePath); - if (value) { - data = JSON.parse(value); - } else if (file || hasFile) { - // 从文件读取配置值 - if (!hasFile) { - console.log('指定的文件不存在:', filePath); - return; - } - data = JSON.parse(fs.readFileSync(filePath, 'utf-8')); - } else { - console.log('请提供配置值,使用 -v 或 --value 选项,或使用 -f 或 --file 从文件读取。'); - return; - } - const res = await queryConfig.updateConfig({ - key, - data, - }); - console.log('Update Config Result:', showMore(res.data)); - } catch (error) { - console.log('Error parsing JSON:'); - } - }); - -const deleteCommand = new Command('delete') - .description('删除远程配置') - .option('-i, --id ', '配置ID') - .option('-k, --key ', '配置键名') - .action(async (options) => { - const { key, id } = options || {}; - if (!key && !id) { - console.log('请提供配置键名或配置ID,使用 -k 或 --key 选项,或 -i 或 --id 选项。'); - return; - } - const res = await queryConfig.deleteConfig({ key, id }); - console.log('Delete Config Result:', showMore(res)); - }); - -command.addCommand(listCommand); -command.addCommand(getCommand); -command.addCommand(updateCommand); -command.addCommand(deleteCommand); - -program.addCommand(command); \ No newline at end of file diff --git a/src/command/config-secret-remote.ts b/src/command/config-secret-remote.ts deleted file mode 100644 index 1acd0b5..0000000 --- a/src/command/config-secret-remote.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { program, Command } from '@/program.ts'; -import { query } from '@/module/query.ts'; -import { QueryConfig } from '@kevisual/api/query-secret'; -import { showMore } from '@/uitls/show-more.ts'; -import fs from 'node:fs'; -import path from 'node:path'; - -const queryConfig = new QueryConfig({ query: query as any }); -const command = new Command('remote-secret') - .alias('rs').description('获取或设置远程配置'); - - -const getCommand = new Command('get') - .option('-k, --key ', '配置键名') - .action(async (options) => { - const { key } = options || {}; - if (!key) { - console.log('Please provide a key using -k or --key option.'); - return; - } - const res = await queryConfig.getItem({ id: key }); - console.log('res Config Result:', showMore(res.data)); - }) - -const listCommand = new Command('list') - .description('列出所有配置') - .action(async () => { - const res = await queryConfig.listItems(); - if (res.code === 200) { - const list = res.data?.list || []; - list.forEach(item => { - console.log(item.id, item.key, showMore(item)); - }); - } else { - console.log('获取错误:', res.message); - } - - }); -const updateCommand = new Command('update') - .description('更新远程配置') - .option('-i, --id ', '配置ID') - .option('-t, --title ', '配置值') - .option('-d, --description <description>', '配置数据,JSON格式') - .action(async (options) => { - const { id, title, description } = options || {}; - let updateData: any = {}; - if (title) { - updateData.title = title; - } - if (description) { - updateData.description = description; - } - if (id) { - updateData.id = id; - } - const res = await queryConfig.updateItem(updateData); - console.log('修改结果:', showMore(res)); - }); -const deleteCommand = new Command('delete') - .description('删除远程配置') - .option('-i, --id <id>', '配置ID') - .option('-k, --key <key>', '配置键名') - .action(async (options) => { - const { key, id } = options || {}; - if (!key && !id) { - console.log('请提供配置键名或配置ID,使用 -k 或 --key 选项,或 -i 或 --id 选项。'); - return; - } - const res = await queryConfig.deleteItem({ key, id }); - console.log('Delete Config Result:', showMore(res)); - }); - -command.addCommand(listCommand); -command.addCommand(getCommand); -command.addCommand(updateCommand); -command.addCommand(deleteCommand); - -program.addCommand(command); \ No newline at end of file diff --git a/src/command/docker.ts b/src/command/docker.ts deleted file mode 100644 index fdb4305..0000000 --- a/src/command/docker.ts +++ /dev/null @@ -1,104 +0,0 @@ -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'; - -// 执行 docker指令 -// docker login --username=${DOCKER_USERNAME} ${DOCKER_REGISTRY} --password ${DOCKER_PASSWORD} -// docker login -u cnb docker.cnb.cool --password ${CNB_TOKEN} -// helm registry login -u cnb helm.cnb.cool --password ${CNB_TOKEN} - -const dockerCommand = new Command('docker') - .description('Docker 相关指令') - .action(async () => { - console.log(chalk.green('Docker command executed')); - }); - -const login = new Command('login') - .description('登录 Docker 镜像仓库') - .option('-r , --registry <registry>', 'Docker 镜像仓库地址', 'default') - .action(async (options) => { - const { registry = 'default' } = options; - let DOCKER_USERNAME = useKey('DOCKER_USERNAME') as string; - let DOCKER_PASSWORD = useKey('DOCKER_PASSWORD') as string; - let DOCKER_REGISTRY = useKey('DOCKER_REGISTRY') as string; - if (registry !== 'default') { - DOCKER_USERNAME = 'cnb'; - DOCKER_PASSWORD = useKey('CNB_TOKEN') as string; - DOCKER_REGISTRY = 'docker.cnb.cool'; - } - if (!DOCKER_USERNAME || !DOCKER_PASSWORD) { - console.log(chalk.red('请先配置 DOCKER_USERNAME 和 DOCKER_PASSWORD')); - return; - } - const loginProcess = spawn('docker', [ - 'login', - '--username', - DOCKER_USERNAME, - DOCKER_REGISTRY, - '--password-stdin' - ], { - stdio: ['pipe', 'inherit', 'inherit'] - }); - - loginProcess.stdin.write(DOCKER_PASSWORD + '\n'); - loginProcess.stdin.end(); - - loginProcess.on('close', (code) => { - if (code === 0) { - console.log(chalk.green('登录成功')); - } else { - console.log(chalk.red(`登录失败,退出码:${code}`)); - } - }); - }); - -dockerCommand.addCommand(login); - -const helmLogin = new Command('helm') - .description('Helm 登录镜像仓库') - .action(async () => { - }); - -const helmLoginCommand = new Command('login') - .description('登录 Helm 镜像仓库') - .action(async () => { - let DOCKER_USERNAME = 'cnb'; - let DOCKER_PASSWORD = useKey('CNB_TOKEN') as string; - - if (!DOCKER_PASSWORD) { - console.log(chalk.red('请先配置 CNB_TOKEN')); - return; - } - - const helmLoginProcess = spawn('helm', [ - 'registry', - 'login', - '--username', - DOCKER_USERNAME, - '--password-stdin', - 'helm.cnb.cool' - ], { - stdio: ['pipe', 'inherit', 'inherit'] - }); - - helmLoginProcess.stdin.write(DOCKER_PASSWORD + '\n'); - helmLoginProcess.stdin.end(); - - helmLoginProcess.on('close', (code) => { - if (code === 0) { - console.log(chalk.green('Helm 登录成功')); - } else { - console.log(chalk.red(`Helm 登录失败,退出码:${code}`)); - } - }); - }); - -helmLogin.addCommand(helmLoginCommand); - -program.addCommand(dockerCommand); -program.addCommand(helmLogin); \ No newline at end of file diff --git a/src/command/jwks.ts b/src/command/jwks.ts deleted file mode 100644 index 75d0314..0000000 --- a/src/command/jwks.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { generate } from '@kevisual/auth' - -import { program, Command } from '@/program.ts'; -import fs from 'node:fs'; -import path from 'node:path'; -export const getPath = async (dir: string) => { - const JWKS_PATH = path.join(dir, 'jwks.json'); - const PRIVATE_JWK_PATH = path.join(dir, 'privateKey.json'); - - const PRIVATE_KEY_PATH = path.join(dir, 'privateKey.txt'); - const PUBLIC_KEY_PATH = path.join(dir, 'publicKey.txt'); - return { - JWKS_PATH, - PRIVATE_JWK_PATH, - PRIVATE_KEY_PATH, - PUBLIC_KEY_PATH, - } -} -const jwksCmd = new Command('jwks') - .description('JWKS 相关命令') - .action(async (opts) => { - }); - -const jwksGenerate = new Command('generate') - .alias('gen') - .option('-d , --dir <dir>', '指定保存目录,默认当前目录下 jwt 文件夹', 'jwt') - .description('生成 JWKS 密钥对') - .action(async (opts) => { - const dir = path.isAbsolute(opts.dir) ? opts.dir : path.join(process.cwd(), opts.dir); - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir, { recursive: true }); - } - const { JWKS_PATH, PRIVATE_JWK_PATH, PRIVATE_KEY_PATH, PUBLIC_KEY_PATH } = await getPath(dir); - const { jwks, privateJWK, privatePEM, publicPEM } = await generate(); - fs.writeFileSync(PUBLIC_KEY_PATH, publicPEM); - fs.writeFileSync(PRIVATE_KEY_PATH, privatePEM); - fs.writeFileSync(PRIVATE_JWK_PATH, JSON.stringify(privateJWK, null, 2)); - fs.writeFileSync(JWKS_PATH, JSON.stringify(jwks, null, 2)); - console.log(`Keys have been saved to directory: ${dir}`); - }); - -jwksCmd.addCommand(jwksGenerate); - -const getJWKS = new Command('get') - .description('获取 JWKS 内容') - .option('-d , --dir <dir>', '指定 JWKS 所在目录,默认当前目录下 jwt 文件夹', 'jwt') - .option('-t, --type <type>', '指定获取类型,jwks 或 privateJWK', 'jwks') - .action(async (opts) => { - const dir = path.isAbsolute(opts.dir) ? opts.dir : path.join(process.cwd(), opts.dir); - const { JWKS_PATH, PRIVATE_JWK_PATH } = await getPath(dir); - const type = opts.type || 'jwks'; - if (type !== 'jwks') { - if (!fs.existsSync(PRIVATE_JWK_PATH)) { - console.error(`Private JWK file not found in directory: ${dir}`); - return; - } - const privateJWKContent = fs.readFileSync(PRIVATE_JWK_PATH, 'utf-8'); - console.log('Private JWK:\n'); - console.log(privateJWKContent); - return; - } - - if (!fs.existsSync(JWKS_PATH)) { - console.error(`JWKS file not found in directory: ${dir}`); - return; - } - const jwksContent = fs.readFileSync(JWKS_PATH, 'utf-8'); - console.log('PublicJWKS:\n'); - console.log(jwksContent); - }); - -jwksCmd.addCommand(getJWKS); - -program.addCommand(jwksCmd); \ No newline at end of file diff --git a/src/command/ls-token.ts b/src/command/ls-token.ts deleted file mode 100644 index 5efe738..0000000 --- a/src/command/ls-token.ts +++ /dev/null @@ -1,240 +0,0 @@ -import { program as app, Command } from '@/program.ts'; -import { getConfig, getEnvToken, writeConfig } from '@/module/index.ts'; -import { queryLogin, storage } from '@/module/query.ts'; -import { input } from '@inquirer/prompts'; -import { Kevisual } from '@/module/kevisual.ts'; -import { showMore } from '@/uitls/show-more.ts'; -function isNumeric(str: string) { - return /^-?\d+\.?\d*$/.test(str); -} -const showList = (list: string[]) => { - if (list.length === 0) { - console.log('expand baseURLList is empty'); - return; - } - const config = getConfig(); - console.log('----current baseURL:' + config.baseURL + '----\n'); - list.forEach((item, index) => { - console.log(`${index + 1}: ${item}`); - }); -}; -const token = new Command('token') - .option('-e, --env', 'show token in env') - .description('show token') - .action(async (opts) => { - const token = storage.getItem('token'); - if (opts.env) { - console.log('token in env', getEnvToken()); - } else { - console.log('token', token); - } - }); -const tokenList = new Command('list') - .description('show token list') - // .option('-r --remove <number>', 'remove token by number') - .action(async (opts) => { - console.log('show token list'); - queryLogin.cacheStore.init(); - // const res = await queryLogin.cacheStore.cache.get('token'); - console.log(queryLogin.cacheStore.cacheData); - // console.log(util.inspect(res, { colors: true, depth: 4 })); - }); - -token.addCommand(tokenList); - -const createToken = new Command('create') - .description('create jwks token') - .action(async (opts) => { - const kevisual = new Kevisual(); - const res = await kevisual.getAdminToken(); - if (res.code === 200) { - const jwtToken = res.data?.accessToken; - console.log('============jwt token============\n\n'); - console.log(jwtToken); - } else { - console.log('create token failed', showMore(res)); - } - }); - -token.addCommand(createToken); -app.addCommand(token); - -const baseURL = new Command('baseURL') - .alias('base') - .description('show baseURL') - .option('-a, --add <baseURL>', 'add baseURL') - .option('-r, --remove <number>', 'remove baseURL number') - .option('-s, --set <number|string>', 'set current baseURL, use number to set from list or string to set') - .option('-l, --list', 'list baseURL') - .option('-c, --clear', 'clear baseURL') - .action(async (opts) => { - let config = getConfig(); - let list = (config.baseURLList as Array<string>) || []; - if (!config.baseURL) { - list = ['https://kevisual.cn']; - writeConfig({ ...config, baseURL: 'https://kevisual.cn', baseURLList: list }); - config = getConfig(); - } - const quineList = (list: string[]) => { - const newList = new Set(list); - return Array.from(newList); - }; - - if (opts.add || opts.set) { - let change = false; - if (opts.add) { - change = true; - list.push(opts.add); - } else if (opts.set) { - if (!isNumeric(opts.set)) { - change = true; - list.push(opts.set); - writeConfig({ ...config, baseURL: opts.set }); - config = getConfig(); - } - } - if (change) { - list = quineList(list); - writeConfig({ ...config, baseURLList: list }); - config = getConfig(); - showList(list); - } - } - if (opts.remove) { - const index = Number(opts.remove) - 1; - if (index < 0 || index >= list.length) { - console.log('index out of range'); - return; - } - const removeBase = list.splice(index, 1); - list = quineList(list); - showList(list); - writeConfig({ ...config, baseURLList: list }); - removeBase[0]; - return; - } - if (opts.set) { - const isNumber = isNumeric(opts.set); - let baseURL = ''; - if (isNumber) { - const index = Number(opts.set) - 1; - if (index < 0 || index >= list.length) { - console.log('index out of range'); - return; - } - baseURL = list[index]; - writeConfig({ ...config, baseURL: list[index] }); - showList(list); - } else { - baseURL = opts.set; - } - return; - } - if (opts.list) { - showList(list); - return; - } - if (opts.clear) { - writeConfig({ ...config, baseURLList: [] }); - return; - } - if (!config.baseURL) { - config = getConfig(); - writeConfig({ ...config, baseURL: 'https://kevisual.cn' }); - config = getConfig(); - } - console.log('current baseURL:', config.baseURL); - }); -app.addCommand(baseURL); - -const setBaseURL = new Command('set') - .option('-b, --baseURL <baseURL>', 'set baseURL') - .description('set baseURL') - .action(async (opt) => { - const config = getConfig(); - let baseURL = opt.baseURL; - if (!baseURL) { - baseURL = await input({ - message: `Enter your baseURL:(current: ${config.baseURL})`, - }); - if (!baseURL) { - console.log('baseURL is required'); - return; - } - } - writeConfig({ ...config, baseURL }); - }); - -baseURL.addCommand(setBaseURL); - -// const showQueryURL = new Command('showQueryURL').description('show query URL').action(async () => { -// console.log("url", query.url); -// }); - -// app.addCommand(showQueryURL); - -const rvm = new Command('registry') - .alias('reg') - .description('registry manager') - .option('-l, --list', 'list registry') - .option('-s, --set <registry>', 'set registry') - .action(async (opts) => { - const config = getConfig(); - const defaultRegistry = ['https://kevisual.cn', 'https://kevisual.silkyai.cn', 'https://kevisual.xiongxiao.me', 'http://localhost:3005']; - if (opts.list) { - showList(defaultRegistry); - return; - } - if (opts.set) { - const isNumber = isNumeric(opts.set); - if (isNumber) { - const index = Number(opts.set) - 1; - if (index < 0 || index >= defaultRegistry.length) { - console.log('index out of range'); - return; - } - writeConfig({ ...config, baseURL: defaultRegistry[index] }); - console.log('set registry', defaultRegistry[index]); - } else { - writeConfig({ ...config, baseURL: opts.set }); - console.log('set registry', opts.set); - } - } - }); - -app.addCommand(rvm); - -const silky = new Command('silky').description('silky registry').action(async (opts) => { - console.log('silky registry'); - const config = getConfig(); - const defaultRegistry = ['https://kevisual.silkyai.cn']; - writeConfig({ ...config, baseURL: defaultRegistry[0] }); - showList(defaultRegistry); -}); -baseURL.addCommand(silky); - -const xiongxiao = new Command('me').description('xiongxiao registry').action(async (opts) => { - console.log('xiongxiao registry'); - const config = getConfig(); - const defaultRegistry = ['https://kevisual.xiongxiao.me']; - writeConfig({ ...config, baseURL: defaultRegistry[0] }); - showList(defaultRegistry); -}); -baseURL.addCommand(xiongxiao); -const local = new Command('local').description('local registry').action(async (opts) => { - console.log('local registry'); - const config = getConfig(); - const defaultRegistry = ['http://localhost:3005']; - writeConfig({ ...config, baseURL: defaultRegistry[0] }); - showList(defaultRegistry); -}); -baseURL.addCommand(local); - -const kv = new Command('kevisual').description('kevisual registry').action(async (opts) => { - console.log('kevisual registry'); - const config = getConfig(); - const defaultRegistry = ['https://kevisual.cn']; - writeConfig({ ...config, baseURL: defaultRegistry[0] }); - showList(defaultRegistry); -}); -baseURL.addCommand(kv); diff --git a/src/command/opencode/plugin.ts b/src/command/opencode/plugin.ts deleted file mode 100644 index 15e482c..0000000 --- a/src/command/opencode/plugin.ts +++ /dev/null @@ -1,2 +0,0 @@ -// TODO: 对 .opencode/plugin/agent.ts 的内容进行管理 -// 例如添加、删除、列出等操作 \ No newline at end of file diff --git a/src/command/proxy.ts b/src/command/proxy.ts deleted file mode 100644 index 871d9a9..0000000 --- a/src/command/proxy.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { program, Command } from '@/program.ts'; -import { chalk } from '@/module/chalk.ts'; - -const command = new Command('proxy') - .description('执行代理相关的命令') - .option('-s, --start', '启动代理') - .option('-u, --unset', '关闭代理') - .action((options) => { - // TODO: 代理相关的逻辑, 进行配置 - const proxyShell = 'export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890'; - const unProxyShell = 'unset https_proxy http_proxy all_proxy'; - - if (options.start) { - console.log(chalk.green('启动代理')); - console.log(chalk.green('执行以下命令以启用代理:')); - console.log(`\n ${chalk.yellow(proxyShell)}\n`); - console.log(`请运行以下命令应用代理:`); - console.log(chalk.cyan(`eval "$(${process.argv[1]} proxy -s)"`)); - } else if (options.unset) { - console.log(chalk.green('关闭代理')); - console.log(chalk.green('执行以下命令以禁用代理:')); - console.log(`\n ${chalk.yellow(unProxyShell)}\n`); - console.log(`请运行以下命令取消代理:`); - console.log(chalk.cyan(`eval "$(${process.argv[1]} proxy -u)"`)); - } else { - console.log(chalk.red('请提供选项 -s 或 -u')); - } - }); - -program.addCommand(command); diff --git a/src/command/router.ts b/src/command/router.ts deleted file mode 100644 index 637c111..0000000 --- a/src/command/router.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { program, Command } from '@/program.ts'; -import { input } from '@inquirer/prompts'; -import { query } from '../module/index.ts'; -import chalk from 'chalk'; -import util from 'util'; - -const router = new Command('router').description('router get'); -program.addCommand(router); -// web 开发模块 -const command = new Command('service') - .description('router services get') - .option('-p, --path <path>', '第一路径 path') - .option('-k, --key <key>', '第二路径 key') - .action(async (options) => { - let { path, key } = options; - // 如果没有传递参数,则通过交互式输入 - if (!path) { - path = await input({ - message: 'Enter your path:', - }); - } - if (!key) { - key = await input({ - message: 'Enter your key:', - }); - } - const res = await query.post({ path, key }); - if (res?.code === 200) { - console.log('query success'); - const _list = res.data?.list || res.data; - if (Array.isArray(_list)) { - const data = _list.map((item: any) => { - // return `id: ${item.id}, title: ${item.title}`; - return { - id: item.id, - title: item.title, - }; - }); - console.log(chalk.green(util.inspect(data, { colors: true, depth: 4 }))); - } - } else { - console.log('error', res.message || ''); - } - }); - -router.addCommand(command); diff --git a/src/command/update.ts b/src/command/update.ts deleted file mode 100644 index c4b1db2..0000000 --- a/src/command/update.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { program, Command } from '@/program.ts'; -import { execSync } from 'node:child_process'; -import path from 'node:path'; -import fs from 'node:fs'; -import { getConfig } from '@/module/get-config.ts'; -import { fetchLink } from '@/module/download/install.ts'; -import { fileIsExist } from '@/uitls/file.ts'; -import { getHash, getBufferHash } from '@/uitls/hash.ts'; -import { useContextKey } from '@kevisual/context' -import semver from 'semver' -const getRunFilePath = () => { - const c = process.argv[1]; // 例子: /home/ubuntu/kevisual/cli/bin/envision.js - const runFilePath = path.resolve(c); - const isJs = runFilePath.endsWith('.js'); - let distDir = ''; - if (isJs) { - const dir = path.dirname(runFilePath); // /home/ubuntu/kevisual/cli/bin - distDir = path.relative(dir, '../dist'); // /home/ubuntu/kevisual/cli - } else { - distDir = path.resolve(process.cwd(), 'dist'); - } - - return distDir; -} -const distFiles = ["assistant-server.js", "assistant.js", "envision.js"]; - -const downloadNewDistFiles = async (distDir: string) => { - const baseURL = getConfig().baseURL || 'https://kevisual.cn'; - const newData = distFiles.map(file => { - const url = `${baseURL}/root/cli/dist/${file}`; - const filePath = path.join(distDir, file); - const exist = fileIsExist(filePath); - let hash = ''; - hash = getHash(filePath); - return { url, filePath, exist, hash }; - }); - const promises = newData.map(async ({ url, filePath }) => { - return await fetchLink(url, { returnContent: true }); - }); - let isUpdate = false; - await Promise.all(promises).then(results => { - results.forEach((res, index) => { - const data = newData[index]; - const filePath = data.filePath; - const newHash = getBufferHash(res.content); - if (data.hash === newHash) { - return; - } - console.log('更新文件:', filePath); - isUpdate = true; - if (data.exist) { - fs.writeFileSync(filePath, res.content, 'utf-8'); - } else { - const dir = path.dirname(filePath); - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir, { recursive: true }); - } - fs.writeFileSync(filePath, res.content, 'utf-8'); - } - }); - if (isUpdate) { - console.log('更新完成,请重新运行命令'); - } else { - console.log('检测完成'); - } - }).catch(error => { - console.error('Error downloading files:', error); - }); -} -const getVersion = async (force?: boolean) => { - const runFilePath = getRunFilePath(); - if (force) { - await downloadNewDistFiles(runFilePath); - return; - } - const baseURL = getConfig().baseURL || 'https://kevisual.cn'; - const file = 'package.json'; - const url = `${baseURL}/root/cli/${file}`; - const res = await fetchLink(url, { returnContent: true }); - const text = res.content.toString('utf-8'); - const json = JSON.parse(text); - const latestVersion = json.version; - const version = useContextKey('version'); - if (semver.lt(version, latestVersion)) { - console.log('当前版本:', version, '最新版本:', latestVersion, '正在更新...'); - downloadNewDistFiles(runFilePath); - } else { - console.log('已经是最新版本', version); - } -} -const update = new Command('update') - .option('-g --global', 'update global') - .option('-n --npm', 'use npm to update', false) - .option('-f --force', 'force update', false) - .description('update cli') - .action((opts) => { - try { - if (opts.npm) { - const cmd = opts.global ? 'npm install -g @kevisual/envision-cli' : 'npm install -D @kevisual/envision-cli'; - execSync(cmd, { stdio: 'inherit', encoding: 'utf-8' }); - } else { - const force = opts.force ? true : false; - getVersion(force) - } - } catch (error) { - console.error('Error updating CLI:', error); - } - }); - -program.addCommand(update); diff --git a/src/index.ts b/src/index.ts index 2458aad..9d88d0b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,21 +1,21 @@ import { app } from './app.ts' // 导入所有路由模块 import './routes/app.ts'; -import './routes/cc.ts'; -import './routes/ccc.ts'; +// import './routes/cc.ts'; +// import './routes/ccc.ts'; import './routes/config.ts'; -import './routes/deploy.ts'; +// import './routes/deploy.ts'; import './routes/docker.ts'; import './routes/download.ts'; import './routes/gist.ts'; import './routes/jwks.ts'; import './routes/login.ts'; -import './routes/npm.ts'; +// import './routes/npm.ts'; import './routes/proxy.ts'; -import './routes/publish.ts'; +// import './routes/publish.ts'; import './routes/remote-config.ts'; import './routes/remote-secret.ts'; -import './routes/sync.ts'; +// import './routes/sync.ts'; import './routes/token-ls.ts'; import './routes/update.ts'; diff --git a/src/oldindex.ts b/src/oldindex.ts index ae2fe78..7083fcd 100644 --- a/src/oldindex.ts +++ b/src/oldindex.ts @@ -1,28 +1,13 @@ import { program } from '@/program.ts'; import './command/login.ts'; -import './command/ls-token.ts'; import './command/deploy.ts'; -import './command/config.ts'; -import './command/router.ts'; import './command/npm.ts'; import './command/publish.ts'; -import './command/proxy.ts'; -import './command/update.ts'; import './command/sync/sync.ts'; -import './command/app/index.ts'; - -import './command/gist/index.ts'; -import './command/config-remote.ts'; -import './command/config-secret-remote.ts'; import './command/coding-plan/cc.ts' import './command/coding-plan/oc.ts' -import './command/docker.ts'; -import './command/jwks.ts'; - -import './command/cnb/index.ts'; -import './command/download.ts'; // program.parse(process.argv); @@ -31,3 +16,5 @@ export const runParser = async (argv: string[]) => { // console.log('argv', argv); program.parse(argv); }; + +export { program }; \ No newline at end of file diff --git a/src/routes/token-ls.ts b/src/routes/token-ls.ts index c24eec2..4e23f13 100644 --- a/src/routes/token-ls.ts +++ b/src/routes/token-ls.ts @@ -199,7 +199,7 @@ app.route({ }).define(async (ctx) => { const { list, set } = ctx.args; const config = getConfig(); - const defaultRegistry = ['https://kevisual.cn', 'https://kevisual.silkyai.cn', 'https://kevisual.xiongxiao.me', 'http://localhost:3005']; + const defaultRegistry = ['https://kevisual.cn', 'https://kevisual.xiongxiao.me', 'http://localhost:3005']; if (list) { showList(defaultRegistry); return; @@ -236,6 +236,21 @@ app.route({ showList(defaultRegistry); }).addTo(app) +app.route({ + path: 'baseURL', + key: 'me', + description: 'xiongxiao.me registry', + metadata: { + middleware: ['auth'], + args: {} + } +}).define(async () => { + const config = getConfig(); + const defaultRegistry = ['https://kevisual.xiongxiao.me']; + writeConfig({ ...config, baseURL: defaultRegistry[0] }); + showList(defaultRegistry); +}).addTo(app) + app.route({ path: 'baseURL', key: 'local',