修复 vscode/trae 下 tab 恢复的问题
This commit is contained in:
parent
37b162155c
commit
e306388f14
@ -1,9 +1,7 @@
|
|||||||
import { useMessageBridge } from "@/api/message-bridge";
|
import { useMessageBridge } from "@/api/message-bridge";
|
||||||
import { llmManager, llms } from "@/views/setting/llm";
|
|
||||||
import { pinkLog } from "@/views/setting/util";
|
import { pinkLog } from "@/views/setting/util";
|
||||||
import I18n from '@/i18n/index';
|
|
||||||
import { debugModes, tabs } from "@/components/main-panel/panel";
|
import { debugModes, tabs } from "@/components/main-panel/panel";
|
||||||
import { markRaw, ref } from "vue";
|
import { markRaw, ref, nextTick } from "vue";
|
||||||
|
|
||||||
interface SaveTabItem {
|
interface SaveTabItem {
|
||||||
name: string;
|
name: string;
|
||||||
@ -53,6 +51,9 @@ export function loadPanels() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tabs.activeIndex = persistTab.currentIndex;
|
tabs.activeIndex = persistTab.currentIndex;
|
||||||
|
nextTick(() => {
|
||||||
|
tabs.activeIndex = persistTab.currentIndex;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
panelLoaded.value = true;
|
panelLoaded.value = true;
|
||||||
@ -73,6 +74,11 @@ export function safeSavePanels() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function savePanels(saveHandler?: () => void) {
|
export function savePanels(saveHandler?: () => void) {
|
||||||
|
// 没有完成 panel 加载就不保存
|
||||||
|
if (!panelLoaded.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const bridge = useMessageBridge();
|
const bridge = useMessageBridge();
|
||||||
|
|
||||||
const saveTabs: SaveTab = {
|
const saveTabs: SaveTab = {
|
||||||
|
@ -2,11 +2,13 @@ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|||||||
|
|
||||||
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
||||||
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
||||||
|
import { Implementation } from "@modelcontextprotocol/sdk/types";
|
||||||
|
|
||||||
// 定义连接类型
|
// 定义连接类型
|
||||||
type ConnectionType = 'STDIO' | 'SSE';
|
type ConnectionType = 'STDIO' | 'SSE';
|
||||||
|
|
||||||
type McpTransport = StdioClientTransport | SSEClientTransport;
|
type McpTransport = StdioClientTransport | SSEClientTransport;
|
||||||
|
export type IServerVersion = Implementation | undefined;
|
||||||
|
|
||||||
// 定义命令行参数接口
|
// 定义命令行参数接口
|
||||||
export interface MCPOptions {
|
export interface MCPOptions {
|
||||||
@ -27,9 +29,11 @@ export class MCPClient {
|
|||||||
private client: Client;
|
private client: Client;
|
||||||
private transport?: McpTransport;
|
private transport?: McpTransport;
|
||||||
private options: MCPOptions;
|
private options: MCPOptions;
|
||||||
|
private serverVersion: IServerVersion;
|
||||||
|
|
||||||
constructor(options: MCPOptions) {
|
constructor(options: MCPOptions) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
this.serverVersion = undefined;
|
||||||
|
|
||||||
this.client = new Client(
|
this.client = new Client(
|
||||||
{
|
{
|
||||||
@ -73,7 +77,13 @@ export class MCPClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getServerVersion() {
|
public getServerVersion() {
|
||||||
return this.client.getServerVersion();
|
if (this.serverVersion) {
|
||||||
|
return this.serverVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
const version = this.client.getServerVersion();
|
||||||
|
this.serverVersion = version;
|
||||||
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 断开连接
|
// 断开连接
|
||||||
|
@ -5,7 +5,8 @@ import { MCPClient } from './connect';
|
|||||||
export async function panelSaveHandler(client: MCPClient | undefined, data: any, webview: PostMessageble) {
|
export async function panelSaveHandler(client: MCPClient | undefined, data: any, webview: PostMessageble) {
|
||||||
try {
|
try {
|
||||||
// 保存配置
|
// 保存配置
|
||||||
saveTabSaveConfig(data);
|
const serverInfo = client?.getServerVersion();
|
||||||
|
saveTabSaveConfig(serverInfo, data);
|
||||||
|
|
||||||
webview.postMessage({
|
webview.postMessage({
|
||||||
command: 'panel/save',
|
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) {
|
export async function panelLoadHandler(client: MCPClient | undefined, webview: PostMessageble) {
|
||||||
try {
|
try {
|
||||||
// 加载配置
|
// 加载配置
|
||||||
const config = loadTabSaveConfig();
|
const serverInfo = client?.getServerVersion();
|
||||||
|
const config = loadTabSaveConfig(serverInfo);
|
||||||
|
|
||||||
webview.postMessage({
|
webview.postMessage({
|
||||||
command: 'panel/load',
|
command: 'panel/load',
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
export { messageController } from './controller';
|
export { messageController } from './controller';
|
||||||
export { VSCodeWebViewLike } from './adapter';
|
export { VSCodeWebViewLike } from './adapter';
|
||||||
export type { VSCodeMessage, MessageHandler } from './main';
|
export { setVscodeWorkspace } from './util';
|
@ -2,10 +2,17 @@ import * as fs from 'fs';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import { llms } from './llm';
|
import { llms } from './llm';
|
||||||
|
import { IServerVersion } from './controller/connect';
|
||||||
|
|
||||||
|
export let VSCODE_WORKSPACE = '';
|
||||||
|
|
||||||
|
export function setVscodeWorkspace(workspace: string) {
|
||||||
|
VSCODE_WORKSPACE = workspace;
|
||||||
|
}
|
||||||
|
|
||||||
function getConfigurationPath() {
|
function getConfigurationPath() {
|
||||||
// 如果是 vscode 插件下,则修改为 ~/.openmcp/config.json
|
// 如果是 vscode 插件下,则修改为 ~/.openmcp/config.json
|
||||||
if (process.env.VSCODE_PID) {
|
if (VSCODE_WORKSPACE) {
|
||||||
// 在 VSCode 插件环境下
|
// 在 VSCode 插件环境下
|
||||||
const homeDir = os.homedir();
|
const homeDir = os.homedir();
|
||||||
const configDir = path.join(homeDir, '.openmcp');
|
const configDir = path.join(homeDir, '.openmcp');
|
||||||
@ -17,18 +24,20 @@ function getConfigurationPath() {
|
|||||||
return 'config.json';
|
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
|
// 如果是 vscode 插件下,则修改为 ~/.vscode/openmcp.json
|
||||||
if (process.env.VSCODE_PID) {
|
if (VSCODE_WORKSPACE) {
|
||||||
// 在 VSCode 插件环境下
|
// 在 VSCode 插件环境下
|
||||||
const homeDir = os.homedir();
|
const configDir = path.join(VSCODE_WORKSPACE, '.vscode');
|
||||||
const configDir = path.join(homeDir, '.openmcp');
|
|
||||||
if (!fs.existsSync(configDir)) {
|
if (!fs.existsSync(configDir)) {
|
||||||
fs.mkdirSync(configDir, { recursive: true });
|
fs.mkdirSync(configDir, { recursive: true });
|
||||||
}
|
}
|
||||||
return path.join(configDir, 'tabs.json');
|
return path.join(configDir, tabSaveName);
|
||||||
}
|
}
|
||||||
return 'tabs.json';
|
return tabSaveName;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDefaultLanguage() {
|
function getDefaultLanguage() {
|
||||||
@ -82,8 +91,8 @@ function createConfig(): IConfig {
|
|||||||
return DEFAULT_CONFIG;
|
return DEFAULT_CONFIG;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createSaveTabConfig(): SaveTab {
|
function createSaveTabConfig(serverInfo: IServerVersion): SaveTab {
|
||||||
const configPath = getTabSavePath();
|
const configPath = getTabSavePath(serverInfo);
|
||||||
const configDir = path.dirname(configPath);
|
const configDir = path.dirname(configPath);
|
||||||
|
|
||||||
// 确保配置目录存在
|
// 确保配置目录存在
|
||||||
@ -114,8 +123,6 @@ export function loadConfig(): IConfig {
|
|||||||
|
|
||||||
export function saveConfig(config: Partial<IConfig>): void {
|
export function saveConfig(config: Partial<IConfig>): void {
|
||||||
const configPath = getConfigurationPath();
|
const configPath = getConfigurationPath();
|
||||||
let currentConfig: IConfig = DEFAULT_CONFIG;
|
|
||||||
|
|
||||||
console.log('save to ' + configPath);
|
console.log('save to ' + configPath);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -126,11 +133,11 @@ export function saveConfig(config: Partial<IConfig>): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loadTabSaveConfig(): SaveTab {
|
export function loadTabSaveConfig(serverInfo: IServerVersion): SaveTab {
|
||||||
const tabSavePath = getTabSavePath();
|
const tabSavePath = getTabSavePath(serverInfo);
|
||||||
|
|
||||||
if (!fs.existsSync(tabSavePath)) {
|
if (!fs.existsSync(tabSavePath)) {
|
||||||
return createSaveTabConfig();
|
return createSaveTabConfig(serverInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -138,12 +145,12 @@ export function loadTabSaveConfig(): SaveTab {
|
|||||||
return JSON.parse(configData) as SaveTab;
|
return JSON.parse(configData) as SaveTab;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error loading config file, creating new one:', error);
|
console.error('Error loading config file, creating new one:', error);
|
||||||
return createSaveTabConfig();
|
return createSaveTabConfig(serverInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function saveTabSaveConfig(config: Partial<IConfig>): void {
|
export function saveTabSaveConfig(serverInfo: IServerVersion, config: Partial<IConfig>): void {
|
||||||
const tabSavePath = getTabSavePath();
|
const tabSavePath = getTabSavePath(serverInfo);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fs.writeFileSync(tabSavePath, JSON.stringify(config, null, 2), 'utf-8');
|
fs.writeFileSync(tabSavePath, JSON.stringify(config, null, 2), 'utf-8');
|
||||||
|
4
service/tabs.untitle.json
Normal file
4
service/tabs.untitle.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"tabs": [],
|
||||||
|
"currentIndex": -1
|
||||||
|
}
|
70
service/tabs.锦恢的 MCP Server.json
Normal file
70
service/tabs.锦恢的 MCP Server.json
Normal 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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -27,6 +27,12 @@ function getLaunchCWD(context: vscode.ExtensionContext, uri: vscode.Uri) {
|
|||||||
export function activate(context: vscode.ExtensionContext) {
|
export function activate(context: vscode.ExtensionContext) {
|
||||||
console.log('activate openmcp');
|
console.log('activate openmcp');
|
||||||
|
|
||||||
|
// 初始化 OpenMCPService
|
||||||
|
// 获取当前打开的项目的路径
|
||||||
|
const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
|
||||||
|
const workspace = workspaceFolder?.uri.fsPath || '';
|
||||||
|
OpenMCPService.setVscodeWorkspace(workspace);
|
||||||
|
|
||||||
// 注册 showOpenMCP 命令
|
// 注册 showOpenMCP 命令
|
||||||
context.subscriptions.push(
|
context.subscriptions.push(
|
||||||
vscode.commands.registerCommand('openmcp.showOpenMCP', async (uri: vscode.Uri) => {
|
vscode.commands.registerCommand('openmcp.showOpenMCP', async (uri: vscode.Uri) => {
|
||||||
@ -51,7 +57,8 @@ export function activate(context: vscode.ExtensionContext) {
|
|||||||
|
|
||||||
// 设置HTML内容
|
// 设置HTML内容
|
||||||
const html = getWebviewContent(context, panel);
|
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的消息
|
// 处理来自webview的消息
|
||||||
panel.webview.onDidReceiveMessage(message => {
|
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)
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user