From 72143608a180aa86a71e44bf78d6c86890bef43d Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Wed, 21 May 2025 20:57:54 -0700 Subject: [PATCH] misc fixes --- .../src/void-settings-tsx/MCPServersList.tsx | 52 +++-------------- .../contrib/void/common/mcpService.ts | 56 ++++++++----------- .../contrib/void/common/mcpServiceTypes.ts | 2 +- .../contrib/void/common/voidSettingsTypes.ts | 2 +- 4 files changed, 34 insertions(+), 78 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/MCPServersList.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/MCPServersList.tsx index f629fb3a..83835f5b 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/MCPServersList.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/MCPServersList.tsx @@ -1,17 +1,7 @@ -import { VoidSwitch } from '../util/inputs.js'; +import { VoidSwitch, VoidButtonBgDarken } from '../util/inputs.js'; import { MCPConfigFileParseErrorResponse, MCPServerEventType, MCPServerEventResponse, MCPServerObject, MCPServerOfName } from '../../../../common/mcpServiceTypes.js'; import { useEffect, useState } from 'react'; import { useAccessor, useMCPServiceState } from '../util/services.js'; -import { IDisposable } from '../../../../../../../base/common/lifecycle.js'; - -// Command display component -const CommandDisplay = ({ command }: { command: string }) => { - return ( -
- {command} -
- ); -}; // MCP Server component @@ -44,7 +34,7 @@ const MCPServer = ({ name, server }: { name: string, server: MCPServerObject }) {/* Power toggle switch */}
@@ -70,11 +60,13 @@ const MCPServer = ({ name, server }: { name: string, server: MCPServerObject })
- {/* Command display */} + {/* Command badge */} {server.isOn && server.command && (
Command:
- +
+ {server.command} +
)} @@ -97,36 +89,8 @@ const MCPServer = ({ name, server }: { name: string, server: MCPServerObject }) const MCPServersList = () => { const mcpServiceState = useMCPServiceState() - - // const handleListeners = (e: MCPServerEventResponse | MCPConfigFileParseErrorResponse) => { - // if (e.response.type === 'config-file-error') { - // // Handle the config error event - // const { error } = e.response; - // setMCPConfigError(error); - // return; - // } - // if (e.response.type === 'add' || e.response.type === 'update' || e.response.type === 'loading') { - // // Handle the add event - // const { name, newServer } = e.response; - // setMCPServers(prevServers => ({ - // ...prevServers, - // [name]: newServer - // })); - // return; - // } - // if (e.response.type === 'delete') { - // // Handle the delete event - // const { name, prevServer } = e.response; - // setMCPServers(prevServers => { - // const newServers = { ...prevServers }; - // delete newServers[name]; - // return newServers; - // }); - // return; - // } - // throw new Error('Event not handled'); - // } - + const accessor = useAccessor(); + const mcpService = accessor.get('IMCPService'); return (
diff --git a/src/vs/workbench/contrib/void/common/mcpService.ts b/src/vs/workbench/contrib/void/common/mcpService.ts index 96beb4c3..de25163c 100644 --- a/src/vs/workbench/contrib/void/common/mcpService.ts +++ b/src/vs/workbench/contrib/void/common/mcpService.ts @@ -10,7 +10,6 @@ import { createDecorator } from '../../../../platform/instantiation/common/insta import { IFileService } from '../../../../platform/files/common/files.js'; import { IPathService } from '../../../services/path/common/pathService.js'; import { IEditorService } from '../../../services/editor/common/editorService.js'; -import { join } from '../../../../base/common/path.js'; import { IProductService } from '../../../../platform/product/common/productService.js'; import { VSBuffer } from '../../../../base/common/buffer.js'; import { IChannel } from '../../../../base/parts/ipc/common/ipc.js'; @@ -148,10 +147,10 @@ class MCPService extends Disposable implements IMCPService { this._onDidChangeState.fire(); } - private readonly _setHasError = async (hasError: string | undefined) => { + private readonly _setHasError = async (errMsg: string | undefined) => { this.state = { ...this.state, - error: hasError ? `MCP config file not found` : undefined, + error: errMsg, } this._onDidChangeState.fire(); } @@ -165,32 +164,6 @@ class MCPService extends Disposable implements IMCPService { await this.fileService.writeFile(mcpConfigUri, buffer); } - private async _parseMCPConfigFile(): Promise { - // TODO!!!!!!! double check this - // this._onConfigParsingError.fire({ - // response: { - // type: 'config-file-error', - // error: null - // } - // }); - - // Process config file - const mcpConfigUri = await this._getMCPConfigFilePath(); - - try { - const fileContent = await this.fileService.readFile(mcpConfigUri); - const contentString = fileContent.value.toString(); - const configJson = JSON.parse(contentString); - if (!configJson.mcpServers) { - throw new Error('Invalid MCP config file: missing mcpServers property'); - } - return configJson as MCPConfigFileType; - } catch (error) { - const fullError = `Error parsing MCP config file: ${error}`; - this._setHasError(fullError) - return null; - } - } private async _addMCPConfigFileWatcher(): Promise { const mcpConfigUri = await this._getMCPConfigFilePath(); @@ -258,8 +231,8 @@ class MCPService extends Disposable implements IMCPService { private async _getMCPConfigFilePath(): Promise { const appName = this.productService.dataFolderName const userHome = await this.pathService.userHome(); - const mcpConfigPath = join(userHome.path, appName, MCP_CONFIG_FILE_NAME); - return URI.file(mcpConfigPath); + const uri = URI.joinPath(userHome, appName, MCP_CONFIG_FILE_NAME) + return uri } private async _configFileExists(mcpConfigUri: URI): Promise { @@ -271,6 +244,25 @@ class MCPService extends Disposable implements IMCPService { } } + + private async _parseMCPConfigFile(): Promise { + const mcpConfigUri = await this._getMCPConfigFilePath(); + try { + const fileContent = await this.fileService.readFile(mcpConfigUri); + const contentString = fileContent.value.toString(); + const configFileJson = JSON.parse(contentString); + if (!configFileJson.mcpServers) { + throw new Error('Missing mcpServers property'); + } + return configFileJson as MCPConfigFileType; + } catch (error) { + const fullError = `Error parsing MCP config file: ${error}`; + this._setHasError(fullError) + return null; + } + } + + // Handle server state changes private async _refreshMCPServers(): Promise { @@ -285,7 +277,7 @@ class MCPService extends Disposable implements IMCPService { const availableServers = Object.keys(mcpConfigFile.mcpServers); // Handle added servers - const addedServers = availableServers.filter(serverName => !currMCPStateOfName[serverName].isOn); + const addedServers = availableServers.filter(serverName => !currMCPStateOfName[serverName]?.isOn); const addedServersObject = addedServers.reduce((acc, serverName) => { acc[serverName] = { isOn: true }; return acc; diff --git a/src/vs/workbench/contrib/void/common/mcpServiceTypes.ts b/src/vs/workbench/contrib/void/common/mcpServiceTypes.ts index 441fdb72..cc568191 100644 --- a/src/vs/workbench/contrib/void/common/mcpServiceTypes.ts +++ b/src/vs/workbench/contrib/void/common/mcpServiceTypes.ts @@ -138,7 +138,7 @@ export interface MCPServerObject { // Command-based server properties tools: MCPTool[], status: 'loading' | 'error' | 'success' | 'offline', - isOn: boolean, + isOn: boolean | undefined, command?: string, error?: string, } diff --git a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts index 6faa40b2..e2faf506 100644 --- a/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts +++ b/src/vs/workbench/contrib/void/common/voidSettingsTypes.ts @@ -495,7 +495,7 @@ export const defaultOverridesOfModel = overridesOfModel export interface MCPServerStateOfName { - [serverName: string]: MCPServerState; + [serverName: string]: MCPServerState | undefined; } export interface MCPServerState {