167 lines
5.1 KiB
TypeScript
167 lines
5.1 KiB
TypeScript
import { getConnectionConfig, panels, saveConnectionConfig, getFirstValidPathFromCommand, McpOptions } from "../global";
|
||
import { exec, spawn } from 'node:child_process';
|
||
import * as vscode from 'vscode';
|
||
|
||
export async function deleteInstalledConnection(item: McpOptions[] | McpOptions) {
|
||
// 弹出确认对话框
|
||
const masterNode = Array.isArray(item) ? item[0] : item;
|
||
const name = masterNode.name;
|
||
const confirm = await vscode.window.showWarningMessage(
|
||
`确定要删除连接 "${name}" 吗?`,
|
||
{ modal: true },
|
||
'确定'
|
||
);
|
||
|
||
if (confirm !== '确定') {
|
||
return; // 用户取消删除
|
||
}
|
||
|
||
const installedConnection = getConnectionConfig();
|
||
|
||
// 从配置中移除该连接项
|
||
const index = installedConnection.items.indexOf(item);
|
||
|
||
|
||
if (index !== -1) {
|
||
installedConnection.items.splice(index, 1);
|
||
|
||
// 保存更新后的配置
|
||
saveConnectionConfig();
|
||
|
||
// 刷新侧边栏视图
|
||
vscode.commands.executeCommand('openmcp.sidebar.installed-connection.refresh');
|
||
|
||
// 如果该连接有对应的webview面板,则关闭它
|
||
const filePath = masterNode.filePath || '';
|
||
const panel = panels.get(filePath);
|
||
panel?.dispose();
|
||
panels.delete(filePath);
|
||
}
|
||
}
|
||
|
||
export async function validateAndGetCommandPath(commandString: string, cwd?: string): Promise<string> {
|
||
try {
|
||
const commands = commandString.split(' ');
|
||
const command = commands[0];
|
||
const args = commands.slice(1);
|
||
const process = spawn(command, args || [], { shell: true, cwd });
|
||
process.disconnect();
|
||
|
||
return '';
|
||
} catch (error) {
|
||
console.log(error);
|
||
throw new Error(`无法找到命令: ${commandString.split(' ')[0]}`);
|
||
}
|
||
}
|
||
|
||
export async function acquireInstalledConnection(): Promise<McpOptions[]> {
|
||
// 让用户选择连接类型
|
||
const connectionType = await vscode.window.showQuickPick(['STDIO', 'SSE', 'STREAMABLE_HTTP'], {
|
||
placeHolder: '请选择连接类型',
|
||
canPickMany: false
|
||
});
|
||
|
||
if (!connectionType) {
|
||
return []; // 用户取消选择
|
||
}
|
||
|
||
if (connectionType === 'STDIO') {
|
||
// 获取 command
|
||
const commandString = await vscode.window.showInputBox({
|
||
prompt: '请输入连接的 command',
|
||
placeHolder: '例如: mcp run main.py'
|
||
});
|
||
|
||
if (!commandString) {
|
||
return []; // 用户取消输入
|
||
}
|
||
|
||
// 获取 cwd
|
||
const cwd = await vscode.window.showInputBox({
|
||
prompt: '请输入工作目录 (cwd),可选',
|
||
placeHolder: '例如: /path/to/project'
|
||
});
|
||
|
||
// 校验 command + cwd 是否有效
|
||
try {
|
||
const commandPath = await validateAndGetCommandPath(commandString, cwd);
|
||
console.log('Command Path:', commandPath);
|
||
} catch (error) {
|
||
vscode.window.showErrorMessage(`无效的 command: ${error}`);
|
||
return [];
|
||
}
|
||
|
||
const commands = commandString.split(' ');
|
||
const command = commands[0];
|
||
const args = commands.slice(1);
|
||
|
||
console.log('Command:', command);
|
||
|
||
const filePath = await getFirstValidPathFromCommand(commandString, cwd || '');
|
||
|
||
// 保存连接配置
|
||
return [{
|
||
connectionType: 'STDIO',
|
||
name: `STDIO-${Date.now()}`,
|
||
command: command,
|
||
args,
|
||
cwd: cwd || '',
|
||
filePath: filePath,
|
||
}];
|
||
|
||
} else if (connectionType === 'SSE') {
|
||
// 获取 url
|
||
const url = await vscode.window.showInputBox({
|
||
prompt: '请输入连接的 URL',
|
||
placeHolder: '例如: https://127.0.0.1:8282/sse'
|
||
});
|
||
|
||
if (!url) {
|
||
return []; // 用户取消输入
|
||
}
|
||
|
||
// 获取 oauth
|
||
const oauth = await vscode.window.showInputBox({
|
||
prompt: '请输入 OAuth 令牌,可选',
|
||
placeHolder: '例如: your-oauth-token'
|
||
});
|
||
|
||
// 保存连接配置
|
||
return [{
|
||
connectionType: 'SSE',
|
||
name: `SSE-${Date.now()}`,
|
||
version: '1.0', // 假设默认版本为 1.0,可根据实际情况修改
|
||
url: url,
|
||
oauth: oauth || ''
|
||
}];
|
||
} else if (connectionType === 'STREAMABLE_HTTP') {
|
||
// 获取 url
|
||
const url = await vscode.window.showInputBox({
|
||
prompt: '请输入连接的 URL',
|
||
placeHolder: '例如: https://127.0.0.1:8282/stream'
|
||
});
|
||
|
||
if (!url) {
|
||
return []; // 用户取消输入
|
||
}
|
||
|
||
// 获取 oauth
|
||
const oauth = await vscode.window.showInputBox({
|
||
prompt: '请输入 OAuth 令牌,可选',
|
||
placeHolder: '例如: your-oauth-token'
|
||
});
|
||
|
||
// 保存连接配置
|
||
return [{
|
||
connectionType: 'STREAMABLE_HTTP',
|
||
name: `STREAMABLE_HTTP-${Date.now()}`,
|
||
version: '1.0', // 假设默认版本为 1.0,可根据实际情况修改
|
||
url: url,
|
||
oauth: oauth || ''
|
||
}];
|
||
}
|
||
|
||
return [];
|
||
}
|
||
|