"feat: 增加助手应用配置管理功能与服务器守护进程支持"
This commit is contained in:
		
							
								
								
									
										9
									
								
								assistant/task-command/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								assistant/task-command/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| node_modules | ||||
| .DS_Store | ||||
|  | ||||
| dist | ||||
|  | ||||
| pack-dist | ||||
|  | ||||
| .env* | ||||
| !.env*example | ||||
							
								
								
									
										4
									
								
								assistant/task-command/.npmrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								assistant/task-command/.npmrc
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										67
									
								
								assistant/task-command/mod.d.ts
									
									
									
									
										vendored
									
									
										Normal 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 }; | ||||
							
								
								
									
										142
									
								
								assistant/task-command/mod.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								assistant/task-command/mod.ts
									
									
									
									
									
										Normal 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(), | ||||
|       }; | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										26
									
								
								assistant/task-command/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								assistant/task-command/package.json
									
									
									
									
									
										Normal 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" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										3
									
								
								assistant/task-command/readme.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								assistant/task-command/readme.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| # task-command | ||||
|  | ||||
| command line task runner | ||||
		Reference in New Issue
	
	Block a user