@@ -148,10 +148,9 @@ onMounted(async () => {
margin-left: 10px;
background-color: var(--main-color);
padding: 2px 5px;
- border-radius: .5em;
+ border-radius: .3em;
height: fit-content;
- font-size: 10px;
-
+ font-size: 13px;
color: black;
}
diff --git a/renderer/src/i18n/ar.json b/renderer/src/i18n/ar.json
index 73f5338..1506e7a 100644
--- a/renderer/src/i18n/ar.json
+++ b/renderer/src/i18n/ar.json
@@ -176,5 +176,11 @@
"tool-manage": "إدارة الأدوات",
"enable-all-tools": "تفعيل جميع الأدوات",
"disable-all-tools": "تعطيل جميع الأدوات",
- "using-tool": "جاري استخدام الأداة"
+ "using-tool": "جاري استخدام الأداة",
+ "copy-success": "تم النسخ بنجاح",
+ "copy-fail": "فشل النسخ",
+ "copy": "نسخ",
+ "export": "تصدير",
+ "export-filename": "اسم ملف التصدير",
+ "how-to-use": "كيفية الاستخدام؟"
}
\ No newline at end of file
diff --git a/renderer/src/i18n/de.json b/renderer/src/i18n/de.json
index 4f45f0c..14dd286 100644
--- a/renderer/src/i18n/de.json
+++ b/renderer/src/i18n/de.json
@@ -176,5 +176,11 @@
"tool-manage": "Werkzeugverwaltung",
"enable-all-tools": "Alle Tools aktivieren",
"disable-all-tools": "Alle Tools deaktivieren",
- "using-tool": "Werkzeug wird verwendet"
+ "using-tool": "Werkzeug wird verwendet",
+ "copy-success": "Erfolgreich kopiert",
+ "copy-fail": "Kopieren fehlgeschlagen",
+ "copy": "Kopieren",
+ "export": "Exportieren",
+ "export-filename": "Exportdateiname",
+ "how-to-use": "Wie benutzt man?"
}
\ No newline at end of file
diff --git a/renderer/src/i18n/en.json b/renderer/src/i18n/en.json
index 6bd6c9e..02c9246 100644
--- a/renderer/src/i18n/en.json
+++ b/renderer/src/i18n/en.json
@@ -176,5 +176,11 @@
"tool-manage": "Tool Management",
"enable-all-tools": "Activate all tools",
"disable-all-tools": "Disable all tools",
- "using-tool": "Using tool"
+ "using-tool": "Using tool",
+ "copy-success": "Copied successfully",
+ "copy-fail": "Copy failed",
+ "copy": "Copy",
+ "export": "Export",
+ "export-filename": "Export file name",
+ "how-to-use": "How to use?"
}
\ No newline at end of file
diff --git a/renderer/src/i18n/fr.json b/renderer/src/i18n/fr.json
index bebf323..1dda9a9 100644
--- a/renderer/src/i18n/fr.json
+++ b/renderer/src/i18n/fr.json
@@ -176,5 +176,11 @@
"tool-manage": "Gestion des outils",
"enable-all-tools": "Activer tous les outils",
"disable-all-tools": "Désactiver tous les outils",
- "using-tool": "Utilisation de l'outil"
+ "using-tool": "Utilisation de l'outil",
+ "copy-success": "Copié avec succès",
+ "copy-fail": "Échec de la copie",
+ "copy": "Copier",
+ "export": "Exporter",
+ "export-filename": "Nom du fichier d'exportation",
+ "how-to-use": "Comment utiliser ?"
}
\ No newline at end of file
diff --git a/renderer/src/i18n/ja.json b/renderer/src/i18n/ja.json
index df0ee58..e5e70fd 100644
--- a/renderer/src/i18n/ja.json
+++ b/renderer/src/i18n/ja.json
@@ -176,5 +176,11 @@
"tool-manage": "ツール管理",
"enable-all-tools": "すべてのツールを有効にする",
"disable-all-tools": "すべてのツールを無効にする",
- "using-tool": "ツール使用中"
+ "using-tool": "ツール使用中",
+ "copy-success": "コピーしました",
+ "copy-fail": "コピーに失敗しました",
+ "copy": "コピー",
+ "export": "エクスポート",
+ "export-filename": "エクスポートファイル名",
+ "how-to-use": "使い方は?"
}
\ No newline at end of file
diff --git a/renderer/src/i18n/ko.json b/renderer/src/i18n/ko.json
index ae18984..d175a89 100644
--- a/renderer/src/i18n/ko.json
+++ b/renderer/src/i18n/ko.json
@@ -176,5 +176,11 @@
"tool-manage": "도구 관리",
"enable-all-tools": "모든 도구 활성화",
"disable-all-tools": "모든 도구 비활성화",
- "using-tool": "도구 사용 중"
+ "using-tool": "도구 사용 중",
+ "copy-success": "성공적으로 복사되었습니다",
+ "copy-fail": "복사 실패",
+ "copy": "복사",
+ "export": "내보내기",
+ "export-filename": "내보내기 파일 이름",
+ "how-to-use": "사용 방법?"
}
\ No newline at end of file
diff --git a/renderer/src/i18n/ru.json b/renderer/src/i18n/ru.json
index 5f009ca..d088ece 100644
--- a/renderer/src/i18n/ru.json
+++ b/renderer/src/i18n/ru.json
@@ -176,5 +176,11 @@
"tool-manage": "Управление инструментами",
"enable-all-tools": "Активировать все инструменты",
"disable-all-tools": "Отключить все инструменты",
- "using-tool": "Использование инструмента"
+ "using-tool": "Использование инструмента",
+ "copy-success": "Скопировано успешно",
+ "copy-fail": "Ошибка копирования",
+ "copy": "Копировать",
+ "export": "Экспорт",
+ "export-filename": "Имя экспортируемого файла",
+ "how-to-use": "Как использовать?"
}
\ No newline at end of file
diff --git a/renderer/src/i18n/zh-cn.json b/renderer/src/i18n/zh-cn.json
index 0096a40..7906cc5 100644
--- a/renderer/src/i18n/zh-cn.json
+++ b/renderer/src/i18n/zh-cn.json
@@ -176,5 +176,11 @@
"tool-manage": "工具管理",
"enable-all-tools": "激活所有工具",
"disable-all-tools": "禁用所有工具",
- "using-tool": "正在使用工具"
+ "using-tool": "正在使用工具",
+ "copy-success": "复制成功",
+ "copy-fail": "复制失败",
+ "copy": "复制",
+ "export": "导出",
+ "export-filename": "导出文件名",
+ "how-to-use": "如何使用?"
}
\ No newline at end of file
diff --git a/renderer/src/i18n/zh-tw.json b/renderer/src/i18n/zh-tw.json
index e3e7c6b..fa951d6 100644
--- a/renderer/src/i18n/zh-tw.json
+++ b/renderer/src/i18n/zh-tw.json
@@ -176,5 +176,11 @@
"tool-manage": "工具管理",
"enable-all-tools": "啟用所有工具",
"disable-all-tools": "禁用所有工具",
- "using-tool": "正在使用工具"
+ "using-tool": "正在使用工具",
+ "copy-success": "複製成功",
+ "copy-fail": "複製失敗",
+ "copy": "複製",
+ "export": "匯出",
+ "export-filename": "匯出檔案名稱",
+ "how-to-use": "如何使用?"
}
\ No newline at end of file
diff --git a/renderer/src/views/about/index.vue b/renderer/src/views/about/index.vue
index a64b720..2f49467 100644
--- a/renderer/src/views/about/index.vue
+++ b/renderer/src/views/about/index.vue
@@ -47,7 +47,7 @@ import { useI18n } from 'vue-i18n';
const { t } = useI18n();
-const version = '0.1.7';
+const version = '0.1.8';
const author = 'LSTM-Kirigaya (锦恢)';
defineComponent({ name: 'about' });
diff --git a/renderer/src/views/connect/core.ts b/renderer/src/views/connect/core.ts
index 126d2be..e90be33 100644
--- a/renderer/src/views/connect/core.ts
+++ b/renderer/src/views/connect/core.ts
@@ -506,7 +506,11 @@ class McpClientAdapter {
constructor(
public platform: string
- ) {}
+ ) {
+ if (platform !== 'nodejs') {
+ this.addConnectRefreshListener();
+ }
+ }
/**
* @description 获取连接参数签名
@@ -564,18 +568,23 @@ class McpClientAdapter {
* @description register HMR
*/
public addConnectRefreshListener() {
- // 创建对于 connect/refresh 的监听
+ // 创建对于 connect/refresh 的监听
if (!this.connectrefreshListener) {
const bridge = useMessageBridge();
- this.connectrefreshListener = bridge.addCommandListener('connect/refresh', async (message) => {
+ this.connectrefreshListener = bridge.addCommandListener('connect/refresh', async (message) => {
const { code, msg } = message;
+ console.log('refresh');
+
+
if (code === 200) {
// 查找目标客户端
const clientIndex = this.findClientIndexByUuid(msg.uuid);
if (clientIndex > -1) {
// 刷新该客户端的所有资源
+ console.log('clientIndex', clientIndex);
+
await this.clients[clientIndex].refreshAllResources();
this.refreshSignal.value++;
} else {
diff --git a/service/src/common/router.ts b/service/src/common/router.ts
index c9d53fb..571b269 100644
--- a/service/src/common/router.ts
+++ b/service/src/common/router.ts
@@ -22,7 +22,6 @@ export async function routeMessage(command: string, data: any, webview: PostMess
const { handler, option = {} } = handlerStore;
try {
- // TODO: select client based on something
const res = await handler(data, webview);
// res.code = -1 代表当前请求不需要返回发送
diff --git a/service/src/hook/adapter.ts b/service/src/hook/adapter.ts
index 0e65837..47fc0ef 100644
--- a/service/src/hook/adapter.ts
+++ b/service/src/hook/adapter.ts
@@ -57,6 +57,7 @@ export class VSCodeWebViewLike {
* @param message - 包含 command 和 args 的消息
*/
postMessage(message: WebSocketMessage): void {
+
if (this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify(message));
} else {
diff --git a/service/src/main.ts b/service/src/main.ts
index cec6a29..10cbce2 100644
--- a/service/src/main.ts
+++ b/service/src/main.ts
@@ -5,8 +5,7 @@ import { dirname, join } from 'path';
import { routeMessage } from './common/router.js';
import { VSCodeWebViewLike } from './hook/adapter.js';
import fs from 'fs/promises'; // 使用 Promise API 替代回调
-import path from 'path';
-import axios from 'axios';
+import chalk from 'chalk';
export interface VSCodeMessage {
command: string;
@@ -101,7 +100,10 @@ wss.on('connection', (ws) => {
acquireConnectionOption().then(option => {
webview.onDidReceiveMessage(async (message) => {
- logger.info(`收到命令: [${message.command || '未定义'}]`);
+ console.log(
+ chalk.white('receive command') +
+ chalk.blue(` [${message.command || '未定义'}]`)
+ );
const { command, data } = message;
diff --git a/service/src/mcp/connect-monitor.service.ts b/service/src/mcp/connect-monitor.service.ts
index e228d6a..b486354 100644
--- a/service/src/mcp/connect-monitor.service.ts
+++ b/service/src/mcp/connect-monitor.service.ts
@@ -4,6 +4,8 @@ import { PostMessageble } from '../hook/adapter.js';
import * as fs from 'fs';
import * as path from 'path';
import { pino } from 'pino';
+import chalk from 'chalk';
+
// 保留现有 logger 配置
const logger = pino({
@@ -59,15 +61,11 @@ export class McpServerConnectMonitor {
debounceTime: 500,
duplicateCheckTime: 500,
onChange: async (curr, prev) => {
- // 使用 info 级别记录文件修改
- logger.info({
- uuid: this.uuid,
- size: curr.size,
- mtime: new Date(curr.mtime).toLocaleString()
- }, 'File modified');
-
try {
await onchange(this.uuid, this.Options);
+
+ console.log('send something');
+
this.sendWebviewMessage('connect/refresh', {
code: 200,
msg: {
@@ -75,7 +73,11 @@ export class McpServerConnectMonitor {
uuid: this.uuid,
}
});
- logger.info({ uuid: this.uuid }, 'Connection refresh successful');
+
+ console.log(
+ chalk.green('Connection refresh successfully')
+ );
+
} catch (err) {
this.sendWebviewMessage('connect/refresh', {
code: 500,
@@ -122,4 +124,9 @@ export class McpServerConnectMonitor {
// 发送消息到webview
this.webview?.postMessage({ command, data });
}
+
+ public close() {
+ this.Monitor?.close();
+ }
+
}
diff --git a/service/src/mcp/connect.service.ts b/service/src/mcp/connect.service.ts
index efc26e0..1e7c6e8 100644
--- a/service/src/mcp/connect.service.ts
+++ b/service/src/mcp/connect.service.ts
@@ -9,7 +9,7 @@ import path from 'node:path';
import fs from 'node:fs';
import * as os from 'os';
import { PostMessageble } from '../hook/adapter.js';
-import Table from 'cli-table3';
+import chalk from 'chalk';
export const clientMap: Map = new Map();
export function getClient(clientId?: string): RequestClientType | undefined {
@@ -21,7 +21,10 @@ export async function updateClientMap(uuid: string, options: McpOptions): Promis
const client = await connect(options);
clientMap.set(uuid, client);
const tools = await client.listTools();
- console.log('[updateClientMap] tools:', tools);
+ console.log(
+ chalk.white('update client tools'),
+ chalk.blue(tools.tools.map(tool => tool.name).join(','))
+ );
return { res: true };
} catch (error) {
console.error('[updateClientMap] error:', error);
@@ -267,25 +270,6 @@ export async function connectService(
webview?: PostMessageble
): Promise {
try {
- // 使用cli-table3创建美观的表格
- // const table = new Table({
- // head: ['Property', 'Value'],
- // colWidths: [20, 60],
- // style: {
- // head: ['green'],
- // border: ['grey']
- // }
- // });
-
- // table.push(
- // ['Connection Type', option.connectionType],
- // ['Command', option.command || 'N/A'],
- // ['Arguments', option.args?.join(' ') || 'N/A'],
- // ['Working Directory', option.cwd || 'N/A'],
- // ['URL', option.url || 'N/A']
- // );
-
- // console.log(table.toString());
// 预处理字符串
await preprocessCommand(option, webview);
@@ -301,6 +285,11 @@ export async function connectService(
// }
// const client = clientMap.get(uuid)!;
+ {
+ clientMap.get(uuid)?.disconnect();
+ clientMonitorMap.get(uuid)?.close();
+ }
+
const client = await connect(option);
clientMap.set(uuid, client);
clientMonitorMap.set(uuid, new McpServerConnectMonitor(uuid, option, updateClientMap, webview));
diff --git a/src/global.ts b/src/global.ts
index c46e6b0..a7d0df8 100644
--- a/src/global.ts
+++ b/src/global.ts
@@ -377,3 +377,18 @@ export async function getFirstValidPathFromCommand(command: string, cwd: string)
return undefined;
}
+
+
+export async function exportFile(filename: string, content: any) {
+ // 使用 vscode 的 api,创建文件导出窗口,询问用户
+ const uri = await vscode.window.showSaveDialog({
+ defaultUri: vscode.Uri.file(filename),
+ filters: {
+ 'JSON': ['json']
+ }
+ });
+
+ if (uri) {
+ fs.writeFileSync(uri.fsPath, content, 'utf-8');
+ }
+}
\ No newline at end of file
diff --git a/src/webview/webview.service.ts b/src/webview/webview.service.ts
index 8be19a3..c392bee 100644
--- a/src/webview/webview.service.ts
+++ b/src/webview/webview.service.ts
@@ -1,7 +1,7 @@
import * as vscode from 'vscode';
import * as fs from 'fs';
import * as fspath from 'path';
-import { ConnectionType, McpOptions, panels, updateInstalledConnectionConfig, updateWorkspaceConnectionConfig } from '../global.js';
+import { ConnectionType, exportFile, McpOptions, panels, updateInstalledConnectionConfig, updateWorkspaceConnectionConfig } from '../global.js';
import { routeMessage } from '../../openmcp-sdk/service/index.js';
export function getWebviewContent(context: vscode.ExtensionContext, panel: vscode.WebviewPanel): string | undefined {
@@ -101,6 +101,10 @@ export function revealOpenMcpWebviewPanel(
}
break;
+ case 'vscode/export-file':
+ exportFile(data.filename, data.content);
+ break;
+
case 'vscode/clipboard/writeText':
vscode.env.clipboard.writeText(data.text);
break;