feat: add user info command and package management for assistant app

- Implemented a new command 'me' to view current user information in the assistant application.
- Created a common configuration file for the assistant app with package details and scripts.
- Added functionality to check and update package.json dependencies and devDependencies in the assistant app.
- Refactored storage initialization in query module to use StorageNode.
This commit is contained in:
2026-02-21 03:08:39 +08:00
parent e53c166c29
commit 68c1976754
26 changed files with 657 additions and 1453 deletions

View File

@@ -1,5 +1,4 @@
import fs from 'node:fs';
import { useKey } from '@kevisual/use-config';
export const getFileConfig = (filePath: string): any => {
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
}

View File

@@ -1,15 +1,11 @@
import path from 'path';
import { homedir } from 'os';
import fs from 'fs';
import { checkFileExists, createDir } from '../file/index.ts';
import { ProxyInfo } from '../proxy/proxy.ts';
import dotenv from 'dotenv';
import { logger } from '@/module/logger.ts';
import { z } from 'zod'
import { HomeConfigDir } from './args.ts'
import { getFileConfig } from './get-assistan-config.ts';
import { useKey } from '@kevisual/use-config';
import { env } from 'pm2';
/**
* 助手配置文件路径, 全局配置文件目录
@@ -231,25 +227,15 @@ export class AssistantConfig {
getConfig(): AssistantConfigData {
try {
if (!checkFileExists(this.configPath.configPath)) {
fs.writeFileSync(this.configPath.configPath, JSON.stringify({ proxy: [] }, null, 2));
return {
app: {
url: 'https://kevisual.cn',
},
proxy: [],
};
const defaultConfig = this.getDefaultInitAssistantConfig();
fs.writeFileSync(this.configPath.configPath, JSON.stringify(defaultConfig, null, 2));
return defaultConfig;
}
assistantConfig = getFileConfig(this.configPath.configPath);
return assistantConfig;
} catch (error) {
console.error('file read', error.message);
process.exit(1);
return {
app: {
url: 'https://kevisual.cn',
},
proxy: [],
};
}
}
getCacheAssistantConfig() {
@@ -393,6 +379,23 @@ export class AssistantConfig {
// 如果没有找到助手配置文件目录,则返回当前目录, 执行默认创建助手配置文件目录
return checkConfigDir;
}
protected getDefaultInitAssistantConfig() {
const id = randomId();
return {
app: {
url: 'https://kevisual.cn',
id,
},
description: '助手配置文件',
docs: "https://kevisual.cn/root/cli/docs/",
home: '/root/home',
proxy: [],
share: {
enabled: false,
url: 'https://kevisual.cn/ws/proxy',
},
} as AssistantConfigData;
}
}
type AppConfig = {
@@ -408,4 +411,6 @@ export const parseIfJson = (content: string) => {
}
};
export * from './args.ts';
export * from './args.ts';
const randomId = () => Math.random().toString(36).substring(2, 8);

View File

@@ -216,7 +216,7 @@ export class AssistantApp extends Manager {
const routeStr = typeof route === 'string' ? route : route.path;
const resolvedPath = this.resolver.resolve(routeStr);
await import(resolvedPath);
console.log('[routes] 路由已初始化', route, resolvedPath);
console.log('[routes] 路由已初始化', route);
} catch (err) {
console.error('初始化路由失败', route, err);
}

View File

@@ -1,14 +1,33 @@
import { DataOpts, Query } from "@kevisual/query/query";
import { AssistantConfig } from "../config/index.ts";
import { QueryLoginNode } from '@kevisual/api/query-login-node'
import { EventEmitter } from 'eventemitter3'
export class AssistantQuery {
config: AssistantConfig;
query: Query ;
query: Query;
queryLogin: QueryLoginNode;
emitter = new EventEmitter();
isLoad = false;
constructor(config: AssistantConfig) {
config.checkMounted();
this.config = config;
this.query = new Query({ url: config.getRegistry() + '/api/router' });
this.query = new Query({ url: config.getRegistry() + '/api/router' });
this.queryLogin = new QueryLoginNode({
query: this.query, onLoad: () => {
this.isLoad = true;
this.emitter.emit('load')
}
});
}
async init() {
if (this.isLoad) return true;
return new Promise((resolve) => {
this.emitter.on('load', () => {
this.isLoad = true;
resolve(true);
})
})
}
post(body: any, options?: DataOpts) {
return this.query.post(body, options);
@@ -16,4 +35,7 @@ export class AssistantQuery {
get(body: any, options?: DataOpts) {
return this.query.get(body, options);
}
getToken() {
return this.queryLogin.getToken();
}
}

View File

@@ -29,9 +29,9 @@ export const installDeps = async (opts: InstallDepsOptions) => {
console.log('installDeps', appPath, params);
const syncSpawn = opts.sync ? spawnSync : spawn;
if (isPnpm) {
syncSpawn('pnpm', params, { cwd: appPath, stdio: 'inherit', env: process.env });
syncSpawn('pnpm', params, { cwd: appPath, stdio: 'inherit', env: { ...process.env, CI: 'true' }, shell: true });
} else {
syncSpawn('npm', params, { cwd: appPath, stdio: 'inherit', env: process.env });
syncSpawn('npm', params, { cwd: appPath, stdio: 'inherit', env: process.env, shell: true });
}
};