修复 vscode/trae 下 tab 恢复的问题

This commit is contained in:
锦恢 2025-04-13 15:19:13 +08:00
parent 37b162155c
commit e306388f14
8 changed files with 131 additions and 31 deletions

View File

@ -1,9 +1,7 @@
import { useMessageBridge } from "@/api/message-bridge";
import { llmManager, llms } from "@/views/setting/llm";
import { pinkLog } from "@/views/setting/util";
import I18n from '@/i18n/index';
import { debugModes, tabs } from "@/components/main-panel/panel";
import { markRaw, ref } from "vue";
import { markRaw, ref, nextTick } from "vue";
interface SaveTabItem {
name: string;
@ -53,6 +51,9 @@ export function loadPanels() {
}
tabs.activeIndex = persistTab.currentIndex;
nextTick(() => {
tabs.activeIndex = persistTab.currentIndex;
});
}
panelLoaded.value = true;
@ -73,6 +74,11 @@ export function safeSavePanels() {
}
export function savePanels(saveHandler?: () => void) {
// 没有完成 panel 加载就不保存
if (!panelLoaded.value) {
return;
}
const bridge = useMessageBridge();
const saveTabs: SaveTab = {

View File

@ -2,11 +2,13 @@ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
import { Implementation } from "@modelcontextprotocol/sdk/types";
// 定义连接类型
type ConnectionType = 'STDIO' | 'SSE';
type McpTransport = StdioClientTransport | SSEClientTransport;
export type IServerVersion = Implementation | undefined;
// 定义命令行参数接口
export interface MCPOptions {
@ -27,9 +29,11 @@ export class MCPClient {
private client: Client;
private transport?: McpTransport;
private options: MCPOptions;
private serverVersion: IServerVersion;
constructor(options: MCPOptions) {
this.options = options;
this.serverVersion = undefined;
this.client = new Client(
{
@ -73,7 +77,13 @@ export class MCPClient {
}
public getServerVersion() {
return this.client.getServerVersion();
if (this.serverVersion) {
return this.serverVersion;
}
const version = this.client.getServerVersion();
this.serverVersion = version;
return version;
}
// 断开连接

View File

@ -5,7 +5,8 @@ import { MCPClient } from './connect';
export async function panelSaveHandler(client: MCPClient | undefined, data: any, webview: PostMessageble) {
try {
// 保存配置
saveTabSaveConfig(data);
const serverInfo = client?.getServerVersion();
saveTabSaveConfig(serverInfo, data);
webview.postMessage({
command: 'panel/save',
@ -28,7 +29,8 @@ export async function panelSaveHandler(client: MCPClient | undefined, data: any,
export async function panelLoadHandler(client: MCPClient | undefined, webview: PostMessageble) {
try {
// 加载配置
const config = loadTabSaveConfig();
const serverInfo = client?.getServerVersion();
const config = loadTabSaveConfig(serverInfo);
webview.postMessage({
command: 'panel/load',

View File

@ -1,3 +1,3 @@
export { messageController } from './controller';
export { VSCodeWebViewLike } from './adapter';
export type { VSCodeMessage, MessageHandler } from './main';
export { setVscodeWorkspace } from './util';

View File

@ -2,10 +2,17 @@ import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
import { llms } from './llm';
import { IServerVersion } from './controller/connect';
export let VSCODE_WORKSPACE = '';
export function setVscodeWorkspace(workspace: string) {
VSCODE_WORKSPACE = workspace;
}
function getConfigurationPath() {
// 如果是 vscode 插件下,则修改为 ~/.openmcp/config.json
if (process.env.VSCODE_PID) {
if (VSCODE_WORKSPACE) {
// 在 VSCode 插件环境下
const homeDir = os.homedir();
const configDir = path.join(homeDir, '.openmcp');
@ -17,18 +24,20 @@ function getConfigurationPath() {
return 'config.json';
}
function getTabSavePath() {
function getTabSavePath(serverInfo: IServerVersion) {
const { name = 'untitle', version = '0.0.0' } = serverInfo || {};
const tabSaveName = `tabs.${name}.json`;
// 如果是 vscode 插件下,则修改为 ~/.vscode/openmcp.json
if (process.env.VSCODE_PID) {
if (VSCODE_WORKSPACE) {
// 在 VSCode 插件环境下
const homeDir = os.homedir();
const configDir = path.join(homeDir, '.openmcp');
const configDir = path.join(VSCODE_WORKSPACE, '.vscode');
if (!fs.existsSync(configDir)) {
fs.mkdirSync(configDir, { recursive: true });
}
return path.join(configDir, 'tabs.json');
return path.join(configDir, tabSaveName);
}
return 'tabs.json';
return tabSaveName;
}
function getDefaultLanguage() {
@ -82,8 +91,8 @@ function createConfig(): IConfig {
return DEFAULT_CONFIG;
}
function createSaveTabConfig(): SaveTab {
const configPath = getTabSavePath();
function createSaveTabConfig(serverInfo: IServerVersion): SaveTab {
const configPath = getTabSavePath(serverInfo);
const configDir = path.dirname(configPath);
// 确保配置目录存在
@ -114,8 +123,6 @@ export function loadConfig(): IConfig {
export function saveConfig(config: Partial<IConfig>): void {
const configPath = getConfigurationPath();
let currentConfig: IConfig = DEFAULT_CONFIG;
console.log('save to ' + configPath);
try {
@ -126,11 +133,11 @@ export function saveConfig(config: Partial<IConfig>): void {
}
}
export function loadTabSaveConfig(): SaveTab {
const tabSavePath = getTabSavePath();
export function loadTabSaveConfig(serverInfo: IServerVersion): SaveTab {
const tabSavePath = getTabSavePath(serverInfo);
if (!fs.existsSync(tabSavePath)) {
return createSaveTabConfig();
return createSaveTabConfig(serverInfo);
}
try {
@ -138,12 +145,12 @@ export function loadTabSaveConfig(): SaveTab {
return JSON.parse(configData) as SaveTab;
} catch (error) {
console.error('Error loading config file, creating new one:', error);
return createSaveTabConfig();
return createSaveTabConfig(serverInfo);
}
}
export function saveTabSaveConfig(config: Partial<IConfig>): void {
const tabSavePath = getTabSavePath();
export function saveTabSaveConfig(serverInfo: IServerVersion, config: Partial<IConfig>): void {
const tabSavePath = getTabSavePath(serverInfo);
try {
fs.writeFileSync(tabSavePath, JSON.stringify(config, null, 2), 'utf-8');

View File

@ -0,0 +1,4 @@
{
"tabs": [],
"currentIndex": -1
}

View File

@ -0,0 +1,70 @@
{
"currentIndex": 0,
"tabs": [
{
"name": "资源",
"icon": "icon-file",
"type": "blank",
"componentIndex": 0,
"storage": {
"currentResourceName": "greeting",
"lastResourceReadResponse": {
"contents": [
{
"uri": "greeting://12312",
"mimeType": "text/plain",
"text": "Hello, 12312!"
}
]
}
}
},
{
"name": "交互测试",
"icon": "icon-robot",
"type": "blank",
"componentIndex": 3,
"storage": {
"messages": [],
"settings": {
"modelIndex": 0,
"enableTools": [
{
"name": "add",
"description": "对两个数字进行实数域的加法",
"enabled": true
},
{
"name": "multiply",
"description": "对两个数字进行实数域的乘法运算",
"enabled": true
},
{
"name": "is_even",
"description": "判断一个整数是否为偶数",
"enabled": true
},
{
"name": "capitalize",
"description": "将字符串首字母大写",
"enabled": true
}
],
"enableWebSearch": false,
"temperature": 0.7,
"contextLength": 10,
"systemPrompt": ""
}
}
},
{
"name": "提词",
"icon": "icon-chat",
"type": "blank",
"componentIndex": 1,
"storage": {
"currentPromptName": "translate"
}
}
]
}

View File

@ -27,6 +27,12 @@ function getLaunchCWD(context: vscode.ExtensionContext, uri: vscode.Uri) {
export function activate(context: vscode.ExtensionContext) {
console.log('activate openmcp');
// 初始化 OpenMCPService
// 获取当前打开的项目的路径
const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
const workspace = workspaceFolder?.uri.fsPath || '';
OpenMCPService.setVscodeWorkspace(workspace);
// 注册 showOpenMCP 命令
context.subscriptions.push(
vscode.commands.registerCommand('openmcp.showOpenMCP', async (uri: vscode.Uri) => {
@ -51,7 +57,8 @@ export function activate(context: vscode.ExtensionContext) {
// 设置HTML内容
const html = getWebviewContent(context, panel);
panel.webview.html = html || '';
panel.webview.html = html || '';
panel.iconPath = vscode.Uri.file(fspath.join(context.extensionPath, 'resources', 'renderer', 'images', 'openmcp.png'));
// 处理来自webview的消息
panel.webview.onDidReceiveMessage(message => {
@ -89,12 +96,6 @@ export function activate(context: vscode.ExtensionContext) {
});
})
);
// const provider = new WebviewViewProvider(context);
// context.subscriptions.push(
// vscode.window.registerWebviewViewProvider('webview-sidebar.view', provider)
// );
}