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

@@ -0,0 +1,38 @@
export const configJson = `{
"name": "assistant-app",
"version": "1.0.1",
"description": "assistant-app package pnpm, node pkgs projects",
"type": "module",
"scripts": {
"start": "pm2 start apps/code-center/dist/app.mjs --name code-center",
"proxy": "pm2 start apps/page-proxy/dist/app.mjs --name page-proxy",
"preview": "pnpm i && ASSISTANT_CONFIG_DIR=/workspace/kevisual asst server -s"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@aws-sdk/client-s3": "^3.990.0",
"@kevisual/oss": "^0.0.19",
"@kevisual/query": "^0.0.40",
"eventemitter3": "^5.0.4",
"@kevisual/router": "^0.0.70",
"@kevisual/use-config": "^1.0.30",
"ioredis": "^5.9.3",
"pg": "^8.18.0",
"pm2": "^6.0.14",
"crypto-js": "^4.2.0",
"unstorage": "^1.17.4",
"dayjs": "^1.11.19",
"es-toolkit": "^1.44.0",
"node-cron": "^4.2.1",
"dotenv": "^17.3.1"
},
"devDependencies": {
"@kevisual/types": "^0.0.12",
"@types/bun": "^1.3.9",
"@types/crypto-js": "^4.2.2",
"@types/node": "^25.2.3"
}
}
`

View File

@@ -3,7 +3,7 @@ import path from 'node:path';
import { checkFileExists, AssistantConfig, AssistantConfigData, parseHomeArg, parseHelpArg } from '@/module/assistant/index.ts';
import { chalk } from '@/module/chalk.ts';
import { Query } from '@kevisual/query/query';
import { installDeps } from '@/module/npm-install.ts'
import { checkNpmConfg } from './update-pkgs.ts';
export { parseHomeArg, parseHelpArg };
export type AssistantInitOptions = {
path?: string;
@@ -118,56 +118,7 @@ export class AssistantInit extends AssistantConfig {
console.log(chalk.green('助手 pnpm-workspace.yaml 文件创建成功'));
}
const packagePath = path.join(this.configDir, 'assistant-app', 'package.json');
if (!checkFileExists(packagePath, true)) {
create = true;
fs.writeFileSync(
packagePath,
`{
"name": "assistant-app",
"version": "1.0.1",
"description": "assistant-app package pnpm, node pkgs projects",
"type": "module",
"scripts": {
"start": "pm2 start apps/code-center/dist/app.mjs --name code-center",
"proxy": "pm2 start apps/page-proxy/dist/app.mjs --name page-proxy",
"preview": "pnpm i && ASSISTANT_CONFIG_DIR=/workspace/kevisual asst server -s"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@aws-sdk/client-s3": "^3.990.0",
"@kevisual/oss": "^0.0.19",
"@kevisual/query": "^0.0.40",
"eventemitter3": "^5.0.4",
"@kevisual/router": "^0.0.70",
"@kevisual/use-config": "^1.0.30",
"ioredis": "^5.9.3",
"pg": "^8.18.0",
"pm2": "^6.0.14",
"crypto-js": "^4.2.0",
"unstorage": "^1.17.4",
"dayjs": "^1.11.19",
"es-toolkit": "^1.44.0",
"node-cron": "^4.2.1",
"dotenv": "^17.3.1"
},
"devDependencies": {
"@kevisual/types": "^0.0.12",
"@types/bun": "^1.3.9",
"@types/crypto-js": "^4.2.2",
"@types/node": "^25.2.3"
}
}
`,
);
console.log(chalk.green('助手 package.json 文件创建成功, 正在安装依赖...'));
installDeps({ appPath: path.dirname(packagePath), isProduction: true }).then(() => {
console.log('------------------------------------------------');
console.log(chalk.green('助手依赖安装完成'));
console.log('------------------------------------------------');
});
}
checkNpmConfg(packagePath);
return {
create,
};
@@ -205,21 +156,4 @@ export class AssistantInit extends AssistantConfig {
console.log(chalk.green('.gitignore 文件更新成功'));
}
}
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;
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "assistant-app",
"version": "1.0.1",
"version": "1.0.3",
"description": "assistant-app package pnpm, node pkgs projects",
"type": "module",
"scripts": {
@@ -12,26 +12,25 @@
"author": "",
"license": "ISC",
"dependencies": {
"@aws-sdk/client-s3": "^3.990.0",
"@aws-sdk/client-s3": "^3.994.0",
"@kevisual/oss": "^0.0.19",
"@kevisual/query": "^0.0.40",
"eventemitter3": "^5.0.4",
"@kevisual/router": "^0.0.70",
"@kevisual/query": "^0.0.49",
"@kevisual/router": "^0.0.83",
"@kevisual/use-config": "^1.0.30",
"dayjs": "^1.11.19",
"dotenv": "^17.3.1",
"es-toolkit": "^1.44.0",
"eventemitter3": "^5.0.4",
"ioredis": "^5.9.3",
"node-cron": "^4.2.1",
"pg": "^8.18.0",
"pm2": "^6.0.14",
"crypto-js": "^4.2.0",
"unstorage": "^1.17.4",
"dayjs": "^1.11.19",
"es-toolkit": "^1.44.0",
"node-cron": "^4.2.1",
"dotenv": "^17.3.1"
"unstorage": "^1.17.4"
},
"devDependencies": {
"@kevisual/types": "^0.0.12",
"@types/bun": "^1.3.9",
"@types/crypto-js": "^4.2.2",
"@types/node": "^25.2.3"
"@types/node": "^25.3.0",
"semver": "^7.7.4"
}
}

View File

@@ -0,0 +1,111 @@
import { configJson } from './common.ts';
import { checkFileExists } from '@/module/assistant/index.ts';
import { chalk } from '@/module/chalk.ts';
import { installDeps } from '@/module/npm-install.ts'
import fs from 'node:fs';
import path from 'node:path';
import { execSync } from 'node:child_process';
import semver from 'semver';
export const checkNpmConfg = (packagePath: string) => {
let create = false;
if (!checkFileExists(packagePath, true)) {
create = true;
fs.writeFileSync(packagePath, configJson);
console.log(chalk.green('助手 package.json 文件创建成功, 正在安装依赖...'));
installDeps({ appPath: path.dirname(packagePath), isProduction: true }).then(() => {
console.log('------------------------------------------------');
console.log(chalk.green('助手依赖安装完成'));
console.log('------------------------------------------------');
});
} else {
checkNpmFileConfig(packagePath);
}
return {
create,
}
}
const checkNpmFileConfig = async (packagePath: string) => {
const existingConfig = JSON.parse(fs.readFileSync(packagePath, 'utf-8'));
const defaultConfig = JSON.parse(configJson);
const appPath = path.dirname(packagePath);
let needUpdate = false;
if (defaultConfig.version !== existingConfig.version) {
existingConfig.version = defaultConfig.version;
existingConfig.scripts = {
...existingConfig.scripts,
...defaultConfig.scripts,
};
needUpdate = true;
fs.writeFileSync(packagePath, JSON.stringify(existingConfig, null, 2));
console.log(chalk.yellow('助手 package.json 文件版本不匹配,正在更新...'));
}
// 收集需要更新的依赖列表
const depsToUpdate: string[] = [];
const devDepsToUpdate: string[] = [];
// 收集需要添加的依赖(不存在的)
const depsToAdd: string[] = [];
const devDepsToAdd: string[] = [];
// 检查 dependencies - 不存在或版本小于 defaultConfig
for (const dep in defaultConfig.dependencies) {
const defaultVersion = defaultConfig.dependencies[dep].replace(/^[~^]/, '');
const existingVersion = existingConfig.dependencies?.[dep]?.replace(/^[~^]/, '');
// console.log(chalk.blue(`检查 dependency: ${dep}, defaultVersion: ${defaultVersion}, existingVersion: ${existingVersion}`));
if (!existingVersion) {
// 依赖不存在,先添加到 package.json
existingConfig.dependencies = existingConfig.dependencies || {};
existingConfig.dependencies[dep] = defaultConfig.dependencies[dep];
depsToAdd.push(dep);
} else if (semver.lt(existingVersion, defaultVersion)) {
depsToUpdate.push(dep);
}
}
// 检查 devDependencies - 不存在或版本小于 defaultConfig
for (const devDep in defaultConfig.devDependencies) {
const defaultVersion = defaultConfig.devDependencies[devDep].replace(/^[~^]/, '');
const existingVersion = existingConfig.devDependencies?.[devDep]?.replace(/^[~^]/, '');
// console.log(chalk.blue(`检查 devDependency: ${devDep}, defaultVersion: ${defaultVersion}, existingVersion: ${existingVersion}`));
if (!existingVersion) {
// 依赖不存在,先添加到 package.json
existingConfig.devDependencies = existingConfig.devDependencies || {};
existingConfig.devDependencies[devDep] = defaultConfig.devDependencies[devDep];
devDepsToAdd.push(devDep);
} else if (semver.lt(existingVersion, defaultVersion)) {
devDepsToUpdate.push(devDep);
}
}
// 如果有新增的依赖,先写入 package.json
if (depsToAdd.length > 0 || devDepsToAdd.length > 0) {
fs.writeFileSync(packagePath, JSON.stringify(existingConfig, null, 2));
console.log(chalk.yellow(`新增的 dependencies: ${depsToAdd.join(', ') || '无'}`));
console.log(chalk.yellow(`新增的 devDependencies: ${devDepsToAdd.join(', ') || '无'}`));
}
if (depsToUpdate.length > 0 || devDepsToUpdate.length > 0 || needUpdate) {
console.log(chalk.yellow(`需要更新的 dependencies: ${depsToUpdate.join(', ') || '无'}`));
console.log(chalk.yellow(`需要更新的 devDependencies: ${devDepsToUpdate.join(', ') || '无'}`));
console.log(chalk.green('正在执行 ncu -u 更新依赖版本...'));
// 执行 ncu -u 更新 package.json
try {
execSync('ncu -u', { cwd: appPath, stdio: 'inherit' });
console.log(chalk.green('ncu -u 执行完成'));
} catch (error) {
console.error(chalk.red('ncu -u 执行失败:', error));
}
console.log(chalk.green('正在安装依赖...'));
installDeps({ appPath, isProduction: true }).then(() => {
console.log('------------------------------------------------');
console.log(chalk.green('助手依赖安装完成'));
console.log('------------------------------------------------');
});
} else {
console.log(chalk.green('助手 package.json 文件已存在且依赖完整,无需更新'));
}
}