diff --git a/mcp-servers/mcp-server-vscode/out/extension.js b/mcp-servers/mcp-server-vscode/out/extension.js index 4681ef9ae..a5437fb13 100644 --- a/mcp-servers/mcp-server-vscode/out/extension.js +++ b/mcp-servers/mcp-server-vscode/out/extension.js @@ -10,6 +10,7 @@ import packageJson from '../package.json'; import { codeCheckerTool } from './tools/code_checker'; import { listDebugSessions, listDebugSessionsSchema, startDebugSession, startDebugSessionSchema, stopDebugSession, stopDebugSessionSchema, } from './tools/debug_tools'; import { focusEditorTool } from './tools/focus_editor'; +import { closeTerminal, closeTerminalSchema, createTerminal, createTerminalSchema, listTerminals, listTerminalsSchema, sendTerminalText, sendTerminalTextSchema, } from './tools/terminal_tools'; import { resolvePort } from './utils/port'; const extensionName = 'vscode-mcp-server'; const extensionDisplayName = 'VSCode MCP Server'; @@ -97,6 +98,49 @@ export const activate = async (context) => { })), }; }); + mcpServer.tool('create_terminal', dedent ` + Create a new integrated terminal in the VSCode workspace. + Optionally set a name, working directory, and an initial command to execute. + `.trim(), createTerminalSchema.shape, async (params) => { + const result = await createTerminal(params); + return { + ...result, + content: result.content.map((item) => ({ + ...item, + type: 'text', + })), + }; + }); + mcpServer.tool('list_terminals', 'List all active terminals in the workspace.', listTerminalsSchema.shape, async () => { + const result = listTerminals(); + return { + ...result, + content: result.content.map((item) => ({ type: 'text', text: JSON.stringify(item.json) })), + }; + }); + mcpServer.tool('send_terminal_text', dedent ` + Send text to an existing terminal by name. + Use this to execute commands or type input in a terminal that was previously created. + `.trim(), sendTerminalTextSchema.shape, async (params) => { + const result = await sendTerminalText(params); + return { + ...result, + content: result.content.map((item) => ({ + ...item, + type: 'text', + })), + }; + }); + mcpServer.tool('close_terminal', 'Close an active terminal by name.', closeTerminalSchema.shape, async (params) => { + const result = await closeTerminal(params); + return { + ...result, + content: result.content.map((item) => ({ + ...item, + type: 'text', + })), + }; + }); const app = express(); const mcpConfig = vscode.workspace.getConfiguration('mcpServer'); const port = await resolvePort(mcpConfig.get('port', 6010)); @@ -198,4 +242,4 @@ export const activate = async (context) => { }; export function deactivate() { } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5zaW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2V4dGVuc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDcEUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDN0UsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBQzVCLE9BQU8sT0FBOEIsTUFBTSxTQUFTLENBQUM7QUFDckQsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxLQUFLLE1BQU0sTUFBTSxRQUFRLENBQUM7QUFDakMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQzVDLE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFDeEIsT0FBTyxXQUFXLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3ZELE9BQU8sRUFDSCxpQkFBaUIsRUFDakIsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQix1QkFBdUIsRUFDdkIsZ0JBQWdCLEVBQ2hCLHNCQUFzQixHQUN6QixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRTNDLE1BQU0sYUFBYSxHQUFHLG1CQUFtQixDQUFDO0FBQzFDLE1BQU0sb0JBQW9CLEdBQUcsbUJBQW1CLENBQUM7QUFFakQsTUFBTSxDQUFDLE1BQU0sUUFBUSxHQUFHLEtBQUssRUFBRSxPQUFnQyxFQUFFLEVBQUU7SUFFL0QsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBRzlFLGFBQWEsQ0FBQyxVQUFV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ZXIgfSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3NlcnZlci9tY3AuanMnO1xuaW1wb3J0IHsgU1NFU2VydmVyVHJhbnNwb3J0IH0gZnJvbSAnQG1vZGVsY29udGV4dHByb3RvY29sL3Nkay9zZXJ2ZXIvc3NlLmpzJztcbmltcG9ydCBkZWRlbnQgZnJvbSAnZGVkZW50JztcbmltcG9ydCBleHByZXNzLCB7IFJlcXVlc3QsIFJlc3BvbnNlIH0gZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgKiBhcyBodHRwIGZyb20gJ2h0dHAnO1xuaW1wb3J0ICogYXMgdnNjb2RlIGZyb20gJ3ZzY29kZSc7XG5pbXBvcnQgeyBEaWFnbm9zdGljU2V2ZXJpdHkgfSBmcm9tICd2c2NvZGUnO1xuaW1wb3J0IHsgeiB9IGZyb20gJ3pvZCc7XG5pbXBvcnQgcGFja2FnZUpzb24gZnJvbSAnLi4vcGFja2FnZS5qc29uJztcbmltcG9ydCB7IGNvZGVDaGVja2VyVG9vbCB9IGZyb20gJy4vdG9vbHMvY29kZV9jaGVja2VyJztcbmltcG9ydCB7XG4gICAgbGlzdERlYnVnU2Vzc2lvbnMsXG4gICAgbGlzdERlYnVnU2Vzc2lvbnNTY2hlbWEsXG4gICAgc3RhcnREZWJ1Z1Nlc3Npb24sXG4gICAgc3RhcnREZWJ1Z1Nlc3Npb25TY2hlbWEsXG4gICAgc3RvcERlYnVnU2Vzc2lvbixcbiAgICBzdG9wRGVidWdTZXNzaW9uU2NoZW1hLFxufSBmcm9tICcuL3Rvb2xzL2RlYnVnX3Rvb2xzJztcbmltcG9ydCB7IGZvY3VzRWRpdG9yVG9vbCB9IGZyb20gJy4vdG9vbHMvZm9jdXNfZWRpdG9yJztcbmltcG9ydCB7IHJlc29sdmVQb3J0IH0gZnJvbSAnLi91dGlscy9wb3J0JztcblxuY29uc3QgZXh0ZW5zaW9uTmFtZSA9ICd2c2NvZGUtbWNwLXNlcnZlcic7XG5jb25zdCBleHRlbnNpb25EaXNwbGF5TmFtZSA9ICdWU0NvZGUgTUNQIFNlcnZlcic7XG5cbmV4cG9ydCBjb25zdCBhY3RpdmF0ZSA9IGFzeW5jIChjb250ZXh0OiB2c2NvZGUuRXh0ZW5zaW9uQ29udGV4dCkgPT4ge1xuICAgIC8vIENyZWF0ZSB0aGUgb3V0cHV0IGNoYW5uZWwgZm9yIGxvZ2dpbmdcbiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gdnNjb2RlLndpbmRvdy5jcmVhdGVPdXRwdXRDaGFubmVsKGV4dGVuc2lvbkRpc3BsYXlOYW1lKTtcblxuICAgIC8vIFdyaXRlIGFuIGluaXRpYWwgbWVzc2FnZSB0byBlbnN1cmUgdGhlIGNoYW5uZWwgYXBwZWFycyBpbiB0aGUgT3V0cHV0IGRyb3Bkb3duXG4gICAgb3V0cHV0Q2hhbm5lbC5hcHBlbmRMaW5lKGBBY3RpdmF0aW5nICR7ZXh0ZW5zaW9uRGlzcGxheU5hbWV9Li4uYCk7XG4gICAgLy8gVW5jb21tZW50IHRvIGF1dG9tYXRpY2FsbHkgc3dpdGNoIHRvIHRoZSBvdXRwdXQgdGFiIGFuZCB0aGlzIGV4dGVuc2lvbiBjaGFubmVsIG9uIGFjdGl2YXRpb25cbiAgICAvLyBvdXRwdXRDaGFubmVsLnNob3coKTtcblxuICAgIC8vIEluaXRpYWxpemUgdGhlIE1DUCBzZXJ2ZXIgaW5zdGFuY2VcbiAgICBjb25zdCBtY3BTZXJ2ZXIgPSBuZXcgTWNwU2VydmVyKHtcbiAgICAgICAgbmFtZTogZXh0ZW5zaW9uTmFtZSxcbiAgICAgICAgdmVyc2lvbjogcGFja2FnZUpzb24udmVyc2lvbixcbiAgICB9KTtcblxuICAgIC8vIFJlZ2lzdGVyIHRoZSBcImNvZGVfY2hlY2tlclwiIHRvb2wuXG4gICAgLy8gVGhpcyB0b29sIHJldHJpZXZlcyBkaWFnbm9zdGljcyBmcm9tIFZTQ29kZSdzIGxhbmd1YWdlIHNlcnZpY2VzLFxuICAgIC8vIGZpbHRlcmluZyBvdXQgZmlsZXMgd2l0aG91dCBpc3N1ZXMuXG4gICAgbWNwU2VydmVyLnRvb2woXG4gICAgICAgICdjb2RlX2NoZWNrZXInLFxuICAgICAgICBkZWRlbnRgXG4gICAgICAgICAgICBSZXRyaWV2ZSBkaWFnbm9zdGljcyBmcm9tIFZTQ29kZSdzIGxhbmd1YWdlIHNlcnZpY2VzIGZvciB0aGUgYWN0aXZlIHdvcmtzcGFjZS5cbiAgICAgICAgICAgIFVzZSB0aGlzIHRvb2wgYWZ0ZXIgbWFraW5nIGNoYW5nZXMgdG8gYW55IGNvZGUgaW4gdGhlIGZpbGVzeXN0ZW0gdG8gZW5zdXJlIG5vIG5ld1xuICAgICAgICAgICAgZXJyb3JzIHdlcmUgaW50cm9kdWNlZCwgb3Igd2hlbiByZXF1ZXN0ZWQgYnkgdGhlIHVzZXIuXG4gICAgICAgIGAudHJpbSgpLFxuICAgICAgICAvLyBQYXNzaW5nIHRoZSByYXcgc2hhcGUgb2JqZWN0IGRpcmVjdGx5XG4gICAgICAgIHtcbiAgICAgICAgICAgIHNldmVyaXR5TGV2ZWw6IHpcbiAgICAgICAgICAgICAgICAuZW51bShbJ0Vycm9yJywgJ1dhcm5pbmcnLCAnSW5mb3JtYXRpb24nLCAnSGludCddKVxuICAgICAgICAgICAgICAgIC5kZWZhdWx0KCdXYXJuaW5nJylcbiAgICAgICAgICAgICAgICAuZGVzY3JpYmUoXCJNaW5pbXVtIHNldmVyaXR5IGxldmVsIGZvciBjaGVja2luZyBpc3N1ZXM6ICdFcnJvcicsICdXYXJuaW5nJywgJ0luZm9ybWF0aW9uJywgb3IgJ0hpbnQnLlwiKSxcbiAgICAgICAgfSxcbiAgICAgICAgYXN5bmMgKHBhcmFtczogeyBzZXZlcml0eUxldmVsPzogJ0Vycm9yJyB8ICdXYXJuaW5nJyB8ICdJbmZvcm1hdGlvbicgfCAnSGludCcgfSkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc2V2ZXJpdHlMZXZlbCA9IHBhcmFtcy5zZXZlcml0eUxldmVsXG4gICAgICAgICAgICAgICAgPyBEaWFnbm9zdGljU2V2ZXJpdHlbcGFyYW1zLnNldmVyaXR5TGV2ZWxdXG4gICAgICAgICAgICAgICAgOiBEaWFnbm9zdGljU2V2ZXJpdHkuV2FybmluZztcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvZGVDaGVja2VyVG9vbChzZXZlcml0eUxldmVsKTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgLi4ucmVzdWx0LFxuICAgICAgICAgICAgICAgIGNvbnRlbnQ6IHJlc3VsdC5jb250ZW50Lm1hcCgoYykgPT4gKHtcbiAgICAgICAgICAgICAgICAgICAgLi4uYyxcbiAgICAgICAgICAgICAgICAgICAgdGV4dDogdHlwZW9mIGMudGV4dCA9PT0gJ3N0cmluZycgPyBjLnRleHQgOiBTdHJpbmcoYy50ZXh0KSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0sXG4gICAgKTtcblxuICAgIC8vIFJlZ2lzdGVyICdmb2N1c19lZGl0b3InIHRvb2xcbiAgICBtY3BTZXJ2ZXIudG9vbChcbiAgICAgICAgJ2ZvY3VzX2VkaXRvcicsXG4gICAgICAgIGRlZGVudGBcbiAgICAgICAgT3BlbiB0aGUgc3BlY2lmaWVkIGZpbGUgaW4gdGhlIFZTQ29kZSBlZGl0b3IgYW5kIG5hdmlnYXRlIHRvIGEgc3BlY2lmaWMgbGluZSBhbmQgY29sdW1uLlxuICAgICAgICBVc2UgdGhpcyB0b29sIHRvIGJyaW5nIGEgZmlsZSBpbnRvIGZvY3VzIGFuZCBwb3NpdGlvbiB0aGUgZWRpdG9yJ3MgY3Vyc29yIHdoZXJlIGRlc2lyZWQuXG4gICAgICAgIE5vdGU6IFRoaXMgdG9vbCBvcGVyYXRlcyBvbiB0aGUgZWRpdG9yIHZpc3VhbCBlbnZpcm9ubWVudCBzbyB0aGF0IHRoZSB1c2VyIGNhbiBzZWUgdGhlIGZpbGUuIEl0IGRvZXMgbm90IHJldHVybiB0aGUgZmlsZSBjb250ZW50cyBpbiB0aGUgdG9vbCBjYWxsIHJlc3VsdC5cbiAgICAgICAgYC50cmltKCksXG4gICAgICAgIHtcbiAgICAgICAgICAgIGZpbGVQYXRoOiB6LnN0cmluZygpLmRlc2NyaWJlKCdUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgZmlsZSB0byBmb2N1cyBpbiB0aGUgZWRpdG9yLicpLFxuICAgICAgICAgICAgbGluZTogei5udW1iZXIoKS5pbnQoKS5taW4oMCkuZGVmYXVsdCgwKS5kZXNjcmliZSgnVGhlIGxpbmUgbnVtYmVyIHRvIG5hdmlnYXRlIHRvIChkZWZhdWx0OiAwKS4nKSxcbiAgICAgICAgICAgIGNvbHVtbjogei5udW1iZXIoKS5pbnQoKS5taW4oMCkuZGVmYXVsdCgwKS5kZXNjcmliZSgnVGhlIGNvbHVtbiBwb3NpdGlvbiB0byBuYXZpZ2F0ZSB0byAoZGVmYXVsdDogMCkuJyksXG4gICAgICAgICAgICBzdGFydExpbmU6IHoubnVtYmVyKCkuaW50KCkubWluKDApLm9wdGlvbmFsKCkuZGVzY3JpYmUoJ1RoZSBzdGFydGluZyBsaW5lIG51bWJlciBmb3IgaGlnaGxpZ2h0aW5nLicpLFxuICAgICAgICAgICAgc3RhcnRDb2x1bW46IHoubnVtYmVyKCkuaW50KCkubWluKDApLm9wdGlvbmFsKCkuZGVzY3JpYmUoJ1RoZSBzdGFydGluZyBjb2x1bW4gbnVtYmVyIGZvciBoaWdobGlnaHRpbmcuJyksXG4gICAgICAgICAgICBlbmRMaW5lOiB6Lm51bWJlcigpLmludCgpLm1pbigwKS5vcHRpb25hbCgpLmRlc2NyaWJlKCdUaGUgZW5kaW5nIGxpbmUgbnVtYmVyIGZvciBoaWdobGlnaHRpbmcuJyksXG4gICAgICAgICAgICBlbmRDb2x1bW46IHoubnVtYmVyKCkuaW50KCkubWluKDApLm9wdGlvbmFsKCkuZGVzY3JpYmUoJ1RoZSBlbmRpbmcgY29sdW1uIG51bWJlciBmb3IgaGlnaGxpZ2h0aW5nLicpLFxuICAgICAgICB9LFxuICAgICAgICBhc3luYyAocGFyYW1zOiB7IGZpbGVQYXRoOiBzdHJpbmc7IGxpbmU/OiBudW1iZXI7IGNvbHVtbj86IG51bWJlciB9KSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBmb2N1c0VkaXRvclRvb2wocGFyYW1zKTtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0sXG4gICAgKTtcblxuICAgIC8vIEZJWE1FOiBUaGlzIGRvZXNuJ3QgcmV0dXJuIHJlc3VsdHMgeWV0XG4gICAgLy8gLy8gUmVnaXN0ZXIgJ3NlYXJjaF9zeW1ib2wnIHRvb2xcbiAgICAvLyBtY3BTZXJ2ZXIudG9vbChcbiAgICAvLyAgICAgJ3NlYXJjaF9zeW1ib2wnLFxuICAgIC8vICAgICBkZWRlbnRgXG4gICAgLy8gICAgIFNlYXJjaCBmb3IgYSBzeW1ib2wgd2l0aGluIHRoZSB3b3Jrc3BhY2UuXG4gICAgLy8gICAgIC0gVHJpZXMgdG8gcmVzb2x2ZSB0aGUgZGVmaW5pdGlvbiB2aWEgVlNDb2Rl4oCZcyBcIkdvIHRvIERlZmluaXRpb25cIi5cbiAgICAvLyAgICAgLSBJZiBub3QgZm91bmQsIHNlYXJjaGVzIHRoZSBlbnRpcmUgd29ya3NwYWNlIGZvciB0aGUgdGV4dCwgc2ltaWxhciB0byBDdHJsK1NoaWZ0K0YuXG4gICAgLy8gICAgIGAudHJpbSgpLFxuICAgIC8vICAgICB7XG4gICAgLy8gICAgICAgICBxdWVyeTogei5zdHJpbmcoKS5kZXNjcmliZSgnVGhlIHN5bWJvbCBvciB0ZXh0IHRvIHNlYXJjaCBmb3IuJyksXG4gICAgLy8gICAgICAgICB1c2VEZWZpbml0aW9uOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLmRlc2NyaWJlKFwiV2hldGhlciB0byB1c2UgJ0dvIHRvIERlZmluaXRpb24nIGFzIHRoZSBmaXJzdCBtZXRob2QuXCIpLFxuICAgIC8vICAgICAgICAgbWF4UmVzdWx0czogei5udW1iZXIoKS5kZWZhdWx0KDUwKS5kZXNjcmliZSgnTWF4aW11bSBudW1iZXIgb2YgZ2xvYmFsIHNlYXJjaCByZXN1bHRzIHRvIHJldHVybi4nKSxcbiAgICAvLyAgICAgICAgIG9wZW5GaWxlOiB6LmJvb2xlYW4oKS5kZWZhdWx0KGZhbHNlKS5kZXNjcmliZSgnV2hldGhlciB0byBvcGVuIHRoZSBmb3VuZCBmaWxlIGluIHRoZSBlZGl0b3IuJyksXG4gICAgLy8gICAgIH0sXG4gICAgLy8gICAgIGFzeW5jIChwYXJhbXM6IHsgcXVlcnk6IHN0cmluZzsgdXNlRGVmaW5pdGlvbj86IGJvb2xlYW47IG1heFJlc3VsdHM/OiBudW1iZXI7IG9wZW5GaWxlPzogYm9vbGVhbiB9KSA9PiB7XG4gICAgLy8gICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzZWFyY2hTeW1ib2xUb29sKHBhcmFtcyk7XG4gICAgLy8gICAgICAgICByZXR1cm4ge1xuICAgIC8vICAgICAgICAgICAgIC4uLnJlc3VsdCxcbiAgICAvLyAgICAgICAgICAgICBjb250ZW50OiBbXG4gICAgLy8gICAgICAgICAgICAgICAgIHtcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIHRleHQ6IEpTT04uc3RyaW5naWZ5KHJlc3VsdCksXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgLy8gICAgICAgICAgICAgICAgIH0sXG4gICAgLy8gICAgICAgICAgICAgXSxcbiAgICAvLyAgICAgICAgIH07XG4gICAgLy8gICAgIH0sXG4gICAgLy8gKTtcblxuICAgIC8vIFJlZ2lzdGVyICdsaXN0X2RlYnVnX3Nlc3Npb25zJyB0b29sXG4gICAgbWNwU2VydmVyLnRvb2woXG4gICAgICAgICdsaXN0X2RlYnVnX3Nlc3Npb25zJyxcbiAgICAgICAgJ0xpc3QgYWxsIGFjdGl2ZSBkZWJ1ZyBzZXNzaW9ucyBpbiB0aGUgd29ya3NwYWNlLicsXG4gICAgICAgIGxpc3REZWJ1Z1Nlc3Npb25zU2NoZW1hLnNoYXBlLCAvLyBObyBwYXJhbWV0ZXJzIHJlcXVpcmVkXG4gICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGxpc3REZWJ1Z1Nlc3Npb25zKCk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIC4uLnJlc3VsdCxcbiAgICAgICAgICAgICAgICBjb250ZW50OiByZXN1bHQuY29udGVudC5tYXAoKGl0ZW0pID0+ICh7IHR5cGU6ICd0ZXh0JywgdGV4dDogSlNPTi5zdHJpbmdpZnkoaXRlbS5qc29uKSB9KSksXG4gICAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICk7XG5cbiAgICAvLyBSZWdpc3RlciAnc3RhcnRfZGVidWdfc2Vzc2lvbicgdG9vbFxuICAgIG1jcFNlcnZlci50b29sKFxuICAgICAgICAnc3RhcnRfZGVidWdfc2Vzc2lvbicsXG4gICAgICAgICdTdGFydCBhIG5ldyBkZWJ1ZyBzZXNzaW9uIHdpdGggdGhlIHByb3ZpZGVkIGNvbmZpZ3VyYXRpb24uJyxcbiAgICAgICAgc3RhcnREZWJ1Z1Nlc3Npb25TY2hlbWEuc2hhcGUsXG4gICAgICAgIGFzeW5jIChwYXJhbXMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0YXJ0RGVidWdTZXNzaW9uKHBhcmFtcyk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIC4uLnJlc3VsdCxcbiAgICAgICAgICAgICAgICBjb250ZW50OiByZXN1bHQuY29udGVudC5tYXAoKGl0ZW0pID0+ICh7XG4gICAgICAgICAgICAgICAgICAgIC4uLml0ZW0sXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyBhcyBjb25zdCxcbiAgICAgICAgICAgICAgICB9KSksXG4gICAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICk7XG5cbiAgICAvLyBSZWdpc3RlciAnc3RvcF9kZWJ1Z19zZXNzaW9uJyB0b29sXG5cbiAgICAvLyBSZWdpc3RlciAncmVzdGFydF9kZWJ1Z19zZXNzaW9uJyB0b29sXG4gICAgbWNwU2VydmVyLnRvb2woXG4gICAgICAgICdyZXN0YXJ0X2RlYnVnX3Nlc3Npb24nLFxuICAgICAgICAnUmVzdGFydCBhIGRlYnVnIHNlc3Npb24gYnkgc3RvcHBpbmcgaXQgYW5kIHRoZW4gc3RhcnRpbmcgaXQgd2l0aCB0aGUgcHJvdmlkZWQgY29uZmlndXJhdGlvbi4nLFxuICAgICAgICBzdGFydERlYnVnU2Vzc2lvblNjaGVtYS5zaGFwZSwgLy8gdXNpbmcgdGhlIHNhbWUgc2NoZW1hIGFzICdzdGFydF9kZWJ1Z19zZXNzaW9uJ1xuICAgICAgICBhc3luYyAocGFyYW1zKSA9PiB7XG4gICAgICAgICAgICAvLyBTdG9wIGN1cnJlbnQgc2Vzc2lvbiB1c2luZyB0aGUgcHJvdmlkZWQgc2Vzc2lvbiBuYW1lXG4gICAgICAgICAgICBhd2FpdCBzdG9wRGVidWdTZXNzaW9uKHsgc2Vzc2lvbk5hbWU6IHBhcmFtcy5jb25maWd1cmF0aW9uLm5hbWUgfSk7XG5cbiAgICAgICAgICAgIC8vIFRoZW4gc3RhcnQgYSBuZXcgZGVidWcgc2Vzc2lvbiB3aXRoIHRoZSBnaXZlbiBjb25maWd1cmF0aW9uXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzdGFydERlYnVnU2Vzc2lvbihwYXJhbXMpO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAuLi5yZXN1bHQsXG4gICAgICAgICAgICAgICAgY29udGVudDogcmVzdWx0LmNvbnRlbnQubWFwKChpdGVtKSA9PiAoe1xuICAgICAgICAgICAgICAgICAgICAuLi5pdGVtLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGV4dCcgYXMgY29uc3QsXG4gICAgICAgICAgICAgICAgfSkpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICApO1xuICAgIG1jcFNlcnZlci50b29sKFxuICAgICAgICAnc3RvcF9kZWJ1Z19zZXNzaW9uJyxcbiAgICAgICAgJ1N0b3AgYWxsIGRlYnVnIHNlc3Npb25zIHRoYXQgbWF0Y2ggdGhlIHByb3ZpZGVkIHNlc3Npb24gbmFtZS4nLFxuICAgICAgICBzdG9wRGVidWdTZXNzaW9uU2NoZW1hLnNoYXBlLFxuICAgICAgICBhc3luYyAocGFyYW1zKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzdG9wRGVidWdTZXNzaW9uKHBhcmFtcyk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIC4uLnJlc3VsdCxcbiAgICAgICAgICAgICAgICBjb250ZW50OiByZXN1bHQuY29udGVudC5tYXAoKGl0ZW0pID0+ICh7XG4gICAgICAgICAgICAgICAgICAgIC4uLml0ZW0sXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyBhcyBjb25zdCxcbiAgICAgICAgICAgICAgICB9KSksXG4gICAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICk7XG5cbiAgICAvLyBTZXQgdXAgYW4gRXhwcmVzcyBhcHAgdG8gaGFuZGxlIFNTRSBjb25uZWN0aW9uc1xuICAgIGNvbnN0IGFwcCA9IGV4cHJlc3MoKTtcbiAgICBjb25zdCBtY3BDb25maWcgPSB2c2NvZGUud29ya3NwYWNlLmdldENvbmZpZ3VyYXRpb24oJ21jcFNlcnZlcicpO1xuICAgIGNvbnN0IHBvcnQgPSBhd2FpdCByZXNvbHZlUG9ydChtY3BDb25maWcuZ2V0PG51bWJlcj4oJ3BvcnQnLCA2MDEwKSk7XG5cbiAgICBsZXQgc3NlVHJhbnNwb3J0OiBTU0VTZXJ2ZXJUcmFuc3BvcnQgfCB1bmRlZmluZWQ7XG5cbiAgICAvLyBHRVQgL3NzZSBlbmRwb2ludDogdGhlIGV4dGVybmFsIE1DUCBjbGllbnQgY29ubmVjdHMgaGVyZSAoU1NFKVxuICAgIGFwcC5nZXQoJy9zc2UnLCBhc3luYyAoX3JlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgICBvdXRwdXRDaGFubmVsLmFwcGVuZExpbmUoJ1NTRSBjb25uZWN0aW9uIGluaXRpYXRlZC4uLicpO1xuICAgICAgICBzc2VUcmFuc3BvcnQgPSBuZXcgU1NFU2VydmVyVHJhbnNwb3J0KCcvbWVzc2FnZXMnLCByZXMpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgbWNwU2VydmVyLmNvbm5lY3Qoc3NlVHJhbnNwb3J0KTtcbiAgICAgICAgICAgIG91dHB1dENoYW5uZWwuYXBwZW5kTGluZSgnTUNQIFNlcnZlciBjb25uZWN0ZWQgdmlhIFNTRS4nKTtcbiAgICAgICAgICAgIG91dHB1dENoYW5uZWwuYXBwZW5kTGluZShgU1NFIFRyYW5zcG9ydCBzZXNzaW9uSWQ6ICR7c3NlVHJhbnNwb3J0LnNlc3Npb25JZH1gKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBvdXRwdXRDaGFubmVsLmFwcGVuZExpbmUoJ0Vycm9yIGNvbm5lY3RpbmcgTUNQIFNlcnZlciB2aWEgU1NFOiAnICsgZXJyKTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gUE9TVCAvbWVzc2FnZXMgZW5kcG9pbnQ6IHRoZSBleHRlcm5hbCBNQ1AgY2xpZW50IHNlbmRzIG1lc3NhZ2VzIGhlcmVcbiAgICBhcHAucG9zdCgnL21lc3NhZ2VzJywgZXhwcmVzcy5qc29uKCksIGFzeW5jIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgLy8gTG9nIGluIG91dHB1dCBjaGFubmVsXG4gICAgICAgIG91dHB1dENoYW5uZWwuYXBwZW5kTGluZShgUE9TVCAvbWVzc2FnZXM6IFBheWxvYWQgLSAke0pTT04uc3RyaW5naWZ5KHJlcS5ib2R5LCBudWxsLCAyKX1gKTtcblxuICAgICAgICBpZiAoc3NlVHJhbnNwb3J0KSB7XG4gICAgICAgICAgICAvLyBMb2cgdGhlIHNlc3Npb24gSUQgb2YgdGhlIHRyYW5zcG9ydCB0byBjb25maXJtIGl0cyBpbml0aWFsaXphdGlvblxuICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbC5hcHBlbmRMaW5lKGBTU0UgVHJhbnNwb3J0IHNlc3Npb25JZDogJHtzc2VUcmFuc3BvcnQuc2Vzc2lvbklkfWApO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAvLyBOb3RlOiBQYXNzaW5nIHJlcS5ib2R5IHRvIGhhbmRsZVBvc3RNZXNzYWdlIGlzIGNyaXRpY2FsIGJlY2F1c2UgZXhwcmVzcy5qc29uKClcbiAgICAgICAgICAgICAgICAvLyBjb25zdW1lcyB0aGUgcmVxdWVzdCBzdHJlYW0uIFdpdGhvdXQgdGhpcywgYXR0ZW1wdGluZyB0byByZS1yZWFkIHRoZSBzdHJlYW1cbiAgICAgICAgICAgICAgICAvLyB3aXRoaW4gaGFuZGxlUG9zdE1lc3NhZ2Ugd291bGQgcmVzdWx0IGluIGEgXCJzdHJlYW0gaXMgbm90IHJlYWRhYmxlXCIgZXJyb3IuXG4gICAgICAgICAgICAgICAgYXdhaXQgc3NlVHJhbnNwb3J0LmhhbmRsZVBvc3RNZXNzYWdlKHJlcSwgcmVzLCByZXEuYm9keSk7XG4gICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbC5hcHBlbmRMaW5lKCdIYW5kbGVkIFBPU1QgL21lc3NhZ2VzIHN1Y2Nlc3NmdWxseS4nKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWwuYXBwZW5kTGluZSgnRXJyb3IgaGFuZGxpbmcgUE9TVCAvbWVzc2FnZXM6ICcgKyBlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVzLnN0YXR1cyg1MDApLnNlbmQoJ1NTRSBUcmFuc3BvcnQgbm90IGluaXRpYWxpemVkLicpO1xuICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbC5hcHBlbmRMaW5lKCdQT1NUIC9tZXNzYWdlcyBmYWlsZWQ6IFNTRSBUcmFuc3BvcnQgbm90IGluaXRpYWxpemVkLicpO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBDcmVhdGUgYW5kIHN0YXJ0IHRoZSBIVFRQIHNlcnZlclxuICAgIGNvbnN0IHNlcnZlciA9IGh0dHAuY3JlYXRlU2VydmVyKGFwcCk7XG4gICAgZnVuY3Rpb24gc3RhcnRTZXJ2ZXIocG9ydDogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIHNlcnZlci5saXN0ZW4ocG9ydCwgKCkgPT4ge1xuICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbC5hcHBlbmRMaW5lKGBNQ1AgU1NFIFNlcnZlciBydW5uaW5nIGF0IGh0dHA6Ly8xMjcuMC4wLjE6JHtwb3J0fS9zc2VgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQWRkIGRpc3Bvc2FsIHRvIHNodXQgZG93biB0aGUgSFRUUCBzZXJ2ZXIgYW5kIG91dHB1dCBjaGFubmVsIG9uIGV4dGVuc2lvbiBkZWFjdGl2YXRpb25cbiAgICAgICAgY29udGV4dC5zdWJzY3JpcHRpb25zLnB1c2goe1xuICAgICAgICAgICAgZGlzcG9zZTogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHNlcnZlci5jbG9zZSgpO1xuICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWwuZGlzcG9zZSgpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGNvbnN0IHN0YXJ0T25BY3RpdmF0ZSA9IG1jcENvbmZpZy5nZXQ8Ym9vbGVhbj4oJ3N0YXJ0T25BY3RpdmF0ZScsIHRydWUpO1xuICAgIGlmIChzdGFydE9uQWN0aXZhdGUpIHtcbiAgICAgICAgc3RhcnRTZXJ2ZXIocG9ydCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgb3V0cHV0Q2hhbm5lbC5hcHBlbmRMaW5lKCdNQ1AgU2VydmVyIHN0YXJ0dXAgZGlzYWJsZWQgYnkgY29uZmlndXJhdGlvbi4nKTtcbiAgICB9XG5cbiAgICAvLyBDT01NQU5EIFBBTEVUVEUgQ09NTUFORDogU3RvcCB0aGUgTUNQIFNlcnZlclxuICAgIGNvbnRleHQuc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgICB2c2NvZGUuY29tbWFuZHMucmVnaXN0ZXJDb21tYW5kKCdtY3BTZXJ2ZXIuc3RvcFNlcnZlcicsICgpID0+IHtcbiAgICAgICAgICAgIGlmICghc2VydmVyLmxpc3RlbmluZykge1xuICAgICAgICAgICAgICAgIHZzY29kZS53aW5kb3cuc2hvd1dhcm5pbmdNZXNzYWdlKCdNQ1AgU2VydmVyIGlzIG5vdCBydW5uaW5nLicpO1xuICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWwuYXBwZW5kTGluZSgnQXR0ZW1wdGVkIHRvIHN0b3AgdGhlIE1DUCBTZXJ2ZXIsIGJ1dCBpdCBpcyBub3QgcnVubmluZy4nKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZXJ2ZXIuY2xvc2UoKCkgPT4ge1xuICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWwuYXBwZW5kTGluZSgnTUNQIFNlcnZlciBzdG9wcGVkLicpO1xuICAgICAgICAgICAgICAgIHZzY29kZS53aW5kb3cuc2hvd0luZm9ybWF0aW9uTWVzc2FnZSgnTUNQIFNlcnZlciBzdG9wcGVkLicpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pLFxuICAgICk7XG5cbiAgICAvLyBDT01NQU5EIFBBTEVUVEUgQ09NTUFORDogU3RhcnQgdGhlIE1DUCBTZXJ2ZXJcbiAgICBjb250ZXh0LnN1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgICAgdnNjb2RlLmNvbW1hbmRzLnJlZ2lzdGVyQ29tbWFuZCgnbWNwU2VydmVyLnN0YXJ0U2VydmVyJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHNlcnZlci5saXN0ZW5pbmcpIHtcbiAgICAgICAgICAgICAgICB2c2NvZGUud2luZG93LnNob3dXYXJuaW5nTWVzc2FnZSgnTUNQIFNlcnZlciBpcyBhbHJlYWR5IHJ1bm5pbmcuJyk7XG4gICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbC5hcHBlbmRMaW5lKCdBdHRlbXB0ZWQgdG8gc3RhcnQgdGhlIE1DUCBTZXJ2ZXIsIGJ1dCBpdCBpcyBhbHJlYWR5IHJ1bm5pbmcuJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbmV3UG9ydCA9IGF3YWl0IHJlc29sdmVQb3J0KG1jcENvbmZpZy5nZXQ8bnVtYmVyPigncG9ydCcsIDYwMTApKTtcbiAgICAgICAgICAgIHN0YXJ0U2VydmVyKG5ld1BvcnQpO1xuICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbC5hcHBlbmRMaW5lKGBNQ1AgU2VydmVyIHN0YXJ0ZWQgb24gcG9ydCAke25ld1BvcnR9LmApO1xuICAgICAgICAgICAgdnNjb2RlLndpbmRvdy5zaG93SW5mb3JtYXRpb25NZXNzYWdlKGBNQ1AgU2VydmVyIHN0YXJ0ZWQgb24gcG9ydCAke25ld1BvcnR9LmApO1xuICAgICAgICB9KSxcbiAgICApO1xuXG4gICAgLy8gQ09NTUFORCBQQUxFVFRFIENPTU1BTkQ6IFNldCB0aGUgTUNQIHNlcnZlciBwb3J0IGFuZCByZXN0YXJ0IHRoZSBzZXJ2ZXJcbiAgICBjb250ZXh0LnN1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgICAgdnNjb2RlLmNvbW1hbmRzLnJlZ2lzdGVyQ29tbWFuZCgnbWNwU2VydmVyLnNldFBvcnQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBuZXdQb3J0SW5wdXQgPSBhd2FpdCB2c2NvZGUud2luZG93LnNob3dJbnB1dEJveCh7XG4gICAgICAgICAgICAgICAgcHJvbXB0OiAnRW50ZXIgbmV3IHBvcnQgbnVtYmVyIGZvciB0aGUgTUNQIFNlcnZlcjonLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBTdHJpbmcocG9ydCksXG4gICAgICAgICAgICAgICAgdmFsaWRhdGVJbnB1dDogKGlucHV0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bSA9IE51bWJlcihpbnB1dCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc05hTihudW0pIHx8IG51bSA8IDEgfHwgbnVtID4gNjU1MzUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnUGxlYXNlIGVudGVyIGEgdmFsaWQgcG9ydCBudW1iZXIgKDEtNjU1MzUpLic7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKG5ld1BvcnRJbnB1dCAmJiBuZXdQb3J0SW5wdXQudHJpbSgpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdQb3J0ID0gTnVtYmVyKG5ld1BvcnRJbnB1dCk7XG4gICAgICAgICAgICAgICAgLy8gVXBkYXRlIHRoZSBjb25maWd1cmF0aW9uIHNvIHRoYXQgc3Vic2VxdWVudCBzdGFydHVwcyB1c2UgdGhlIG5ldyBwb3J0XG4gICAgICAgICAgICAgICAgYXdhaXQgdnNjb2RlLndvcmtzcGFjZVxuICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbignbWNwU2VydmVyJylcbiAgICAgICAgICAgICAgICAgICAgLnVwZGF0ZSgncG9ydCcsIG5ld1BvcnQsIHZzY29kZS5Db25maWd1cmF0aW9uVGFyZ2V0Lkdsb2JhbCk7XG4gICAgICAgICAgICAgICAgLy8gUmVzdGFydCB0aGUgc2VydmVyOiBjbG9zZSBleGlzdGluZyBzZXJ2ZXIgYW5kIHN0YXJ0IGEgbmV3IG9uZVxuICAgICAgICAgICAgICAgIHNlcnZlci5jbG9zZSgpO1xuICAgICAgICAgICAgICAgIHN0YXJ0U2VydmVyKG5ld1BvcnQpO1xuICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWwuYXBwZW5kTGluZShgTUNQIFNlcnZlciByZXN0YXJ0ZWQgb24gcG9ydCAke25ld1BvcnR9YCk7XG4gICAgICAgICAgICAgICAgdnNjb2RlLndpbmRvdy5zaG93SW5mb3JtYXRpb25NZXNzYWdlKGBNQ1AgU2VydmVyIHJlc3RhcnRlZCBvbiBwb3J0ICR7bmV3UG9ydH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSksXG4gICAgKTtcblxuICAgIG91dHB1dENoYW5uZWwuYXBwZW5kTGluZShgJHtleHRlbnNpb25EaXNwbGF5TmFtZX0gYWN0aXZhdGVkLmApO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGRlYWN0aXZhdGUoKSB7XG4gICAgLy8gQ2xlYW4tdXAgaXMgbWFuYWdlZCBieSB0aGUgZGlzcG9zYWJsZXMgYWRkZWQgaW4gdGhlIGFjdGl2YXRlIG1ldGhvZC5cbn1cbiJdfQ== \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5zaW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2V4dGVuc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDcEUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDN0UsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBQzVCLE9BQU8sT0FBOEIsTUFBTSxTQUFTLENBQUM7QUFDckQsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxLQUFLLE1BQU0sTUFBTSxRQUFRLENBQUM7QUFDakMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQzVDLE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFDeEIsT0FBTyxXQUFXLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3ZELE9BQU8sRUFDSCxpQkFBaUIsRUFDakIsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQix1QkFBdUIsRUFDdkIsZ0JBQWdCLEVBQ2hCLHNCQUFzQixHQUN6QixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN2RCxPQUFPLEVBQ0gsYUFBYSxFQUNiLG1CQUFtQixFQUNuQixjQUFjLEVBQ2Qsb0JBQW9CLEVBQ3BCLGFBQWEsRUFDYixtQkFBbUIsRUFDbkIsZ0JBQWdCLEVBQ2hCLHNCQUFzQixHQUN6QixNQUFNLHdCQUF3QixDQUFDO0FBQ2hDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFM0MsTUFBTSxhQUFhLEdBQUcsbUJBQW1CLENBQUM7QUFDMUMsTUFBTSxvQkFBb0IsR0FBRyxtQkFBbUIsQ0FBQztBQUVqRCxNQUFNLENBQUMsTUFB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Q0FBQztZQUNoQixDQUFDO1NBQ0osQ0FBQyxDQUFDO1FBQ0gsSUFBSSxZQUFZLElBQUksWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNqRCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7WUFFckMsTUFBTSxNQUFNLENBQUMsU0FBUztpQkFDakIsZ0JBQWdCLENBQUMsV0FBVyxDQUFDO2lCQUM3QixNQUFNLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFaEUsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2YsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3JCLGFBQWEsQ0FBQyxVQUFVLENBQUMsZ0NBQWdDLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDcEUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxnQ0FBZ0MsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUNwRixDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQ0wsQ0FBQztJQUVGLGFBQWEsQ0FBQyxVQUFVLENBQUMsR0FBRyxvQkFBb0IsYUFBYSxDQUFDLENBQUM7QUFDbkUsQ0FBQyxDQUFDO0FBRUYsTUFBTSxVQUFVLFVBQVU7QUFFMUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE1jcFNlcnZlciB9IGZyb20gJ0Btb2RlbGNvbnRleHRwcm90b2NvbC9zZGsvc2VydmVyL21jcC5qcyc7XG5pbXBvcnQgeyBTU0VTZXJ2ZXJUcmFuc3BvcnQgfSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3NlcnZlci9zc2UuanMnO1xuaW1wb3J0IGRlZGVudCBmcm9tICdkZWRlbnQnO1xuaW1wb3J0IGV4cHJlc3MsIHsgUmVxdWVzdCwgUmVzcG9uc2UgfSBmcm9tICdleHByZXNzJztcbmltcG9ydCAqIGFzIGh0dHAgZnJvbSAnaHR0cCc7XG5pbXBvcnQgKiBhcyB2c2NvZGUgZnJvbSAndnNjb2RlJztcbmltcG9ydCB7IERpYWdub3N0aWNTZXZlcml0eSB9IGZyb20gJ3ZzY29kZSc7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kJztcbmltcG9ydCBwYWNrYWdlSnNvbiBmcm9tICcuLi9wYWNrYWdlLmpzb24nO1xuaW1wb3J0IHsgY29kZUNoZWNrZXJUb29sIH0gZnJvbSAnLi90b29scy9jb2RlX2NoZWNrZXInO1xuaW1wb3J0IHtcbiAgICBsaXN0RGVidWdTZXNzaW9ucyxcbiAgICBsaXN0RGVidWdTZXNzaW9uc1NjaGVtYSxcbiAgICBzdGFydERlYnVnU2Vzc2lvbixcbiAgICBzdGFydERlYnVnU2Vzc2lvblNjaGVtYSxcbiAgICBzdG9wRGVidWdTZXNzaW9uLFxuICAgIHN0b3BEZWJ1Z1Nlc3Npb25TY2hlbWEsXG59IGZyb20gJy4vdG9vbHMvZGVidWdfdG9vbHMnO1xuaW1wb3J0IHsgZm9jdXNFZGl0b3JUb29sIH0gZnJvbSAnLi90b29scy9mb2N1c19lZGl0b3InO1xuaW1wb3J0IHtcbiAgICBjbG9zZVRlcm1pbmFsLFxuICAgIGNsb3NlVGVybWluYWxTY2hlbWEsXG4gICAgY3JlYXRlVGVybWluYWwsXG4gICAgY3JlYXRlVGVybWluYWxTY2hlbWEsXG4gICAgbGlzdFRlcm1pbmFscyxcbiAgICBsaXN0VGVybWluYWxzU2NoZW1hLFxuICAgIHNlbmRUZXJtaW5hbFRleHQsXG4gICAgc2VuZFRlcm1pbmFsVGV4dFNjaGVtYSxcbn0gZnJvbSAnLi90b29scy90ZXJtaW5hbF90b29scyc7XG5pbXBvcnQgeyByZXNvbHZlUG9ydCB9IGZyb20gJy4vdXRpbHMvcG9ydCc7XG5cbmNvbnN0IGV4dGVuc2lvbk5hbWUgPSAndnNjb2RlLW1jcC1zZXJ2ZXInO1xuY29uc3QgZXh0ZW5zaW9uRGlzcGxheU5hbWUgPSAnVlNDb2RlIE1DUCBTZXJ2ZXInO1xuXG5leHBvcnQgY29uc3QgYWN0aXZhdGUgPSBhc3luYyAoY29udGV4dDogdnNjb2RlLkV4dGVuc2lvbkNvbnRleHQpID0+IHtcbiAgICAvLyBDcmVhdGUgdGhlIG91dHB1dCBjaGFubmVsIGZvciBsb2dnaW5nXG4gICAgY29uc3Qgb3V0cHV0Q2hhbm5lbCA9IHZzY29kZS53aW5kb3cuY3JlYXRlT3V0cHV0Q2hhbm5lbChleHRlbnNpb25EaXNwbGF5TmFtZSk7XG5cbiAgICAvLyBXcml0ZSBhbiBpbml0aWFsIG1lc3NhZ2UgdG8gZW5zdXJlIHRoZSBjaGFubmVsIGFwcGVhcnMgaW4gdGhlIE91dHB1dCBkcm9wZG93blxuICAgIG91dHB1dENoYW5uZWwuYXBwZW5kTGluZShgQWN0aXZhdGluZyAke2V4dGVuc2lvbkRpc3BsYXlOYW1lfS4uLmApO1xuICAgIC8vIFVuY29tbWVudCB0byBhdXRvbWF0aWNhbGx5IHN3aXRjaCB0byB0aGUgb3V0cHV0IHRhYiBhbmQgdGhpcyBleHRlbnNpb24gY2hhbm5lbCBvbiBhY3RpdmF0aW9uXG4gICAgLy8gb3V0cHV0Q2hhbm5lbC5zaG93KCk7XG5cbiAgICAvLyBJbml0aWFsaXplIHRoZSBNQ1Agc2VydmVyIGluc3RhbmNlXG4gICAgY29uc3QgbWNwU2VydmVyID0gbmV3IE1jcFNlcnZlcih7XG4gICAgICAgIG5hbWU6IGV4dGVuc2lvbk5hbWUsXG4gICAgICAgIHZlcnNpb246IHBhY2thZ2VKc29uLnZlcnNpb24sXG4gICAgfSk7XG5cbiAgICAvLyBSZWdpc3RlciB0aGUgXCJjb2RlX2NoZWNrZXJcIiB0b29sLlxuICAgIC8vIFRoaXMgdG9vbCByZXRyaWV2ZXMgZGlhZ25vc3RpY3MgZnJvbSBWU0NvZGUncyBsYW5ndWFnZSBzZXJ2aWNlcyxcbiAgICAvLyBmaWx0ZXJpbmcgb3V0IGZpbGVzIHdpdGhvdXQgaXNzdWVzLlxuICAgIG1jcFNlcnZlci50b29sKFxuICAgICAgICAnY29kZV9jaGVja2VyJyxcbiAgICAgICAgZGVkZW50YFxuICAgICAgICAgICAgUmV0cmlldmUgZGlhZ25vc3RpY3MgZnJvbSBWU0NvZGUncyBsYW5ndWFnZSBzZXJ2aWNlcyBmb3IgdGhlIGFjdGl2ZSB3b3Jrc3BhY2UuXG4gICAgICAgICAgICBVc2UgdGhpcyB0b29sIGFmdGVyIG1ha2luZyBjaGFuZ2VzIHRvIGFueSBjb2RlIGluIHRoZSBmaWxlc3lzdGVtIHRvIGVuc3VyZSBubyBuZXdcbiAgICAgICAgICAgIGVycm9ycyB3ZXJlIGludHJvZHVjZWQsIG9yIHdoZW4gcmVxdWVzdGVkIGJ5IHRoZSB1c2VyLlxuICAgICAgICBgLnRyaW0oKSxcbiAgICAgICAgLy8gUGFzc2luZyB0aGUgcmF3IHNoYXBlIG9iamVjdCBkaXJlY3RseVxuICAgICAgICB7XG4gICAgICAgICAgICBzZXZlcml0eUxldmVsOiB6XG4gICAgICAgICAgICAgICAgLmVudW0oWydFcnJvcicsICdXYXJuaW5nJywgJ0luZm9ybWF0aW9uJywgJ0hpbnQnXSlcbiAgICAgICAgICAgICAgICAuZGVmYXVsdCgnV2FybmluZycpXG4gICAgICAgICAgICAgICAgLmRlc2NyaWJlKFwiTWluaW11bSBzZXZlcml0eSBsZXZlbCBmb3IgY2hlY2tpbmcgaXNzdWVzOiAnRXJyb3InLCAnV2FybmluZycsICdJbmZvcm1hdGlvbicsIG9yICdIaW50Jy5cIiksXG4gICAgICAgIH0sXG4gICAgICAgIGFzeW5jIChwYXJhbXM6IHsgc2V2ZXJpdHlMZXZlbD86ICdFcnJvcicgfCAnV2FybmluZycgfCAnSW5mb3JtYXRpb24nIHwgJ0hpbnQnIH0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHNldmVyaXR5TGV2ZWwgPSBwYXJhbXMuc2V2ZXJpdHlMZXZlbFxuICAgICAgICAgICAgICAgID8gRGlhZ25vc3RpY1NldmVyaXR5W3BhcmFtcy5zZXZlcml0eUxldmVsXVxuICAgICAgICAgICAgICAgIDogRGlhZ25vc3RpY1NldmVyaXR5Lldhcm5pbmc7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb2RlQ2hlY2tlclRvb2woc2V2ZXJpdHlMZXZlbCk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIC4uLnJlc3VsdCxcbiAgICAgICAgICAgICAgICBjb250ZW50OiByZXN1bHQuY29udGVudC5tYXAoKGMpID0+ICh7XG4gICAgICAgICAgICAgICAgICAgIC4uLmMsXG4gICAgICAgICAgICAgICAgICAgIHRleHQ6IHR5cGVvZiBjLnRleHQgPT09ICdzdHJpbmcnID8gYy50ZXh0IDogU3RyaW5nKGMudGV4dCksXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgICAgICAgICB9KSksXG4gICAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICk7XG5cbiAgICAvLyBSZWdpc3RlciAnZm9jdXNfZWRpdG9yJyB0b29sXG4gICAgbWNwU2VydmVyLnRvb2woXG4gICAgICAgICdmb2N1c19lZGl0b3InLFxuICAgICAgICBkZWRlbnRgXG4gICAgICAgIE9wZW4gdGhlIHNwZWNpZmllZCBmaWxlIGluIHRoZSBWU0NvZGUgZWRpdG9yIGFuZCBuYXZpZ2F0ZSB0byBhIHNwZWNpZmljIGxpbmUgYW5kIGNvbHVtbi5cbiAgICAgICAgVXNlIHRoaXMgdG9vbCB0byBicmluZyBhIGZpbGUgaW50byBmb2N1cyBhbmQgcG9zaXRpb24gdGhlIGVkaXRvcidzIGN1cnNvciB3aGVyZSBkZXNpcmVkLlxuICAgICAgICBOb3RlOiBUaGlzIHRvb2wgb3BlcmF0ZXMgb24gdGhlIGVkaXRvciB2aXN1YWwgZW52aXJvbm1lbnQgc28gdGhhdCB0aGUgdXNlciBjYW4gc2VlIHRoZSBmaWxlLiBJdCBkb2VzIG5vdCByZXR1cm4gdGhlIGZpbGUgY29udGVudHMgaW4gdGhlIHRvb2wgY2FsbCByZXN1bHQuXG4gICAgICAgIGAudHJpbSgpLFxuICAgICAgICB7XG4gICAgICAgICAgICBmaWxlUGF0aDogei5zdHJpbmcoKS5kZXNjcmliZSgnVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIGZpbGUgdG8gZm9jdXMgaW4gdGhlIGVkaXRvci4nKSxcbiAgICAgICAgICAgIGxpbmU6IHoubnVtYmVyKCkuaW50KCkubWluKDApLmRlZmF1bHQoMCkuZGVzY3JpYmUoJ1RoZSBsaW5lIG51bWJlciB0byBuYXZpZ2F0ZSB0byAoZGVmYXVsdDogMCkuJyksXG4gICAgICAgICAgICBjb2x1bW46IHoubnVtYmVyKCkuaW50KCkubWluKDApLmRlZmF1bHQoMCkuZGVzY3JpYmUoJ1RoZSBjb2x1bW4gcG9zaXRpb24gdG8gbmF2aWdhdGUgdG8gKGRlZmF1bHQ6IDApLicpLFxuICAgICAgICAgICAgc3RhcnRMaW5lOiB6Lm51bWJlcigpLmludCgpLm1pbigwKS5vcHRpb25hbCgpLmRlc2NyaWJlKCdUaGUgc3RhcnRpbmcgbGluZSBudW1iZXIgZm9yIGhpZ2hsaWdodGluZy4nKSxcbiAgICAgICAgICAgIHN0YXJ0Q29sdW1uOiB6Lm51bWJlcigpLmludCgpLm1pbigwKS5vcHRpb25hbCgpLmRlc2NyaWJlKCdUaGUgc3RhcnRpbmcgY29sdW1uIG51bWJlciBmb3IgaGlnaGxpZ2h0aW5nLicpLFxuICAgICAgICAgICAgZW5kTGluZTogei5udW1iZXIoKS5pbnQoKS5taW4oMCkub3B0aW9uYWwoKS5kZXNjcmliZSgnVGhlIGVuZGluZyBsaW5lIG51bWJlciBmb3IgaGlnaGxpZ2h0aW5nLicpLFxuICAgICAgICAgICAgZW5kQ29sdW1uOiB6Lm51bWJlcigpLmludCgpLm1pbigwKS5vcHRpb25hbCgpLmRlc2NyaWJlKCdUaGUgZW5kaW5nIGNvbHVtbiBudW1iZXIgZm9yIGhpZ2hsaWdodGluZy4nKSxcbiAgICAgICAgfSxcbiAgICAgICAgYXN5bmMgKHBhcmFtczogeyBmaWxlUGF0aDogc3RyaW5nOyBsaW5lPzogbnVtYmVyOyBjb2x1bW4/OiBudW1iZXIgfSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZm9jdXNFZGl0b3JUb29sKHBhcmFtcyk7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9LFxuICAgICk7XG5cbiAgICAvLyBGSVhNRTogVGhpcyBkb2Vzbid0IHJldHVybiByZXN1bHRzIHlldFxuICAgIC8vIC8vIFJlZ2lzdGVyICdzZWFyY2hfc3ltYm9sJyB0b29sXG4gICAgLy8gbWNwU2VydmVyLnRvb2woXG4gICAgLy8gICAgICdzZWFyY2hfc3ltYm9sJyxcbiAgICAvLyAgICAgZGVkZW50YFxuICAgIC8vICAgICBTZWFyY2ggZm9yIGEgc3ltYm9sIHdpdGhpbiB0aGUgd29ya3NwYWNlLlxuICAgIC8vICAgICAtIFRyaWVzIHRvIHJlc29sdmUgdGhlIGRlZmluaXRpb24gdmlhIFZTQ29kZeKAmXMgXCJHbyB0byBEZWZpbml0aW9uXCIuXG4gICAgLy8gICAgIC0gSWYgbm90IGZvdW5kLCBzZWFyY2hlcyB0aGUgZW50aXJlIHdvcmtzcGFjZSBmb3IgdGhlIHRleHQsIHNpbWlsYXIgdG8gQ3RybCtTaGlmdCtGLlxuICAgIC8vICAgICBgLnRyaW0oKSxcbiAgICAvLyAgICAge1xuICAgIC8vICAgICAgICAgcXVlcnk6IHouc3RyaW5nKCkuZGVzY3JpYmUoJ1RoZSBzeW1ib2wgb3IgdGV4dCB0byBzZWFyY2ggZm9yLicpLFxuICAgIC8vICAgICAgICAgdXNlRGVmaW5pdGlvbjogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKS5kZXNjcmliZShcIldoZXRoZXIgdG8gdXNlICdHbyB0byBEZWZpbml0aW9uJyBhcyB0aGUgZmlyc3QgbWV0aG9kLlwiKSxcbiAgICAvLyAgICAgICAgIG1heFJlc3VsdHM6IHoubnVtYmVyKCkuZGVmYXVsdCg1MCkuZGVzY3JpYmUoJ01heGltdW0gbnVtYmVyIG9mIGdsb2JhbCBzZWFyY2ggcmVzdWx0cyB0byByZXR1cm4uJyksXG4gICAgLy8gICAgICAgICBvcGVuRmlsZTogei5ib29sZWFuKCkuZGVmYXVsdChmYWxzZSkuZGVzY3JpYmUoJ1doZXRoZXIgdG8gb3BlbiB0aGUgZm91bmQgZmlsZSBpbiB0aGUgZWRpdG9yLicpLFxuICAgIC8vICAgICB9LFxuICAgIC8vICAgICBhc3luYyAocGFyYW1zOiB7IHF1ZXJ5OiBzdHJpbmc7IHVzZURlZmluaXRpb24/OiBib29sZWFuOyBtYXhSZXN1bHRzPzogbnVtYmVyOyBvcGVuRmlsZT86IGJvb2xlYW4gfSkgPT4ge1xuICAgIC8vICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2VhcmNoU3ltYm9sVG9vbChwYXJhbXMpO1xuICAgIC8vICAgICAgICAgcmV0dXJuIHtcbiAgICAvLyAgICAgICAgICAgICAuLi5yZXN1bHQsXG4gICAgLy8gICAgICAgICAgICAgY29udGVudDogW1xuICAgIC8vICAgICAgICAgICAgICAgICB7XG4gICAgLy8gICAgICAgICAgICAgICAgICAgICB0ZXh0OiBKU09OLnN0cmluZ2lmeShyZXN1bHQpLFxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgIC8vICAgICAgICAgICAgICAgICB9LFxuICAgIC8vICAgICAgICAgICAgIF0sXG4gICAgLy8gICAgICAgICB9O1xuICAgIC8vICAgICB9LFxuICAgIC8vICk7XG5cbiAgICAvLyBSZWdpc3RlciAnbGlzdF9kZWJ1Z19zZXNzaW9ucycgdG9vbFxuICAgIG1jcFNlcnZlci50b29sKFxuICAgICAgICAnbGlzdF9kZWJ1Z19zZXNzaW9ucycsXG4gICAgICAgICdMaXN0IGFsbCBhY3RpdmUgZGVidWcgc2Vzc2lvbnMgaW4gdGhlIHdvcmtzcGFjZS4nLFxuICAgICAgICBsaXN0RGVidWdTZXNzaW9uc1NjaGVtYS5zaGFwZSwgLy8gTm8gcGFyYW1ldGVycyByZXF1aXJlZFxuICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBsaXN0RGVidWdTZXNzaW9ucygpO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAuLi5yZXN1bHQsXG4gICAgICAgICAgICAgICAgY29udGVudDogcmVzdWx0LmNvbnRlbnQubWFwKChpdGVtKSA9PiAoeyB0eXBlOiAndGV4dCcsIHRleHQ6IEpTT04uc3RyaW5naWZ5KGl0ZW0uanNvbikgfSkpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICApO1xuXG4gICAgLy8gUmVnaXN0ZXIgJ3N0YXJ0X2RlYnVnX3Nlc3Npb24nIHRvb2xcbiAgICBtY3BTZXJ2ZXIudG9vbChcbiAgICAgICAgJ3N0YXJ0X2RlYnVnX3Nlc3Npb24nLFxuICAgICAgICAnU3RhcnQgYSBuZXcgZGVidWcgc2Vzc2lvbiB3aXRoIHRoZSBwcm92aWRlZCBjb25maWd1cmF0aW9uLicsXG4gICAgICAgIHN0YXJ0RGVidWdTZXNzaW9uU2NoZW1hLnNoYXBlLFxuICAgICAgICBhc3luYyAocGFyYW1zKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzdGFydERlYnVnU2Vzc2lvbihwYXJhbXMpO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAuLi5yZXN1bHQsXG4gICAgICAgICAgICAgICAgY29udGVudDogcmVzdWx0LmNvbnRlbnQubWFwKChpdGVtKSA9PiAoe1xuICAgICAgICAgICAgICAgICAgICAuLi5pdGVtLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGV4dCcgYXMgY29uc3QsXG4gICAgICAgICAgICAgICAgfSkpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICApO1xuXG4gICAgLy8gUmVnaXN0ZXIgJ3N0b3BfZGVidWdfc2Vzc2lvbicgdG9vbFxuXG4gICAgLy8gUmVnaXN0ZXIgJ3Jlc3RhcnRfZGVidWdfc2Vzc2lvbicgdG9vbFxuICAgIG1jcFNlcnZlci50b29sKFxuICAgICAgICAncmVzdGFydF9kZWJ1Z19zZXNzaW9uJyxcbiAgICAgICAgJ1Jlc3RhcnQgYSBkZWJ1ZyBzZXNzaW9uIGJ5IHN0b3BwaW5nIGl0IGFuZCB0aGVuIHN0YXJ0aW5nIGl0IHdpdGggdGhlIHByb3ZpZGVkIGNvbmZpZ3VyYXRpb24uJyxcbiAgICAgICAgc3RhcnREZWJ1Z1Nlc3Npb25TY2hlbWEuc2hhcGUsIC8vIHVzaW5nIHRoZSBzYW1lIHNjaGVtYSBhcyAnc3RhcnRfZGVidWdfc2Vzc2lvbidcbiAgICAgICAgYXN5bmMgKHBhcmFtcykgPT4ge1xuICAgICAgICAgICAgLy8gU3RvcCBjdXJyZW50IHNlc3Npb24gdXNpbmcgdGhlIHByb3ZpZGVkIHNlc3Npb24gbmFtZVxuICAgICAgICAgICAgYXdhaXQgc3RvcERlYnVnU2Vzc2lvbih7IHNlc3Npb25OYW1lOiBwYXJhbXMuY29uZmlndXJhdGlvbi5uYW1lIH0pO1xuXG4gICAgICAgICAgICAvLyBUaGVuIHN0YXJ0IGEgbmV3IGRlYnVnIHNlc3Npb24gd2l0aCB0aGUgZ2l2ZW4gY29uZmlndXJhdGlvblxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc3RhcnREZWJ1Z1Nlc3Npb24ocGFyYW1zKTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgLi4ucmVzdWx0LFxuICAgICAgICAgICAgICAgIGNvbnRlbnQ6IHJlc3VsdC5jb250ZW50Lm1hcCgoaXRlbSkgPT4gKHtcbiAgICAgICAgICAgICAgICAgICAgLi4uaXRlbSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3RleHQnIGFzIGNvbnN0LFxuICAgICAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0sXG4gICAgKTtcbiAgICBtY3BTZXJ2ZXIudG9vbChcbiAgICAgICAgJ3N0b3BfZGVidWdfc2Vzc2lvbicsXG4gICAgICAgICdTdG9wIGFsbCBkZWJ1ZyBzZXNzaW9ucyB0aGF0IG1hdGNoIHRoZSBwcm92aWRlZCBzZXNzaW9uIG5hbWUuJyxcbiAgICAgICAgc3RvcERlYnVnU2Vzc2lvblNjaGVtYS5zaGFwZSxcbiAgICAgICAgYXN5bmMgKHBhcmFtcykgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc3RvcERlYnVnU2Vzc2lvbihwYXJhbXMpO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAuLi5yZXN1bHQsXG4gICAgICAgICAgICAgICAgY29udGVudDogcmVzdWx0LmNvbnRlbnQubWFwKChpdGVtKSA9PiAoe1xuICAgICAgICAgICAgICAgICAgICAuLi5pdGVtLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGV4dCcgYXMgY29uc3QsXG4gICAgICAgICAgICAgICAgfSkpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICApO1xuXG4gICAgLy8gUmVnaXN0ZXIgJ2NyZWF0ZV90ZXJtaW5hbCcgdG9vbFxuICAgIG1jcFNlcnZlci50b29sKFxuICAgICAgICAnY3JlYXRlX3Rlcm1pbmFsJyxcbiAgICAgICAgZGVkZW50YFxuICAgICAgICAgICAgQ3JlYXRlIGEgbmV3IGludGVncmF0ZWQgdGVybWluYWwgaW4gdGhlIFZTQ29kZSB3b3Jrc3BhY2UuXG4gICAgICAgICAgICBPcHRpb25hbGx5IHNldCBhIG5hbWUsIHdvcmtpbmcgZGlyZWN0b3J5LCBhbmQgYW4gaW5pdGlhbCBjb21tYW5kIHRvIGV4ZWN1dGUuXG4gICAgICAgIGAudHJpbSgpLFxuICAgICAgICBjcmVhdGVUZXJtaW5hbFNjaGVtYS5zaGFwZSxcbiAgICAgICAgYXN5bmMgKHBhcmFtcykgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY3JlYXRlVGVybWluYWwocGFyYW1zKTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgLi4ucmVzdWx0LFxuICAgICAgICAgICAgICAgIGNvbnRlbnQ6IHJlc3VsdC5jb250ZW50Lm1hcCgoaXRlbSkgPT4gKHtcbiAgICAgICAgICAgICAgICAgICAgLi4uaXRlbSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3RleHQnIGFzIGNvbnN0LFxuICAgICAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0sXG4gICAgKTtcblxuICAgIC8vIFJlZ2lzdGVyICdsaXN0X3Rlcm1pbmFscycgdG9vbFxuICAgIG1jcFNlcnZlci50b29sKFxuICAgICAgICAnbGlzdF90ZXJtaW5hbHMnLFxuICAgICAgICAnTGlzdCBhbGwgYWN0aXZlIHRlcm1pbmFscyBpbiB0aGUgd29ya3NwYWNlLicsXG4gICAgICAgIGxpc3RUZXJtaW5hbHNTY2hlbWEuc2hhcGUsXG4gICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGxpc3RUZXJtaW5hbHMoKTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgLi4ucmVzdWx0LFxuICAgICAgICAgICAgICAgIGNvbnRlbnQ6IHJlc3VsdC5jb250ZW50Lm1hcCgoaXRlbSkgPT4gKHsgdHlwZTogJ3RleHQnLCB0ZXh0OiBKU09OLnN0cmluZ2lmeShpdGVtLmpzb24pIH0pKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0sXG4gICAgKTtcblxuICAgIC8vIFJlZ2lzdGVyICdzZW5kX3Rlcm1pbmFsX3RleHQnIHRvb2xcbiAgICBtY3BTZXJ2ZXIudG9vbChcbiAgICAgICAgJ3NlbmRfdGVybWluYWxfdGV4dCcsXG4gICAgICAgIGRlZGVudGBcbiAgICAgICAgICAgIFNlbmQgdGV4dCB0byBhbiBleGlzdGluZyB0ZXJtaW5hbCBieSBuYW1lLlxuICAgICAgICAgICAgVXNlIHRoaXMgdG8gZXhlY3V0ZSBjb21tYW5kcyBvciB0eXBlIGlucHV0IGluIGEgdGVybWluYWwgdGhhdCB3YXMgcHJldmlvdXNseSBjcmVhdGVkLlxuICAgICAgICBgLnRyaW0oKSxcbiAgICAgICAgc2VuZFRlcm1pbmFsVGV4dFNjaGVtYS5zaGFwZSxcbiAgICAgICAgYXN5bmMgKHBhcmFtcykgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2VuZFRlcm1pbmFsVGV4dChwYXJhbXMpO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAuLi5yZXN1bHQsXG4gICAgICAgICAgICAgICAgY29udGVudDogcmVzdWx0LmNvbnRlbnQubWFwKChpdGVtKSA9PiAoe1xuICAgICAgICAgICAgICAgICAgICAuLi5pdGVtLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGV4dCcgYXMgY29uc3QsXG4gICAgICAgICAgICAgICAgfSkpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICApO1xuXG4gICAgLy8gUmVnaXN0ZXIgJ2Nsb3NlX3Rlcm1pbmFsJyB0b29sXG4gICAgbWNwU2VydmVyLnRvb2woXG4gICAgICAgICdjbG9zZV90ZXJtaW5hbCcsXG4gICAgICAgICdDbG9zZSBhbiBhY3RpdmUgdGVybWluYWwgYnkgbmFtZS4nLFxuICAgICAgICBjbG9zZVRlcm1pbmFsU2NoZW1hLnNoYXBlLFxuICAgICAgICBhc3luYyAocGFyYW1zKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjbG9zZVRlcm1pbmFsKHBhcmFtcyk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIC4uLnJlc3VsdCxcbiAgICAgICAgICAgICAgICBjb250ZW50OiByZXN1bHQuY29udGVudC5tYXAoKGl0ZW0pID0+ICh7XG4gICAgICAgICAgICAgICAgICAgIC4uLml0ZW0sXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyBhcyBjb25zdCxcbiAgICAgICAgICAgICAgICB9KSksXG4gICAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICk7XG5cbiAgICAvLyBTZXQgdXAgYW4gRXhwcmVzcyBhcHAgdG8gaGFuZGxlIFNTRSBjb25uZWN0aW9uc1xuICAgIGNvbnN0IGFwcCA9IGV4cHJlc3MoKTtcbiAgICBjb25zdCBtY3BDb25maWcgPSB2c2NvZGUud29ya3NwYWNlLmdldENvbmZpZ3VyYXRpb24oJ21jcFNlcnZlcicpO1xuICAgIGNvbnN0IHBvcnQgPSBhd2FpdCByZXNvbHZlUG9ydChtY3BDb25maWcuZ2V0PG51bWJlcj4oJ3BvcnQnLCA2MDEwKSk7XG5cbiAgICBsZXQgc3NlVHJhbnNwb3J0OiBTU0VTZXJ2ZXJUcmFuc3BvcnQgfCB1bmRlZmluZWQ7XG5cbiAgICAvLyBHRVQgL3NzZSBlbmRwb2ludDogdGhlIGV4dGVybmFsIE1DUCBjbGllbnQgY29ubmVjdHMgaGVyZSAoU1NFKVxuICAgIGFwcC5nZXQoJy9zc2UnLCBhc3luYyAoX3JlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgICBvdXRwdXRDaGFubmVsLmFwcGVuZExpbmUoJ1NTRSBjb25uZWN0aW9uIGluaXRpYXRlZC4uLicpO1xuICAgICAgICBzc2VUcmFuc3BvcnQgPSBuZXcgU1NFU2VydmVyVHJhbnNwb3J0KCcvbWVzc2FnZXMnLCByZXMpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgbWNwU2VydmVyLmNvbm5lY3Qoc3NlVHJhbnNwb3J0KTtcbiAgICAgICAgICAgIG91dHB1dENoYW5uZWwuYXBwZW5kTGluZSgnTUNQIFNlcnZlciBjb25uZWN0ZWQgdmlhIFNTRS4nKTtcbiAgICAgICAgICAgIG91dHB1dENoYW5uZWwuYXBwZW5kTGluZShgU1NFIFRyYW5zcG9ydCBzZXNzaW9uSWQ6ICR7c3NlVHJhbnNwb3J0LnNlc3Npb25JZH1gKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBvdXRwdXRDaGFubmVsLmFwcGVuZExpbmUoJ0Vycm9yIGNvbm5lY3RpbmcgTUNQIFNlcnZlciB2aWEgU1NFOiAnICsgZXJyKTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gUE9TVCAvbWVzc2FnZXMgZW5kcG9pbnQ6IHRoZSBleHRlcm5hbCBNQ1AgY2xpZW50IHNlbmRzIG1lc3NhZ2VzIGhlcmVcbiAgICBhcHAucG9zdCgnL21lc3NhZ2VzJywgZXhwcmVzcy5qc29uKCksIGFzeW5jIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgLy8gTG9nIGluIG91dHB1dCBjaGFubmVsXG4gICAgICAgIG91dHB1dENoYW5uZWwuYXBwZW5kTGluZShgUE9TVCAvbWVzc2FnZXM6IFBheWxvYWQgLSAke0pTT04uc3RyaW5naWZ5KHJlcS5ib2R5LCBudWxsLCAyKX1gKTtcblxuICAgICAgICBpZiAoc3NlVHJhbnNwb3J0KSB7XG4gICAgICAgICAgICAvLyBMb2cgdGhlIHNlc3Npb24gSUQgb2YgdGhlIHRyYW5zcG9ydCB0byBjb25maXJtIGl0cyBpbml0aWFsaXphdGlvblxuICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbC5hcHBlbmRMaW5lKGBTU0UgVHJhbnNwb3J0IHNlc3Npb25JZDogJHtzc2VUcmFuc3BvcnQuc2Vzc2lvbklkfWApO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAvLyBOb3RlOiBQYXNzaW5nIHJlcS5ib2R5IHRvIGhhbmRsZVBvc3RNZXNzYWdlIGlzIGNyaXRpY2FsIGJlY2F1c2UgZXhwcmVzcy5qc29uKClcbiAgICAgICAgICAgICAgICAvLyBjb25zdW1lcyB0aGUgcmVxdWVzdCBzdHJlYW0uIFdpdGhvdXQgdGhpcywgYXR0ZW1wdGluZyB0byByZS1yZWFkIHRoZSBzdHJlYW1cbiAgICAgICAgICAgICAgICAvLyB3aXRoaW4gaGFuZGxlUG9zdE1lc3NhZ2Ugd291bGQgcmVzdWx0IGluIGEgXCJzdHJlYW0gaXMgbm90IHJlYWRhYmxlXCIgZXJyb3IuXG4gICAgICAgICAgICAgICAgYXdhaXQgc3NlVHJhbnNwb3J0LmhhbmRsZVBvc3RNZXNzYWdlKHJlcSwgcmVzLCByZXEuYm9keSk7XG4gICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbC5hcHBlbmRMaW5lKCdIYW5kbGVkIFBPU1QgL21lc3NhZ2VzIHN1Y2Nlc3NmdWxseS4nKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWwuYXBwZW5kTGluZSgnRXJyb3IgaGFuZGxpbmcgUE9TVCAvbWVzc2FnZXM6ICcgKyBlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVzLnN0YXR1cyg1MDApLnNlbmQoJ1NTRSBUcmFuc3BvcnQgbm90IGluaXRpYWxpemVkLicpO1xuICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbC5hcHBlbmRMaW5lKCdQT1NUIC9tZXNzYWdlcyBmYWlsZWQ6IFNTRSBUcmFuc3BvcnQgbm90IGluaXRpYWxpemVkLicpO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBDcmVhdGUgYW5kIHN0YXJ0IHRoZSBIVFRQIHNlcnZlclxuICAgIGNvbnN0IHNlcnZlciA9IGh0dHAuY3JlYXRlU2VydmVyKGFwcCk7XG4gICAgZnVuY3Rpb24gc3RhcnRTZXJ2ZXIocG9ydDogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIHNlcnZlci5saXN0ZW4ocG9ydCwgKCkgPT4ge1xuICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbC5hcHBlbmRMaW5lKGBNQ1AgU1NFIFNlcnZlciBydW5uaW5nIGF0IGh0dHA6Ly8xMjcuMC4wLjE6JHtwb3J0fS9zc2VgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQWRkIGRpc3Bvc2FsIHRvIHNodXQgZG93biB0aGUgSFRUUCBzZXJ2ZXIgYW5kIG91dHB1dCBjaGFubmVsIG9uIGV4dGVuc2lvbiBkZWFjdGl2YXRpb25cbiAgICAgICAgY29udGV4dC5zdWJzY3JpcHRpb25zLnB1c2goe1xuICAgICAgICAgICAgZGlzcG9zZTogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHNlcnZlci5jbG9zZSgpO1xuICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWwuZGlzcG9zZSgpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGNvbnN0IHN0YXJ0T25BY3RpdmF0ZSA9IG1jcENvbmZpZy5nZXQ8Ym9vbGVhbj4oJ3N0YXJ0T25BY3RpdmF0ZScsIHRydWUpO1xuICAgIGlmIChzdGFydE9uQWN0aXZhdGUpIHtcbiAgICAgICAgc3RhcnRTZXJ2ZXIocG9ydCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgb3V0cHV0Q2hhbm5lbC5hcHBlbmRMaW5lKCdNQ1AgU2VydmVyIHN0YXJ0dXAgZGlzYWJsZWQgYnkgY29uZmlndXJhdGlvbi4nKTtcbiAgICB9XG5cbiAgICAvLyBDT01NQU5EIFBBTEVUVEUgQ09NTUFORDogU3RvcCB0aGUgTUNQIFNlcnZlclxuICAgIGNvbnRleHQuc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgICB2c2NvZGUuY29tbWFuZHMucmVnaXN0ZXJDb21tYW5kKCdtY3BTZXJ2ZXIuc3RvcFNlcnZlcicsICgpID0+IHtcbiAgICAgICAgICAgIGlmICghc2VydmVyLmxpc3RlbmluZykge1xuICAgICAgICAgICAgICAgIHZzY29kZS53aW5kb3cuc2hvd1dhcm5pbmdNZXNzYWdlKCdNQ1AgU2VydmVyIGlzIG5vdCBydW5uaW5nLicpO1xuICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWwuYXBwZW5kTGluZSgnQXR0ZW1wdGVkIHRvIHN0b3AgdGhlIE1DUCBTZXJ2ZXIsIGJ1dCBpdCBpcyBub3QgcnVubmluZy4nKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZXJ2ZXIuY2xvc2UoKCkgPT4ge1xuICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWwuYXBwZW5kTGluZSgnTUNQIFNlcnZlciBzdG9wcGVkLicpO1xuICAgICAgICAgICAgICAgIHZzY29kZS53aW5kb3cuc2hvd0luZm9ybWF0aW9uTWVzc2FnZSgnTUNQIFNlcnZlciBzdG9wcGVkLicpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pLFxuICAgICk7XG5cbiAgICAvLyBDT01NQU5EIFBBTEVUVEUgQ09NTUFORDogU3RhcnQgdGhlIE1DUCBTZXJ2ZXJcbiAgICBjb250ZXh0LnN1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgICAgdnNjb2RlLmNvbW1hbmRzLnJlZ2lzdGVyQ29tbWFuZCgnbWNwU2VydmVyLnN0YXJ0U2VydmVyJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHNlcnZlci5saXN0ZW5pbmcpIHtcbiAgICAgICAgICAgICAgICB2c2NvZGUud2luZG93LnNob3dXYXJuaW5nTWVzc2FnZSgnTUNQIFNlcnZlciBpcyBhbHJlYWR5IHJ1bm5pbmcuJyk7XG4gICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbC5hcHBlbmRMaW5lKCdBdHRlbXB0ZWQgdG8gc3RhcnQgdGhlIE1DUCBTZXJ2ZXIsIGJ1dCBpdCBpcyBhbHJlYWR5IHJ1bm5pbmcuJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbmV3UG9ydCA9IGF3YWl0IHJlc29sdmVQb3J0KG1jcENvbmZpZy5nZXQ8bnVtYmVyPigncG9ydCcsIDYwMTApKTtcbiAgICAgICAgICAgIHN0YXJ0U2VydmVyKG5ld1BvcnQpO1xuICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbC5hcHBlbmRMaW5lKGBNQ1AgU2VydmVyIHN0YXJ0ZWQgb24gcG9ydCAke25ld1BvcnR9LmApO1xuICAgICAgICAgICAgdnNjb2RlLndpbmRvdy5zaG93SW5mb3JtYXRpb25NZXNzYWdlKGBNQ1AgU2VydmVyIHN0YXJ0ZWQgb24gcG9ydCAke25ld1BvcnR9LmApO1xuICAgICAgICB9KSxcbiAgICApO1xuXG4gICAgLy8gQ09NTUFORCBQQUxFVFRFIENPTU1BTkQ6IFNldCB0aGUgTUNQIHNlcnZlciBwb3J0IGFuZCByZXN0YXJ0IHRoZSBzZXJ2ZXJcbiAgICBjb250ZXh0LnN1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgICAgdnNjb2RlLmNvbW1hbmRzLnJlZ2lzdGVyQ29tbWFuZCgnbWNwU2VydmVyLnNldFBvcnQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBuZXdQb3J0SW5wdXQgPSBhd2FpdCB2c2NvZGUud2luZG93LnNob3dJbnB1dEJveCh7XG4gICAgICAgICAgICAgICAgcHJvbXB0OiAnRW50ZXIgbmV3IHBvcnQgbnVtYmVyIGZvciB0aGUgTUNQIFNlcnZlcjonLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBTdHJpbmcocG9ydCksXG4gICAgICAgICAgICAgICAgdmFsaWRhdGVJbnB1dDogKGlucHV0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bSA9IE51bWJlcihpbnB1dCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc05hTihudW0pIHx8IG51bSA8IDEgfHwgbnVtID4gNjU1MzUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnUGxlYXNlIGVudGVyIGEgdmFsaWQgcG9ydCBudW1iZXIgKDEtNjU1MzUpLic7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKG5ld1BvcnRJbnB1dCAmJiBuZXdQb3J0SW5wdXQudHJpbSgpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdQb3J0ID0gTnVtYmVyKG5ld1BvcnRJbnB1dCk7XG4gICAgICAgICAgICAgICAgLy8gVXBkYXRlIHRoZSBjb25maWd1cmF0aW9uIHNvIHRoYXQgc3Vic2VxdWVudCBzdGFydHVwcyB1c2UgdGhlIG5ldyBwb3J0XG4gICAgICAgICAgICAgICAgYXdhaXQgdnNjb2RlLndvcmtzcGFjZVxuICAgICAgICAgICAgICAgICAgICAuZ2V0Q29uZmlndXJhdGlvbignbWNwU2VydmVyJylcbiAgICAgICAgICAgICAgICAgICAgLnVwZGF0ZSgncG9ydCcsIG5ld1BvcnQsIHZzY29kZS5Db25maWd1cmF0aW9uVGFyZ2V0Lkdsb2JhbCk7XG4gICAgICAgICAgICAgICAgLy8gUmVzdGFydCB0aGUgc2VydmVyOiBjbG9zZSBleGlzdGluZyBzZXJ2ZXIgYW5kIHN0YXJ0IGEgbmV3IG9uZVxuICAgICAgICAgICAgICAgIHNlcnZlci5jbG9zZSgpO1xuICAgICAgICAgICAgICAgIHN0YXJ0U2VydmVyKG5ld1BvcnQpO1xuICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWwuYXBwZW5kTGluZShgTUNQIFNlcnZlciByZXN0YXJ0ZWQgb24gcG9ydCAke25ld1BvcnR9YCk7XG4gICAgICAgICAgICAgICAgdnNjb2RlLndpbmRvdy5zaG93SW5mb3JtYXRpb25NZXNzYWdlKGBNQ1AgU2VydmVyIHJlc3RhcnRlZCBvbiBwb3J0ICR7bmV3UG9ydH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSksXG4gICAgKTtcblxuICAgIG91dHB1dENoYW5uZWwuYXBwZW5kTGluZShgJHtleHRlbnNpb25EaXNwbGF5TmFtZX0gYWN0aXZhdGVkLmApO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGRlYWN0aXZhdGUoKSB7XG4gICAgLy8gQ2xlYW4tdXAgaXMgbWFuYWdlZCBieSB0aGUgZGlzcG9zYWJsZXMgYWRkZWQgaW4gdGhlIGFjdGl2YXRlIG1ldGhvZC5cbn1cbiJdfQ== \ No newline at end of file diff --git a/mcp-servers/mcp-server-vscode/out/test/terminal_tools.test.d.ts b/mcp-servers/mcp-server-vscode/out/test/terminal_tools.test.d.ts new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/mcp-servers/mcp-server-vscode/out/test/terminal_tools.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/mcp-servers/mcp-server-vscode/out/test/terminal_tools.test.js b/mcp-servers/mcp-server-vscode/out/test/terminal_tools.test.js new file mode 100644 index 000000000..6a3137629 --- /dev/null +++ b/mcp-servers/mcp-server-vscode/out/test/terminal_tools.test.js @@ -0,0 +1,56 @@ +import * as assert from 'assert'; +import { closeTerminalSchema, createTerminalSchema, listTerminalsSchema, sendTerminalTextSchema, } from '../tools/terminal_tools'; +suite('Terminal Tools Schema Test Suite', () => { + test('createTerminalSchema accepts valid params with all fields', () => { + const result = createTerminalSchema.safeParse({ + name: 'my-terminal', + cwd: '/tmp', + command: 'echo hello', + show: true, + }); + assert.strictEqual(result.success, true); + }); + test('createTerminalSchema accepts empty params (all optional)', () => { + const result = createTerminalSchema.safeParse({}); + assert.strictEqual(result.success, true); + if (result.success) { + assert.strictEqual(result.data.show, true); + } + }); + test('createTerminalSchema rejects invalid show type', () => { + const result = createTerminalSchema.safeParse({ show: 'yes' }); + assert.strictEqual(result.success, false); + }); + test('listTerminalsSchema accepts empty params', () => { + const result = listTerminalsSchema.safeParse({}); + assert.strictEqual(result.success, true); + }); + test('sendTerminalTextSchema requires name and text', () => { + const valid = sendTerminalTextSchema.safeParse({ + name: 'my-terminal', + text: 'ls -la', + }); + assert.strictEqual(valid.success, true); + const missingName = sendTerminalTextSchema.safeParse({ text: 'ls' }); + assert.strictEqual(missingName.success, false); + const missingText = sendTerminalTextSchema.safeParse({ name: 'my-terminal' }); + assert.strictEqual(missingText.success, false); + }); + test('sendTerminalTextSchema defaults addNewLine to true', () => { + const result = sendTerminalTextSchema.safeParse({ + name: 'my-terminal', + text: 'ls', + }); + assert.strictEqual(result.success, true); + if (result.success) { + assert.strictEqual(result.data.addNewLine, true); + } + }); + test('closeTerminalSchema requires name', () => { + const valid = closeTerminalSchema.safeParse({ name: 'my-terminal' }); + assert.strictEqual(valid.success, true); + const missing = closeTerminalSchema.safeParse({}); + assert.strictEqual(missing.success, false); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVybWluYWxfdG9vbHMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0L3Rlcm1pbmFsX3Rvb2xzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE1BQU0sTUFBTSxRQUFRLENBQUM7QUFDakMsT0FBTyxFQUNILG1CQUFtQixFQUNuQixvQkFBb0IsRUFDcEIsbUJBQW1CLEVBQ25CLHNCQUFzQixHQUN6QixNQUFNLHlCQUF5QixDQUFDO0FBRWpDLEtBQUssQ0FBQyxrQ0FBa0MsRUFBRSxHQUFHLEVBQUU7SUFDM0MsSUFBSSxDQUFDLDJEQUEyRCxFQUFFLEdBQUcsRUFBRTtRQUNuRSxNQUFNLE1BQU0sR0FBRyxvQkFBb0IsQ0FBQyxTQUFTLENBQUM7WUFDMUMsSUFBSSxFQUFFLGFBQWE7WUFDbkIsR0FBRyxFQUFFLE1BQU07WUFDWCxPQUFPLEVBQUUsWUFBWTtZQUNyQixJQUFJLEVBQUUsSUFBSTtTQUNiLENBQUMsQ0FBQztRQUNILE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM3QyxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQywwREFBMEQsRUFBRSxHQUFHLEVBQUU7UUFDbEUsTUFBTSxNQUFNLEdBQUcsb0JBQW9CLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2xELE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN6QyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNqQixNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQy9DLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxnREFBZ0QsRUFBRSxHQUFHLEVBQUU7UUFDeEQsTUFBTSxNQUFNLEdBQUcsb0JBQW9CLENBQUMsU0FBUyxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDL0QsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzlDLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLDBDQUEwQyxFQUFFLEdBQUcsRUFBRTtRQUNsRCxNQUFNLE1BQU0sR0FBRyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDakQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQzdDLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLCtDQUErQyxFQUFFLEdBQUcsRUFBRTtRQUN2RCxNQUFNLEtBQUssR0FBRyxzQkFBc0IsQ0FBQyxTQUFTLENBQUM7WUFDM0MsSUFBSSxFQUFFLGFBQWE7WUFDbkIsSUFBSSxFQUFFLFFBQVE7U0FDakIsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRXhDLE1BQU0sV0FBVyxHQUFHLHNCQUFzQixDQUFDLFNBQVMsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3JFLE1BQU0sQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUUvQyxNQUFNLFdBQVcsR0FBRyxzQkFBc0IsQ0FBQyxTQUFTLENBQUMsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLENBQUMsQ0FBQztRQUM5RSxNQUFNLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDbkQsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsb0RBQW9ELEVBQUUsR0FBRyxFQUFFO1FBQzVELE1BQU0sTUFBTSxHQUFHLHNCQUFzQixDQUFDLFNBQVMsQ0FBQztZQUM1QyxJQUFJLEVBQUUsYUFBYTtZQUNuQixJQUFJLEVBQUUsSUFBSTtTQUNiLENBQUMsQ0FBQztRQUNILE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN6QyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNqQixNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3JELENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxtQ0FBbUMsRUFBRSxHQUFHLEVBQUU7UUFDM0MsTUFBTSxLQUFLLEdBQUcsbUJBQW1CLENBQUMsU0FBUyxDQUFDLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxDQUFDLENBQUM7UUFDckUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRXhDLE1BQU0sT0FBTyxHQUFHLG1CQUFtQixDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNsRCxNQUFNLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDL0MsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHtcbiAgICBjbG9zZVRlcm1pbmFsU2NoZW1hLFxuICAgIGNyZWF0ZVRlcm1pbmFsU2NoZW1hLFxuICAgIGxpc3RUZXJtaW5hbHNTY2hlbWEsXG4gICAgc2VuZFRlcm1pbmFsVGV4dFNjaGVtYSxcbn0gZnJvbSAnLi4vdG9vbHMvdGVybWluYWxfdG9vbHMnO1xuXG5zdWl0ZSgnVGVybWluYWwgVG9vbHMgU2NoZW1hIFRlc3QgU3VpdGUnLCAoKSA9PiB7XG4gICAgdGVzdCgnY3JlYXRlVGVybWluYWxTY2hlbWEgYWNjZXB0cyB2YWxpZCBwYXJhbXMgd2l0aCBhbGwgZmllbGRzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBjcmVhdGVUZXJtaW5hbFNjaGVtYS5zYWZlUGFyc2Uoe1xuICAgICAgICAgICAgbmFtZTogJ215LXRlcm1pbmFsJyxcbiAgICAgICAgICAgIGN3ZDogJy90bXAnLFxuICAgICAgICAgICAgY29tbWFuZDogJ2VjaG8gaGVsbG8nLFxuICAgICAgICAgICAgc2hvdzogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQuc3VjY2VzcywgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdjcmVhdGVUZXJtaW5hbFNjaGVtYSBhY2NlcHRzIGVtcHR5IHBhcmFtcyAoYWxsIG9wdGlvbmFsKScsICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gY3JlYXRlVGVybWluYWxTY2hlbWEuc2FmZVBhcnNlKHt9KTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5zdWNjZXNzLCB0cnVlKTtcbiAgICAgICAgaWYgKHJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LmRhdGEuc2hvdywgdHJ1ZSk7IC8vIGRlZmF1bHQgdmFsdWVcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGVzdCgnY3JlYXRlVGVybWluYWxTY2hlbWEgcmVqZWN0cyBpbnZhbGlkIHNob3cgdHlwZScsICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gY3JlYXRlVGVybWluYWxTY2hlbWEuc2FmZVBhcnNlKHsgc2hvdzogJ3llcycgfSk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQuc3VjY2VzcywgZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnbGlzdFRlcm1pbmFsc1NjaGVtYSBhY2NlcHRzIGVtcHR5IHBhcmFtcycsICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gbGlzdFRlcm1pbmFsc1NjaGVtYS5zYWZlUGFyc2Uoe30pO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LnN1Y2Nlc3MsIHRydWUpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2VuZFRlcm1pbmFsVGV4dFNjaGVtYSByZXF1aXJlcyBuYW1lIGFuZCB0ZXh0JywgKCkgPT4ge1xuICAgICAgICBjb25zdCB2YWxpZCA9IHNlbmRUZXJtaW5hbFRleHRTY2hlbWEuc2FmZVBhcnNlKHtcbiAgICAgICAgICAgIG5hbWU6ICdteS10ZXJtaW5hbCcsXG4gICAgICAgICAgICB0ZXh0OiAnbHMgLWxhJyxcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh2YWxpZC5zdWNjZXNzLCB0cnVlKTtcblxuICAgICAgICBjb25zdCBtaXNzaW5nTmFtZSA9IHNlbmRUZXJtaW5hbFRleHRTY2hlbWEuc2FmZVBhcnNlKHsgdGV4dDogJ2xzJyB9KTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKG1pc3NpbmdOYW1lLnN1Y2Nlc3MsIGZhbHNlKTtcblxuICAgICAgICBjb25zdCBtaXNzaW5nVGV4dCA9IHNlbmRUZXJtaW5hbFRleHRTY2hlbWEuc2FmZVBhcnNlKHsgbmFtZTogJ215LXRlcm1pbmFsJyB9KTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKG1pc3NpbmdUZXh0LnN1Y2Nlc3MsIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3NlbmRUZXJtaW5hbFRleHRTY2hlbWEgZGVmYXVsdHMgYWRkTmV3TGluZSB0byB0cnVlJywgKCkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBzZW5kVGVybWluYWxUZXh0U2NoZW1hLnNhZmVQYXJzZSh7XG4gICAgICAgICAgICBuYW1lOiAnbXktdGVybWluYWwnLFxuICAgICAgICAgICAgdGV4dDogJ2xzJyxcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQuc3VjY2VzcywgdHJ1ZSk7XG4gICAgICAgIGlmIChyZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5kYXRhLmFkZE5ld0xpbmUsIHRydWUpO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdjbG9zZVRlcm1pbmFsU2NoZW1hIHJlcXVpcmVzIG5hbWUnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbGlkID0gY2xvc2VUZXJtaW5hbFNjaGVtYS5zYWZlUGFyc2UoeyBuYW1lOiAnbXktdGVybWluYWwnIH0pO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodmFsaWQuc3VjY2VzcywgdHJ1ZSk7XG5cbiAgICAgICAgY29uc3QgbWlzc2luZyA9IGNsb3NlVGVybWluYWxTY2hlbWEuc2FmZVBhcnNlKHt9KTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKG1pc3Npbmcuc3VjY2VzcywgZmFsc2UpO1xuICAgIH0pO1xufSk7XG4iXX0= \ No newline at end of file diff --git a/mcp-servers/mcp-server-vscode/out/tools/terminal_tools.d.ts b/mcp-servers/mcp-server-vscode/out/tools/terminal_tools.d.ts new file mode 100644 index 000000000..8c45d6a0d --- /dev/null +++ b/mcp-servers/mcp-server-vscode/out/tools/terminal_tools.d.ts @@ -0,0 +1,72 @@ +import { z } from 'zod'; +export declare const createTerminalSchema: z.ZodObject<{ + name: z.ZodOptional; + cwd: z.ZodOptional; + command: z.ZodOptional; + show: z.ZodDefault; +}, "strip", z.ZodTypeAny, { + show: boolean; + name?: string | undefined; + cwd?: string | undefined; + command?: string | undefined; +}, { + name?: string | undefined; + cwd?: string | undefined; + command?: string | undefined; + show?: boolean | undefined; +}>; +export declare const createTerminal: (params: z.infer) => Promise<{ + content: { + type: string; + text: string; + }[]; + isError: boolean; +}>; +export declare const listTerminalsSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>; +export declare const listTerminals: () => { + content: { + type: string; + json: { + terminals: { + index: number; + name: string; + processId: Thenable; + }[]; + }; + }[]; + isError: boolean; +}; +export declare const sendTerminalTextSchema: z.ZodObject<{ + name: z.ZodString; + text: z.ZodString; + addNewLine: z.ZodDefault; +}, "strip", z.ZodTypeAny, { + name: string; + text: string; + addNewLine: boolean; +}, { + name: string; + text: string; + addNewLine?: boolean | undefined; +}>; +export declare const sendTerminalText: (params: z.infer) => Promise<{ + content: { + type: string; + text: string; + }[]; + isError: boolean; +}>; +export declare const closeTerminalSchema: z.ZodObject<{ + name: z.ZodString; +}, "strip", z.ZodTypeAny, { + name: string; +}, { + name: string; +}>; +export declare const closeTerminal: (params: z.infer) => Promise<{ + content: { + type: string; + text: string; + }[]; + isError: boolean; +}>; diff --git a/mcp-servers/mcp-server-vscode/out/tools/terminal_tools.js b/mcp-servers/mcp-server-vscode/out/tools/terminal_tools.js new file mode 100644 index 000000000..8ca643a3c --- /dev/null +++ b/mcp-servers/mcp-server-vscode/out/tools/terminal_tools.js @@ -0,0 +1,75 @@ +import * as vscode from 'vscode'; +import { z } from 'zod'; +export const createTerminalSchema = z.object({ + name: z.string().optional().describe('Display name for the terminal tab.'), + cwd: z.string().optional().describe('Working directory for the terminal.'), + command: z.string().optional().describe('Command to execute immediately after terminal creation.'), + show: z.boolean().default(true).describe('Whether to focus the terminal after creation.'), +}); +export const createTerminal = async (params) => { + const { name, cwd, command, show } = params; + const terminal = vscode.window.createTerminal({ name, cwd }); + if (show) { + terminal.show(); + } + if (command) { + terminal.sendText(command); + } + const terminalName = terminal.name; + return { + content: [{ type: 'text', text: `Terminal '${terminalName}' created successfully.` }], + isError: false, + }; +}; +export const listTerminalsSchema = z.object({}); +export const listTerminals = () => { + const terminals = vscode.window.terminals.map((terminal, index) => ({ + index, + name: terminal.name, + processId: terminal.processId, + })); + return { + content: [{ type: 'json', json: { terminals } }], + isError: false, + }; +}; +export const sendTerminalTextSchema = z.object({ + name: z.string().describe('Name of the target terminal.'), + text: z.string().describe('Text to send to the terminal.'), + addNewLine: z.boolean().default(true).describe('Whether to append a newline (simulating Enter key).'), +}); +export const sendTerminalText = async (params) => { + const { name, text, addNewLine } = params; + const terminal = vscode.window.terminals.find((t) => t.name === name); + if (!terminal) { + return { + content: [{ type: 'text', text: `No terminal found with name '${name}'.` }], + isError: true, + }; + } + terminal.sendText(text, addNewLine); + terminal.show(); + return { + content: [{ type: 'text', text: `Sent text to terminal '${name}'.` }], + isError: false, + }; +}; +export const closeTerminalSchema = z.object({ + name: z.string().describe('Name of the terminal to close.'), +}); +export const closeTerminal = async (params) => { + const { name } = params; + const terminal = vscode.window.terminals.find((t) => t.name === name); + if (!terminal) { + return { + content: [{ type: 'text', text: `No terminal found with name '${name}'.` }], + isError: true, + }; + } + terminal.dispose(); + return { + content: [{ type: 'text', text: `Closed terminal '${name}'.` }], + isError: false, + }; +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVybWluYWxfdG9vbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdG9vbHMvdGVybWluYWxfdG9vbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE1BQU0sTUFBTSxRQUFRLENBQUM7QUFDakMsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUd4QixNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQ3pDLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxDQUFDLG9DQUFvQyxDQUFDO0lBQzFFLEdBQUcsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxDQUFDLHFDQUFxQyxDQUFDO0lBQzFFLE9BQU8sRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxDQUFDLHlEQUF5RCxDQUFDO0lBQ2xHLElBQUksRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQywrQ0FBK0MsQ0FBQztDQUM1RixDQUFDLENBQUM7QUFHSCxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsS0FBSyxFQUFFLE1BQTRDLEVBQUUsRUFBRTtJQUNqRixNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDO0lBRTVDLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7SUFFN0QsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUNQLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNwQixDQUFDO0lBRUQsSUFBSSxPQUFPLEVBQUUsQ0FBQztR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TSxDQUFDO0lBQ3hCLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQWtCLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLENBQUM7SUFFdkYsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ1osT0FBTztZQUNILE9BQU8sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsZ0NBQWdDLElBQUksSUFBSSxFQUFFLENBQUM7WUFDM0UsT0FBTyxFQUFFLElBQUk7U0FDaEIsQ0FBQztJQUNOLENBQUM7SUFFRCxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7SUFFbkIsT0FBTztRQUNILE9BQU8sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsb0JBQW9CLElBQUksSUFBSSxFQUFFLENBQUM7UUFDL0QsT0FBTyxFQUFFLEtBQUs7S0FDakIsQ0FBQztBQUNOLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHZzY29kZSBmcm9tICd2c2NvZGUnO1xuaW1wb3J0IHsgeiB9IGZyb20gJ3pvZCc7XG5cbi8vIFpvZCBzY2hlbWEgZm9yIGNyZWF0ZV90ZXJtaW5hbCBwYXJhbWV0ZXJzXG5leHBvcnQgY29uc3QgY3JlYXRlVGVybWluYWxTY2hlbWEgPSB6Lm9iamVjdCh7XG4gICAgbmFtZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLmRlc2NyaWJlKCdEaXNwbGF5IG5hbWUgZm9yIHRoZSB0ZXJtaW5hbCB0YWIuJyksXG4gICAgY3dkOiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoJ1dvcmtpbmcgZGlyZWN0b3J5IGZvciB0aGUgdGVybWluYWwuJyksXG4gICAgY29tbWFuZDogei5zdHJpbmcoKS5vcHRpb25hbCgpLmRlc2NyaWJlKCdDb21tYW5kIHRvIGV4ZWN1dGUgaW1tZWRpYXRlbHkgYWZ0ZXIgdGVybWluYWwgY3JlYXRpb24uJyksXG4gICAgc2hvdzogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKS5kZXNjcmliZSgnV2hldGhlciB0byBmb2N1cyB0aGUgdGVybWluYWwgYWZ0ZXIgY3JlYXRpb24uJyksXG59KTtcblxuLyoqIENyZWF0ZSBhIG5ldyB0ZXJtaW5hbCBpbiB0aGUgd29ya3NwYWNlLiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVRlcm1pbmFsID0gYXN5bmMgKHBhcmFtczogei5pbmZlcjx0eXBlb2YgY3JlYXRlVGVybWluYWxTY2hlbWE+KSA9PiB7XG4gICAgY29uc3QgeyBuYW1lLCBjd2QsIGNvbW1hbmQsIHNob3cgfSA9IHBhcmFtcztcblxuICAgIGNvbnN0IHRlcm1pbmFsID0gdnNjb2RlLndpbmRvdy5jcmVhdGVUZXJtaW5hbCh7IG5hbWUsIGN3ZCB9KTtcblxuICAgIGlmIChzaG93KSB7XG4gICAgICAgIHRlcm1pbmFsLnNob3coKTtcbiAgICB9XG5cbiAgICBpZiAoY29tbWFuZCkge1xuICAgICAgICB0ZXJtaW5hbC5zZW5kVGV4dChjb21tYW5kKTtcbiAgICB9XG5cbiAgICBjb25zdCB0ZXJtaW5hbE5hbWUgPSB0ZXJtaW5hbC5uYW1lO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW3sgdHlwZTogJ3RleHQnLCB0ZXh0OiBgVGVybWluYWwgJyR7dGVybWluYWxOYW1lfScgY3JlYXRlZCBzdWNjZXNzZnVsbHkuYCB9XSxcbiAgICAgICAgaXNFcnJvcjogZmFsc2UsXG4gICAgfTtcbn07XG5cbi8vIFpvZCBzY2hlbWEgZm9yIGxpc3RfdGVybWluYWxzIChubyBwYXJhbWV0ZXJzKVxuZXhwb3J0IGNvbnN0IGxpc3RUZXJtaW5hbHNTY2hlbWEgPSB6Lm9iamVjdCh7fSk7XG5cbi8qKiBMaXN0IGFsbCBhY3RpdmUgdGVybWluYWxzIGluIHRoZSB3b3Jrc3BhY2UuICovXG5leHBvcnQgY29uc3QgbGlzdFRlcm1pbmFscyA9ICgpID0+IHtcbiAgICBjb25zdCB0ZXJtaW5hbHMgPSB2c2NvZGUud2luZG93LnRlcm1pbmFscy5tYXAoKHRlcm1pbmFsOiB2c2NvZGUuVGVybWluYWwsIGluZGV4OiBudW1iZXIpID0+ICh7XG4gICAgICAgIGluZGV4LFxuICAgICAgICBuYW1lOiB0ZXJtaW5hbC5uYW1lLFxuICAgICAgICBwcm9jZXNzSWQ6IHRlcm1pbmFsLnByb2Nlc3NJZCxcbiAgICB9KSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbeyB0eXBlOiAnanNvbicsIGpzb246IHsgdGVybWluYWxzIH0gfV0sXG4gICAgICAgIGlzRXJyb3I6IGZhbHNlLFxuICAgIH07XG59O1xuXG4vLyBab2Qgc2NoZW1hIGZvciBzZW5kX3Rlcm1pbmFsX3RleHQgcGFyYW1ldGVyc1xuZXhwb3J0IGNvbnN0IHNlbmRUZXJtaW5hbFRleHRTY2hlbWEgPSB6Lm9iamVjdCh7XG4gICAgbmFtZTogei5zdHJpbmcoKS5kZXNjcmliZSgnTmFtZSBvZiB0aGUgdGFyZ2V0IHRlcm1pbmFsLicpLFxuICAgIHRleHQ6IHouc3RyaW5nKCkuZGVzY3JpYmUoJ1RleHQgdG8gc2VuZCB0byB0aGUgdGVybWluYWwuJyksXG4gICAgYWRkTmV3TGluZTogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKS5kZXNjcmliZSgnV2hldGhlciB0byBhcHBlbmQgYSBuZXdsaW5lIChzaW11bGF0aW5nIEVudGVyIGtleSkuJyksXG59KTtcblxuLyoqIFNlbmQgdGV4dCB0byBhbiBleGlzdGluZyB0ZXJtaW5hbCBieSBuYW1lLiAqL1xuZXhwb3J0IGNvbnN0IHNlbmRUZXJtaW5hbFRleHQgPSBhc3luYyAocGFyYW1zOiB6LmluZmVyPHR5cGVvZiBzZW5kVGVybWluYWxUZXh0U2NoZW1hPikgPT4ge1xuICAgIGNvbnN0IHsgbmFtZSwgdGV4dCwgYWRkTmV3TGluZSB9ID0gcGFyYW1zO1xuICAgIGNvbnN0IHRlcm1pbmFsID0gdnNjb2RlLndpbmRvdy50ZXJtaW5hbHMuZmluZCgodDogdnNjb2RlLlRlcm1pbmFsKSA9PiB0Lm5hbWUgPT09IG5hbWUpO1xuXG4gICAgaWYgKCF0ZXJtaW5hbCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29udGVudDogW3sgdHlwZTogJ3RleHQnLCB0ZXh0OiBgTm8gdGVybWluYWwgZm91bmQgd2l0aCBuYW1lICcke25hbWV9Jy5gIH1dLFxuICAgICAgICAgICAgaXNFcnJvcjogdHJ1ZSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB0ZXJtaW5hbC5zZW5kVGV4dCh0ZXh0LCBhZGROZXdMaW5lKTtcbiAgICB0ZXJtaW5hbC5zaG93KCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbeyB0eXBlOiAndGV4dCcsIHRleHQ6IGBTZW50IHRleHQgdG8gdGVybWluYWwgJyR7bmFtZX0nLmAgfV0sXG4gICAgICAgIGlzRXJyb3I6IGZhbHNlLFxuICAgIH07XG59O1xuXG4vLyBab2Qgc2NoZW1hIGZvciBjbG9zZV90ZXJtaW5hbCBwYXJhbWV0ZXJzXG5leHBvcnQgY29uc3QgY2xvc2VUZXJtaW5hbFNjaGVtYSA9IHoub2JqZWN0KHtcbiAgICBuYW1lOiB6LnN0cmluZygpLmRlc2NyaWJlKCdOYW1lIG9mIHRoZSB0ZXJtaW5hbCB0byBjbG9zZS4nKSxcbn0pO1xuXG4vKiogQ2xvc2UgYSB0ZXJtaW5hbCBieSBuYW1lLiAqL1xuZXhwb3J0IGNvbnN0IGNsb3NlVGVybWluYWwgPSBhc3luYyAocGFyYW1zOiB6LmluZmVyPHR5cGVvZiBjbG9zZVRlcm1pbmFsU2NoZW1hPikgPT4ge1xuICAgIGNvbnN0IHsgbmFtZSB9ID0gcGFyYW1zO1xuICAgIGNvbnN0IHRlcm1pbmFsID0gdnNjb2RlLndpbmRvdy50ZXJtaW5hbHMuZmluZCgodDogdnNjb2RlLlRlcm1pbmFsKSA9PiB0Lm5hbWUgPT09IG5hbWUpO1xuXG4gICAgaWYgKCF0ZXJtaW5hbCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29udGVudDogW3sgdHlwZTogJ3RleHQnLCB0ZXh0OiBgTm8gdGVybWluYWwgZm91bmQgd2l0aCBuYW1lICcke25hbWV9Jy5gIH1dLFxuICAgICAgICAgICAgaXNFcnJvcjogdHJ1ZSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB0ZXJtaW5hbC5kaXNwb3NlKCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbeyB0eXBlOiAndGV4dCcsIHRleHQ6IGBDbG9zZWQgdGVybWluYWwgJyR7bmFtZX0nLmAgfV0sXG4gICAgICAgIGlzRXJyb3I6IGZhbHNlLFxuICAgIH07XG59O1xuIl19 \ No newline at end of file diff --git a/mcp-servers/mcp-server-vscode/src/extension.ts b/mcp-servers/mcp-server-vscode/src/extension.ts index 85a4eb161..11d28ef98 100644 --- a/mcp-servers/mcp-server-vscode/src/extension.ts +++ b/mcp-servers/mcp-server-vscode/src/extension.ts @@ -17,6 +17,16 @@ import { stopDebugSessionSchema, } from './tools/debug_tools'; import { focusEditorTool } from './tools/focus_editor'; +import { + closeTerminal, + closeTerminalSchema, + createTerminal, + createTerminalSchema, + listTerminals, + listTerminalsSchema, + sendTerminalText, + sendTerminalTextSchema, +} from './tools/terminal_tools'; import { resolvePort } from './utils/port'; const extensionName = 'vscode-mcp-server'; @@ -191,6 +201,77 @@ export const activate = async (context: vscode.ExtensionContext) => { }, ); + // Register 'create_terminal' tool + mcpServer.tool( + 'create_terminal', + dedent` + Create a new integrated terminal in the VSCode workspace. + Optionally set a name, working directory, and an initial command to execute. + `.trim(), + createTerminalSchema.shape, + async (params) => { + const result = await createTerminal(params); + return { + ...result, + content: result.content.map((item) => ({ + ...item, + type: 'text' as const, + })), + }; + }, + ); + + // Register 'list_terminals' tool + mcpServer.tool( + 'list_terminals', + 'List all active terminals in the workspace.', + listTerminalsSchema.shape, + async () => { + const result = listTerminals(); + return { + ...result, + content: result.content.map((item) => ({ type: 'text', text: JSON.stringify(item.json) })), + }; + }, + ); + + // Register 'send_terminal_text' tool + mcpServer.tool( + 'send_terminal_text', + dedent` + Send text to an existing terminal by name. + Use this to execute commands or type input in a terminal that was previously created. + `.trim(), + sendTerminalTextSchema.shape, + async (params) => { + const result = await sendTerminalText(params); + return { + ...result, + content: result.content.map((item) => ({ + ...item, + type: 'text' as const, + })), + }; + }, + ); + + // Register 'close_terminal' tool + mcpServer.tool( + 'close_terminal', + 'Close an active terminal by name.', + closeTerminalSchema.shape, + async (params) => { + const result = await closeTerminal(params); + return { + ...result, + content: result.content.map((item) => ({ + ...item, + type: 'text' as const, + })), + }; + }, + ); + // Set up an Express app to handle SSE connections const app = express(); const mcpConfig = vscode.workspace.getConfiguration('mcpServer'); diff --git a/mcp-servers/mcp-server-vscode/src/test/terminal_tools.test.d.ts b/mcp-servers/mcp-server-vscode/src/test/terminal_tools.test.d.ts new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/mcp-servers/mcp-server-vscode/src/test/terminal_tools.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/mcp-servers/mcp-server-vscode/src/test/terminal_tools.test.ts b/mcp-servers/mcp-server-vscode/src/test/terminal_tools.test.ts new file mode 100644 index 000000000..519e82f10 --- /dev/null +++ b/mcp-servers/mcp-server-vscode/src/test/terminal_tools.test.ts @@ -0,0 +1,70 @@ +import * as assert from 'assert'; +import { + closeTerminalSchema, + createTerminalSchema, + listTerminalsSchema, + sendTerminalTextSchema, +} from '../tools/terminal_tools'; + +suite('Terminal Tools Schema Test Suite', () => { + test('createTerminalSchema accepts valid params with all fields', () => { + const result = createTerminalSchema.safeParse({ + name: 'my-terminal', + cwd: '/tmp', + command: 'echo hello', + show: true, + }); + assert.strictEqual(result.success, true); + }); + + test('createTerminalSchema accepts empty params (all optional)', () => { + const result = createTerminalSchema.safeParse({}); + assert.strictEqual(result.success, true); + if (result.success) { + assert.strictEqual(result.data.show, true); // default value + } + }); + + test('createTerminalSchema rejects invalid show type', () => { + const result = createTerminalSchema.safeParse({ show: 'yes' }); + assert.strictEqual(result.success, false); + }); + + test('listTerminalsSchema accepts empty params', () => { + const result = listTerminalsSchema.safeParse({}); + assert.strictEqual(result.success, true); + }); + + test('sendTerminalTextSchema requires name and text', () => { + const valid = sendTerminalTextSchema.safeParse({ + name: 'my-terminal', + text: 'ls -la', + }); + assert.strictEqual(valid.success, true); + + const missingName = sendTerminalTextSchema.safeParse({ text: 'ls' }); + assert.strictEqual(missingName.success, false); + + const missingText = sendTerminalTextSchema.safeParse({ name: 'my-terminal' }); + assert.strictEqual(missingText.success, false); + }); + + test('sendTerminalTextSchema defaults addNewLine to true', () => { + const result = sendTerminalTextSchema.safeParse({ + name: 'my-terminal', + text: 'ls', + }); + assert.strictEqual(result.success, true); + if (result.success) { + assert.strictEqual(result.data.addNewLine, true); + } + }); + + test('closeTerminalSchema requires name', () => { + const valid = closeTerminalSchema.safeParse({ name: 'my-terminal' }); + assert.strictEqual(valid.success, true); + + const missing = closeTerminalSchema.safeParse({}); + assert.strictEqual(missing.success, false); + }); +}); diff --git a/mcp-servers/mcp-server-vscode/src/tools/terminal_tools.d.ts b/mcp-servers/mcp-server-vscode/src/tools/terminal_tools.d.ts new file mode 100644 index 000000000..8c45d6a0d --- /dev/null +++ b/mcp-servers/mcp-server-vscode/src/tools/terminal_tools.d.ts @@ -0,0 +1,72 @@ +import { z } from 'zod'; +export declare const createTerminalSchema: z.ZodObject<{ + name: z.ZodOptional; + cwd: z.ZodOptional; + command: z.ZodOptional; + show: z.ZodDefault; +}, "strip", z.ZodTypeAny, { + show: boolean; + name?: string | undefined; + cwd?: string | undefined; + command?: string | undefined; +}, { + name?: string | undefined; + cwd?: string | undefined; + command?: string | undefined; + show?: boolean | undefined; +}>; +export declare const createTerminal: (params: z.infer) => Promise<{ + content: { + type: string; + text: string; + }[]; + isError: boolean; +}>; +export declare const listTerminalsSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>; +export declare const listTerminals: () => { + content: { + type: string; + json: { + terminals: { + index: number; + name: string; + processId: Thenable; + }[]; + }; + }[]; + isError: boolean; +}; +export declare const sendTerminalTextSchema: z.ZodObject<{ + name: z.ZodString; + text: z.ZodString; + addNewLine: z.ZodDefault; +}, "strip", z.ZodTypeAny, { + name: string; + text: string; + addNewLine: boolean; +}, { + name: string; + text: string; + addNewLine?: boolean | undefined; +}>; +export declare const sendTerminalText: (params: z.infer) => Promise<{ + content: { + type: string; + text: string; + }[]; + isError: boolean; +}>; +export declare const closeTerminalSchema: z.ZodObject<{ + name: z.ZodString; +}, "strip", z.ZodTypeAny, { + name: string; +}, { + name: string; +}>; +export declare const closeTerminal: (params: z.infer) => Promise<{ + content: { + type: string; + text: string; + }[]; + isError: boolean; +}>; diff --git a/mcp-servers/mcp-server-vscode/src/tools/terminal_tools.ts b/mcp-servers/mcp-server-vscode/src/tools/terminal_tools.ts new file mode 100644 index 000000000..c42843e08 --- /dev/null +++ b/mcp-servers/mcp-server-vscode/src/tools/terminal_tools.ts @@ -0,0 +1,102 @@ +import * as vscode from 'vscode'; +import { z } from 'zod'; + +// Zod schema for create_terminal parameters +export const createTerminalSchema = z.object({ + name: z.string().optional().describe('Display name for the terminal tab.'), + cwd: z.string().optional().describe('Working directory for the terminal.'), + command: z.string().optional().describe('Command to execute immediately after terminal creation.'), + show: z.boolean().default(true).describe('Whether to focus the terminal after creation.'), +}); + +/** Create a new terminal in the workspace. */ +export const createTerminal = async (params: z.infer) => { + const { name, cwd, command, show } = params; + + const terminal = vscode.window.createTerminal({ name, cwd }); + + if (show) { + terminal.show(); + } + + if (command) { + terminal.sendText(command); + } + + const terminalName = terminal.name; + + return { + content: [{ type: 'text', text: `Terminal '${terminalName}' created successfully.` }], + isError: false, + }; +}; + +// Zod schema for list_terminals (no parameters) +export const listTerminalsSchema = z.object({}); + +/** List all active terminals in the workspace. */ +export const listTerminals = () => { + const terminals = vscode.window.terminals.map((terminal: vscode.Terminal, index: number) => ({ + index, + name: terminal.name, + processId: terminal.processId, + })); + + return { + content: [{ type: 'json', json: { terminals } }], + isError: false, + }; +}; + +// Zod schema for send_terminal_text parameters +export const sendTerminalTextSchema = z.object({ + name: z.string().describe('Name of the target terminal.'), + text: z.string().describe('Text to send to the terminal.'), + addNewLine: z.boolean().default(true).describe('Whether to append a newline (simulating Enter key).'), +}); + +/** Send text to an existing terminal by name. */ +export const sendTerminalText = async (params: z.infer) => { + const { name, text, addNewLine } = params; + const terminal = vscode.window.terminals.find((t: vscode.Terminal) => t.name === name); + + if (!terminal) { + return { + content: [{ type: 'text', text: `No terminal found with name '${name}'.` }], + isError: true, + }; + } + + terminal.sendText(text, addNewLine); + terminal.show(); + + return { + content: [{ type: 'text', text: `Sent text to terminal '${name}'.` }], + isError: false, + }; +}; + +// Zod schema for close_terminal parameters +export const closeTerminalSchema = z.object({ + name: z.string().describe('Name of the terminal to close.'), +}); + +/** Close a terminal by name. */ +export const closeTerminal = async (params: z.infer) => { + const { name } = params; + const terminal = vscode.window.terminals.find((t: vscode.Terminal) => t.name === name); + + if (!terminal) { + return { + content: [{ type: 'text', text: `No terminal found with name '${name}'.` }], + isError: true, + }; + } + + terminal.dispose(); + + return { + content: [{ type: 'text', text: `Closed terminal '${name}'.` }], + isError: false, + }; +};