feat: 添加系统命令支持 (:clear)
- 新增系统命令模块 (core/system-commands) - 支持 :clear/:cls/:c 清空对话历史 - 命令注册表支持别名 - 可扩展的命令执行器 - Server 端支持 - 新增 /api/system-commands API - WebSocket 处理系统命令消息 - 会话清空 API 端点 - UI 端支持 - 新增 SystemCommandMenu 组件 - 输入 : 时显示命令建议菜单 - 键盘导航和选择 - 底部提示添加 : 快捷键
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* System Command 执行器
|
||||
*
|
||||
* 解析和执行系统命令
|
||||
*/
|
||||
|
||||
import type {
|
||||
SystemCommandContext,
|
||||
SystemCommandInput,
|
||||
SystemCommandResult,
|
||||
} from './types.js';
|
||||
import { getSystemCommandRegistry } from './registry.js';
|
||||
|
||||
/**
|
||||
* System Command 执行器
|
||||
*/
|
||||
export class SystemCommandExecutor {
|
||||
/**
|
||||
* 检查输入是否为系统命令
|
||||
*/
|
||||
static isSystemCommand(input: string): boolean {
|
||||
return input.trim().startsWith(':');
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析系统命令输入
|
||||
*/
|
||||
static parseInput(input: string): SystemCommandInput | null {
|
||||
const trimmed = input.trim();
|
||||
|
||||
if (!trimmed.startsWith(':')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 移除 : 前缀
|
||||
const content = trimmed.slice(1);
|
||||
|
||||
// 分割命令和参数
|
||||
const spaceIndex = content.indexOf(' ');
|
||||
|
||||
if (spaceIndex === -1) {
|
||||
return {
|
||||
command: content.toLowerCase(),
|
||||
arguments: '',
|
||||
args: [],
|
||||
};
|
||||
}
|
||||
|
||||
const command = content.slice(0, spaceIndex).toLowerCase();
|
||||
const argsString = content.slice(spaceIndex + 1).trim();
|
||||
|
||||
return {
|
||||
command,
|
||||
arguments: argsString,
|
||||
args: argsString ? argsString.split(/\s+/) : [],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行系统命令
|
||||
*/
|
||||
static async execute(
|
||||
input: string,
|
||||
context: Partial<SystemCommandContext> = {}
|
||||
): Promise<SystemCommandResult> {
|
||||
const parsed = this.parseInput(input);
|
||||
|
||||
if (!parsed) {
|
||||
return {
|
||||
success: false,
|
||||
error: '无效的系统命令格式',
|
||||
};
|
||||
}
|
||||
|
||||
const registry = getSystemCommandRegistry();
|
||||
const command = registry.get(parsed.command);
|
||||
|
||||
if (!command) {
|
||||
// 列出可用命令作为提示
|
||||
const available = registry
|
||||
.list()
|
||||
.map((c) => `:${c.name}`)
|
||||
.join(', ');
|
||||
|
||||
return {
|
||||
success: false,
|
||||
error: `未知的系统命令: :${parsed.command}`,
|
||||
message: available ? `可用的系统命令: ${available}` : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await command.execute({
|
||||
arguments: parsed.arguments,
|
||||
args: parsed.args,
|
||||
sessionId: context.sessionId,
|
||||
workdir: context.workdir,
|
||||
});
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error:
|
||||
error instanceof Error ? error.message : '系统命令执行失败',
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 便捷函数:检查是否为系统命令
|
||||
*/
|
||||
export function isSystemCommand(input: string): boolean {
|
||||
return SystemCommandExecutor.isSystemCommand(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* 便捷函数:解析系统命令
|
||||
*/
|
||||
export function parseSystemCommand(
|
||||
input: string
|
||||
): SystemCommandInput | null {
|
||||
return SystemCommandExecutor.parseInput(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* 便捷函数:执行系统命令
|
||||
*/
|
||||
export async function executeSystemCommand(
|
||||
input: string,
|
||||
context?: Partial<SystemCommandContext>
|
||||
): Promise<SystemCommandResult> {
|
||||
return SystemCommandExecutor.execute(input, context);
|
||||
}
|
||||
Reference in New Issue
Block a user