UNPKG

vscode-mcp-comprehensive

Version:

Comprehensive MCP server exposing all VSCode features to AI agents with 101 tools including advanced debugging and console access

441 lines 19.2 kB
import * as vscode from 'vscode'; export class UITools { constructor(server) { this.server = server; this.statusBarItems = new Map(); this.registerTools(); } registerTools() { // Show information message this.server.registerTool('ui_show_information_message', 'Show info notification', { type: 'object', properties: { message: { type: 'string', description: 'Message to display' }, modal: { type: 'boolean', description: 'Show as modal dialog', default: false }, items: { type: 'array', items: { type: 'string' }, description: 'Action items to show' }, }, required: ['message'], }, this.showInformationMessage.bind(this)); // Show warning message this.server.registerTool('ui_show_warning_message', 'Show warning notification', { type: 'object', properties: { message: { type: 'string', description: 'Warning message to display' }, modal: { type: 'boolean', description: 'Show as modal dialog', default: false }, items: { type: 'array', items: { type: 'string' }, description: 'Action items to show' }, }, required: ['message'], }, this.showWarningMessage.bind(this)); // Show error message this.server.registerTool('ui_show_error_message', 'Show error notification', { type: 'object', properties: { message: { type: 'string', description: 'Error message to display' }, modal: { type: 'boolean', description: 'Show as modal dialog', default: false }, items: { type: 'array', items: { type: 'string' }, description: 'Action items to show' }, }, required: ['message'], }, this.showErrorMessage.bind(this)); // Show input box this.server.registerTool('ui_show_input_box', 'Show input dialog', { type: 'object', properties: { prompt: { type: 'string', description: 'Input prompt' }, placeholder: { type: 'string', description: 'Placeholder text' }, value: { type: 'string', description: 'Default value' }, password: { type: 'boolean', description: 'Hide input (password)', default: false }, validateInput: { type: 'string', description: 'Validation pattern (regex)' }, }, required: ['prompt'], }, this.showInputBox.bind(this)); // Show quick pick this.server.registerTool('ui_show_quick_pick', 'Show selection menu', { type: 'object', properties: { items: { type: 'array', items: { type: 'object', properties: { label: { type: 'string' }, description: { type: 'string' }, detail: { type: 'string' }, picked: { type: 'boolean' }, }, required: ['label'], }, description: 'Items to choose from' }, canPickMany: { type: 'boolean', description: 'Allow multiple selection', default: false }, placeholder: { type: 'string', description: 'Placeholder text' }, ignoreFocusOut: { type: 'boolean', description: 'Keep open when focus lost', default: false }, }, required: ['items'], }, this.showQuickPick.bind(this)); // Show open dialog this.server.registerTool('ui_show_open_dialog', 'Show file open dialog', { type: 'object', properties: { canSelectFiles: { type: 'boolean', description: 'Allow file selection', default: true }, canSelectFolders: { type: 'boolean', description: 'Allow folder selection', default: false }, canSelectMany: { type: 'boolean', description: 'Allow multiple selection', default: false }, defaultUri: { type: 'string', description: 'Default URI to open' }, openLabel: { type: 'string', description: 'Open button label' }, filters: { type: 'object', description: 'File type filters', additionalProperties: { type: 'array', items: { type: 'string' } } }, }, }, this.showOpenDialog.bind(this)); // Show save dialog this.server.registerTool('ui_show_save_dialog', 'Show file save dialog', { type: 'object', properties: { defaultUri: { type: 'string', description: 'Default URI to save' }, saveLabel: { type: 'string', description: 'Save button label' }, filters: { type: 'object', description: 'File type filters', additionalProperties: { type: 'array', items: { type: 'string' } } }, }, }, this.showSaveDialog.bind(this)); // Set status bar message this.server.registerTool('ui_set_status_bar_message', 'Set status bar text', { type: 'object', properties: { message: { type: 'string', description: 'Status bar message' }, hideAfterTimeout: { type: 'number', description: 'Hide after milliseconds (optional)' }, }, required: ['message'], }, this.setStatusBarMessage.bind(this)); // Create status bar item this.server.registerTool('ui_create_status_bar_item', 'Create status bar item', { type: 'object', properties: { id: { type: 'string', description: 'Unique identifier for the item' }, text: { type: 'string', description: 'Text to display' }, tooltip: { type: 'string', description: 'Tooltip text' }, command: { type: 'string', description: 'Command to execute on click' }, alignment: { type: 'string', description: 'Alignment (left/right)', default: 'left' }, priority: { type: 'number', description: 'Priority for ordering' }, color: { type: 'string', description: 'Text color' }, backgroundColor: { type: 'string', description: 'Background color' }, }, required: ['id', 'text'], }, this.createStatusBarItem.bind(this)); // Show progress this.server.registerTool('ui_show_progress', 'Show progress indicator', { type: 'object', properties: { title: { type: 'string', description: 'Progress title' }, location: { type: 'string', description: 'Progress location (notification/window/source-control)', default: 'notification' }, cancellable: { type: 'boolean', description: 'Allow cancellation', default: false }, steps: { type: 'array', items: { type: 'object', properties: { message: { type: 'string' }, increment: { type: 'number' }, }, required: ['message'], }, description: 'Progress steps' }, }, required: ['title'], }, this.showProgress.bind(this)); // Update status bar item this.server.registerTool('ui_update_status_bar_item', 'Update existing status bar item', { type: 'object', properties: { id: { type: 'string', description: 'Status bar item ID' }, text: { type: 'string', description: 'New text' }, tooltip: { type: 'string', description: 'New tooltip' }, command: { type: 'string', description: 'New command' }, color: { type: 'string', description: 'New color' }, show: { type: 'boolean', description: 'Show/hide the item' }, }, required: ['id'], }, this.updateStatusBarItem.bind(this)); // Remove status bar item this.server.registerTool('ui_remove_status_bar_item', 'Remove status bar item', { type: 'object', properties: { id: { type: 'string', description: 'Status bar item ID to remove' }, }, required: ['id'], }, this.removeStatusBarItem.bind(this)); } async showInformationMessage(args) { try { this.server.validateRequiredParams(args, ['message']); const options = { modal: args.modal || false }; const result = await vscode.window.showInformationMessage(args.message, options, ...(args.items || [])); return this.server.createSuccessResponse({ selectedItem: result, dismissed: !result }); } catch (error) { return this.server.createErrorResponse(error); } } async showWarningMessage(args) { try { this.server.validateRequiredParams(args, ['message']); const options = { modal: args.modal || false }; const result = await vscode.window.showWarningMessage(args.message, options, ...(args.items || [])); return this.server.createSuccessResponse({ selectedItem: result, dismissed: !result }); } catch (error) { return this.server.createErrorResponse(error); } } async showErrorMessage(args) { try { this.server.validateRequiredParams(args, ['message']); const options = { modal: args.modal || false }; const result = await vscode.window.showErrorMessage(args.message, options, ...(args.items || [])); return this.server.createSuccessResponse({ selectedItem: result, dismissed: !result }); } catch (error) { return this.server.createErrorResponse(error); } } async showInputBox(args) { try { this.server.validateRequiredParams(args, ['prompt']); const options = { prompt: args.prompt, placeHolder: args.placeholder, value: args.value, password: args.password || false, validateInput: args.validateInput ? (value) => { const regex = new RegExp(args.validateInput); return regex.test(value) ? null : 'Invalid input format'; } : undefined, }; const result = await vscode.window.showInputBox(options); return this.server.createSuccessResponse({ value: result, cancelled: result === undefined }); } catch (error) { return this.server.createErrorResponse(error); } } async showQuickPick(args) { try { this.server.validateRequiredParams(args, ['items']); const quickPickItems = args.items.map(item => ({ label: item.label, description: item.description, detail: item.detail, picked: item.picked, })); const options = { canPickMany: args.canPickMany || false, placeHolder: args.placeholder, ignoreFocusOut: args.ignoreFocusOut || false, }; const result = await vscode.window.showQuickPick(quickPickItems, options); return this.server.createSuccessResponse({ selectedItems: Array.isArray(result) ? result : result ? [result] : [], cancelled: !result }); } catch (error) { return this.server.createErrorResponse(error); } } async showOpenDialog(args) { try { const options = { canSelectFiles: args.canSelectFiles !== false, canSelectFolders: args.canSelectFolders || false, canSelectMany: args.canSelectMany || false, defaultUri: args.defaultUri ? vscode.Uri.parse(args.defaultUri) : undefined, openLabel: args.openLabel, filters: args.filters, }; const result = await vscode.window.showOpenDialog(options); return this.server.createSuccessResponse({ selectedUris: result ? result.map(uri => uri.toString()) : [], cancelled: !result }); } catch (error) { return this.server.createErrorResponse(error); } } async showSaveDialog(args) { try { const options = { defaultUri: args.defaultUri ? vscode.Uri.parse(args.defaultUri) : undefined, saveLabel: args.saveLabel, filters: args.filters, }; const result = await vscode.window.showSaveDialog(options); return this.server.createSuccessResponse({ selectedUri: result ? result.toString() : null, cancelled: !result }); } catch (error) { return this.server.createErrorResponse(error); } } async setStatusBarMessage(args) { try { this.server.validateRequiredParams(args, ['message']); if (args.hideAfterTimeout) { vscode.window.setStatusBarMessage(args.message, args.hideAfterTimeout); } else { vscode.window.setStatusBarMessage(args.message); } return this.server.createSuccessResponse({ success: true }, 'Status bar message set'); } catch (error) { return this.server.createErrorResponse(error); } } async createStatusBarItem(args) { try { this.server.validateRequiredParams(args, ['id', 'text']); const alignment = args.alignment === 'right' ? vscode.StatusBarAlignment.Right : vscode.StatusBarAlignment.Left; const item = vscode.window.createStatusBarItem(alignment, args.priority); item.text = args.text; if (args.tooltip) item.tooltip = args.tooltip; if (args.command) item.command = args.command; if (args.color) item.color = args.color; if (args.backgroundColor) item.backgroundColor = new vscode.ThemeColor(args.backgroundColor); item.show(); this.statusBarItems.set(args.id, item); return this.server.createSuccessResponse({ success: true }, `Status bar item '${args.id}' created`); } catch (error) { return this.server.createErrorResponse(error); } } async updateStatusBarItem(args) { try { this.server.validateRequiredParams(args, ['id']); const item = this.statusBarItems.get(args.id); if (!item) { return this.server.createErrorResponse(`Status bar item '${args.id}' not found`); } if (args.text !== undefined) item.text = args.text; if (args.tooltip !== undefined) item.tooltip = args.tooltip; if (args.command !== undefined) item.command = args.command; if (args.color !== undefined) item.color = args.color; if (args.show !== undefined) { if (args.show) { item.show(); } else { item.hide(); } } return this.server.createSuccessResponse({ success: true }, `Status bar item '${args.id}' updated`); } catch (error) { return this.server.createErrorResponse(error); } } async removeStatusBarItem(args) { try { this.server.validateRequiredParams(args, ['id']); const item = this.statusBarItems.get(args.id); if (!item) { return this.server.createErrorResponse(`Status bar item '${args.id}' not found`); } item.dispose(); this.statusBarItems.delete(args.id); return this.server.createSuccessResponse({ success: true }, `Status bar item '${args.id}' removed`); } catch (error) { return this.server.createErrorResponse(error); } } async showProgress(args) { try { this.server.validateRequiredParams(args, ['title']); const locationMap = { 'notification': vscode.ProgressLocation.Notification, 'window': vscode.ProgressLocation.Window, 'source-control': vscode.ProgressLocation.SourceControl, }; const location = locationMap[args.location || 'notification'] || vscode.ProgressLocation.Notification; return new Promise((resolve) => { vscode.window.withProgress({ location, title: args.title, cancellable: args.cancellable || false, }, async (progress, token) => { if (args.steps && args.steps.length > 0) { for (const step of args.steps) { if (token.isCancellationRequested) { resolve(this.server.createSuccessResponse({ cancelled: true }, 'Progress cancelled')); return; } progress.report({ message: step.message, increment: step.increment, }); // Small delay to show progress await new Promise(resolve => setTimeout(resolve, 100)); } } resolve(this.server.createSuccessResponse({ success: true }, 'Progress completed')); }); }); } catch (error) { return this.server.createErrorResponse(error); } } dispose() { for (const item of this.statusBarItems.values()) { item.dispose(); } this.statusBarItems.clear(); } } //# sourceMappingURL=uiTools.js.map