fix
This commit is contained in:
parent
bd23bfe17c
commit
e7856dd8a6
@ -1,12 +1,11 @@
|
||||
import { WebSocketServer } from 'ws';
|
||||
import {pino} from 'pino';
|
||||
import { pino } from 'pino';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { dirname } from 'path';
|
||||
import { dirname, join } from 'path';
|
||||
import { routeMessage } from './common/router.js';
|
||||
import { VSCodeWebViewLike } from './hook/adapter.js';
|
||||
import path from 'node:path';
|
||||
import * as fs from 'node:fs';
|
||||
import { setRunningCWD } from './hook/setting.js';
|
||||
import fs from 'fs/promises'; // 使用 Promise API 替代回调
|
||||
import path from 'path';
|
||||
import axios from 'axios';
|
||||
|
||||
export interface VSCodeMessage {
|
||||
@ -15,91 +14,91 @@ export interface VSCodeMessage {
|
||||
callbackId?: string;
|
||||
}
|
||||
|
||||
// 适配 ESM 的 __dirname
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
// 统一路径变量
|
||||
const devHome = join(__dirname, '..', '..');
|
||||
const serverPath = join(devHome, 'servers');
|
||||
const envPath = join(__dirname, '..', '.env');
|
||||
|
||||
const logger = pino({
|
||||
transport: {
|
||||
target: 'pino-pretty', // 启用 pino-pretty
|
||||
target: 'pino-pretty',
|
||||
options: {
|
||||
colorize: true, // 开启颜色
|
||||
levelFirst: true, // 先打印日志级别
|
||||
translateTime: 'SYS:yyyy-mm-dd HH:MM:ss', // 格式化时间
|
||||
ignore: 'pid,hostname', // 忽略部分字段
|
||||
colorize: true,
|
||||
levelFirst: true,
|
||||
translateTime: 'SYS:yyyy-mm-dd HH:MM:ss',
|
||||
ignore: 'pid,hostname',
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export type MessageHandler = (message: VSCodeMessage) => void;
|
||||
|
||||
function refreshConnectionOption(envPath: string) {
|
||||
const serverPath = path.join(__dirname, '..', '..', 'servers');
|
||||
|
||||
async function refreshConnectionOption() {
|
||||
const defaultOption = {
|
||||
connectionType: 'STDIO',
|
||||
commandString: 'mcp run main.py',
|
||||
cwd: serverPath
|
||||
};
|
||||
|
||||
fs.writeFileSync(envPath, JSON.stringify(defaultOption, null, 4));
|
||||
|
||||
return { items: [ defaultOption ] };
|
||||
try {
|
||||
await fs.writeFile(envPath, JSON.stringify(defaultOption, null, 4), 'utf-8');
|
||||
return { items: [defaultOption] };
|
||||
} catch (error) {
|
||||
logger.error('刷新连接配置失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
function acquireConnectionOption() {
|
||||
const envPath = path.join(__dirname, '..', '.env');
|
||||
|
||||
if (!fs.existsSync(envPath)) {
|
||||
return refreshConnectionOption(envPath);
|
||||
}
|
||||
|
||||
async function acquireConnectionOption() {
|
||||
try {
|
||||
const option = JSON.parse(fs.readFileSync(envPath, 'utf-8'));
|
||||
const data = await fs.readFile(envPath, 'utf-8');
|
||||
const option = JSON.parse(data);
|
||||
|
||||
if (!option.items) {
|
||||
return refreshConnectionOption(envPath);
|
||||
}
|
||||
|
||||
if (option.items && option.items.length === 0) {
|
||||
return refreshConnectionOption(envPath);
|
||||
if (!option.items || option.items.length === 0) {
|
||||
return await refreshConnectionOption();
|
||||
}
|
||||
|
||||
// 按照前端的规范,整理成 commandString 样式
|
||||
option.items = option.items.map((item: any) => {
|
||||
option.items = option.items.map((item: { connectionType: string; commandString: string; command: any; args: any; url: any; }) => {
|
||||
if (item.connectionType === 'STDIO') {
|
||||
item.commandString = [item.command, ...item.args]?.join(' ');
|
||||
} else {
|
||||
item.url = item.url;
|
||||
}
|
||||
|
||||
return item;
|
||||
});
|
||||
|
||||
return option;
|
||||
|
||||
} catch (error) {
|
||||
logger.error('读取 .env 配置文件');
|
||||
return refreshConnectionOption(envPath);
|
||||
logger.error('读取 .env 配置文件失败:', error);
|
||||
return await refreshConnectionOption();
|
||||
}
|
||||
}
|
||||
|
||||
function updateConnectionOption(data: any) {
|
||||
const envPath = path.join(__dirname, '..', '.env');
|
||||
const connection = { items: data };
|
||||
fs.writeFileSync(envPath, JSON.stringify(connection, null, 4));
|
||||
async function updateConnectionOption(data: any) {
|
||||
try {
|
||||
await fs.writeFile(envPath, JSON.stringify({ items: data }, null, 4), 'utf-8');
|
||||
} catch (error) {
|
||||
logger.error('更新连接配置失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const devHome = path.join(__dirname, '..', '..');
|
||||
// 设置运行时路径
|
||||
import { setRunningCWD } from './hook/setting.js';
|
||||
setRunningCWD(devHome);
|
||||
|
||||
// 启动 WebSocket 服务器
|
||||
const wss = new WebSocketServer({ port: 8282 });
|
||||
console.log('WebSocket 服务器已启动:', 'ws://localhost:8282');
|
||||
|
||||
console.log('listen on ws://localhost:8282');
|
||||
|
||||
wss.on('connection', (ws: any) => {
|
||||
|
||||
// 仿造 webview 进行统一接口访问
|
||||
wss.on('connection', (ws) => {
|
||||
const webview = new VSCodeWebViewLike(ws);
|
||||
|
||||
// 先发送成功建立的消息
|
||||
webview.postMessage({
|
||||
command: 'hello',
|
||||
data: {
|
||||
@ -108,34 +107,33 @@ wss.on('connection', (ws: any) => {
|
||||
}
|
||||
});
|
||||
|
||||
const option = acquireConnectionOption();
|
||||
acquireConnectionOption().then(option => {
|
||||
webview.onDidReceiveMessage(async (message) => {
|
||||
logger.info(`收到命令: [${message.command || '未定义'}]`);
|
||||
|
||||
// 注册消息接受的管线
|
||||
webview.onDidReceiveMessage(message => {
|
||||
logger.info(`command: [${message.command || 'No Command'}]`);
|
||||
const { command, data } = message;
|
||||
const { command, data } = message;
|
||||
|
||||
switch (command) {
|
||||
case 'web/launch-signature':
|
||||
const launchResult = {
|
||||
code: 200,
|
||||
msg: option.items
|
||||
};
|
||||
switch (command) {
|
||||
case 'web/launch-signature':
|
||||
webview.postMessage({
|
||||
command: 'web/launch-signature',
|
||||
data: {
|
||||
code: 200,
|
||||
msg: option.items
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
webview.postMessage({
|
||||
command: 'web/launch-signature',
|
||||
data: launchResult
|
||||
});
|
||||
case 'web/update-connection-signature':
|
||||
await updateConnectionOption(data);
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
case 'web/update-connection-signature':
|
||||
updateConnectionOption(data);
|
||||
break;
|
||||
|
||||
default:
|
||||
routeMessage(command, data, webview);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
routeMessage(command, data, webview);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}).catch(error => {
|
||||
logger.error('初始化连接配置失败:', error);
|
||||
});
|
||||
});
|
@ -1,12 +1,17 @@
|
||||
import { WebSocketServer } from 'ws';
|
||||
import pino from 'pino';
|
||||
|
||||
import { fileURLToPath } from 'url';
|
||||
import { dirname, join } from 'path';
|
||||
import { routeMessage } from './common/router.js';
|
||||
import { VSCodeWebViewLike } from './hook/adapter.js';
|
||||
import path from 'node:path';
|
||||
import * as fs from 'node:fs';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { setRunningCWD } from './hook/setting.js';
|
||||
import { exit } from 'node:process';
|
||||
import { exit } from 'process';
|
||||
|
||||
// 适配 ESM 的 __dirname
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
export interface VSCodeMessage {
|
||||
command: string;
|
||||
@ -16,12 +21,12 @@ export interface VSCodeMessage {
|
||||
|
||||
const logger = pino.default({
|
||||
transport: {
|
||||
target: 'pino-pretty', // 启用 pino-pretty
|
||||
target: 'pino-pretty',
|
||||
options: {
|
||||
colorize: true, // 开启颜色
|
||||
levelFirst: true, // 先打印日志级别
|
||||
translateTime: 'SYS:yyyy-mm-dd HH:MM:ss', // 格式化时间
|
||||
ignore: 'pid,hostname', // 忽略部分字段
|
||||
colorize: true,
|
||||
levelFirst: true,
|
||||
translateTime: 'SYS:yyyy-mm-dd HH:MM:ss',
|
||||
ignore: 'pid,hostname',
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -29,8 +34,7 @@ const logger = pino.default({
|
||||
export type MessageHandler = (message: VSCodeMessage) => void;
|
||||
|
||||
function refreshConnectionOption(envPath: string) {
|
||||
const serverPath = path.join(__dirname, '..', '..', 'servers');
|
||||
|
||||
const serverPath = join(__dirname, '..', '..', 'servers');
|
||||
const defaultOption = {
|
||||
connectionType: 'STDIO',
|
||||
commandString: 'mcp run main.py',
|
||||
@ -38,12 +42,11 @@ function refreshConnectionOption(envPath: string) {
|
||||
};
|
||||
|
||||
fs.writeFileSync(envPath, JSON.stringify(defaultOption, null, 4));
|
||||
|
||||
return { items: [defaultOption] };
|
||||
}
|
||||
|
||||
function acquireConnectionOption() {
|
||||
const envPath = path.join(__dirname, '..', '.env');
|
||||
const envPath = join(__dirname, '..', '.env');
|
||||
|
||||
if (!fs.existsSync(envPath)) {
|
||||
return refreshConnectionOption(envPath);
|
||||
@ -52,11 +55,7 @@ function acquireConnectionOption() {
|
||||
try {
|
||||
const option = JSON.parse(fs.readFileSync(envPath, 'utf-8'));
|
||||
|
||||
if (!option.items) {
|
||||
return refreshConnectionOption(envPath);
|
||||
}
|
||||
|
||||
if (option.items && option.items.length === 0) {
|
||||
if (!option.items || option.items.length === 0) {
|
||||
return refreshConnectionOption(envPath);
|
||||
}
|
||||
|
||||
@ -67,7 +66,6 @@ function acquireConnectionOption() {
|
||||
} else {
|
||||
item.url = item.url;
|
||||
}
|
||||
|
||||
return item;
|
||||
});
|
||||
|
||||
@ -79,20 +77,22 @@ function acquireConnectionOption() {
|
||||
}
|
||||
}
|
||||
|
||||
if (!fs.existsSync(path.join(__dirname, '..', '.env.website.local'))) {
|
||||
// 验证 .env.website.local 存在性
|
||||
const localEnvPath = join(__dirname, '..', '.env.website.local');
|
||||
if (!fs.existsSync(localEnvPath)) {
|
||||
console.log('.env.website.local 不存在!');
|
||||
exit(0);
|
||||
}
|
||||
|
||||
const authPassword = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '.env.website.local'), 'utf-8')).password;
|
||||
// 读取认证密码
|
||||
const authPassword = JSON.parse(fs.readFileSync(localEnvPath, 'utf-8')).password;
|
||||
|
||||
function updateConnectionOption(data: any) {
|
||||
const envPath = path.join(__dirname, '..', '.env');
|
||||
const connection = { items: data };
|
||||
fs.writeFileSync(envPath, JSON.stringify(connection, null, 4));
|
||||
const envPath = join(__dirname, '..', '.env');
|
||||
fs.writeFileSync(envPath, JSON.stringify({ items: data }, null, 4));
|
||||
}
|
||||
|
||||
const devHome = path.join(__dirname, '..', '..');
|
||||
const devHome = join(__dirname, '..', '..');
|
||||
setRunningCWD(devHome);
|
||||
|
||||
function verifyToken(url: string) {
|
||||
@ -104,30 +104,25 @@ function verifyToken(url: string) {
|
||||
}
|
||||
}
|
||||
|
||||
const wss = new WebSocketServer(
|
||||
{
|
||||
port: 8282,
|
||||
verifyClient: (info, callback) => {
|
||||
console.log(info.req.url);
|
||||
const ok = verifyToken(info.req.url || '');
|
||||
const wss = new WebSocketServer({
|
||||
port: 8282,
|
||||
verifyClient: (info, callback) => {
|
||||
const url = info.req.url || '';
|
||||
const ok = verifyToken(url);
|
||||
|
||||
if (!ok) {
|
||||
callback(false, 401, 'Unauthorized: Invalid token');
|
||||
} else {
|
||||
callback(true); // 允许连接
|
||||
}
|
||||
if (!ok) {
|
||||
callback(false, 401, 'Unauthorized: Invalid token');
|
||||
} else {
|
||||
callback(true);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('listen on ws://localhost:8282');
|
||||
|
||||
wss.on('connection', (ws: any) => {
|
||||
|
||||
// 仿造 webview 进行统一接口访问
|
||||
wss.on('connection', (ws) => {
|
||||
const webview = new VSCodeWebViewLike(ws);
|
||||
|
||||
// 先发送成功建立的消息
|
||||
webview.postMessage({
|
||||
command: 'hello',
|
||||
data: {
|
||||
@ -138,23 +133,19 @@ wss.on('connection', (ws: any) => {
|
||||
|
||||
const option = acquireConnectionOption();
|
||||
|
||||
// 注册消息接受的管线
|
||||
webview.onDidReceiveMessage(message => {
|
||||
logger.info(`command: [${message.command || 'No Command'}]`);
|
||||
const { command, data } = message;
|
||||
|
||||
switch (command) {
|
||||
case 'web/launch-signature':
|
||||
const launchResult = {
|
||||
code: 200,
|
||||
msg: option.items
|
||||
};
|
||||
|
||||
webview.postMessage({
|
||||
command: 'web/launch-signature',
|
||||
data: launchResult
|
||||
data: {
|
||||
code: 200,
|
||||
msg: option.items
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
case 'web/update-connection-signature':
|
||||
|
Loading…
x
Reference in New Issue
Block a user