@aws/lsp-codewhisperer 0.0.69 → 0.0.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +56 -0
- package/out/language-server/agenticChat/agenticChatController.js +53 -28
- package/out/language-server/agenticChat/agenticChatController.js.map +1 -1
- package/out/language-server/agenticChat/constants/constants.d.ts +1 -1
- package/out/language-server/agenticChat/constants/constants.js +2 -1
- package/out/language-server/agenticChat/constants/constants.js.map +1 -1
- package/out/language-server/agenticChat/constants/toolConstants.d.ts +1 -1
- package/out/language-server/agenticChat/constants/toolConstants.js +2 -2
- package/out/language-server/agenticChat/constants/toolConstants.js.map +1 -1
- package/out/language-server/agenticChat/context/agenticChatTriggerContext.js +1 -1
- package/out/language-server/agenticChat/context/agenticChatTriggerContext.js.map +1 -1
- package/out/language-server/agenticChat/qAgenticChatServer.d.ts +1 -1
- package/out/language-server/agenticChat/qAgenticChatServer.js +7 -8
- package/out/language-server/agenticChat/qAgenticChatServer.js.map +1 -1
- package/out/language-server/agenticChat/tools/chatDb/chatDb.d.ts +1 -0
- package/out/language-server/agenticChat/tools/chatDb/chatDb.js +3 -3
- package/out/language-server/agenticChat/tools/chatDb/chatDb.js.map +1 -1
- package/out/language-server/agenticChat/tools/executeBash.d.ts +3 -1
- package/out/language-server/agenticChat/tools/executeBash.js +28 -24
- package/out/language-server/agenticChat/tools/executeBash.js.map +1 -1
- package/out/language-server/agenticChat/tools/mcp/mcpEventHandler.js +258 -165
- package/out/language-server/agenticChat/tools/mcp/mcpEventHandler.js.map +1 -1
- package/out/language-server/agenticChat/tools/mcp/mcpManager.d.ts +42 -17
- package/out/language-server/agenticChat/tools/mcp/mcpManager.js +254 -78
- package/out/language-server/agenticChat/tools/mcp/mcpManager.js.map +1 -1
- package/out/language-server/agenticChat/tools/mcp/mcpTypes.d.ts +3 -1
- package/out/language-server/agenticChat/tools/mcp/mcpTypes.js.map +1 -1
- package/out/language-server/agenticChat/tools/mcp/mcpUtils.js +36 -16
- package/out/language-server/agenticChat/tools/mcp/mcpUtils.js.map +1 -1
- package/out/language-server/agenticChat/tools/qCodeAnalysis/{qCodeReview.d.ts → codeReview.d.ts} +4 -3
- package/out/language-server/agenticChat/tools/qCodeAnalysis/{qCodeReview.js → codeReview.js} +179 -127
- package/out/language-server/agenticChat/tools/qCodeAnalysis/codeReview.js.map +1 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/{qCodeReviewConstants.d.ts → codeReviewConstants.d.ts} +8 -6
- package/out/language-server/agenticChat/tools/qCodeAnalysis/{qCodeReviewConstants.js → codeReviewConstants.js} +32 -20
- package/out/language-server/agenticChat/tools/qCodeAnalysis/codeReviewConstants.js.map +1 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/codeReviewErrors.d.ts +12 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/codeReviewErrors.js +32 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/codeReviewErrors.js.map +1 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/{qCodeReviewSchemas.d.ts → codeReviewSchemas.d.ts} +6 -6
- package/out/language-server/agenticChat/tools/qCodeAnalysis/{qCodeReviewSchemas.js → codeReviewSchemas.js} +15 -15
- package/out/language-server/agenticChat/tools/qCodeAnalysis/codeReviewSchemas.js.map +1 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/{qCodeReviewTypes.d.ts → codeReviewTypes.d.ts} +22 -1
- package/out/language-server/agenticChat/tools/qCodeAnalysis/codeReviewTypes.js +15 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/codeReviewTypes.js.map +1 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/{qCodeReviewUtils.d.ts → codeReviewUtils.d.ts} +16 -14
- package/out/language-server/agenticChat/tools/qCodeAnalysis/{qCodeReviewUtils.js → codeReviewUtils.js} +38 -46
- package/out/language-server/agenticChat/tools/qCodeAnalysis/codeReviewUtils.js.map +1 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/displayFindings.d.ts +89 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/displayFindings.js +138 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/displayFindings.js.map +1 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/displayFindingsConstants.d.ts +14 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/displayFindingsConstants.js +40 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/displayFindingsConstants.js.map +1 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/displayFindingsSchemas.d.ts +177 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/displayFindingsSchemas.js +93 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/displayFindingsSchemas.js.map +1 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/displayFindingsTypes.d.ts +27 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/displayFindingsTypes.js +12 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/displayFindingsTypes.js.map +1 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/displayFindingsUtils.d.ts +17 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/displayFindingsUtils.js +33 -0
- package/out/language-server/agenticChat/tools/qCodeAnalysis/displayFindingsUtils.js.map +1 -0
- package/out/language-server/agenticChat/tools/toolServer.js +30 -10
- package/out/language-server/agenticChat/tools/toolServer.js.map +1 -1
- package/out/language-server/agenticChat/utils/commandParser.d.ts +17 -0
- package/out/language-server/agenticChat/utils/commandParser.js +85 -0
- package/out/language-server/agenticChat/utils/commandParser.js.map +1 -0
- package/out/language-server/chat/chatController.js +77 -0
- package/out/language-server/chat/chatController.js.map +1 -1
- package/out/language-server/chat/chatSessionService.js +19 -5
- package/out/language-server/chat/chatSessionService.js.map +1 -1
- package/out/language-server/chat/constants.d.ts +1 -0
- package/out/language-server/chat/constants.js +2 -1
- package/out/language-server/chat/constants.js.map +1 -1
- package/out/language-server/chat/telemetry/chatTelemetryController.d.ts +4 -2
- package/out/language-server/chat/telemetry/chatTelemetryController.js +13 -2
- package/out/language-server/chat/telemetry/chatTelemetryController.js.map +1 -1
- package/out/language-server/chat/utils.js +6 -0
- package/out/language-server/chat/utils.js.map +1 -1
- package/out/language-server/configuration/qConfigurationServer.d.ts +2 -1
- package/out/language-server/configuration/qConfigurationServer.js.map +1 -1
- package/out/language-server/inline-completion/auto-trigger/autoTrigger.js +2 -1
- package/out/language-server/inline-completion/auto-trigger/autoTrigger.js.map +1 -1
- package/out/language-server/inline-completion/codeWhispererServer.js +48 -143
- package/out/language-server/inline-completion/codeWhispererServer.js.map +1 -1
- package/out/language-server/inline-completion/telemetry.d.ts +9 -0
- package/out/language-server/inline-completion/telemetry.js +109 -0
- package/out/language-server/inline-completion/telemetry.js.map +1 -0
- package/out/language-server/netTransform/validation.d.ts +5 -0
- package/out/language-server/netTransform/validation.js +9 -2
- package/out/language-server/netTransform/validation.js.map +1 -1
- package/out/language-server/workspaceContext/artifactManager.d.ts +1 -0
- package/out/language-server/workspaceContext/artifactManager.js +55 -19
- package/out/language-server/workspaceContext/artifactManager.js.map +1 -1
- package/out/language-server/workspaceContext/workspaceContextServer.js +2 -0
- package/out/language-server/workspaceContext/workspaceContextServer.js.map +1 -1
- package/out/language-server/workspaceContext/workspaceFolderManager.d.ts +3 -0
- package/out/language-server/workspaceContext/workspaceFolderManager.js +24 -5
- package/out/language-server/workspaceContext/workspaceFolderManager.js.map +1 -1
- package/out/shared/amazonQServiceManager/AmazonQTokenServiceManager.d.ts +1 -0
- package/out/shared/amazonQServiceManager/AmazonQTokenServiceManager.js +16 -7
- package/out/shared/amazonQServiceManager/AmazonQTokenServiceManager.js.map +1 -1
- package/out/shared/amazonQServiceManager/qDeveloperProfiles.js +48 -5
- package/out/shared/amazonQServiceManager/qDeveloperProfiles.js.map +1 -1
- package/out/shared/codeWhispererService.js +1 -0
- package/out/shared/codeWhispererService.js.map +1 -1
- package/out/shared/languageDetection.d.ts +14 -0
- package/out/shared/languageDetection.js +20 -0
- package/out/shared/languageDetection.js.map +1 -1
- package/out/shared/localProjectContextController.js +1 -3
- package/out/shared/localProjectContextController.js.map +1 -1
- package/out/shared/models/constants.js +2 -1
- package/out/shared/models/constants.js.map +1 -1
- package/out/shared/supplementalContextUtil/crossFileContextUtil.d.ts +4 -4
- package/out/shared/supplementalContextUtil/crossFileContextUtil.js +112 -18
- package/out/shared/supplementalContextUtil/crossFileContextUtil.js.map +1 -1
- package/out/shared/supplementalContextUtil/supplementalContextUtil.d.ts +1 -1
- package/out/shared/supplementalContextUtil/supplementalContextUtil.js +2 -2
- package/out/shared/supplementalContextUtil/supplementalContextUtil.js.map +1 -1
- package/out/shared/telemetry/telemetryService.js +36 -17
- package/out/shared/telemetry/telemetryService.js.map +1 -1
- package/out/shared/telemetry/types.d.ts +19 -1
- package/out/shared/telemetry/types.js +8 -1
- package/out/shared/telemetry/types.js.map +1 -1
- package/out/shared/utils.d.ts +12 -0
- package/out/shared/utils.js +53 -3
- package/out/shared/utils.js.map +1 -1
- package/package.json +4 -4
- package/out/language-server/agenticChat/tools/qCodeAnalysis/qCodeReview.js.map +0 -1
- package/out/language-server/agenticChat/tools/qCodeAnalysis/qCodeReviewConstants.js.map +0 -1
- package/out/language-server/agenticChat/tools/qCodeAnalysis/qCodeReviewErrors.d.ts +0 -12
- package/out/language-server/agenticChat/tools/qCodeAnalysis/qCodeReviewErrors.js +0 -32
- package/out/language-server/agenticChat/tools/qCodeAnalysis/qCodeReviewErrors.js.map +0 -1
- package/out/language-server/agenticChat/tools/qCodeAnalysis/qCodeReviewSchemas.js.map +0 -1
- package/out/language-server/agenticChat/tools/qCodeAnalysis/qCodeReviewTypes.js +0 -3
- package/out/language-server/agenticChat/tools/qCodeAnalysis/qCodeReviewTypes.js.map +0 -1
- package/out/language-server/agenticChat/tools/qCodeAnalysis/qCodeReviewUtils.js.map +0 -1
|
@@ -18,6 +18,7 @@ class McpEventHandler {
|
|
|
18
18
|
#isProgrammaticChange = false;
|
|
19
19
|
#debounceTimer = null;
|
|
20
20
|
#lastProgrammaticState = false;
|
|
21
|
+
#serverNameBeforeUpdate;
|
|
21
22
|
constructor(features, telemetryService) {
|
|
22
23
|
this.#features = features;
|
|
23
24
|
this.#eventListenerRegistered = false;
|
|
@@ -186,11 +187,15 @@ class McpEventHandler {
|
|
|
186
187
|
* Handles MCP server click events
|
|
187
188
|
*/
|
|
188
189
|
async onMcpServerClick(params) {
|
|
189
|
-
this.#features.logging.log(`
|
|
190
|
+
this.#features.logging.log(`onMcpServerClick event with params: ${JSON.stringify(params)}`);
|
|
190
191
|
// Use a map of handlers for different action types
|
|
191
192
|
const handlers = {
|
|
192
|
-
'add-new-mcp': () =>
|
|
193
|
+
'add-new-mcp': () => {
|
|
194
|
+
this.#currentEditingServerName = undefined;
|
|
195
|
+
return this.#handleAddNewMcp(params);
|
|
196
|
+
},
|
|
193
197
|
'save-mcp': () => this.#handleSaveMcp(params),
|
|
198
|
+
'change-transport': () => this.#handleChangeTransport(params),
|
|
194
199
|
'open-mcp-server': () => this.#handleOpenMcpServer(params),
|
|
195
200
|
'edit-mcp': () => this.#handleEditMcpServer(params),
|
|
196
201
|
'mcp-permission-change': () => this.#handleMcpPermissionChange(params),
|
|
@@ -225,27 +230,19 @@ class McpEventHandler {
|
|
|
225
230
|
}
|
|
226
231
|
async #handleAddNewMcp(params, error) {
|
|
227
232
|
const existingValues = params.optionsValues || {};
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
persistent: true,
|
|
231
|
-
value: { arg_key: '' },
|
|
232
|
-
},
|
|
233
|
-
];
|
|
233
|
+
// Arguments (stdio)
|
|
234
|
+
let argsValue = [{ persistent: true, value: { arg_key: '' } }];
|
|
234
235
|
if (existingValues.args && Array.isArray(existingValues.args)) {
|
|
235
236
|
argsValue = existingValues.args.map((arg, index) => ({
|
|
236
237
|
persistent: index === 0,
|
|
237
|
-
value: {
|
|
238
|
-
arg_key: arg.arg_key || '',
|
|
239
|
-
},
|
|
238
|
+
value: { arg_key: arg.arg_key || '' },
|
|
240
239
|
}));
|
|
241
240
|
}
|
|
241
|
+
// Environment variables (stdio)
|
|
242
242
|
let envVarsValue = [
|
|
243
243
|
{
|
|
244
244
|
persistent: true,
|
|
245
|
-
value: {
|
|
246
|
-
env_var_name: '',
|
|
247
|
-
env_var_value: '',
|
|
248
|
-
},
|
|
245
|
+
value: { env_var_name: '', env_var_value: '' },
|
|
249
246
|
},
|
|
250
247
|
];
|
|
251
248
|
if (existingValues.env_variables && Array.isArray(existingValues.env_variables)) {
|
|
@@ -257,6 +254,17 @@ class McpEventHandler {
|
|
|
257
254
|
},
|
|
258
255
|
}));
|
|
259
256
|
}
|
|
257
|
+
// Headers (http)
|
|
258
|
+
let headersValue = [];
|
|
259
|
+
if (existingValues.headers && Array.isArray(existingValues.headers)) {
|
|
260
|
+
headersValue = existingValues.headers.map(hdr => ({
|
|
261
|
+
persistent: false, // allow every row to be deleted
|
|
262
|
+
value: {
|
|
263
|
+
key: hdr.key || '',
|
|
264
|
+
value: hdr.value || '',
|
|
265
|
+
},
|
|
266
|
+
}));
|
|
267
|
+
}
|
|
260
268
|
if (existingValues.name) {
|
|
261
269
|
const serverName = existingValues.name;
|
|
262
270
|
const sanitizedServerName = (0, mcpUtils_1.sanitizeName)(serverName);
|
|
@@ -274,114 +282,116 @@ class McpEventHandler {
|
|
|
274
282
|
}
|
|
275
283
|
}
|
|
276
284
|
const serverStatusError = this.#getServerStatusError(existingValues.name) || {};
|
|
285
|
+
// Determine which transport is selected (default to stdio)
|
|
286
|
+
const selectedTransport = existingValues.transport || 'stdio';
|
|
277
287
|
return {
|
|
278
288
|
id: params.id,
|
|
279
289
|
header: {
|
|
280
290
|
title: 'Add MCP Server',
|
|
281
|
-
status: error
|
|
282
|
-
? {
|
|
283
|
-
title: error,
|
|
284
|
-
icon: 'cancel-circle',
|
|
285
|
-
status: 'error',
|
|
286
|
-
}
|
|
287
|
-
: serverStatusError,
|
|
291
|
+
status: error ? { title: error, icon: 'cancel-circle', status: 'error' } : serverStatusError,
|
|
288
292
|
actions: [],
|
|
289
293
|
},
|
|
290
294
|
list: [],
|
|
291
295
|
filterActions: [
|
|
292
|
-
{
|
|
293
|
-
|
|
294
|
-
text: 'Cancel',
|
|
295
|
-
},
|
|
296
|
-
{
|
|
297
|
-
id: 'save-mcp',
|
|
298
|
-
text: 'Save',
|
|
299
|
-
status: error ? 'error' : 'primary',
|
|
300
|
-
},
|
|
296
|
+
{ id: 'cancel-mcp', text: 'Cancel' },
|
|
297
|
+
{ id: 'save-mcp', text: 'Save', status: error ? 'error' : 'primary' },
|
|
301
298
|
],
|
|
302
|
-
filterOptions:
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
299
|
+
filterOptions: (() => {
|
|
300
|
+
const common = [
|
|
301
|
+
{
|
|
302
|
+
type: 'radiogroup',
|
|
303
|
+
id: 'scope',
|
|
304
|
+
title: 'Scope',
|
|
305
|
+
options: [
|
|
306
|
+
{ label: 'Global - Used globally.', value: 'global' },
|
|
307
|
+
{ label: 'This workspace - Only used in this workspace.', value: 'workspace' },
|
|
308
|
+
],
|
|
309
|
+
value: existingValues.scope || 'global',
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
type: 'textinput',
|
|
313
|
+
id: 'name',
|
|
314
|
+
title: 'Name',
|
|
315
|
+
value: existingValues.name || '',
|
|
316
|
+
mandatory: true,
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
type: 'select',
|
|
320
|
+
id: 'transport',
|
|
321
|
+
title: 'Transport',
|
|
322
|
+
mandatory: true,
|
|
323
|
+
options: [
|
|
324
|
+
{ label: 'stdio', value: 'stdio' },
|
|
325
|
+
{ label: 'http', value: 'http' },
|
|
326
|
+
],
|
|
327
|
+
value: selectedTransport,
|
|
328
|
+
},
|
|
329
|
+
];
|
|
330
|
+
if (selectedTransport === 'http') {
|
|
331
|
+
return [
|
|
332
|
+
...common,
|
|
308
333
|
{
|
|
309
|
-
|
|
310
|
-
|
|
334
|
+
type: 'textinput',
|
|
335
|
+
id: 'url',
|
|
336
|
+
title: 'URL',
|
|
337
|
+
value: existingValues.url || '',
|
|
338
|
+
mandatory: true,
|
|
311
339
|
},
|
|
312
340
|
{
|
|
313
|
-
|
|
314
|
-
|
|
341
|
+
type: 'list',
|
|
342
|
+
id: 'headers',
|
|
343
|
+
title: 'Headers - optional',
|
|
344
|
+
items: [
|
|
345
|
+
{ id: 'key', title: 'Key', type: 'textinput' },
|
|
346
|
+
{ id: 'value', title: 'Value', type: 'textinput' },
|
|
347
|
+
],
|
|
348
|
+
...(headersValue.length > 0 ? { value: headersValue } : {}),
|
|
315
349
|
},
|
|
316
|
-
],
|
|
317
|
-
value: existingValues.scope || 'global',
|
|
318
|
-
},
|
|
319
|
-
{
|
|
320
|
-
type: 'textinput',
|
|
321
|
-
id: 'name',
|
|
322
|
-
title: 'Name',
|
|
323
|
-
value: existingValues.name || '',
|
|
324
|
-
mandatory: true,
|
|
325
|
-
},
|
|
326
|
-
{
|
|
327
|
-
type: 'select',
|
|
328
|
-
id: 'transport',
|
|
329
|
-
title: 'Transport',
|
|
330
|
-
mandatory: true,
|
|
331
|
-
options: [
|
|
332
350
|
{
|
|
333
|
-
|
|
334
|
-
|
|
351
|
+
type: 'numericinput',
|
|
352
|
+
id: 'timeout',
|
|
353
|
+
title: 'Timeout - use 0 to disable',
|
|
354
|
+
value: existingValues.timeout || 60,
|
|
335
355
|
},
|
|
336
|
-
]
|
|
337
|
-
}
|
|
338
|
-
{
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
value: existingValues.command || '',
|
|
343
|
-
mandatory: true,
|
|
344
|
-
},
|
|
345
|
-
{
|
|
346
|
-
type: 'list',
|
|
347
|
-
id: 'args',
|
|
348
|
-
title: 'Arguments - optional',
|
|
349
|
-
mandatory: false,
|
|
350
|
-
items: [
|
|
356
|
+
];
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
// stdio transport
|
|
360
|
+
return [
|
|
361
|
+
...common,
|
|
351
362
|
{
|
|
352
|
-
id: 'arg_key',
|
|
353
363
|
type: 'textinput',
|
|
364
|
+
id: 'command',
|
|
365
|
+
title: 'Command',
|
|
366
|
+
value: existingValues.command || '',
|
|
367
|
+
mandatory: true,
|
|
354
368
|
},
|
|
355
|
-
],
|
|
356
|
-
value: argsValue,
|
|
357
|
-
},
|
|
358
|
-
{
|
|
359
|
-
type: 'list',
|
|
360
|
-
id: 'env_variables',
|
|
361
|
-
title: 'Environment variables - optional',
|
|
362
|
-
mandatory: false,
|
|
363
|
-
items: [
|
|
364
369
|
{
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
370
|
+
type: 'list',
|
|
371
|
+
id: 'args',
|
|
372
|
+
title: 'Arguments - optional',
|
|
373
|
+
items: [{ id: 'arg_key', type: 'textinput' }],
|
|
374
|
+
value: argsValue,
|
|
368
375
|
},
|
|
369
376
|
{
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
377
|
+
type: 'list',
|
|
378
|
+
id: 'env_variables',
|
|
379
|
+
title: 'Environment variables - optional',
|
|
380
|
+
items: [
|
|
381
|
+
{ id: 'env_var_name', title: 'Name', type: 'textinput' },
|
|
382
|
+
{ id: 'env_var_value', title: 'Value', type: 'textinput' },
|
|
383
|
+
],
|
|
384
|
+
value: envVarsValue,
|
|
373
385
|
},
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
},
|
|
384
|
-
],
|
|
386
|
+
{
|
|
387
|
+
type: 'numericinput',
|
|
388
|
+
id: 'timeout',
|
|
389
|
+
title: 'Timeout - use 0 to disable',
|
|
390
|
+
value: existingValues.timeout || 60,
|
|
391
|
+
},
|
|
392
|
+
];
|
|
393
|
+
}
|
|
394
|
+
})(),
|
|
385
395
|
};
|
|
386
396
|
}
|
|
387
397
|
/**
|
|
@@ -404,6 +414,8 @@ class McpEventHandler {
|
|
|
404
414
|
timeout: config.timeout?.toString() || '',
|
|
405
415
|
env: config.env,
|
|
406
416
|
args: config.args,
|
|
417
|
+
url: config.url,
|
|
418
|
+
headers: config.headers,
|
|
407
419
|
};
|
|
408
420
|
const validation = this.#validateMcpServerForm(values, false);
|
|
409
421
|
if (!validation.isValid) {
|
|
@@ -453,8 +465,18 @@ class McpEventHandler {
|
|
|
453
465
|
}
|
|
454
466
|
}
|
|
455
467
|
}
|
|
456
|
-
|
|
457
|
-
|
|
468
|
+
const transport = values.transport;
|
|
469
|
+
const command = values.command?.trim() || '';
|
|
470
|
+
const url = values.url?.trim() || '';
|
|
471
|
+
// Basic validation for command/url presence and exclusivity
|
|
472
|
+
if (!command && !url) {
|
|
473
|
+
errors.push('Either command or url is required');
|
|
474
|
+
}
|
|
475
|
+
else if (command && url) {
|
|
476
|
+
errors.push('Provide either command OR url, not both');
|
|
477
|
+
}
|
|
478
|
+
else if (transport && ((transport === 'stdio' && !command) || (transport !== 'stdio' && !url))) {
|
|
479
|
+
errors.push(`${transport === 'stdio' ? 'Command' : 'URL'} is required for ${transport} transport`);
|
|
458
480
|
}
|
|
459
481
|
if (values.timeout && values.timeout.trim() !== '') {
|
|
460
482
|
const timeoutNum = Number(values.timeout.trim());
|
|
@@ -478,6 +500,20 @@ class McpEventHandler {
|
|
|
478
500
|
errors.push('Environment variable value cannot be empty when name is provided');
|
|
479
501
|
}
|
|
480
502
|
}
|
|
503
|
+
if (Array.isArray(values.headers)) {
|
|
504
|
+
const hdrs = values.headers;
|
|
505
|
+
const invalidHeaders = hdrs.find(h => {
|
|
506
|
+
const key = h.key?.trim() || '';
|
|
507
|
+
const value = h.value?.trim() || '';
|
|
508
|
+
return (key === '' && value !== '') || (key !== '' && value === '');
|
|
509
|
+
});
|
|
510
|
+
if (invalidHeaders) {
|
|
511
|
+
const hasKey = invalidHeaders.key?.trim();
|
|
512
|
+
errors.push(hasKey
|
|
513
|
+
? 'Header value cannot be empty when key is provided'
|
|
514
|
+
: 'Header key cannot be empty when value is provided');
|
|
515
|
+
}
|
|
516
|
+
}
|
|
481
517
|
return {
|
|
482
518
|
isValid: errors.length === 0,
|
|
483
519
|
errors,
|
|
@@ -490,6 +526,7 @@ class McpEventHandler {
|
|
|
490
526
|
if (!params.optionsValues) {
|
|
491
527
|
return this.#getDefaultMcpResponse(params.id);
|
|
492
528
|
}
|
|
529
|
+
const selectedTransport = params.optionsValues.transport;
|
|
493
530
|
const serverName = params.optionsValues.name;
|
|
494
531
|
const sanitizedServerName = (0, mcpUtils_1.sanitizeName)(serverName);
|
|
495
532
|
const originalServerName = this.#currentEditingServerName;
|
|
@@ -498,55 +535,75 @@ class McpEventHandler {
|
|
|
498
535
|
const validation = this.#validateMcpServerForm(params.optionsValues, true, isEditMode ? originalServerName : undefined);
|
|
499
536
|
if (!validation.isValid) {
|
|
500
537
|
const error = validation.errors[0];
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
params
|
|
504
|
-
|
|
505
|
-
}
|
|
506
|
-
else {
|
|
507
|
-
params.id = 'add-new-mcp';
|
|
508
|
-
return this.#handleAddNewMcp(params, error);
|
|
509
|
-
}
|
|
538
|
+
params.id = isEditMode ? 'edit-mcp' : 'add-new-mcp';
|
|
539
|
+
return isEditMode
|
|
540
|
+
? this.#handleEditMcpServer({ ...params, title: originalServerName }, error)
|
|
541
|
+
: this.#handleAddNewMcp(params, error);
|
|
510
542
|
}
|
|
511
|
-
//
|
|
543
|
+
// stdio‑specific parsing
|
|
512
544
|
let args = [];
|
|
513
|
-
const argsValue = params.optionsValues.args;
|
|
514
|
-
// Handle the case where argsValue might be a direct array or another type
|
|
515
|
-
try {
|
|
516
|
-
// Try to safely access and process the value
|
|
517
|
-
const argsArray = Array.isArray(argsValue) ? argsValue : [];
|
|
518
|
-
args = argsArray
|
|
519
|
-
.map((item) => {
|
|
520
|
-
return typeof item === 'object' && item !== null && 'arg_key' in item ? String(item.arg_key) : '';
|
|
521
|
-
})
|
|
522
|
-
.filter(Boolean);
|
|
523
|
-
}
|
|
524
|
-
catch (e) {
|
|
525
|
-
this.#features.logging.warn(`Failed to process args: ${e}`);
|
|
526
|
-
}
|
|
527
|
-
// Process env_variables to Record<string, string>
|
|
528
545
|
let env = {};
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
}
|
|
546
|
+
if (selectedTransport === 'stdio') {
|
|
547
|
+
try {
|
|
548
|
+
args = (Array.isArray(params.optionsValues.args) ? params.optionsValues.args : [])
|
|
549
|
+
.map((item) => item && typeof item === 'object' && 'arg_key' in item ? String(item.arg_key) : '')
|
|
550
|
+
.filter(Boolean);
|
|
551
|
+
}
|
|
552
|
+
catch (e) {
|
|
553
|
+
this.#features.logging.warn(`MCP: Failed to process args: ${e}`);
|
|
554
|
+
}
|
|
555
|
+
try {
|
|
556
|
+
env = (Array.isArray(params.optionsValues.env_variables) ? params.optionsValues.env_variables : []).reduce((acc, item) => {
|
|
557
|
+
if (item && 'env_var_name' in item && 'env_var_value' in item) {
|
|
558
|
+
acc[String(item.env_var_name)] = String(item.env_var_value);
|
|
559
|
+
}
|
|
560
|
+
return acc;
|
|
561
|
+
}, {});
|
|
562
|
+
}
|
|
563
|
+
catch (e) {
|
|
564
|
+
this.#features.logging.warn(`MCP: Failed to process env variables: ${e}`);
|
|
565
|
+
}
|
|
538
566
|
}
|
|
539
|
-
|
|
540
|
-
|
|
567
|
+
// http‑specific parsing
|
|
568
|
+
let headers = {};
|
|
569
|
+
if (selectedTransport === 'http') {
|
|
570
|
+
try {
|
|
571
|
+
const raw = Array.isArray(params.optionsValues.headers) ? params.optionsValues.headers : [];
|
|
572
|
+
headers = raw.reduce((acc, item) => {
|
|
573
|
+
const k = item.key?.toString().trim() ?? '';
|
|
574
|
+
const v = item.value?.toString().trim() ?? '';
|
|
575
|
+
// both empty → skip
|
|
576
|
+
if (k === '' && v === '') {
|
|
577
|
+
return acc;
|
|
578
|
+
}
|
|
579
|
+
// otherwise keep (validation layer handles partial-empty cases)
|
|
580
|
+
acc[k] = item.value ?? '';
|
|
581
|
+
return acc;
|
|
582
|
+
}, {});
|
|
583
|
+
}
|
|
584
|
+
catch (e) {
|
|
585
|
+
this.#features.logging.warn(`MCP: Failed to process headers: ${e}`);
|
|
586
|
+
}
|
|
541
587
|
}
|
|
542
588
|
// Config file requires timeout in milliseconds
|
|
543
589
|
const timeoutInMs = (parseInt(params.optionsValues.timeout) ?? 60) * 1000;
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
590
|
+
// build final config (no transport field persisted)
|
|
591
|
+
let config;
|
|
592
|
+
if (selectedTransport === 'http') {
|
|
593
|
+
config = {
|
|
594
|
+
url: params.optionsValues.url,
|
|
595
|
+
headers,
|
|
596
|
+
timeout: timeoutInMs,
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
config = {
|
|
601
|
+
command: params.optionsValues.command,
|
|
602
|
+
args,
|
|
603
|
+
env,
|
|
604
|
+
timeout: timeoutInMs,
|
|
605
|
+
};
|
|
606
|
+
}
|
|
550
607
|
// Get agent path based on scope
|
|
551
608
|
const isGlobal = params.optionsValues['scope'] === 'global';
|
|
552
609
|
const agentPath = await this.#getAgentPath(isGlobal);
|
|
@@ -558,7 +615,8 @@ class McpEventHandler {
|
|
|
558
615
|
this.#isProgrammaticChange = true;
|
|
559
616
|
try {
|
|
560
617
|
if (isEditMode && originalServerName) {
|
|
561
|
-
|
|
618
|
+
const serverToRemove = this.#serverNameBeforeUpdate || originalServerName;
|
|
619
|
+
await mcpManager_1.McpManager.instance.removeServer(serverToRemove);
|
|
562
620
|
await mcpManager_1.McpManager.instance.addServer(serverName, config, agentPath);
|
|
563
621
|
}
|
|
564
622
|
else {
|
|
@@ -573,14 +631,14 @@ class McpEventHandler {
|
|
|
573
631
|
this.#currentEditingServerName = undefined;
|
|
574
632
|
// need to check server state now, as there is possibility of error during server initialization
|
|
575
633
|
const serverStatusError = this.#getServerStatusError(serverName);
|
|
576
|
-
// Emit telemetry event regardless of success/failure
|
|
577
634
|
this.#telemetryController?.emitMCPServerInitializeEvent({
|
|
578
635
|
source: isEditMode ? 'updateServer' : 'addServer',
|
|
579
|
-
command:
|
|
636
|
+
command: selectedTransport === 'stdio' ? params.optionsValues.command : undefined,
|
|
637
|
+
url: selectedTransport === 'http' ? params.optionsValues.url : undefined,
|
|
580
638
|
enabled: true,
|
|
581
639
|
numTools: mcpManager_1.McpManager.instance.getAllToolsWithPermissions(serverName).length,
|
|
582
640
|
scope: params.optionsValues['scope'] === 'global' ? 'global' : 'workspace',
|
|
583
|
-
transportType:
|
|
641
|
+
transportType: selectedTransport,
|
|
584
642
|
languageServerVersion: this.#features.runtime.serverInfo.version,
|
|
585
643
|
});
|
|
586
644
|
if (serverStatusError) {
|
|
@@ -780,18 +838,28 @@ class McpEventHandler {
|
|
|
780
838
|
list: [],
|
|
781
839
|
};
|
|
782
840
|
}
|
|
841
|
+
// Respect a user flip first; otherwise fall back to what the stored configuration implies.
|
|
842
|
+
const transport = params.optionsValues?.transport ?? (config.url ? 'http' : 'stdio');
|
|
843
|
+
// Convert stored structures to UI‑friendly lists
|
|
844
|
+
const argsList = (config.args ?? []).map(a => ({ arg_key: a })); // for stdio
|
|
845
|
+
const envList = Object.entries(config.env ?? {}).map(([k, v]) => ({
|
|
846
|
+
env_var_name: k,
|
|
847
|
+
env_var_value: v,
|
|
848
|
+
})); // for stdio
|
|
849
|
+
const headersList = Object.entries(config.headers ?? {}).map(([k, v]) => ({
|
|
850
|
+
key: k,
|
|
851
|
+
value: v,
|
|
852
|
+
})); // for http
|
|
783
853
|
// UI must display timeout to user in seconds
|
|
784
854
|
const timeoutInSeconds = params.optionsValues?.timeout || Math.floor((config.timeout ?? 60000) / 1000).toString();
|
|
785
855
|
const existingValues = {
|
|
786
856
|
name: params.optionsValues?.name || serverName,
|
|
787
|
-
transport
|
|
857
|
+
transport,
|
|
788
858
|
command: params.optionsValues?.command || config.command,
|
|
789
|
-
args: params.optionsValues?.args ||
|
|
790
|
-
env_variables: params.optionsValues?.env_variables ||
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
env_var_value: v,
|
|
794
|
-
})),
|
|
859
|
+
args: params.optionsValues?.args || argsList,
|
|
860
|
+
env_variables: params.optionsValues?.env_variables || envList,
|
|
861
|
+
url: params.optionsValues?.url || config.url,
|
|
862
|
+
headers: params.optionsValues?.headers || headersList,
|
|
795
863
|
timeout: timeoutInSeconds,
|
|
796
864
|
scope: params.optionsValues?.scope,
|
|
797
865
|
};
|
|
@@ -828,6 +896,30 @@ class McpEventHandler {
|
|
|
828
896
|
});
|
|
829
897
|
return filterOptions;
|
|
830
898
|
}
|
|
899
|
+
async #handleChangeTransport(params) {
|
|
900
|
+
const { optionsValues, title } = params;
|
|
901
|
+
const editingServerName = this.#currentEditingServerName;
|
|
902
|
+
// Clean up transport-specific fields
|
|
903
|
+
if (optionsValues) {
|
|
904
|
+
const transport = optionsValues.transport ?? 'stdio'; // Maintain default to 'stdio'
|
|
905
|
+
const fieldsToDelete = transport === 'http' ? ['command', 'args', 'env_variables'] : ['url', 'headers'];
|
|
906
|
+
fieldsToDelete.forEach(field => delete optionsValues[field]);
|
|
907
|
+
}
|
|
908
|
+
// Handle server name change in edit mode
|
|
909
|
+
if (editingServerName && title && editingServerName !== title) {
|
|
910
|
+
const servers = mcpManager_1.McpManager.instance.getAllServerConfigs();
|
|
911
|
+
const existingConfig = servers.get(editingServerName);
|
|
912
|
+
if (existingConfig) {
|
|
913
|
+
const updatedServers = new Map(servers);
|
|
914
|
+
updatedServers.delete(editingServerName);
|
|
915
|
+
updatedServers.set(title, existingConfig);
|
|
916
|
+
await mcpManager_1.McpManager.instance.updateServerMap(updatedServers);
|
|
917
|
+
}
|
|
918
|
+
this.#serverNameBeforeUpdate = editingServerName;
|
|
919
|
+
}
|
|
920
|
+
params.id = editingServerName ? 'edit-mcp' : 'add-new-mcp';
|
|
921
|
+
return editingServerName ? this.#handleEditMcpServer(params) : this.#handleAddNewMcp(params);
|
|
922
|
+
}
|
|
831
923
|
/**
|
|
832
924
|
* Gets the current permission setting for a tool
|
|
833
925
|
*/
|
|
@@ -888,13 +980,13 @@ class McpEventHandler {
|
|
|
888
980
|
}
|
|
889
981
|
try {
|
|
890
982
|
// Skip server config check for Built-in server
|
|
983
|
+
const serverConfig = mcpManager_1.McpManager.instance.getAllServerConfigs().get(serverName);
|
|
891
984
|
if (serverName !== 'Built-in') {
|
|
892
|
-
const serverConfig = mcpManager_1.McpManager.instance.getAllServerConfigs().get(serverName);
|
|
893
985
|
if (!serverConfig) {
|
|
894
986
|
throw new Error(`Server '${serverName}' not found`);
|
|
895
987
|
}
|
|
896
988
|
}
|
|
897
|
-
const mcpServerPermission = await this.#processPermissionUpdates(updatedPermissionConfig);
|
|
989
|
+
const mcpServerPermission = await this.#processPermissionUpdates(updatedPermissionConfig, serverConfig?.__configPath__);
|
|
898
990
|
// Store the permission config instead of applying it immediately
|
|
899
991
|
this.#pendingPermissionConfig = {
|
|
900
992
|
serverName,
|
|
@@ -928,23 +1020,24 @@ class McpEventHandler {
|
|
|
928
1020
|
const serverConfig = mcpManager_1.McpManager.instance.getAllServerConfigs().get(serverName);
|
|
929
1021
|
if (serverConfig) {
|
|
930
1022
|
// Emit server initialize event after permission change
|
|
1023
|
+
const transportType = serverConfig.command ? 'stdio' : 'http';
|
|
931
1024
|
this.#telemetryController?.emitMCPServerInitializeEvent({
|
|
932
1025
|
source: 'updatePermission',
|
|
933
|
-
command: serverConfig.command,
|
|
1026
|
+
command: transportType === 'stdio' ? serverConfig.command : undefined,
|
|
1027
|
+
url: transportType === 'http' ? serverConfig.url : undefined,
|
|
934
1028
|
enabled: true,
|
|
935
1029
|
numTools: mcpManager_1.McpManager.instance.getAllToolsWithPermissions(serverName).length,
|
|
936
1030
|
scope: serverConfig.__configPath__ ===
|
|
937
1031
|
(0, mcpUtils_1.getGlobalAgentConfigPath)(this.#features.workspace.fs.getUserHomeDir())
|
|
938
1032
|
? 'global'
|
|
939
1033
|
: 'workspace',
|
|
940
|
-
transportType:
|
|
1034
|
+
transportType: transportType,
|
|
941
1035
|
languageServerVersion: this.#features.runtime.serverInfo.version,
|
|
942
1036
|
});
|
|
943
1037
|
}
|
|
944
1038
|
// Clear the pending permission config after applying
|
|
945
1039
|
this.#pendingPermissionConfig = undefined;
|
|
946
1040
|
this.#features.logging.info(`Applied permission changes for server: ${serverName}`);
|
|
947
|
-
this.#isProgrammaticChange = false;
|
|
948
1041
|
return { id: params.id };
|
|
949
1042
|
}
|
|
950
1043
|
catch (error) {
|
|
@@ -987,10 +1080,12 @@ class McpEventHandler {
|
|
|
987
1080
|
});
|
|
988
1081
|
// Emit server initialize events for all active servers
|
|
989
1082
|
for (const [serverName, config] of serverConfigs.entries()) {
|
|
1083
|
+
const transportType = config.command ? 'stdio' : 'http';
|
|
990
1084
|
// const enabled = !mcpManager.isServerDisabled(serverName)
|
|
991
1085
|
this.#telemetryController?.emitMCPServerInitializeEvent({
|
|
992
1086
|
source: 'reload',
|
|
993
|
-
command: config.command,
|
|
1087
|
+
command: transportType === 'stdio' ? config.command : undefined,
|
|
1088
|
+
url: transportType === 'http' ? config.url : undefined,
|
|
994
1089
|
enabled: true,
|
|
995
1090
|
numTools: mcpManager.getAllToolsWithPermissions(serverName).length,
|
|
996
1091
|
scope: config.__configPath__ === globalAgentPath ? 'global' : 'workspace',
|
|
@@ -1057,9 +1152,7 @@ class McpEventHandler {
|
|
|
1057
1152
|
/**
|
|
1058
1153
|
* Processes permission updates from the UI
|
|
1059
1154
|
*/
|
|
1060
|
-
async #processPermissionUpdates(updatedPermissionConfig) {
|
|
1061
|
-
// Get the appropriate agent path
|
|
1062
|
-
const agentPath = await this.#getAgentPath();
|
|
1155
|
+
async #processPermissionUpdates(updatedPermissionConfig, agentPath) {
|
|
1063
1156
|
const perm = {
|
|
1064
1157
|
enabled: true,
|
|
1065
1158
|
toolPerms: {},
|