From 7a46ac4d80ce172c04fb25da043aae54063a51dd Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt <2644648+TylerLeonhardt@users.noreply.github.com> Date: Mon, 25 Aug 2025 11:46:20 -0700 Subject: [PATCH] First pass at disabling tools that aren't useful for this MCP flow (#263298) * First pass at disabling tools that aren't useful for this MCP flow And enable the multiplexer server * revert that * revert that * revert that * disable a couple more * add a start to improve model behavior & rewrite prompt file --- .github/prompts/playwright.prompt.md | 25 +- test/mcp/src/automationTools/activityBar.ts | 38 +- test/mcp/src/automationTools/core.ts | 264 +++++++------- test/mcp/src/automationTools/debug.ts | 135 +++---- test/mcp/src/automationTools/editor.ts | 348 ++++++++++--------- test/mcp/src/automationTools/explorer.ts | 27 +- test/mcp/src/automationTools/extensions.ts | 70 ++-- test/mcp/src/automationTools/keybindings.ts | 42 +-- test/mcp/src/automationTools/localization.ts | 54 +-- test/mcp/src/automationTools/notebook.ts | 331 +++++++++--------- test/mcp/src/automationTools/problems.ts | 72 ++-- test/mcp/src/automationTools/profiler.ts | 35 +- test/mcp/src/automationTools/quickAccess.ts | 72 ++-- test/mcp/src/automationTools/scm.ts | 196 ++++++----- test/mcp/src/automationTools/search.ts | 117 ++++--- test/mcp/src/automationTools/settings.ts | 128 +++---- test/mcp/src/automationTools/statusbar.ts | 223 ++++++------ test/mcp/src/automationTools/task.ts | 65 ++-- test/mcp/src/automationTools/terminal.ts | 137 ++++---- test/mcp/src/stdio.ts | 2 +- 20 files changed, 1228 insertions(+), 1153 deletions(-) diff --git a/.github/prompts/playwright.prompt.md b/.github/prompts/playwright.prompt.md index 6310eed092a..107c91475c0 100644 --- a/.github/prompts/playwright.prompt.md +++ b/.github/prompts/playwright.prompt.md @@ -1,18 +1,15 @@ --- mode: agent -description: 'Use playwright to _see_ the code changes you have made' -tools: ['codebase', 'usages', 'vscodeAPI', 'problems', 'changes', 'testFailure', 'openSimpleBrowser', 'fetch', 'findTestFiles', 'searchResults', 'githubRepo', 'todos', 'runTests', 'editFiles', 'runNotebooks', 'search', 'new', 'runCommands', 'runTasks', 'browser_click', 'browser_close', 'browser_console_messages', 'browser_drag', 'browser_evaluate', 'browser_file_upload', 'browser_handle_dialog', 'browser_hover', 'browser_network_requests', 'browser_press_key', 'browser_resize', 'browser_select_option', 'browser_snapshot', 'browser_tab_close', 'browser_tab_list', 'browser_tab_new', 'browser_tab_select', 'browser_take_screenshot', 'browser_type', 'browser_wait_for', 'get_commit', 'get_discussion', 'get_discussion_comments', 'get_issue', 'get_issue_comments'] +description: 'Use playwright & automation tools to _see_ the code changes you have made' +tools: ['codebase', 'usages', 'vscodeAPI', 'problems', 'changes', 'testFailure', 'openSimpleBrowser', 'fetch', 'findTestFiles', 'searchResults', 'githubRepo', 'todos', 'runTests', 'editFiles', 'runNotebooks', 'search', 'new', 'runCommands', 'runTasks', 'vscode-playwright-mcp', 'get_commit', 'get_discussion', 'get_discussion_comments', 'get_issue', 'get_issue_comments'] --- -For every UI change you make, verify the result interactively using vscode-playwright-mcp. Use Playwright to open the relevant UI, perform the change, and take screenshots to visually confirm the update. This ensures that every modification is visible, correct, and meets the intended requirements. +You are being requested to visually confirm the code changes you are making using vscode-playwright-mcp. -Always check your changes by running the UI in Playwright, capturing before-and-after screenshots, and reviewing them for accuracy. This approach helps catch regressions, improves reliability, and provides clear evidence of the effect of your work. - -NOTE: When you use a playwright tool, it will automatically open a VS Code dev build so just assume that one will be opened for you. You do not need to open a dev build yourself. - -In addition to visual verification, follow best practices for writing robust, maintainable, and extendable code. Ensure all user-facing messages are localized, use consistent naming and indentation, and prefer async/await for asynchronous operations. Write and update relevant tests, clean up temporary files, and adhere to project coding guidelines for quality and consistency. - -If the task is unreasonable or infeasible, or if any of the tests are incorrect, please tell the user. The solution should be robust, maintainable, and extendable. - -Tips for navigating VS Code: -* When running a command in the command palette, the line needs to start with `>` -* For Quick Pick bugs, you may need to temporarily modify an existing quick pick to see the issue. +You MUST run vscode_automation_start & browser_snapshot. +You MUST verify the bad behavior you are investigating using vscode-playwright-mcp. +You MUST verify the code changes you have made using vscode-playwright-mcp. +You MUST take before and after screenshots. +Remember, you are NOT writing playwright tests; instead, focus on using the tools to validate and explore the changes. +You MAY need to make multiple passes, iterating between making code changes and verifying them with the tools. +You MUST reload the window (`Developer: Reload Window` command) after making changes to ensure they are applied correctly. +You MAY make temporary changes to the code to facilitate testing and exploration. For example, using the quick pick in the Configure Display Language action as a scratch pad to add buttons to it. diff --git a/test/mcp/src/automationTools/activityBar.ts b/test/mcp/src/automationTools/activityBar.ts index 574e68ef3f4..651b0762b54 100644 --- a/test/mcp/src/automationTools/activityBar.ts +++ b/test/mcp/src/automationTools/activityBar.ts @@ -5,28 +5,28 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { Application } from '../../../automation'; -import { z } from 'zod'; /** * Activity Bar Tools */ export function applyActivityBarTools(server: McpServer, app: Application) { - server.tool( - 'vscode_automation_activitybar_wait_for_position', - 'Wait for the activity bar to appear at a specific position', - { - position: z.enum(['LEFT', 'RIGHT']).describe('Position of the activity bar (LEFT or RIGHT)') - }, - async (args) => { - const { position } = args; - const activityBarPosition = position === 'LEFT' ? 0 : 1; // ActivityBarPosition.LEFT = 0, RIGHT = 1 - await app.workbench.activitybar.waitForActivityBar(activityBarPosition); - return { - content: [{ - type: 'text' as const, - text: `Activity bar found at position: ${position}` - }] - }; - } - ); + // Doesn't seem particularly useful + // server.tool( + // 'vscode_automation_activitybar_wait_for_position', + // 'Wait for the activity bar to appear at a specific position', + // { + // position: z.enum(['LEFT', 'RIGHT']).describe('Position of the activity bar (LEFT or RIGHT)') + // }, + // async (args) => { + // const { position } = args; + // const activityBarPosition = position === 'LEFT' ? 0 : 1; // ActivityBarPosition.LEFT = 0, RIGHT = 1 + // await app.workbench.activitybar.waitForActivityBar(activityBarPosition); + // return { + // content: [{ + // type: 'text' as const, + // text: `Activity bar found at position: ${position}` + // }] + // }; + // } + // ); } diff --git a/test/mcp/src/automationTools/core.ts b/test/mcp/src/automationTools/core.ts index 4217ef9902c..4a00011b9a4 100644 --- a/test/mcp/src/automationTools/core.ts +++ b/test/mcp/src/automationTools/core.ts @@ -5,145 +5,165 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { Application } from '../../../automation'; -import { z } from 'zod'; /** * Core Application Management Tools */ export function applyCoreTools(server: McpServer, app: Application) { + // A dummy start tool just so that the model has something to hold on to. server.tool( - 'vscode_automation_restart', - 'Restart VS Code with optional workspace or folder and extra arguments', - { - workspaceOrFolder: z.string().optional().describe('Optional path to workspace or folder to open'), - extraArgs: z.array(z.string()).optional().describe('Optional extra command line arguments') - }, - async (args) => { - const { workspaceOrFolder, extraArgs } = args; - await app.restart({ workspaceOrFolder, extraArgs }); - return { - content: [{ - type: 'text' as const, - text: `VS Code restarted successfully${workspaceOrFolder ? ` with workspace: ${workspaceOrFolder}` : ''}` - }] - }; - } - ); - - server.tool( - 'vscode_automation_stop', - 'Stop the VS Code application', + 'vscode_automation_start', + 'Start VS Code Build', + {}, async () => { - await app.stop(); return { content: [{ type: 'text' as const, - text: 'VS Code stopped successfully' + text: `VS Code started successfully` }] }; } ); + // Playwright keeps using this as a start... maybe it needs some massaging + // server.tool( + // 'vscode_automation_restart', + // 'Restart VS Code with optional workspace or folder and extra arguments', + // { + // workspaceOrFolder: z.string().optional().describe('Optional path to workspace or folder to open'), + // extraArgs: z.array(z.string()).optional().describe('Optional extra command line arguments') + // }, + // async (args) => { + // const { workspaceOrFolder, extraArgs } = args; + // await app.restart({ workspaceOrFolder, extraArgs }); + // return { + // content: [{ + // type: 'text' as const, + // text: `VS Code restarted successfully${workspaceOrFolder ? ` with workspace: ${workspaceOrFolder}` : ''}` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_get_quality', - 'Get the quality/build type of VS Code (Dev, Insiders, Stable, etc.)', - async () => { - const info = { - quality: app.quality, - remote: app.remote, - web: app.web, - workspacePathOrFolder: app.workspacePathOrFolder, - extensionsPath: app.extensionsPath, - userDataPath: app.userDataPath - }; - return { - content: [{ - type: 'text' as const, - text: `VS Code Info:\n${JSON.stringify(info, null, 2)}` - }] - }; - } - ); + // I don't think Playwright needs this + // server.tool( + // 'vscode_automation_stop', + // 'Stop the VS Code application', + // async () => { + // await app.stop(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'VS Code stopped successfully' + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_wait_for_element', - 'Wait for a UI element to appear using CSS selector - prefer using specific workbench methods when available', - { - selector: z.string().describe('CSS selector for the element to wait for'), - timeout: z.number().optional().default(20).describe('Timeout in seconds (default: 20)') - }, - async (args) => { - const { selector, timeout = 20 } = args; - const retryCount = Math.floor((timeout * 1000) / 100); // 100ms intervals - const element = await app.code.waitForElement(selector, undefined, retryCount); - return { - content: [{ - type: 'text' as const, - text: `Element found: ${selector} (${!!element ? 'success' : 'not found'})` - }] - }; - } - ); + // This doesn't seem particularly useful + // server.tool( + // 'vscode_automation_get_quality', + // 'Get the quality/build type of VS Code (Dev, Insiders, Stable, etc.)', + // async () => { + // const info = { + // quality: app.quality, + // remote: app.remote, + // web: app.web, + // workspacePathOrFolder: app.workspacePathOrFolder, + // extensionsPath: app.extensionsPath, + // userDataPath: app.userDataPath + // }; + // return { + // content: [{ + // type: 'text' as const, + // text: `VS Code Info:\n${JSON.stringify(info, null, 2)}` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_click_element', - 'Click on a UI element - prefer using specific workbench methods when available', - { - selector: z.string().describe('CSS selector for the element to click'), - xOffset: z.number().optional().describe('Optional X offset from element center'), - yOffset: z.number().optional().describe('Optional Y offset from element center') - }, - async (args) => { - const { selector, xOffset, yOffset } = args; - await app.code.waitAndClick(selector, xOffset, yOffset); - return { - content: [{ - type: 'text' as const, - text: `Clicked element: ${selector}${xOffset !== undefined ? ` (offset: ${xOffset}, ${yOffset})` : ''}` - }] - }; - } - ); + // This doesn't seem particularly useful + // server.tool( + // 'vscode_automation_wait_for_element', + // 'Wait for a UI element to appear using CSS selector - prefer using specific workbench methods when available', + // { + // selector: z.string().describe('CSS selector for the element to wait for'), + // timeout: z.number().optional().default(20).describe('Timeout in seconds (default: 20)') + // }, + // async (args) => { + // const { selector, timeout = 20 } = args; + // const retryCount = Math.floor((timeout * 1000) / 100); // 100ms intervals + // const element = await app.code.waitForElement(selector, undefined, retryCount); + // return { + // content: [{ + // type: 'text' as const, + // text: `Element found: ${selector} (${!!element ? 'success' : 'not found'})` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_send_keybinding', - 'Send a keybinding to VS Code (e.g., ctrl+shift+p, cmd+s)', - { - keybinding: z.string().describe('The keybinding to send (e.g., ctrl+shift+p, cmd+s, escape)'), - waitSelector: z.string().optional().describe('Optional CSS selector to wait for after sending the keybinding') - }, - async (args) => { - const { keybinding, waitSelector } = args; - await app.code.dispatchKeybinding(keybinding, async () => { - if (waitSelector) { - await app.code.waitForElement(waitSelector); - } - }); - return { - content: [{ - type: 'text' as const, - text: `Sent keybinding: ${keybinding}${waitSelector ? ` (waited for: ${waitSelector})` : ''}` - }] - }; - } - ); + // Defer to Playwright's tool + // server.tool( + // 'vscode_automation_click_element', + // 'Click on a UI element - prefer using specific workbench methods when available', + // { + // selector: z.string().describe('CSS selector for the element to click'), + // xOffset: z.number().optional().describe('Optional X offset from element center'), + // yOffset: z.number().optional().describe('Optional Y offset from element center') + // }, + // async (args) => { + // const { selector, xOffset, yOffset } = args; + // await app.code.waitAndClick(selector, xOffset, yOffset); + // return { + // content: [{ + // type: 'text' as const, + // text: `Clicked element: ${selector}${xOffset !== undefined ? ` (offset: ${xOffset}, ${yOffset})` : ''}` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_get_text_content', - 'Get text content from a UI element using CSS selector', - { - selector: z.string().describe('CSS selector for the element'), - expectedText: z.string().optional().describe('Optional expected text to wait for') - }, - async (args) => { - const { selector, expectedText } = args; - const text = await app.code.waitForTextContent(selector, expectedText); - return { - content: [{ - type: 'text' as const, - text: `Text content from ${selector}: "${text}"` - }] - }; - } - ); + // Defer to Playwright's tool + // server.tool( + // 'vscode_automation_send_keybinding', + // 'Send a keybinding to VS Code (e.g., ctrl+shift+p, cmd+s)', + // { + // keybinding: z.string().describe('The keybinding to send (e.g., ctrl+shift+p, cmd+s, escape)'), + // waitSelector: z.string().optional().describe('Optional CSS selector to wait for after sending the keybinding') + // }, + // async (args) => { + // const { keybinding, waitSelector } = args; + // await app.code.dispatchKeybinding(keybinding, async () => { + // if (waitSelector) { + // await app.code.waitForElement(waitSelector); + // } + // }); + // return { + // content: [{ + // type: 'text' as const, + // text: `Sent keybinding: ${keybinding}${waitSelector ? ` (waited for: ${waitSelector})` : ''}` + // }] + // }; + // } + // ); + + // Defer to Playwright's tool + // server.tool( + // 'vscode_automation_get_text_content', + // 'Get text content from a UI element using CSS selector', + // { + // selector: z.string().describe('CSS selector for the element'), + // expectedText: z.string().optional().describe('Optional expected text to wait for') + // }, + // async (args) => { + // const { selector, expectedText } = args; + // const text = await app.code.waitForTextContent(selector, expectedText); + // return { + // content: [{ + // type: 'text' as const, + // text: `Text content from ${selector}: "${text}"` + // }] + // }; + // } + // ); } diff --git a/test/mcp/src/automationTools/debug.ts b/test/mcp/src/automationTools/debug.ts index 094de6c1253..8e98e875970 100644 --- a/test/mcp/src/automationTools/debug.ts +++ b/test/mcp/src/automationTools/debug.ts @@ -57,73 +57,78 @@ export function applyDebugTools(server: McpServer, app: Application) { } ); - server.tool( - 'vscode_automation_debug_stop', - 'Stop debugging', - async () => { - await app.workbench.debug.stopDebugging(); - return { - content: [{ - type: 'text' as const, - text: 'Stopped debugging' - }] - }; - } - ); + // Playwright can probably figure this out + // server.tool( + // 'vscode_automation_debug_stop', + // 'Stop debugging', + // async () => { + // await app.workbench.debug.stopDebugging(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Stopped debugging' + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_debug_step_over', - 'Step over in debugger', - async () => { - await app.workbench.debug.stepOver(); - return { - content: [{ - type: 'text' as const, - text: 'Stepped over' - }] - }; - } - ); + // Playwright can probably figure this out + // server.tool( + // 'vscode_automation_debug_step_over', + // 'Step over in debugger', + // async () => { + // await app.workbench.debug.stepOver(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Stepped over' + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_debug_step_in', - 'Step into in debugger', - async () => { - await app.workbench.debug.stepIn(); - return { - content: [{ - type: 'text' as const, - text: 'Stepped in' - }] - }; - } - ); + // Playwright can probably figure this out + // server.tool( + // 'vscode_automation_debug_step_in', + // 'Step into in debugger', + // async () => { + // await app.workbench.debug.stepIn(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Stepped in' + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_debug_step_out', - 'Step out in debugger', - async () => { - await app.workbench.debug.stepOut(); - return { - content: [{ - type: 'text' as const, - text: 'Stepped out' - }] - }; - } - ); + // Playwright can probably figure this out + // server.tool( + // 'vscode_automation_debug_step_out', + // 'Step out in debugger', + // async () => { + // await app.workbench.debug.stepOut(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Stepped out' + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_debug_continue', - 'Continue execution in debugger', - async () => { - await app.workbench.debug.continue(); - return { - content: [{ - type: 'text' as const, - text: 'Continued execution' - }] - }; - } - ); + // Playwright can probably figure this out + // server.tool( + // 'vscode_automation_debug_continue', + // 'Continue execution in debugger', + // async () => { + // await app.workbench.debug.continue(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Continued execution' + // }] + // }; + // } + // ); } diff --git a/test/mcp/src/automationTools/editor.ts b/test/mcp/src/automationTools/editor.ts index b503d323a73..f94c111fec4 100644 --- a/test/mcp/src/automationTools/editor.ts +++ b/test/mcp/src/automationTools/editor.ts @@ -11,24 +11,26 @@ import { z } from 'zod'; * Editor Management Tools */ export function applyEditorTools(server: McpServer, app: Application) { - server.tool( - 'vscode_automation_editor_open_file', - 'Open a file in the VS Code editor through quick open', - { - fileName: z.string().describe('Name of the file to open (partial names work)') - }, - async (args) => { - const { fileName } = args; - await app.workbench.quickaccess.openFileQuickAccessAndWait(fileName, fileName); - return { - content: [{ - type: 'text' as const, - text: `Opened file: ${fileName}` - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_editor_open_file', + // 'Open a file in the VS Code editor through quick open', + // { + // fileName: z.string().describe('Name of the file to open (partial names work)') + // }, + // async (args) => { + // const { fileName } = args; + // await app.workbench.quickaccess.openFileQuickAccessAndWait(fileName, fileName); + // return { + // content: [{ + // type: 'text' as const, + // text: `Opened file: ${fileName}` + // }] + // }; + // } + // ); + // This one is critical as Playwright had trouble typing in monaco server.tool( 'vscode_automation_editor_type_text', 'Type text in the currently active editor', @@ -48,110 +50,115 @@ export function applyEditorTools(server: McpServer, app: Application) { } ); - server.tool( - 'vscode_automation_editor_get_selection', - 'Get the current selection in the editor', - { - filename: z.string().describe('Filename to target specific editor') - }, - async (args) => { - const { filename } = args; - return new Promise((resolve, reject) => { - const selectionHandler = (selection: { selectionStart: number; selectionEnd: number }) => { - resolve({ - content: [{ - type: 'text' as const, - text: `Selection: start=${selection.selectionStart}, end=${selection.selectionEnd}` - }] - }); - return true; - }; + // Doesn't seem particularly useful + // server.tool( + // 'vscode_automation_editor_get_selection', + // 'Get the current selection in the editor', + // { + // filename: z.string().describe('Filename to target specific editor') + // }, + // async (args) => { + // const { filename } = args; + // return new Promise((resolve, reject) => { + // const selectionHandler = (selection: { selectionStart: number; selectionEnd: number }) => { + // resolve({ + // content: [{ + // type: 'text' as const, + // text: `Selection: start=${selection.selectionStart}, end=${selection.selectionEnd}` + // }] + // }); + // return true; + // }; - app.workbench.editor.waitForEditorSelection(filename, selectionHandler).catch(reject); - }); - } - ); + // app.workbench.editor.waitForEditorSelection(filename, selectionHandler).catch(reject); + // }); + // } + // ); - server.tool( - 'vscode_automation_editor_go_to_definition', - 'Go to definition of symbol at current cursor position', - { - filename: z.string().describe('File containing the symbol'), - term: z.string().describe('The symbol/term to go to definition for'), - line: z.number().describe('Line number where the symbol is located') - }, - async (args) => { - const { filename, term, line } = args; - await app.workbench.editor.gotoDefinition(filename, term, line); - return { - content: [{ - type: 'text' as const, - text: `Navigated to definition of "${term}" in ${filename} at line ${line}` - }] - }; - } - ); + // Doesn't seem particularly useful + // server.tool( + // 'vscode_automation_editor_go_to_definition', + // 'Go to definition of symbol at current cursor position', + // { + // filename: z.string().describe('File containing the symbol'), + // term: z.string().describe('The symbol/term to go to definition for'), + // line: z.number().describe('Line number where the symbol is located') + // }, + // async (args) => { + // const { filename, term, line } = args; + // await app.workbench.editor.gotoDefinition(filename, term, line); + // return { + // content: [{ + // type: 'text' as const, + // text: `Navigated to definition of "${term}" in ${filename} at line ${line}` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_editor_peek_definition', - 'Peek definition of symbol at current cursor position', - { - filename: z.string().describe('File containing the symbol'), - term: z.string().describe('The symbol/term to peek definition for'), - line: z.number().describe('Line number where the symbol is located') - }, - async (args) => { - const { filename, term, line } = args; - await app.workbench.editor.peekDefinition(filename, term, line); - return { - content: [{ - type: 'text' as const, - text: `Peeked definition of "${term}" in ${filename} at line ${line}` - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_editor_peek_definition', + // 'Peek definition of symbol at current cursor position', + // { + // filename: z.string().describe('File containing the symbol'), + // term: z.string().describe('The symbol/term to peek definition for'), + // line: z.number().describe('Line number where the symbol is located') + // }, + // async (args) => { + // const { filename, term, line } = args; + // await app.workbench.editor.peekDefinition(filename, term, line); + // return { + // content: [{ + // type: 'text' as const, + // text: `Peeked definition of "${term}" in ${filename} at line ${line}` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_editor_rename_symbol', - 'Rename a symbol in the editor', - { - filename: z.string().describe('File containing the symbol'), - line: z.number().describe('Line number where the symbol is located'), - oldName: z.string().describe('Current name of the symbol'), - newName: z.string().describe('New name for the symbol') - }, - async (args) => { - const { filename, line, oldName, newName } = args; - await app.workbench.editor.rename(filename, line, oldName, newName); - return { - content: [{ - type: 'text' as const, - text: `Renamed "${oldName}" to "${newName}" in ${filename} at line ${line}` - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_editor_rename_symbol', + // 'Rename a symbol in the editor', + // { + // filename: z.string().describe('File containing the symbol'), + // line: z.number().describe('Line number where the symbol is located'), + // oldName: z.string().describe('Current name of the symbol'), + // newName: z.string().describe('New name for the symbol') + // }, + // async (args) => { + // const { filename, line, oldName, newName } = args; + // await app.workbench.editor.rename(filename, line, oldName, newName); + // return { + // content: [{ + // type: 'text' as const, + // text: `Renamed "${oldName}" to "${newName}" in ${filename} at line ${line}` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_editor_find_references', - 'Find all references to a symbol', - { - filename: z.string().describe('File containing the symbol'), - term: z.string().describe('The symbol/term to find references for'), - line: z.number().describe('Line number where the symbol is located') - }, - async (args) => { - const { filename, term, line } = args; - await app.workbench.editor.findReferences(filename, term, line); - return { - content: [{ - type: 'text' as const, - text: `Found references for "${term}" in ${filename} at line ${line}` - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_editor_find_references', + // 'Find all references to a symbol', + // { + // filename: z.string().describe('File containing the symbol'), + // term: z.string().describe('The symbol/term to find references for'), + // line: z.number().describe('Line number where the symbol is located') + // }, + // async (args) => { + // const { filename, term, line } = args; + // await app.workbench.editor.findReferences(filename, term, line); + // return { + // content: [{ + // type: 'text' as const, + // text: `Found references for "${term}" in ${filename} at line ${line}` + // }] + // }; + // } + // ); // Editor File Management Tools server.tool( @@ -182,59 +189,62 @@ export function applyEditorTools(server: McpServer, app: Application) { } ); - server.tool( - 'vscode_automation_editor_select_tab', - 'Select a specific tab by filename', - { - fileName: z.string().describe('Name of the file tab to select') - }, - async (args) => { - const { fileName } = args; - await app.workbench.editors.selectTab(fileName); - return { - content: [{ - type: 'text' as const, - text: `Selected tab: ${fileName}` - }] - }; - } - ); + // Playwright can probably figure this out + // server.tool( + // 'vscode_automation_editor_select_tab', + // 'Select a specific tab by filename', + // { + // fileName: z.string().describe('Name of the file tab to select') + // }, + // async (args) => { + // const { fileName } = args; + // await app.workbench.editors.selectTab(fileName); + // return { + // content: [{ + // type: 'text' as const, + // text: `Selected tab: ${fileName}` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_editor_wait_for_tab', - 'Wait for a specific tab to appear', - { - fileName: z.string().describe('Name of the file tab to wait for'), - isDirty: z.boolean().optional().describe('Whether to wait for the tab to be dirty (unsaved)') - }, - async (args) => { - const { fileName, isDirty = false } = args; - await app.workbench.editors.waitForTab(fileName, isDirty); - return { - content: [{ - type: 'text' as const, - text: `Tab appeared: ${fileName}${isDirty ? ' (dirty)' : ''}` - }] - }; - } - ); + // Playwright can probably figure this out + // server.tool( + // 'vscode_automation_editor_wait_for_tab', + // 'Wait for a specific tab to appear', + // { + // fileName: z.string().describe('Name of the file tab to wait for'), + // isDirty: z.boolean().optional().describe('Whether to wait for the tab to be dirty (unsaved)') + // }, + // async (args) => { + // const { fileName, isDirty = false } = args; + // await app.workbench.editors.waitForTab(fileName, isDirty); + // return { + // content: [{ + // type: 'text' as const, + // text: `Tab appeared: ${fileName}${isDirty ? ' (dirty)' : ''}` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_editor_wait_for_focus', - 'Wait for an editor to have focus', - { - fileName: z.string().describe('Name of the file to wait for focus'), - retryCount: z.number().optional().describe('Number of retries') - }, - async (args) => { - const { fileName, retryCount } = args; - await app.workbench.editors.waitForEditorFocus(fileName, retryCount); - return { - content: [{ - type: 'text' as const, - text: `Editor has focus: ${fileName}` - }] - }; - } - ); + // Playwright can probably figure this out + // server.tool( + // 'vscode_automation_editor_wait_for_focus', + // 'Wait for an editor to have focus', + // { + // fileName: z.string().describe('Name of the file to wait for focus'), + // retryCount: z.number().optional().describe('Number of retries') + // }, + // async (args) => { + // const { fileName, retryCount } = args; + // await app.workbench.editors.waitForEditorFocus(fileName, retryCount); + // return { + // content: [{ + // type: 'text' as const, + // text: `Editor has focus: ${fileName}` + // }] + // }; + // } + // ); } diff --git a/test/mcp/src/automationTools/explorer.ts b/test/mcp/src/automationTools/explorer.ts index 9ff482b415d..ebf3c7e2072 100644 --- a/test/mcp/src/automationTools/explorer.ts +++ b/test/mcp/src/automationTools/explorer.ts @@ -10,17 +10,18 @@ import { Application } from '../../../automation'; * Explorer and File Management Tools */ export function applyExplorerTools(server: McpServer, app: Application) { - server.tool( - 'vscode_automation_explorer_open', - 'Open the file explorer viewlet', - async () => { - await app.workbench.explorer.openExplorerView(); - return { - content: [{ - type: 'text' as const, - text: 'Opened file explorer' - }] - }; - } - ); + // Playwright can probably figure this out + // server.tool( + // 'vscode_automation_explorer_open', + // 'Open the file explorer viewlet', + // async () => { + // await app.workbench.explorer.openExplorerView(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Opened file explorer' + // }] + // }; + // } + // ); } diff --git a/test/mcp/src/automationTools/extensions.ts b/test/mcp/src/automationTools/extensions.ts index 104ea87a35b..d84c17b1eef 100644 --- a/test/mcp/src/automationTools/extensions.ts +++ b/test/mcp/src/automationTools/extensions.ts @@ -11,23 +11,24 @@ import { z } from 'zod'; * Extensions Tools */ export function applyExtensionsTools(server: McpServer, app: Application) { - server.tool( - 'vscode_automation_extensions_search', - 'Search for an extension by ID', - { - extensionId: z.string().describe('Extension ID to search for (e.g., "ms-python.python")') - }, - async (args) => { - const { extensionId } = args; - await app.workbench.extensions.searchForExtension(extensionId); - return { - content: [{ - type: 'text' as const, - text: `Searched for extension: ${extensionId}` - }] - }; - } - ); + // Playwright can probably figure this out + // server.tool( + // 'vscode_automation_extensions_search', + // 'Search for an extension by ID', + // { + // extensionId: z.string().describe('Extension ID to search for (e.g., "ms-python.python")') + // }, + // async (args) => { + // const { extensionId } = args; + // await app.workbench.extensions.searchForExtension(extensionId); + // return { + // content: [{ + // type: 'text' as const, + // text: `Searched for extension: ${extensionId}` + // }] + // }; + // } + // ); server.tool( 'vscode_automation_extensions_open', @@ -47,23 +48,24 @@ export function applyExtensionsTools(server: McpServer, app: Application) { } ); - server.tool( - 'vscode_automation_extensions_close', - 'Close an extension tab by title', - { - title: z.string().describe('Extension title to close') - }, - async (args) => { - const { title } = args; - await app.workbench.extensions.closeExtension(title); - return { - content: [{ - type: 'text' as const, - text: `Closed extension: ${title}` - }] - }; - } - ); + // Playwright can probably figure this out + // server.tool( + // 'vscode_automation_extensions_close', + // 'Close an extension tab by title', + // { + // title: z.string().describe('Extension title to close') + // }, + // async (args) => { + // const { title } = args; + // await app.workbench.extensions.closeExtension(title); + // return { + // content: [{ + // type: 'text' as const, + // text: `Closed extension: ${title}` + // }] + // }; + // } + // ); server.tool( 'vscode_automation_extensions_install', diff --git a/test/mcp/src/automationTools/keybindings.ts b/test/mcp/src/automationTools/keybindings.ts index 75b19b4c26f..c2d8375633e 100644 --- a/test/mcp/src/automationTools/keybindings.ts +++ b/test/mcp/src/automationTools/keybindings.ts @@ -5,30 +5,30 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { Application } from '../../../automation'; -import { z } from 'zod'; /** * Keybindings Editor Tools */ export function applyKeybindingsTools(server: McpServer, app: Application) { - server.tool( - 'vscode_automation_keybindings_update', - 'Update a keybinding for a specific command', - { - command: z.string().describe('Command ID to update keybinding for'), - commandName: z.string().optional().describe('Optional command display name'), - keybinding: z.string().describe('New keybinding (e.g., "ctrl+k ctrl+c")'), - keybindingTitle: z.string().describe('Display title for the keybinding') - }, - async (args) => { - const { command, commandName, keybinding, keybindingTitle } = args; - await app.workbench.keybindingsEditor.updateKeybinding(command, commandName, keybinding, keybindingTitle); - return { - content: [{ - type: 'text' as const, - text: `Updated keybinding for "${command}"${commandName ? ` (${commandName})` : ''}: ${keybinding} (${keybindingTitle})` - }] - }; - } - ); + // Seems too niche + // server.tool( + // 'vscode_automation_keybindings_update', + // 'Update a keybinding for a specific command', + // { + // command: z.string().describe('Command ID to update keybinding for'), + // commandName: z.string().optional().describe('Optional command display name'), + // keybinding: z.string().describe('New keybinding (e.g., "ctrl+k ctrl+c")'), + // keybindingTitle: z.string().describe('Display title for the keybinding') + // }, + // async (args) => { + // const { command, commandName, keybinding, keybindingTitle } = args; + // await app.workbench.keybindingsEditor.updateKeybinding(command, commandName, keybinding, keybindingTitle); + // return { + // content: [{ + // type: 'text' as const, + // text: `Updated keybinding for "${command}"${commandName ? ` (${commandName})` : ''}: ${keybinding} (${keybindingTitle})` + // }] + // }; + // } + // ); } diff --git a/test/mcp/src/automationTools/localization.ts b/test/mcp/src/automationTools/localization.ts index 3efb2c7a0b4..207a5a86618 100644 --- a/test/mcp/src/automationTools/localization.ts +++ b/test/mcp/src/automationTools/localization.ts @@ -10,31 +10,33 @@ import { Application } from '../../../automation'; * Localization Tools */ export function applyLocalizationTools(server: McpServer, app: Application) { - server.tool( - 'vscode_automation_localization_get_locale_info', - 'Get current locale information', - async () => { - const localeInfo = await app.workbench.localization.getLocaleInfo(); - return { - content: [{ - type: 'text' as const, - text: `Locale info:\n${JSON.stringify(localeInfo, null, 2)}` - }] - }; - } - ); + // Seems too niche + // server.tool( + // 'vscode_automation_localization_get_locale_info', + // 'Get current locale information', + // async () => { + // const localeInfo = await app.workbench.localization.getLocaleInfo(); + // return { + // content: [{ + // type: 'text' as const, + // text: `Locale info:\n${JSON.stringify(localeInfo, null, 2)}` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_localization_get_localized_strings', - 'Get all localized strings', - async () => { - const localizedStrings = await app.workbench.localization.getLocalizedStrings(); - return { - content: [{ - type: 'text' as const, - text: `Localized strings:\n${JSON.stringify(localizedStrings, null, 2)}` - }] - }; - } - ); + // Seems too niche + // server.tool( + // 'vscode_automation_localization_get_localized_strings', + // 'Get all localized strings', + // async () => { + // const localizedStrings = await app.workbench.localization.getLocalizedStrings(); + // return { + // content: [{ + // type: 'text' as const, + // text: `Localized strings:\n${JSON.stringify(localizedStrings, null, 2)}` + // }] + // }; + // } + // ); } diff --git a/test/mcp/src/automationTools/notebook.ts b/test/mcp/src/automationTools/notebook.ts index a7ee25eeecd..37e30c8f792 100644 --- a/test/mcp/src/automationTools/notebook.ts +++ b/test/mcp/src/automationTools/notebook.ts @@ -25,33 +25,35 @@ export function applyNotebookTools(server: McpServer, app: Application) { } ); - server.tool( - 'vscode_automation_notebook_focus_next_cell', - 'Focus the next cell in the notebook', - async () => { - await app.workbench.notebook.focusNextCell(); - return { - content: [{ - type: 'text' as const, - text: 'Focused next cell' - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_notebook_focus_next_cell', + // 'Focus the next cell in the notebook', + // async () => { + // await app.workbench.notebook.focusNextCell(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Focused next cell' + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_notebook_focus_first_cell', - 'Focus the first cell in the notebook', - async () => { - await app.workbench.notebook.focusFirstCell(); - return { - content: [{ - type: 'text' as const, - text: 'Focused first cell' - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_notebook_focus_first_cell', + // 'Focus the first cell in the notebook', + // async () => { + // await app.workbench.notebook.focusFirstCell(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Focused first cell' + // }] + // }; + // } + // ); server.tool( 'vscode_automation_notebook_edit_cell', @@ -67,19 +69,20 @@ export function applyNotebookTools(server: McpServer, app: Application) { } ); - server.tool( - 'vscode_automation_notebook_stop_editing_cell', - 'Exit edit mode for the current cell', - async () => { - await app.workbench.notebook.stopEditingCell(); - return { - content: [{ - type: 'text' as const, - text: 'Exited cell edit mode' - }] - }; - } - ); + // Seems too niche + // server.tool( + // 'vscode_automation_notebook_stop_editing_cell', + // 'Exit edit mode for the current cell', + // async () => { + // await app.workbench.notebook.stopEditingCell(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Exited cell edit mode' + // }] + // }; + // } + // ); server.tool( 'vscode_automation_notebook_type_in_editor', @@ -99,132 +102,140 @@ export function applyNotebookTools(server: McpServer, app: Application) { } ); - server.tool( - 'vscode_automation_notebook_wait_for_cell_contents', - 'Wait for specific contents in the active cell editor', - { - contents: z.string().describe('Expected contents in the active cell') - }, - async (args) => { - const { contents } = args; - await app.workbench.notebook.waitForActiveCellEditorContents(contents); - return { - content: [{ - type: 'text' as const, - text: `Active cell contains expected contents: "${contents}"` - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_notebook_wait_for_cell_contents', + // 'Wait for specific contents in the active cell editor', + // { + // contents: z.string().describe('Expected contents in the active cell') + // }, + // async (args) => { + // const { contents } = args; + // await app.workbench.notebook.waitForActiveCellEditorContents(contents); + // return { + // content: [{ + // type: 'text' as const, + // text: `Active cell contains expected contents: "${contents}"` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_notebook_wait_for_markdown_contents', - 'Wait for specific text in markdown cell output', - { - markdownSelector: z.string().describe('CSS selector for the markdown element'), - text: z.string().describe('Expected text in the markdown output') - }, - async (args) => { - const { markdownSelector, text } = args; - await app.workbench.notebook.waitForMarkdownContents(markdownSelector, text); - return { - content: [{ - type: 'text' as const, - text: `Markdown content found: "${text}" in ${markdownSelector}` - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_notebook_wait_for_markdown_contents', + // 'Wait for specific text in markdown cell output', + // { + // markdownSelector: z.string().describe('CSS selector for the markdown element'), + // text: z.string().describe('Expected text in the markdown output') + // }, + // async (args) => { + // const { markdownSelector, text } = args; + // await app.workbench.notebook.waitForMarkdownContents(markdownSelector, text); + // return { + // content: [{ + // type: 'text' as const, + // text: `Markdown content found: "${text}" in ${markdownSelector}` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_notebook_insert_cell', - 'Insert a new cell of specified type', - { - kind: z.enum(['markdown', 'code']).describe('Type of cell to insert') - }, - async (args) => { - const { kind } = args; - await app.workbench.notebook.insertNotebookCell(kind); - return { - content: [{ - type: 'text' as const, - text: `Inserted ${kind} cell` - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_notebook_insert_cell', + // 'Insert a new cell of specified type', + // { + // kind: z.enum(['markdown', 'code']).describe('Type of cell to insert') + // }, + // async (args) => { + // const { kind } = args; + // await app.workbench.notebook.insertNotebookCell(kind); + // return { + // content: [{ + // type: 'text' as const, + // text: `Inserted ${kind} cell` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_notebook_delete_active_cell', - 'Delete the currently active cell', - async () => { - await app.workbench.notebook.deleteActiveCell(); - return { - content: [{ - type: 'text' as const, - text: 'Deleted active cell' - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_notebook_delete_active_cell', + // 'Delete the currently active cell', + // async () => { + // await app.workbench.notebook.deleteActiveCell(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Deleted active cell' + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_notebook_focus_in_cell_output', - 'Focus inside cell output area', - async () => { - await app.workbench.notebook.focusInCellOutput(); - return { - content: [{ - type: 'text' as const, - text: 'Focused in cell output' - }] - }; - } - ); + // Seems too niche + // server.tool( + // 'vscode_automation_notebook_focus_in_cell_output', + // 'Focus inside cell output area', + // async () => { + // await app.workbench.notebook.focusInCellOutput(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Focused in cell output' + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_notebook_focus_out_cell_output', - 'Focus outside cell output area', - async () => { - await app.workbench.notebook.focusOutCellOutput(); - return { - content: [{ - type: 'text' as const, - text: 'Focused out of cell output' - }] - }; - } - ); + // Seems too niche + // server.tool( + // 'vscode_automation_notebook_focus_out_cell_output', + // 'Focus outside cell output area', + // async () => { + // await app.workbench.notebook.focusOutCellOutput(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Focused out of cell output' + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_notebook_execute_active_cell', - 'Execute the currently active cell', - async () => { - await app.workbench.notebook.executeActiveCell(); - return { - content: [{ - type: 'text' as const, - text: 'Executed active cell' - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_notebook_execute_active_cell', + // 'Execute the currently active cell', + // async () => { + // await app.workbench.notebook.executeActiveCell(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Executed active cell' + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_notebook_execute_cell_action', - 'Execute a specific cell action using CSS selector', - { - selector: z.string().describe('CSS selector for the cell action to execute') - }, - async (args) => { - const { selector } = args; - await app.workbench.notebook.executeCellAction(selector); - return { - content: [{ - type: 'text' as const, - text: `Executed cell action: ${selector}` - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_notebook_execute_cell_action', + // 'Execute a specific cell action using CSS selector', + // { + // selector: z.string().describe('CSS selector for the cell action to execute') + // }, + // async (args) => { + // const { selector } = args; + // await app.workbench.notebook.executeCellAction(selector); + // return { + // content: [{ + // type: 'text' as const, + // text: `Executed cell action: ${selector}` + // }] + // }; + // } + // ); } diff --git a/test/mcp/src/automationTools/problems.ts b/test/mcp/src/automationTools/problems.ts index 5f59e1f833b..827dc33c075 100644 --- a/test/mcp/src/automationTools/problems.ts +++ b/test/mcp/src/automationTools/problems.ts @@ -39,19 +39,20 @@ export function applyProblemsTools(server: McpServer, app: Application) { } ); - server.tool( - 'vscode_automation_problems_wait_for_view', - 'Wait for the problems view to appear', - async () => { - await app.workbench.problems.waitForProblemsView(); - return { - content: [{ - type: 'text' as const, - text: 'Problems view is now visible' - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_problems_wait_for_view', + // 'Wait for the problems view to appear', + // async () => { + // await app.workbench.problems.waitForProblemsView(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Problems view is now visible' + // }] + // }; + // } + // ); server.tool( 'vscode_automation_problems_get_selector_in_view', @@ -77,27 +78,28 @@ export function applyProblemsTools(server: McpServer, app: Application) { } ); - server.tool( - 'vscode_automation_problems_get_selector_in_editor', - 'Get CSS selector for problems of a specific severity in the editor', - { - severity: z.enum(['WARNING', 'ERROR']).describe('Problem severity (WARNING or ERROR)') - }, - async (args) => { - const { severity } = args; - const severityMap: Record = { - 'WARNING': 0, - 'ERROR': 1 - }; + // Seems too niche + // server.tool( + // 'vscode_automation_problems_get_selector_in_editor', + // 'Get CSS selector for problems of a specific severity in the editor', + // { + // severity: z.enum(['WARNING', 'ERROR']).describe('Problem severity (WARNING or ERROR)') + // }, + // async (args) => { + // const { severity } = args; + // const severityMap: Record = { + // 'WARNING': 0, + // 'ERROR': 1 + // }; - // This is a static method that returns a selector, not an async operation - const selector = (app.workbench.problems.constructor as any).getSelectorInEditor(severityMap[severity]); - return { - content: [{ - type: 'text' as const, - text: `CSS selector for ${severity} problems in editor: ${selector}` - }] - }; - } - ); + // // This is a static method that returns a selector, not an async operation + // const selector = (app.workbench.problems.constructor as any).getSelectorInEditor(severityMap[severity]); + // return { + // content: [{ + // type: 'text' as const, + // text: `CSS selector for ${severity} problems in editor: ${selector}` + // }] + // }; + // } + // ); } diff --git a/test/mcp/src/automationTools/profiler.ts b/test/mcp/src/automationTools/profiler.ts index 56537e68622..b5a19ab5013 100644 --- a/test/mcp/src/automationTools/profiler.ts +++ b/test/mcp/src/automationTools/profiler.ts @@ -12,22 +12,23 @@ import { Application } from '../../../automation'; * but cannot execute them directly as they require function parameters */ export function applyProfilerTools(server: McpServer, app: Application) { - server.tool( - 'vscode_automation_profiler_info', - 'Get information about available profiler methods', - {}, - async () => { - return { - content: [{ - type: 'text' as const, - text: `Profiler methods available: -- checkObjectLeaks(classNames, fn): Check for object leaks during function execution -- checkHeapLeaks(classNames, fn): Check for heap leaks during function execution + // Seems too niche + // server.tool( + // 'vscode_automation_profiler_info', + // 'Get information about available profiler methods', + // {}, + // async () => { + // return { + // content: [{ + // type: 'text' as const, + // text: `Profiler methods available: + // - checkObjectLeaks(classNames, fn): Check for object leaks during function execution + // - checkHeapLeaks(classNames, fn): Check for heap leaks during function execution -Note: These methods require function parameters and cannot be executed directly via MCP. -They are primarily used within VS Code's automation test framework.` - }] - }; - } - ); + // Note: These methods require function parameters and cannot be executed directly via MCP. + // They are primarily used within VS Code's automation test framework.` + // }] + // }; + // } + // ); } diff --git a/test/mcp/src/automationTools/quickAccess.ts b/test/mcp/src/automationTools/quickAccess.ts index 08961e1dc84..4592cc7e3be 100644 --- a/test/mcp/src/automationTools/quickAccess.ts +++ b/test/mcp/src/automationTools/quickAccess.ts @@ -49,40 +49,42 @@ export function applyQuickAccessTools(server: McpServer, app: Application) { } ); - server.tool( - 'vscode_automation_quick_input_type', - 'Type text into the currently open quick input', - { - text: z.string().describe('Text to type into quick input') - }, - async (args) => { - const { text } = args; - await app.workbench.quickinput.type(text); - return { - content: [{ - type: 'text' as const, - text: `Typed in quick input: "${text}"` - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_quick_input_type', + // 'Type text into the currently open quick input', + // { + // text: z.string().describe('Text to type into quick input') + // }, + // async (args) => { + // const { text } = args; + // await app.workbench.quickinput.type(text); + // return { + // content: [{ + // type: 'text' as const, + // text: `Typed in quick input: "${text}"` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_quick_input_select_item', - 'Select an item from the quick input list', - { - index: z.number().optional().describe('Index of item to select (0-based)'), - keepOpen: z.boolean().optional().describe('Keep quick input open after selection') - }, - async (args) => { - const { index = 0, keepOpen } = args; - await app.workbench.quickinput.selectQuickInputElement(index, keepOpen); - return { - content: [{ - type: 'text' as const, - text: `Selected quick input item at index ${index}` - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_quick_input_select_item', + // 'Select an item from the quick input list', + // { + // index: z.number().optional().describe('Index of item to select (0-based)'), + // keepOpen: z.boolean().optional().describe('Keep quick input open after selection') + // }, + // async (args) => { + // const { index = 0, keepOpen } = args; + // await app.workbench.quickinput.selectQuickInputElement(index, keepOpen); + // return { + // content: [{ + // type: 'text' as const, + // text: `Selected quick input item at index ${index}` + // }] + // }; + // } + // ); } diff --git a/test/mcp/src/automationTools/scm.ts b/test/mcp/src/automationTools/scm.ts index 81048837a42..39b90659168 100644 --- a/test/mcp/src/automationTools/scm.ts +++ b/test/mcp/src/automationTools/scm.ts @@ -11,106 +11,112 @@ import { z } from 'zod'; * Source Control Management (SCM) Tools */ export function applySCMTools(server: McpServer, app: Application) { - server.tool( - 'vscode_automation_scm_open', - 'Open the Source Control Management viewlet', - async () => { - await app.workbench.scm.openSCMViewlet(); - return { - content: [{ - type: 'text' as const, - text: 'Opened SCM viewlet' - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_scm_open', + // 'Open the Source Control Management viewlet', + // async () => { + // await app.workbench.scm.openSCMViewlet(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Opened SCM viewlet' + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_scm_wait_for_change', - 'Wait for a specific change to appear in SCM', - { - name: z.string().describe('Name of the file change to wait for'), - type: z.string().optional().describe('Type of change (optional)') - }, - async (args) => { - const { name, type } = args; - await app.workbench.scm.waitForChange(name, type); - return { - content: [{ - type: 'text' as const, - text: `Change detected: ${name}${type ? ` (${type})` : ''}` - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_scm_wait_for_change', + // 'Wait for a specific change to appear in SCM', + // { + // name: z.string().describe('Name of the file change to wait for'), + // type: z.string().optional().describe('Type of change (optional)') + // }, + // async (args) => { + // const { name, type } = args; + // await app.workbench.scm.waitForChange(name, type); + // return { + // content: [{ + // type: 'text' as const, + // text: `Change detected: ${name}${type ? ` (${type})` : ''}` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_scm_refresh', - 'Refresh the SCM viewlet', - async () => { - await app.workbench.scm.refreshSCMViewlet(); - return { - content: [{ - type: 'text' as const, - text: 'Refreshed SCM viewlet' - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_scm_refresh', + // 'Refresh the SCM viewlet', + // async () => { + // await app.workbench.scm.refreshSCMViewlet(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Refreshed SCM viewlet' + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_scm_open_change', - 'Open a specific change in the SCM viewlet', - { - name: z.string().describe('Name of the file change to open') - }, - async (args) => { - const { name } = args; - await app.workbench.scm.openChange(name); - return { - content: [{ - type: 'text' as const, - text: `Opened change: ${name}` - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_scm_open_change', + // 'Open a specific change in the SCM viewlet', + // { + // name: z.string().describe('Name of the file change to open') + // }, + // async (args) => { + // const { name } = args; + // await app.workbench.scm.openChange(name); + // return { + // content: [{ + // type: 'text' as const, + // text: `Opened change: ${name}` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_scm_stage', - 'Stage a specific file change', - { - name: z.string().describe('Name of the file to stage') - }, - async (args) => { - const { name } = args; - await app.workbench.scm.stage(name); - return { - content: [{ - type: 'text' as const, - text: `Staged file: ${name}` - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_scm_stage', + // 'Stage a specific file change', + // { + // name: z.string().describe('Name of the file to stage') + // }, + // async (args) => { + // const { name } = args; + // await app.workbench.scm.stage(name); + // return { + // content: [{ + // type: 'text' as const, + // text: `Staged file: ${name}` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_scm_unstage', - 'Unstage a specific file change', - { - name: z.string().describe('Name of the file to unstage') - }, - async (args) => { - const { name } = args; - await app.workbench.scm.unstage(name); - return { - content: [{ - type: 'text' as const, - text: `Unstaged file: ${name}` - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_scm_unstage', + // 'Unstage a specific file change', + // { + // name: z.string().describe('Name of the file to unstage') + // }, + // async (args) => { + // const { name } = args; + // await app.workbench.scm.unstage(name); + // return { + // content: [{ + // type: 'text' as const, + // text: `Unstaged file: ${name}` + // }] + // }; + // } + // ); server.tool( 'vscode_automation_scm_commit', diff --git a/test/mcp/src/automationTools/search.ts b/test/mcp/src/automationTools/search.ts index 5bf4366430d..5d92a2de84c 100644 --- a/test/mcp/src/automationTools/search.ts +++ b/test/mcp/src/automationTools/search.ts @@ -11,19 +11,20 @@ import { z } from 'zod'; * Search Tools */ export function applySearchTools(server: McpServer, app: Application) { - server.tool( - 'vscode_automation_search_open', - 'Open the search viewlet', - async () => { - await app.workbench.search.openSearchViewlet(); - return { - content: [{ - type: 'text' as const, - text: 'Opened search viewlet' - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_search_open', + // 'Open the search viewlet', + // async () => { + // await app.workbench.search.openSearchViewlet(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Opened search viewlet' + // }] + // }; + // } + // ); server.tool( 'vscode_automation_search_for_text', @@ -33,6 +34,7 @@ export function applySearchTools(server: McpServer, app: Application) { }, async (args) => { const { searchText } = args; + await app.workbench.search.openSearchViewlet(); await app.workbench.search.searchFor(searchText); return { content: [{ @@ -43,49 +45,52 @@ export function applySearchTools(server: McpServer, app: Application) { } ); - server.tool( - 'vscode_automation_search_set_files_to_include', - 'Set files to include in search', - { - pattern: z.string().describe('File pattern to include (e.g., "*.ts", "src/**")') - }, - async (args) => { - const { pattern } = args; - await app.workbench.search.setFilesToIncludeText(pattern); - return { - content: [{ - type: 'text' as const, - text: `Set files to include: "${pattern}"` - }] - }; - } - ); + // Seems too niche + // server.tool( + // 'vscode_automation_search_set_files_to_include', + // 'Set files to include in search', + // { + // pattern: z.string().describe('File pattern to include (e.g., "*.ts", "src/**")') + // }, + // async (args) => { + // const { pattern } = args; + // await app.workbench.search.setFilesToIncludeText(pattern); + // return { + // content: [{ + // type: 'text' as const, + // text: `Set files to include: "${pattern}"` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_search_submit', - 'Submit the current search', - async () => { - await app.workbench.search.submitSearch(); - return { - content: [{ - type: 'text' as const, - text: 'Submitted search' - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_search_submit', + // 'Submit the current search', + // async () => { + // await app.workbench.search.submitSearch(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Submitted search' + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_search_clear_results', - 'Clear search results', - async () => { - await app.workbench.search.clearSearchResults(); - return { - content: [{ - type: 'text' as const, - text: 'Cleared search results' - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_search_clear_results', + // 'Clear search results', + // async () => { + // await app.workbench.search.clearSearchResults(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Cleared search results' + // }] + // }; + // } + // ); } diff --git a/test/mcp/src/automationTools/settings.ts b/test/mcp/src/automationTools/settings.ts index 99a1cb41577..0cefde6889e 100644 --- a/test/mcp/src/automationTools/settings.ts +++ b/test/mcp/src/automationTools/settings.ts @@ -11,28 +11,29 @@ import { z } from 'zod'; * Settings Editor Tools */ export function applySettingsTools(server: McpServer, app: Application) { - server.tool( - 'vscode_automation_settings_add_user_setting', - 'Add a single user setting key-value pair', - { - setting: z.string().describe('Setting key (e.g., "editor.fontSize")'), - value: z.string().describe('Setting value (as JSON string)') - }, - async (args) => { - const { setting, value } = args; - await app.workbench.settingsEditor.addUserSetting(setting, value); - return { - content: [{ - type: 'text' as const, - text: `Added user setting: ${setting} = ${value}` - }] - }; - } - ); + // I don't think we need this and the batch version + // server.tool( + // 'vscode_automation_settings_add_user_setting', + // 'Add a single user setting key-value pair', + // { + // setting: z.string().describe('Setting key (e.g., "editor.fontSize")'), + // value: z.string().describe('Setting value (as JSON string)') + // }, + // async (args) => { + // const { setting, value } = args; + // await app.workbench.settingsEditor.addUserSetting(setting, value); + // return { + // content: [{ + // type: 'text' as const, + // text: `Added user setting: ${setting} = ${value}` + // }] + // }; + // } + // ); server.tool( 'vscode_automation_settings_add_user_settings', - 'Add multiple user settings at once for better performance', + 'Add multiple user settings at once', { settings: z.array(z.tuple([z.string(), z.string()])).describe('Array of [key, value] setting pairs') }, @@ -62,49 +63,52 @@ export function applySettingsTools(server: McpServer, app: Application) { } ); - server.tool( - 'vscode_automation_settings_open_user_file', - 'Open the user settings JSON file', - async () => { - await app.workbench.settingsEditor.openUserSettingsFile(); - return { - content: [{ - type: 'text' as const, - text: 'Opened user settings file' - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_settings_open_user_file', + // 'Open the user settings JSON file', + // async () => { + // await app.workbench.settingsEditor.openUserSettingsFile(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Opened user settings file' + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_settings_open_user_ui', - 'Open the user settings UI', - async () => { - await app.workbench.settingsEditor.openUserSettingsUI(); - return { - content: [{ - type: 'text' as const, - text: 'Opened user settings UI' - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_settings_open_user_ui', + // 'Open the user settings UI', + // async () => { + // await app.workbench.settingsEditor.openUserSettingsUI(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Opened user settings UI' + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_settings_search_ui', - 'Search for settings in the settings UI', - { - query: z.string().describe('Search query for settings') - }, - async (args) => { - const { query } = args; - await app.workbench.settingsEditor.searchSettingsUI(query); - return { - content: [{ - type: 'text' as const, - text: `Searched settings UI for: "${query}"` - }] - }; - } - ); + // Playwright can probably figure this one out + // server.tool( + // 'vscode_automation_settings_search_ui', + // 'Search for settings in the settings UI', + // { + // query: z.string().describe('Search query for settings') + // }, + // async (args) => { + // const { query } = args; + // await app.workbench.settingsEditor.searchSettingsUI(query); + // return { + // content: [{ + // type: 'text' as const, + // text: `Searched settings UI for: "${query}"` + // }] + // }; + // } + // ); } diff --git a/test/mcp/src/automationTools/statusbar.ts b/test/mcp/src/automationTools/statusbar.ts index 8094f4c632e..96ac1085acf 100644 --- a/test/mcp/src/automationTools/statusbar.ts +++ b/test/mcp/src/automationTools/statusbar.ts @@ -5,124 +5,127 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { Application } from '../../../automation'; -import { z } from 'zod'; /** * Status Bar Tools */ export function applyStatusBarTools(server: McpServer, app: Application) { - server.tool( - 'vscode_automation_statusbar_wait_for_element', - 'Wait for a specific status bar element to appear', - { - element: z.enum([ - 'BRANCH_STATUS', - 'SYNC_STATUS', - 'PROBLEMS_STATUS', - 'SELECTION_STATUS', - 'INDENTATION_STATUS', - 'ENCODING_STATUS', - 'EOL_STATUS', - 'LANGUAGE_STATUS' - ]).describe('Status bar element to wait for') - }, - async (args) => { - const { element } = args; - // Map string to enum value - const elementMap: Record = { - 'BRANCH_STATUS': 0, - 'SYNC_STATUS': 1, - 'PROBLEMS_STATUS': 2, - 'SELECTION_STATUS': 3, - 'INDENTATION_STATUS': 4, - 'ENCODING_STATUS': 5, - 'EOL_STATUS': 6, - 'LANGUAGE_STATUS': 7 - }; + // Seems too niche + // server.tool( + // 'vscode_automation_statusbar_wait_for_element', + // 'Wait for a specific status bar element to appear', + // { + // element: z.enum([ + // 'BRANCH_STATUS', + // 'SYNC_STATUS', + // 'PROBLEMS_STATUS', + // 'SELECTION_STATUS', + // 'INDENTATION_STATUS', + // 'ENCODING_STATUS', + // 'EOL_STATUS', + // 'LANGUAGE_STATUS' + // ]).describe('Status bar element to wait for') + // }, + // async (args) => { + // const { element } = args; + // // Map string to enum value + // const elementMap: Record = { + // 'BRANCH_STATUS': 0, + // 'SYNC_STATUS': 1, + // 'PROBLEMS_STATUS': 2, + // 'SELECTION_STATUS': 3, + // 'INDENTATION_STATUS': 4, + // 'ENCODING_STATUS': 5, + // 'EOL_STATUS': 6, + // 'LANGUAGE_STATUS': 7 + // }; - await app.workbench.statusbar.waitForStatusbarElement(elementMap[element]); - return { - content: [{ - type: 'text' as const, - text: `Status bar element found: ${element}` - }] - }; - } - ); + // await app.workbench.statusbar.waitForStatusbarElement(elementMap[element]); + // return { + // content: [{ + // type: 'text' as const, + // text: `Status bar element found: ${element}` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_statusbar_click', - 'Click on a specific status bar element', - { - element: z.enum([ - 'BRANCH_STATUS', - 'SYNC_STATUS', - 'PROBLEMS_STATUS', - 'SELECTION_STATUS', - 'INDENTATION_STATUS', - 'ENCODING_STATUS', - 'EOL_STATUS', - 'LANGUAGE_STATUS' - ]).describe('Status bar element to click') - }, - async (args) => { - const { element } = args; - // Map string to enum value - const elementMap: Record = { - 'BRANCH_STATUS': 0, - 'SYNC_STATUS': 1, - 'PROBLEMS_STATUS': 2, - 'SELECTION_STATUS': 3, - 'INDENTATION_STATUS': 4, - 'ENCODING_STATUS': 5, - 'EOL_STATUS': 6, - 'LANGUAGE_STATUS': 7 - }; + // Playwright can probably figure this out + // server.tool( + // 'vscode_automation_statusbar_click', + // 'Click on a specific status bar element', + // { + // element: z.enum([ + // 'BRANCH_STATUS', + // 'SYNC_STATUS', + // 'PROBLEMS_STATUS', + // 'SELECTION_STATUS', + // 'INDENTATION_STATUS', + // 'ENCODING_STATUS', + // 'EOL_STATUS', + // 'LANGUAGE_STATUS' + // ]).describe('Status bar element to click') + // }, + // async (args) => { + // const { element } = args; + // // Map string to enum value + // const elementMap: Record = { + // 'BRANCH_STATUS': 0, + // 'SYNC_STATUS': 1, + // 'PROBLEMS_STATUS': 2, + // 'SELECTION_STATUS': 3, + // 'INDENTATION_STATUS': 4, + // 'ENCODING_STATUS': 5, + // 'EOL_STATUS': 6, + // 'LANGUAGE_STATUS': 7 + // }; - await app.workbench.statusbar.clickOn(elementMap[element]); - return { - content: [{ - type: 'text' as const, - text: `Clicked status bar element: ${element}` - }] - }; - } - ); + // await app.workbench.statusbar.clickOn(elementMap[element]); + // return { + // content: [{ + // type: 'text' as const, + // text: `Clicked status bar element: ${element}` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_statusbar_wait_for_eol', - 'Wait for a specific End of Line (EOL) type in the status bar', - { - eol: z.string().describe('EOL type to wait for (e.g., "LF", "CRLF")') - }, - async (args) => { - const { eol } = args; - const result = await app.workbench.statusbar.waitForEOL(eol); - return { - content: [{ - type: 'text' as const, - text: `EOL status found: ${result}` - }] - }; - } - ); + // Seems too niche + // server.tool( + // 'vscode_automation_statusbar_wait_for_eol', + // 'Wait for a specific End of Line (EOL) type in the status bar', + // { + // eol: z.string().describe('EOL type to wait for (e.g., "LF", "CRLF")') + // }, + // async (args) => { + // const { eol } = args; + // const result = await app.workbench.statusbar.waitForEOL(eol); + // return { + // content: [{ + // type: 'text' as const, + // text: `EOL status found: ${result}` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_statusbar_wait_for_text', - 'Wait for specific text to appear in a status bar element', - { - title: z.string().describe('Title/identifier of the status bar element'), - text: z.string().describe('Text to wait for in the status bar element') - }, - async (args) => { - const { title, text } = args; - await app.workbench.statusbar.waitForStatusbarText(title, text); - return { - content: [{ - type: 'text' as const, - text: `Status bar text found - ${title}: "${text}"` - }] - }; - } - ); + // Playwright can probably figure this out + // server.tool( + // 'vscode_automation_statusbar_wait_for_text', + // 'Wait for specific text to appear in a status bar element', + // { + // title: z.string().describe('Title/identifier of the status bar element'), + // text: z.string().describe('Text to wait for in the status bar element') + // }, + // async (args) => { + // const { title, text } = args; + // await app.workbench.statusbar.waitForStatusbarText(title, text); + // return { + // content: [{ + // type: 'text' as const, + // text: `Status bar text found - ${title}: "${text}"` + // }] + // }; + // } + // ); } diff --git a/test/mcp/src/automationTools/task.ts b/test/mcp/src/automationTools/task.ts index bce14f62838..eceabc153ca 100644 --- a/test/mcp/src/automationTools/task.ts +++ b/test/mcp/src/automationTools/task.ts @@ -11,38 +11,39 @@ import { z } from 'zod'; * Task Tools */ export function applyTaskTools(server: McpServer, app: Application) { - server.tool( - 'vscode_automation_task_assert_tasks', - 'Assert that specific tasks exist with given properties', - { - filter: z.string().describe('Filter string for tasks'), - expected: z.array(z.object({ - label: z.string().optional(), - type: z.string().optional(), - command: z.string().optional(), - identifier: z.string().optional(), - group: z.string().optional(), - isBackground: z.boolean().optional(), - promptOnClose: z.boolean().optional(), - icon: z.object({ - id: z.string().optional(), - color: z.string().optional() - }).optional(), - hide: z.boolean().optional() - })).describe('Array of expected task properties'), - type: z.enum(['run', 'configure']).describe('Type of task operation') - }, - async (args) => { - const { filter, expected, type } = args; - await app.workbench.task.assertTasks(filter, expected, type); - return { - content: [{ - type: 'text' as const, - text: `Asserted ${expected.length} tasks for ${type} with filter: "${filter}"` - }] - }; - } - ); + // Seems too niche + // server.tool( + // 'vscode_automation_task_assert_tasks', + // 'Assert that specific tasks exist with given properties', + // { + // filter: z.string().describe('Filter string for tasks'), + // expected: z.array(z.object({ + // label: z.string().optional(), + // type: z.string().optional(), + // command: z.string().optional(), + // identifier: z.string().optional(), + // group: z.string().optional(), + // isBackground: z.boolean().optional(), + // promptOnClose: z.boolean().optional(), + // icon: z.object({ + // id: z.string().optional(), + // color: z.string().optional() + // }).optional(), + // hide: z.boolean().optional() + // })).describe('Array of expected task properties'), + // type: z.enum(['run', 'configure']).describe('Type of task operation') + // }, + // async (args) => { + // const { filter, expected, type } = args; + // await app.workbench.task.assertTasks(filter, expected, type); + // return { + // content: [{ + // type: 'text' as const, + // text: `Asserted ${expected.length} tasks for ${type} with filter: "${filter}"` + // }] + // }; + // } + // ); server.tool( 'vscode_automation_task_configure', diff --git a/test/mcp/src/automationTools/terminal.ts b/test/mcp/src/automationTools/terminal.ts index 77c8577703a..b16e922d95e 100644 --- a/test/mcp/src/automationTools/terminal.ts +++ b/test/mcp/src/automationTools/terminal.ts @@ -48,28 +48,29 @@ export function applyTerminalTools(server: McpServer, app: Application) { } ); - server.tool( - 'vscode_automation_terminal_wait_for_text', - 'Wait for specific text to appear in terminal output', - { - acceptFunction: z.string().describe('JavaScript function body that takes buffer array and returns boolean'), - message: z.string().optional().describe('Optional message for waiting'), - splitIndex: z.number().optional().describe('Split terminal index (0 or 1)') - }, - async (args) => { - const { acceptFunction, message, splitIndex } = args; - // Create function from string - const acceptFn = new Function('buffer', acceptFunction) as (buffer: string[]) => boolean; - const terminalSplitIndex = splitIndex === 0 ? 0 : splitIndex === 1 ? 1 : undefined; - await app.workbench.terminal.waitForTerminalText(acceptFn, message, terminalSplitIndex); - return { - content: [{ - type: 'text' as const, - text: `Terminal text condition met: ${message || 'custom condition'}` - }] - }; - } - ); + // Playwright can probably figure this out + // server.tool( + // 'vscode_automation_terminal_wait_for_text', + // 'Wait for specific text to appear in terminal output', + // { + // acceptFunction: z.string().describe('JavaScript function body that takes buffer array and returns boolean'), + // message: z.string().optional().describe('Optional message for waiting'), + // splitIndex: z.number().optional().describe('Split terminal index (0 or 1)') + // }, + // async (args) => { + // const { acceptFunction, message, splitIndex } = args; + // // Create function from string + // const acceptFn = new Function('buffer', acceptFunction) as (buffer: string[]) => boolean; + // const terminalSplitIndex = splitIndex === 0 ? 0 : splitIndex === 1 ? 1 : undefined; + // await app.workbench.terminal.waitForTerminalText(acceptFn, message, terminalSplitIndex); + // return { + // content: [{ + // type: 'text' as const, + // text: `Terminal text condition met: ${message || 'custom condition'}` + // }] + // }; + // } + // ); server.tool( 'vscode_automation_terminal_get_groups', @@ -85,50 +86,52 @@ export function applyTerminalTools(server: McpServer, app: Application) { } ); - server.tool( - 'vscode_automation_terminal_run_command_by_id', - 'Run a terminal command by ID', - { - commandId: z.enum([ - 'workbench.action.terminal.split', - 'workbench.action.terminal.killAll', - 'workbench.action.terminal.unsplit', - 'workbench.action.terminal.join', - 'workbench.action.terminal.toggleTerminal', - 'workbench.action.createTerminalEditor', - 'workbench.action.createTerminalEditorSide', - 'workbench.action.terminal.moveToTerminalPanel', - 'workbench.action.terminal.moveToEditor', - 'workbench.action.terminal.newWithProfile', - 'workbench.action.terminal.selectDefaultShell', - 'workbench.action.terminal.detachSession', - 'workbench.action.terminal.new' - ]).describe('Terminal command ID to execute'), - expectedLocation: z.enum(['editor', 'panel']).optional().describe('Expected location after command') - }, - async (args) => { - const { commandId, expectedLocation } = args; - await app.workbench.terminal.runCommand(commandId as any, expectedLocation); - return { - content: [{ - type: 'text' as const, - text: `Executed terminal command: ${commandId}` - }] - }; - } - ); + // Seems too niche and redundant with runCommand tool + // server.tool( + // 'vscode_automation_terminal_run_command_by_id', + // 'Run a terminal command by ID', + // { + // commandId: z.enum([ + // 'workbench.action.terminal.split', + // 'workbench.action.terminal.killAll', + // 'workbench.action.terminal.unsplit', + // 'workbench.action.terminal.join', + // 'workbench.action.terminal.toggleTerminal', + // 'workbench.action.createTerminalEditor', + // 'workbench.action.createTerminalEditorSide', + // 'workbench.action.terminal.moveToTerminalPanel', + // 'workbench.action.terminal.moveToEditor', + // 'workbench.action.terminal.newWithProfile', + // 'workbench.action.terminal.selectDefaultShell', + // 'workbench.action.terminal.detachSession', + // 'workbench.action.terminal.new' + // ]).describe('Terminal command ID to execute'), + // expectedLocation: z.enum(['editor', 'panel']).optional().describe('Expected location after command') + // }, + // async (args) => { + // const { commandId, expectedLocation } = args; + // await app.workbench.terminal.runCommand(commandId as any, expectedLocation); + // return { + // content: [{ + // type: 'text' as const, + // text: `Executed terminal command: ${commandId}` + // }] + // }; + // } + // ); - server.tool( - 'vscode_automation_terminal_split', - 'Split the current terminal', - async () => { - await app.workbench.terminal.clickSplitButton(); - return { - content: [{ - type: 'text' as const, - text: 'Split terminal' - }] - }; - } - ); + // Playwright can probably figure this out + // server.tool( + // 'vscode_automation_terminal_split', + // 'Split the current terminal', + // async () => { + // await app.workbench.terminal.clickSplitButton(); + // return { + // content: [{ + // type: 'text' as const, + // text: 'Split terminal' + // }] + // }; + // } + // ); } diff --git a/test/mcp/src/stdio.ts b/test/mcp/src/stdio.ts index fec36847aa2..97387ad449e 100644 --- a/test/mcp/src/stdio.ts +++ b/test/mcp/src/stdio.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; -import { getServer } from './playwright'; +import { getServer } from './multiplex'; const transport: StdioServerTransport = new StdioServerTransport(); (async () => {