Commit edb4b5cb authored by Yi-Ann Chen's avatar Yi-Ann Chen
Browse files

feat: open MCP Dashboard from agent platform nav menu

Handle the new `openMcpDashboard` notification sent by the Duo Agent
Platform webview and reveal the MCP Dashboard by executing the
`gl.webview.root.mcp.show` command.

- command_names: add `WEBVIEW_ROOT_MCP_SHOW` to a shared common
  `PROGRAMMATIC_COMMANDS` and reference it from desktop
- duo_chat_handlers: add `openMcpDashboard` handler and register it for
  the agent platform webview
parent cba8ac6c
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -28,3 +28,12 @@ export const USER_COMMANDS = {
  AGENTIC_CHAT_HISTORY: 'gl.agenticChat.showHistoryView',
  MCP_OPEN_USER_CONFIG: 'gl.mcp.openUserConfig',
};

/*
  User can't trigger these commands directly. We use them from within the code.
*/
export const PROGRAMMATIC_COMMANDS = {
  // Reveals the MCP Dashboard editor webview. Registered dynamically in setupWebviews
  // as `gl.webview.<normalized MCP_DASHBOARD_WEBVIEW_ID>.show`.
  WEBVIEW_ROOT_MCP_SHOW: 'gl.webview.root.mcp.show',
};
+13 −0
Original line number Diff line number Diff line
import * as vscode from 'vscode';
import { DUO_CHAT_WEBVIEW_ID } from '../../constants';
import { PROGRAMMATIC_COMMANDS } from '../../command_names';
import { WebviewMessageRegistry } from '../message_handlers/webview_message_registry';
import { createFakePartial } from '../../test_utils/create_fake_partial';
import { log } from '../../log';
@@ -13,6 +14,7 @@ import {
  copyMessage,
  insertCodeSnippet,
  copyCodeSnippet,
  openMcpDashboard,
} from './duo_chat_handlers';
import { LSDuoChatWebviewController } from './duo_chat_controller';

@@ -42,6 +44,7 @@ describe('registerDuoChatHandlers', () => {
    'showMessage',
    'openLink',
    'openUrl',
    'openMcpDashboard',
  ];

  it('should register a request handler for `getCurrentFileContext` request', () => {
@@ -170,6 +173,16 @@ describe('registerDuoChatHandlers', () => {
    });
  });

  describe('openMcpDashboard', () => {
    it('executes the command that reveals the MCP Dashboard webview', async () => {
      const executeCommandSpy = jest.spyOn(vscode.commands, 'executeCommand');

      await openMcpDashboard();

      expect(executeCommandSpy).toHaveBeenCalledWith(PROGRAMMATIC_COMMANDS.WEBVIEW_ROOT_MCP_SHOW);
    });
  });

  describe('insertCodeSnippet', () => {
    it('inserts snippet when valid snippet is provided', async () => {
      const snippet = 'const test = "hello";';
+11 −0
Original line number Diff line number Diff line
import * as vscode from 'vscode';
import { log } from '../../log';
import { DUO_CHAT_WEBVIEW_ID, AGENTIC_CHAT_WEBVIEW_ID } from '../../constants';
import { PROGRAMMATIC_COMMANDS } from '../../command_names';
import { getActiveFileContext } from '../../chat/gitlab_chat_file_context';
import { WebviewMessageRegistry } from '../message_handlers/webview_message_registry';
import { insertCodeSnippet as insertCodeSnippetFn } from '../../chat/insert_code_snippet';
@@ -99,6 +100,15 @@ export const openLink = async (params: OpenLinkParams | unknown) => {
    log.warn(e.message);
  }
};
/**
 * Reveals the MCP Dashboard webview. Opening a panel is host-specific, so the
 * Duo Agent Platform webview sends the `openMcpDashboard` notification and the
 * extension executes the command that shows the dashboard.
 */
export const openMcpDashboard = async () => {
  await vscode.commands.executeCommand(PROGRAMMATIC_COMMANDS.WEBVIEW_ROOT_MCP_SHOW);
};

export type WebviewId = typeof DUO_CHAT_WEBVIEW_ID | typeof AGENTIC_CHAT_WEBVIEW_ID;

export const registerDuoChatHandlers = (
@@ -116,4 +126,5 @@ export const registerDuoChatHandlers = (
  registry.onNotification(webviewId, 'openLink', openLink);
  registry.onNotification(webviewId, 'openUrl', openLink);
  registry.onNotification(webviewId, 'copyMessage', copyMessage);
  registry.onNotification(webviewId, 'openMcpDashboard', openMcpDashboard);
};
+5 −2
Original line number Diff line number Diff line
import { USER_COMMANDS as COMMON_USER_COMMANDS } from '../common/command_names';
import {
  USER_COMMANDS as COMMON_USER_COMMANDS,
  PROGRAMMATIC_COMMANDS as COMMON_PROGRAMMATIC_COMMANDS,
} from '../common/command_names';
/*
  Commands that can be triggered from the command palette or context menus.
  These commands must be exactly the same as the contributed commands in package.json.
@@ -71,7 +74,7 @@ export const USER_COMMANDS = {
  MCP_OPEN_USER_CONFIG: COMMON_USER_COMMANDS.MCP_OPEN_USER_CONFIG,
  MCP_OPEN_WORKSPACE_CONFIG: 'gl.mcp.openWorkspaceConfig',
  SHOW_KNOWLEDGE_GRAPH: 'gl.knowledgeGraph.show',
  WEBVIEW_ROOT_MCP_SHOW: 'gl.webview.root.mcp.show',
  WEBVIEW_ROOT_MCP_SHOW: COMMON_PROGRAMMATIC_COMMANDS.WEBVIEW_ROOT_MCP_SHOW,
  OPEN_FLOW_BUILDER: 'gl.openFlowBuilder',
  DUO_AGENT_PLATFORM_ENABLE_NEW_UI: 'gl.duoAgentPlatform.enableNewUi',
  DUO_AGENT_PLATFORM_DISABLE_NEW_UI: 'gl.duoAgentPlatform.disableNewUi',