index.ts•3.37 kB
import { ToolDefinition, ToolResponse } from '../types.js';
import { exec, ExecException } from 'child_process';
import { promisify } from 'util';
import path from 'path';
import { Config } from '../../config/config.js';
const execAsync = promisify(exec);
interface ExecError extends ExecException {
stdout?: string;
stderr?: string;
killed?: boolean;
}
interface CommandOptions {
command: string;
timeout?: number;
workingDir?: string;
env?: Record<string, string>;
}
// 命令执行函数
async function executeCommand(
options: CommandOptions
): Promise<{
stdout: string;
stderr: string;
duration: number;
}> {
const {
command,
timeout = 30000,
env = {}
} = options;
const startTime = Date.now();
// 合并环境变量
const execEnv = {
...process.env,
...env
};
// 使用指定的工作目录或当前目录
const workingDir = options.workingDir || process.cwd();
// 创建执行选项
const execOptions = {
cwd: workingDir,
env: execEnv,
timeout,
maxBuffer: 10 * 1024 * 1024 // 10MB buffer
};
const { stdout, stderr } = await execAsync(command, execOptions);
const duration = Date.now() - startTime;
return { stdout, stderr, duration };
}
// 创建命令工具
export function createCommandTools(
config: Config
): ToolDefinition[] {
// 修改命令处理器,不再使用工作空间管理器
async function commandHandler(args: CommandOptions): Promise<ToolResponse> {
try {
const result = await executeCommand(args);
// 格式化输出文本
let outputText = '';
// 添加当前工作目录信息
outputText += `工作目录: ${args.workingDir || process.cwd()}\n\n`;
// 添加标准输出
if (result.stdout.trim()) {
outputText += `输出:\n${result.stdout.trim()}\n`;
}
// 添加标准错误(如果有)
if (result.stderr.trim()) {
outputText += `\n错误输出:\n${result.stderr.trim()}\n`;
}
// 添加执行时间
outputText += `\n执行时间: ${result.duration}ms`;
return {
content: [{
type: 'text',
text: outputText.trim()
}]
};
} catch (error) {
const execError = error as ExecError;
const isTimeout = execError.signal === 'SIGTERM' && execError.killed;
const errorMessage = isTimeout
? `命令执行超时(${args.timeout}ms)`
: execError.message || String(error);
return {
content: [{
type: 'text',
text: errorMessage
}],
isError: true
};
}
}
return [{
name: 'execute_command',
description: '执行命令行命令',
inputSchema: {
type: 'object',
properties: {
command: {
type: 'string',
description: '要执行的命令'
},
timeout: {
type: 'number',
description: '命令超时时间(毫秒)',
minimum: 0
},
workingDir: {
type: 'string',
description: '工作目录'
},
env: {
type: 'object',
description: '环境变量',
additionalProperties: {
type: 'string'
}
}
},
required: ['command']
},
handler: commandHandler
}];
}