"feat: 增加助手应用配置管理功能与服务器守护进程支持"

This commit is contained in:
熊潇 2025-04-27 00:35:44 +08:00
parent bcc12209e0
commit f2abfbf17c
27 changed files with 658 additions and 102 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ dist
pack-dist
apps
assistant-app

View File

@ -1,17 +1,26 @@
// @ts-check
// https://bun.sh/docs/bundler
// @ts-ignore
import path from 'node:path';
import pkg from './package.json';
import fs from 'node:fs';
// bun run src/index.ts --
import { fileURLToPath } from 'node:url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
/**
*
* @param {string} p
* @returns
*/
export const w = (p) => path.join(__dirname, p);
await Bun.build({
target: 'node',
format: 'esm',
entrypoints: ['./src/index.ts'],
outdir: './dist',
entrypoints: [w('./src/index.ts')],
outdir: w('./dist'),
naming: {
entry: 'assistant.mjs',
},
external: ['pm2'],
define: {
ENVISION_VERSION: JSON.stringify(pkg.version),
},
@ -21,13 +30,33 @@ await Bun.build({
await Bun.build({
target: 'node',
format: 'esm',
entrypoints: ['./src/server.ts'],
outdir: './dist',
entrypoints: [w('./src/server.ts')],
outdir: w('./dist'),
naming: {
entry: 'assistan-server.mjs',
},
define: {
ENVISION_VERSION: JSON.stringify(pkg.version),
entry: 'assistant-server.mjs',
},
external: ['pm2'],
env: 'ENVISION_*',
});
export const copyFileToEnvision = async () => {
const src = ['dist', 'bin'].map((dir) => {
return { absolute: path.join(__dirname, dir), name: dir };
});
const dest = path.join(__dirname, '..');
for (const dir of src) {
const files = fs.readdirSync(dir.absolute);
for (const file of files) {
const srcFile = path.join(dir.absolute, file);
const destFile = path.join(dest, dir.name, file);
try {
fs.copyFileSync(srcFile, destFile);
} catch (err) {
console.error('Error copying files: origin: ', srcFile, 'dest: ', destFile);
console.error('Error copying files:', err);
continue;
}
}
}
};
await copyFileToEnvision();

View File

@ -19,7 +19,7 @@
],
"scripts": {
"dev": "bun run src/run.ts ",
"dev:server": "cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 bun --watch src/server.ts",
"dev:server": "cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 bun --watch src/run-server.ts",
"build": "rimraf dist && bun run bun.config.mjs"
},
"bin": {
@ -27,6 +27,7 @@
"ev-asst": "bin/assistant.js"
},
"devDependencies": {
"@kevisual/ai-center": "^0.0.3",
"@kevisual/load": "^0.0.6",
"@kevisual/local-app-manager": "^0.1.16",
"@kevisual/query": "0.0.17",
@ -41,6 +42,8 @@
"chalk": "^5.4.1",
"commander": "^13.1.0",
"cross-env": "^7.0.3",
"dotenv": "^16.5.0",
"get-port": "^7.1.0",
"inquirer": "^12.6.0",
"lodash-es": "^4.17.21",
"nanoid": "^5.1.5",
@ -49,6 +52,7 @@
"send": "^1.2.0",
"supports-color": "^10.0.0",
"ws": "npm:@kevisual/ws",
"dayjs": "^1.11.13",
"zustand": "^5.0.3"
},
"engines": {
@ -58,9 +62,11 @@
"access": "public"
},
"dependencies": {
"dayjs": "^1.11.13"
"pm2": "^6.0.5"
},
"overrides": {
"ws": "npm:@kevisual/ws"
"ws": "npm:@kevisual/ws",
"@kevisual/query": "0.0.17",
"@kevisual/router": "0.0.13"
}
}

View File

@ -1,15 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICXTCCAcagAwIBAgIJUmN5oWFZdxK8MA0GCSqGSIb3DQEBBQUAMF8xCjAIBgNV
BAMTASoxCzAJBgNVBAYTAkNOMREwDwYDVQQIEwhaaGVKaWFuZzERMA8GA1UEBxMI
SGFuZ3pob3UxETAPBgNVBAoTCEVudmlzaW9uMQswCQYDVQQLEwJJVDAeFw0yNTA0
MjQxODExMjZaFw0yNjA0MjQxODExMjZaMF8xCjAIBgNVBAMTASoxCzAJBgNVBAYT
AkNOMREwDwYDVQQIEwhaaGVKaWFuZzERMA8GA1UEBxMISGFuZ3pob3UxETAPBgNV
BAoTCEVudmlzaW9uMQswCQYDVQQLEwJJVDCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
gYkCgYEAirpqS9Lwh5JNY7N303wphXCR/HZDgfw1HnP6b62WVJTHtU97hLKjrTXx
zUYPEyySXLzFGjptKSjT3ZgulV1I9YBXg2gdDibxxxZUZHoJ8j0oh+MSxRv1fTzw
+HEBErUJQJ4lHnf9nbi7Tf48XiNWqh9Lce3XvyDFQoRDASX5yeUCAwEAAaMhMB8w
HQYDVR0RBBYwFIIBKoIJbG9jYWxob3N0hwR/AAABMA0GCSqGSIb3DQEBBQUAA4GB
AGCYapPzhY0zUVZxo6CsijdDQpuHe2G3cDs4bzpF2YHRGN3t8/cPwROt7FWCkzBt
b7g/Tar+200fGspmLS95QisjiKo0fAKfaEE8CHXr2jlt8+omOz0tPg9LCZi2GtgI
8EC+Vvvcd9UjzHmoPBZQF4qAvJ2IyOwBh6Vwyh8las+e
-----END CERTIFICATE-----

View File

@ -1,15 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCKumpL0vCHkk1js3fTfCmFcJH8dkOB/DUec/pvrZZUlMe1T3uE
sqOtNfHNRg8TLJJcvMUaOm0pKNPdmC6VXUj1gFeDaB0OJvHHFlRkegnyPSiH4xLF
G/V9PPD4cQEStQlAniUed/2duLtN/jxeI1aqH0tx7de/IMVChEMBJfnJ5QIDAQAB
AoGAGmBUKoN6OQSPk0fBniOqz1S2ZP5lWncF8HrToF0sSnuZNvdcQEAoz5uElGdg
IWClmV1IynJWY+9/zM+M99grMT6it3VHHVM3MQoTf1Am4Vy0qgKR6Y1TzE0XLrVW
3e3ezDph3gG0EQsRxVbn/goCEfstuhJaFyxHvsQRtPY+Z1ECQQC8ffbjV8hb911o
iUw67FquOL9AYrFfQfohkQZ1TrDv0VTCAYpB7e5ml4dBhUL1dQbFV7avZIufD5fl
pxCKkAPNAkEAvGnQPByrKj6ggf2l1CzgjXzZ24wm3AkJutWkFjAcf5EFy0+MIBOi
ejyrGcGi9eovXCLGLrgzaBeAHa4XNkX2eQJAEZE73VxlFA0t63xAWo2EthAb4whP
t60SfuZhT7WR0AgWei5ikFp4iZ89v+GHqBDMHMBcCmS4jo6JfaHgbMmXUQJAAIDL
1I1DC77VEOPLgJCKHPabYlGyfN3tT7loUcLZIKITgOJ6fk9vHKJy1oPE2qFAdR+G
pfNJ99owNmQTncp8CQJAI3fp5VABViB3uha4cHmpRUvoGNWmmh9Ob6LypDsGtd8z
8ah+4Ek1DvsQC4XDuwgwnQsCmEYfa2P1T/GIdqPadw==
-----END RSA PRIVATE KEY-----

View File

@ -15,8 +15,10 @@ const Init = new Command('init')
} else if (opts.path) {
opts.path = path.resolve(opts.path);
}
const configDir = AssistantInit.detectConfigDir(opts.path);
console.log('configDir', configDir);
const assistantInit = new AssistantInit({
path: opts.path,
path: configDir,
});
assistantInit.init();
});

View File

@ -1,5 +1,5 @@
import { program, runProgram } from '@/program.ts';
import './command/init/index.ts';
import './command/config-manager/index.ts';
import './command/app-manager/index.ts';
/**

View File

@ -37,7 +37,7 @@ export const initConfig = (configRootPath: string) => {
*/
appsDir,
/**
* assistant-service-config.json
* assistant-apps-config.json
*/
appsConfigPath,
/**
@ -65,6 +65,15 @@ type AssistantConfigData = {
proxy?: ProxyInfo[];
apiProxyList?: ProxyInfo[];
description?: string;
/**
*
*/
home?: string;
ai?: {
provider?: string | 'DeepSeek' | 'SiliconFlow';
apiKey?: string;
model?: string;
};
};
let assistantConfig: AssistantConfigData;
type AssistantConfigOptions = {
@ -142,7 +151,7 @@ export class AssistantConfig {
fs.writeFileSync(pageConfigPath, JSON.stringify(_saveConfig, null, 2));
return _saveConfig;
}
assAppConfig(app: any) {
addAppConfig(app: any) {
const config = this.getPageConfig();
const assistantConfig = this.getCacheAssistantConfig();
const _apps = config.list;

View File

@ -0,0 +1,3 @@
import { runServer } from "./server.ts";
runServer();

View File

@ -1,10 +1,71 @@
import { app } from './app.ts';
import { proxyRoute, proxyWs } from './services/proxy/proxy-page-index.ts';
import getPort, { portNumbers } from 'get-port';
import { program } from 'commander';
import { spawnSync } from 'child_process';
export const runServer = async (port?: number) => {
let _port: number | undefined;
if (port) {
_port = await getPort({ port });
if (_port !== port) {
console.log(`Port ${port} is not available`);
_port = undefined;
}
}
if (!_port) {
// 检车端口可用性
const isPortAvailable = await getPort({ port: portNumbers(51015, 52000) });
if (!isPortAvailable) {
console.log(`Port ${isPortAvailable} is not available`);
process.exit(1);
}
_port = isPortAvailable;
}
app.listen(_port, () => {
console.log(`Server is running on https://localhost:${_port}`);
});
app.server.on(proxyRoute);
proxyWs();
return {
app,
port: _port,
};
};
program
.description('启动服务')
.option('-d, --daemon', '是否以守护进程方式运行')
.option('-n, --name <name>', '服务名称', 'assistant-server')
.option('-p, --port <port>', '服务端口')
.option('-s, --start', '是否启动服务')
.action(async (options) => {
// console.log('当前执行路径:', execPath, inte);
if (options.daemon) {
const [_interpreter, execPath] = process.argv;
const name = options.name;
const port = options.port;
let pm2Command = `pm2 start ${execPath} --name ${name} -- -s `;
if (port) {
pm2Command += ` -p ${port}`;
}
const result = spawnSync(pm2Command, {
shell: true,
stdio: 'inherit',
});
if (result.error) {
console.error('Error starting server:', result.error);
process.exit(1);
}
console.log('以守护进程方式运行');
} else if (options.start) {
console.log('启动服务');
const server = await runServer(options.port);
}
});
app.listen(51015, () => {
console.log('Server is running on http://localhost:51015');
});
app.server.on(proxyRoute);
proxyWs();
export const runParser = async (argv: string[]) => {
try {
program.parse(argv);
} catch (error) {
console.error('执行错误:', error.message);
}
};

View File

@ -4,6 +4,7 @@ import { checkFileExists, AssistantConfig } from '@/module/assistant/index.ts';
import { chalk } from '@/module/chalk.ts';
export type AssistantInitOptions = {
path?: string;
init?: boolean;
};
/**
*
@ -14,6 +15,7 @@ export class AssistantInit extends AssistantConfig {
const configDir = opts?.path || process.cwd();
super({
configDir,
init: opts?.init ?? false,
});
}
@ -30,21 +32,30 @@ export class AssistantInit extends AssistantConfig {
}
}
checkConfigPath() {
const assistantPath = path.join(this.configDir, 'assistant-config.json');
const assistantPath = path.join(this.configDir, 'assistant-app', 'assistant-config.json');
return checkFileExists(assistantPath);
}
createAssistantConfig() {
const assistantPath = this.configPath?.configPath;
// 创建助手配置文件 assistant-config.json
if (!checkFileExists(assistantPath, true)) {
this.setConfig({
description: '助手配置文件',
});
console.log(chalk.green('助手配置文件创建成功'));
console.log(chalk.green('助手配置文件assistant-config.json创建成功'));
}
const env = this.configPath?.envConfigPath;
// 创建助手环境配置文件 env
if (!checkFileExists(env, true)) {
fs.writeFileSync(env, '# 环境配置文件\n');
console.log(chalk.green('助手环境配置文件创建成功'));
console.log(chalk.green('助手环境配置.env文件创建成功'));
}
const appsConfig = this.configPath?.appsConfigPath;
// 创建助手应用配置文件 apps
if (!checkFileExists(appsConfig, true)) {
fs.writeFileSync(appsConfig, JSON.stringify({ description: 'apps manager.', list: [] }));
console.log(chalk.green('助手应用配置文件apps.json创建成功'));
}
}
}

View File

@ -11,6 +11,10 @@ export const proxyRoute = async (req: http.IncomingMessage, res: http.ServerResp
const appDir = assistantConfig.configPath?.pageDir;
const url = new URL(req.url, 'http://localhost');
const pathname = url.pathname;
if (pathname === '/' && _assistantConfig?.home) {
res.writeHead(302, { Location: `${_assistantConfig?.home}/` });
return res.end();
}
if (pathname.startsWith('/favicon.ico')) {
res.statusCode = 404;
res.end('Not Found Favicon');

View File

@ -0,0 +1,53 @@
// import { AssistantConfig } from '@/module/assistant/index.ts';
import { assistantConfig } from '../config.ts';
import { ProviderManager, SiliconFlowProvider } from '@kevisual/ai-center';
const config = assistantConfig.getConfig();
console.log('aiConfig', config.ai);
const providerManager = new ProviderManager({
provider: config.ai.provider,
apiKey: config.ai.apiKey!,
model: config.ai.model!,
});
const chatTest = async (text: string) => {
const result = await providerManager.provider.chat([
{
role: 'user',
content: text,
},
]);
console.log('result', result);
return result.choices[0].message.content;
};
chatTest('你好').then((res) => {
console.log('chatTest', res);
});
// providerManager.provider.test().then((res) => {
// console.log('test', res);
// });
// const siliconflow = providerManager.provider as any;
const siliconflow = new SiliconFlowProvider({
apiKey: config.ai.apiKey!,
model: config.ai.model!,
});
const main = async () => {
const usage = await siliconflow.getUsageInfo();
console.log(usage);
};
// main();
const test = async () => {
const result = await siliconflow.chat([
{
role: 'user',
content: '你好',
},
]);
console.log('result', result, 'result.choices[0].message.content', result.choices[0].message.content);
return result.choices[0].message.content;
};
// test();

View File

@ -0,0 +1,22 @@
import { ProviderManager, SiliconFlowProvider, ModelScopeProvider } from '@kevisual/ai-center';
import { config } from 'dotenv';
config();
const providerTest = async () => {
const providerConfig = { provider: 'ModelScope', model: 'Qwen/Qwen2.5-Coder-32B-Instruct', apiKey: process.env.MODEL_SCOPE_API_KEY };
const provider = await ProviderManager.createProvider(providerConfig);
const result = await provider.chat([{ role: 'user', content: '你好' }]);
console.log(result);
};
providerTest();
const modelScopeTest = async () => {
const provider = new ModelScopeProvider({
apiKey: process.env.MODEL_SCOPE_API_KEY,
model: 'Qwen/Qwen2.5-Coder-32B-Instruct',
});
const result = await provider.chat([{ role: 'user', content: '你好' }]);
console.log(result);
};
// modelScopeTest();

9
assistant/task-command/.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
node_modules
.DS_Store
dist
pack-dist
.env*
!.env*example

View File

@ -0,0 +1,4 @@
//npm.xiongxiao.me/:_authToken=${ME_NPM_TOKEN}
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
ignore-workspace-root-check=true

67
assistant/task-command/mod.d.ts vendored Normal file
View File

@ -0,0 +1,67 @@
declare const TaskCommandType: readonly ["npm-install"];
type TaskCommand = {
key?: string;
/**
*
*/
description?: string;
/**
* ,
*/
command: string;
type?: (typeof TaskCommandType)[number] | string;
/**
*
*/
after?: string;
/**
*
*/
before?: string;
/**
* ,
*
*/
afterCheck?: string;
/**
* ,
*
*/
beforeCheck?: string;
};
declare class TasksCommand {
tasks: Map<string, TaskCommand>;
constructor();
addTask(task: TaskCommand, run?: boolean): this;
getTask(name: string): TaskCommand;
runTask(name: string): {
task: TaskCommand;
code: number;
} | {
code: number;
message: string;
};
/**
*
* 1. res.code === 500 ,
* 2. res.code === 200
* 2.1 check
* 2.2 check
* @param res
* @param check
* @returns
*/
private checkForContainue;
runCommand(command: string): {
code: number;
data: string;
message?: undefined;
} | {
code: number;
data: string;
message: any;
};
}
export { TaskCommandType, TasksCommand };
export type { TaskCommand };

View File

@ -0,0 +1,142 @@
import { execSync } from 'node:child_process';
export const TaskCommandType = ['npm-install'] as const;
export type TaskCommand = {
key?: string;
/**
*
*/
description?: string;
/**
* ,
*/
command: string;
type?: (typeof TaskCommandType)[number] | string;
/**
*
*/
after?: string;
/**
*
*/
before?: string;
/**
* ,
*
*/
afterCheck?: string;
/**
* ,
*
*/
beforeCheck?: string;
};
export class TasksCommand {
tasks: Map<string, TaskCommand> = new Map();
constructor() {}
addTask(task: TaskCommand, run?: boolean) {
const key = task?.key || task?.description;
if (!key) {
throw new Error('当前的任务没有key');
}
this.tasks.set(key, task);
if (run) {
this.runTask(key);
}
return this;
}
getTask(name: string) {
return this.tasks.get(name);
}
runTask(name: string) {
const task = this.getTask(name);
const end = (data?: { code: number; [key: string]: any }) => {
return {
...data,
task,
};
};
if (!task) {
return {
code: 500,
message: `没有找到 ${name} 这个任务`,
};
}
let { command, before, after, afterCheck, beforeCheck, type } = task;
if (type === 'npm-install' && !afterCheck) {
afterCheck = 'added';
}
if (before) {
const res = this.runCommand(before);
console.log('before', res, beforeCheck, this.checkForContainue(res, beforeCheck));
if (!this.checkForContainue(res, beforeCheck)) {
return end({
code: 200,
message: `当前任务不需要执行, ${command}`,
});
}
}
const res = this.runCommand(command);
console.log('runCommand', res);
if (res.code !== 200) {
return end(res);
}
let checkText = res.data || '';
if (after) {
const res = this.runCommand(after);
if (res.code !== 200) {
return end(res);
}
checkText = res.data || '';
}
if (afterCheck) {
const isSuccess = checkText?.includes?.(afterCheck);
return end({
code: isSuccess ? 200 : 500,
output: res.data,
check: afterCheck,
message: isSuccess ? `当前任务执行成功, ${command}` : `当前任务执行失败, ${command}`,
});
}
return end(res);
}
/**
*
* 1. res.code === 500 ,
* 2. res.code === 200
* 2.1 check
* 2.2 check
* @param res
* @param check
* @returns
*/
private checkForContainue(res: { data: string; code: number; [key: string]: any }, check?: string, isBefore = true) {
if (res.code !== 200) {
return true;
}
if (!check) {
return true;
}
const hasIncludes = res.data?.includes?.(check);
if (isBefore) {
// 代表已经安装, 不需要继续执行
return !hasIncludes;
}
return hasIncludes;
}
runCommand(command: string) {
try {
const res = execSync(command, { encoding: 'utf-8' });
return {
code: 200,
data: res.toString(),
};
} catch (error) {
return {
code: 500,
data: '',
message: error.toString(),
};
}
}
}

View File

@ -0,0 +1,26 @@
{
"name": "@kevisual/task-command",
"version": "0.0.1",
"description": "",
"types": "mod.d.ts",
"scripts": {
"dts": "dts -i mod.ts -o mod.d.ts -d ."
},
"keywords": [],
"publishConfig": {
"registry": "https://registry.npmjs.org/",
"access": "public"
},
"files": [
"mod.ts",
"mod.d.ts"
],
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
"license": "MIT",
"packageManager": "pnpm@10.7.0",
"type": "module",
"exports": {
".": "./mod.ts",
"./mod.ts": "./mod.ts"
}
}

View File

@ -0,0 +1,3 @@
# task-command
command line task runner

View File

@ -0,0 +1,34 @@
{
"tasks": {
"dev": {
"command": "deno run -A talkshow.ts",
"desc": "Run the server in development mode"
},
"build": {
"command": "deno run --allow-all --unstable src/build.ts",
"desc": "Build the project"
},
"build:dts": {
"command": "deno run -A talkshow.ts --dts",
"desc": "Build the project with dts"
}
},
"lint": {
"files": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.js",
"src/**/*.jsx"
],
"options": {
"rules": {
"ban-untagged-todo": false,
"no-explicit-any": false,
"no-unused-vars": false
}
}
},
"imports": {
"https://esm.xiongxiao.me/@kevisual/task-command/mod.ts": "../../task-command/mod.ts"
}
}

17
assistant/tasks/silkyai/deno.lock generated Normal file
View File

@ -0,0 +1,17 @@
{
"version": "4",
"specifiers": {
"npm:@types/node@*": "22.12.0"
},
"npm": {
"@types/node@22.12.0": {
"integrity": "sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==",
"dependencies": [
"undici-types"
]
},
"undici-types@6.20.0": {
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="
}
}
}

View File

@ -1,3 +1,40 @@
import { TasksCommand } from 'https://esm.xiongxiao.me/@kevisual/task-command/mod.ts';
// import { TasksCommand } from '../../task-command/mod.ts';
const init = {
description: '安装依赖',
command: 'npm install -g @kevisual/cli --registry=https://registry.npmmirror.com',
afterCheck: 'added',
};
const init1 = {
description: '安装 pm2',
type: 'npm-install',
command: 'npm install -g pm2 --registry=https://registry.npmmirror.com',
before: 'pm2 -v',
};
const init2 = {
description: '安装 deno',
command: 'npm install -g deno --registry=https://registry.npmmirror.com',
type: 'npm-install',
before: 'deno -v',
beforeCheck: 'deno',
};
const init3 = {
description: '安装 bun',
type: 'npm-install',
command: 'npm install -g bun --registry=https://registry.npmmirror.com',
beforeCheck: 'bun -v',
};
// ===========================
// 安装talkshow的程序到本地
const talk = {
description: '设置默认的 base registry 地址 为 https://kevisual.silkyai.cn',
command: 'ev base -s https://kevisual.silkyai.cn',
};
const talkInit = {
description: '初始化一个助手客户端,生成配置文件。',
command: 'asst init',
};
const task1 = {
description: '下载前端应用 root/center 应用',
command: 'ev app download -i root/center -o assistant-app/page',
@ -12,3 +49,26 @@ const task3 = {
description: '安装后端应用 root/talkshow-code-center 应用',
command: 'ev app download -i root/talkshow-code-center -t app -o assistant-app/apps/talkshow-code-center',
};
// ===========================
const runTask1 = async () => {
const tasksCommand = new TasksCommand();
tasksCommand.addTask(init2);
const res = tasksCommand.runTask(init2.description);
console.log(res);
};
// runTask1();
const runTestTask = async () => {
const tasksCommand = new TasksCommand();
const task = {
description: 'test',
command: 'npm i -g rollup --registry=https://registry.npmmirror.com',
type: 'npm-install',
};
tasksCommand.addTask(task);
const res = tasksCommand.runTask(task.description);
console.log(res);
return res;
};
runTestTask();

4
bin/assistant-server.js Executable file
View File

@ -0,0 +1,4 @@
#!/usr/bin/env node
import { runParser } from '../dist/assistant-server.mjs';
runParser(process.argv);

0
bin/assistant.js Normal file → Executable file
View File

View File

@ -1,6 +1,6 @@
{
"name": "@kevisual/envision-cli",
"version": "0.0.41",
"version": "0.0.42",
"description": "envision command tools",
"main": "dist/app.mjs",
"type": "module",
@ -15,7 +15,9 @@
"envision": "bin/envision.js",
"ev": "bin/envision.js",
"assistant": "bin/assistant.js",
"asst": "bin/assistant.js"
"assistant-server": "bin/assistant-server.js",
"asst": "bin/assistant.js",
"asst-server": "bin/assistant-server.js"
},
"files": [
"dist",
@ -32,6 +34,11 @@
"cli"
],
"author": "abearxiong",
"dependencies": {
"pino": "^9.6.0",
"pino-pretty": "^13.0.0",
"pm2": "^6.0.5"
},
"devDependencies": {
"@kevisual/load": "^0.0.6",
"@kevisual/query": "0.0.17",

98
pnpm-lock.yaml generated
View File

@ -7,6 +7,16 @@ settings:
importers:
.:
dependencies:
pino:
specifier: ^9.6.0
version: 9.6.0
pino-pretty:
specifier: ^13.0.0
version: 13.0.0
pm2:
specifier: ^6.0.5
version: 6.0.5(supports-color@10.0.0)
devDependencies:
'@kevisual/load':
specifier: ^0.0.6
@ -71,16 +81,19 @@ importers:
assistant:
dependencies:
dayjs:
specifier: ^1.11.13
version: 1.11.13
pm2:
specifier: ^6.0.5
version: 6.0.5(supports-color@10.0.0)
devDependencies:
'@kevisual/ai-center':
specifier: ^0.0.3
version: 0.0.3
'@kevisual/load':
specifier: ^0.0.6
version: 0.0.6
'@kevisual/local-app-manager':
specifier: ^0.1.16
version: 0.1.16(@kevisual/router@0.0.13)(@kevisual/types@0.0.1)(@kevisual/use-config@1.0.11(dotenv@16.5.0))(pm2@5.4.3(supports-color@10.0.0))
version: 0.1.16(@kevisual/router@0.0.13)(@kevisual/types@0.0.1)(@kevisual/use-config@1.0.11(dotenv@16.5.0))(pm2@6.0.5(supports-color@10.0.0))
'@kevisual/query':
specifier: 0.0.17
version: 0.0.17(@kevisual/ws@8.0.0)(encoding@0.1.13)
@ -117,6 +130,15 @@ importers:
cross-env:
specifier: ^7.0.3
version: 7.0.3
dayjs:
specifier: ^1.11.13
version: 1.11.13
dotenv:
specifier: ^16.5.0
version: 16.5.0
get-port:
specifier: ^7.1.0
version: 7.1.0
inquirer:
specifier: ^12.6.0
version: 12.6.0(@types/node@22.15.2)
@ -498,6 +520,9 @@ packages:
'@jridgewell/trace-mapping@0.3.25':
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
'@kevisual/ai-center@0.0.3':
resolution: {integrity: sha512-GYY8PyOxh8G9VYkm5rBCmOabrdIdN5b5kyx15OaX0fZEi1rG5bzDTL4BTqx5KhurG01HHbXiq32BbCv4ZaSMVA==}
'@kevisual/cache@0.0.2':
resolution: {integrity: sha512-2Cl5KF2Gi27uLfhO6CdTMFnRzx9vYnqevAo7d9ab3rOaqTgF8tLeAXglXyRbaWW3WUbHU2XaOb4r98uUsqIQQw==}
@ -551,11 +576,11 @@ packages:
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
'@pm2/agent@2.0.4':
resolution: {integrity: sha512-n7WYvvTJhHLS2oBb1PjOtgLpMhgImOq8sXkPBw6smeg9LJBWZjiEgPKOpR8mn9UJZsB5P3W4V/MyvNnp31LKeA==}
'@pm2/agent@2.1.1':
resolution: {integrity: sha512-0V9ckHWd/HSC8BgAbZSoq8KXUG81X97nSkAxmhKDhmF8vanyaoc1YXwc2KVkbWz82Rg4gjd2n9qiT3i7bdvGrQ==}
'@pm2/io@6.0.1':
resolution: {integrity: sha512-KiA+shC6sULQAr9mGZ1pg+6KVW9MF8NpG99x26Lf/082/Qy8qsTCtnJy+HQReW1A9Rdf0C/404cz0RZGZro+IA==}
'@pm2/io@6.1.0':
resolution: {integrity: sha512-IxHuYURa3+FQ6BKePlgChZkqABUKFYH6Bwbw7V/pWU1pP6iR1sCI26l7P9ThUEB385ruZn/tZS3CXDUF5IA1NQ==}
engines: {node: '>=6.0'}
'@pm2/js-api@0.8.0':
@ -1210,9 +1235,6 @@ packages:
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
engines: {node: '>=6'}
eventemitter2@0.4.14:
resolution: {integrity: sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==}
eventemitter2@5.0.1:
resolution: {integrity: sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg==}
@ -1316,6 +1338,10 @@ packages:
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
engines: {node: '>= 0.4'}
get-port@7.1.0:
resolution: {integrity: sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==}
engines: {node: '>=16'}
get-proto@1.0.1:
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
engines: {node: '>= 0.4'}
@ -1490,10 +1516,6 @@ packages:
jws@3.2.2:
resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==}
lazy@1.0.11:
resolution: {integrity: sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA==}
engines: {node: '>=0.2.0'}
lilconfig@3.1.3:
resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
engines: {node: '>=14'}
@ -1661,10 +1683,6 @@ packages:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
nssocket@0.6.0:
resolution: {integrity: sha512-a9GSOIql5IqgWJR3F/JXG4KpJTA3Z53Cj0MeMvGpglytB1nxE4PdFNC0jINe27CS7cGivoynwc054EzCcT3M3w==}
engines: {node: '>= 0.10.x'}
object-assign@4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
@ -1780,9 +1798,9 @@ packages:
pm2-sysmonit@1.2.8:
resolution: {integrity: sha512-ACOhlONEXdCTVwKieBIQLSi2tQZ8eKinhcr9JpZSUAL8Qy0ajIgRtsLxG/lwPOW3JEKqPyw/UaHmTWhUzpP4kA==}
pm2@5.4.3:
resolution: {integrity: sha512-4/I1htIHzZk1Y67UgOCo4F1cJtas1kSds31N8zN0PybO230id1nigyjGuGFzUnGmUFPmrJ0On22fO1ChFlp7VQ==}
engines: {node: '>=12.0.0'}
pm2@6.0.5:
resolution: {integrity: sha512-+O43WPaEiwYbm6/XSpAOO1Rtya/Uof0n7x8hJZGfwIuepesNTIVArpZh4KqFfze0cvvqZMr0maTW3ifhvmyeMQ==}
engines: {node: '>=16.0.0'}
hasBin: true
postcss-load-config@6.0.1:
@ -1813,8 +1831,8 @@ packages:
promptly@2.2.0:
resolution: {integrity: sha512-aC9j+BZsRSSzEsXBNBwDnAxujdx19HycZoKgRgzWnS8eOHg1asuf9heuLprfbe739zY3IdUQx+Egv6Jn135WHA==}
proxy-agent@6.3.1:
resolution: {integrity: sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==}
proxy-agent@6.4.0:
resolution: {integrity: sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==}
engines: {node: '>= 14'}
proxy-from-env@1.1.0:
@ -2578,6 +2596,8 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.0
'@kevisual/ai-center@0.0.3': {}
'@kevisual/cache@0.0.2(rollup@4.40.0)(tslib@2.8.1)(typescript@5.8.2)':
dependencies:
'@rollup/plugin-commonjs': 28.0.3(rollup@4.40.0)
@ -2594,12 +2614,12 @@ snapshots:
dependencies:
eventemitter3: 5.0.1
'@kevisual/local-app-manager@0.1.16(@kevisual/router@0.0.13)(@kevisual/types@0.0.1)(@kevisual/use-config@1.0.11(dotenv@16.5.0))(pm2@5.4.3(supports-color@10.0.0))':
'@kevisual/local-app-manager@0.1.16(@kevisual/router@0.0.13)(@kevisual/types@0.0.1)(@kevisual/use-config@1.0.11(dotenv@16.5.0))(pm2@6.0.5(supports-color@10.0.0))':
dependencies:
'@kevisual/router': 0.0.13
'@kevisual/types': 0.0.1
'@kevisual/use-config': 1.0.11(dotenv@16.5.0)
pm2: 5.4.3(supports-color@10.0.0)
pm2: 6.0.5(supports-color@10.0.0)
'@kevisual/query-login@0.0.5(@kevisual/query@0.0.17(@kevisual/ws@8.0.0)(encoding@0.1.13))(rollup@4.40.0)(typescript@5.8.2)':
dependencies:
@ -2666,7 +2686,7 @@ snapshots:
'@pkgjs/parseargs@0.11.0':
optional: true
'@pm2/agent@2.0.4(supports-color@10.0.0)':
'@pm2/agent@2.1.1(supports-color@10.0.0)':
dependencies:
async: 3.2.6
chalk: 3.0.0
@ -2675,10 +2695,9 @@ snapshots:
eventemitter2: 5.0.1
fast-json-patch: 3.1.1
fclone: 1.0.11
nssocket: 0.6.0
pm2-axon: 4.0.1(supports-color@10.0.0)
pm2-axon-rpc: 0.7.1(supports-color@10.0.0)
proxy-agent: 6.3.1(supports-color@10.0.0)
proxy-agent: 6.4.0(supports-color@10.0.0)
semver: 7.5.4
ws: 7.5.10
transitivePeerDependencies:
@ -2686,7 +2705,7 @@ snapshots:
- supports-color
- utf-8-validate
'@pm2/io@6.0.1(supports-color@10.0.0)':
'@pm2/io@6.1.0(supports-color@10.0.0)':
dependencies:
async: 2.6.4
debug: 4.3.7(supports-color@10.0.0)
@ -3241,8 +3260,6 @@ snapshots:
event-target-shim@5.0.1: {}
eventemitter2@0.4.14: {}
eventemitter2@5.0.1: {}
eventemitter2@6.4.9: {}
@ -3340,6 +3357,8 @@ snapshots:
hasown: 2.0.2
math-intrinsics: 1.1.0
get-port@7.1.0: {}
get-proto@1.0.1:
dependencies:
dunder-proto: 1.0.1
@ -3537,8 +3556,6 @@ snapshots:
jwa: 1.4.1
safe-buffer: 5.2.1
lazy@1.0.11: {}
lilconfig@3.1.3: {}
lines-and-columns@1.2.4: {}
@ -3660,11 +3677,6 @@ snapshots:
normalize-path@3.0.0: {}
nssocket@0.6.0:
dependencies:
eventemitter2: 0.4.14
lazy: 1.0.11
object-assign@4.1.1: {}
on-exit-leak-free@2.1.2: {}
@ -3828,10 +3840,10 @@ snapshots:
- supports-color
optional: true
pm2@5.4.3(supports-color@10.0.0):
pm2@6.0.5(supports-color@10.0.0):
dependencies:
'@pm2/agent': 2.0.4(supports-color@10.0.0)
'@pm2/io': 6.0.1(supports-color@10.0.0)
'@pm2/agent': 2.1.1(supports-color@10.0.0)
'@pm2/io': 6.1.0(supports-color@10.0.0)
'@pm2/js-api': 0.8.0(supports-color@10.0.0)
'@pm2/pm2-version-check': 1.0.4(supports-color@10.0.0)
async: 3.2.6
@ -3885,7 +3897,7 @@ snapshots:
dependencies:
read: 1.0.7
proxy-agent@6.3.1(supports-color@10.0.0):
proxy-agent@6.4.0(supports-color@10.0.0):
dependencies:
agent-base: 7.1.3
debug: 4.4.0(supports-color@10.0.0)