Skip to content

Commit 41bdcab

Browse files
CopilotPower-Maverick
authored andcommitted
[Feature] Add preview feature flagging, gate MCP Server behind it, move MCP icon to activity bar footer (#589)
* Add preview feature flagging and move MCP button to activity bar footer * Rename mcpBtn to mcpButton for consistency --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
1 parent 9dcdc25 commit 41bdcab

7 files changed

Lines changed: 51 additions & 5 deletions

File tree

src/common/types/settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,5 @@ export interface UserSettings {
9696
environmentColorThickness?: number; // Thickness in pixels of the environment color border around the tool panel
9797
mcpAccessToken?: string; // Access token for local MCP server authentication
9898
splitDividerRatio?: number; // Persisted position of the split-pane divider (0.15–0.85)
99+
enablePreviewFeatures?: boolean; // Show preview/experimental features in the UI
99100
}

src/main/managers/settingsManager.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export class SettingsManager {
3838
toolSecondaryConnections: {}, // Map of toolId to secondary connectionId
3939
connectionsSort: "last-used",
4040
restoreSessionOnStartup: true, // Reopen previously open tools on app start
41+
enablePreviewFeatures: false, // Show preview/experimental features in the UI
4142
},
4243
});
4344

src/renderer/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@
3232
<button class="activity-item" id="global-search-btn" title="Global Search (Ctrl+Shift+P)">
3333
<img id="search-icon" src="icons/dark/search.svg" alt="Search Icon" class="activity-icon" />
3434
</button>
35-
<button class="activity-item" id="agent-invocation-logs-btn" title="MCP Server">
36-
<img id="logs-icon" src="icons/dark/mcp.svg" alt="MCP Icon" class="activity-icon" />
37-
</button>
3835
<button class="activity-item" data-sidebar="links" title="Community Resources">
3936
<img id="links-icon" src="icons/dark/bookmark.svg" alt="Links Icon" class="activity-icon" />
4037
</button>
@@ -43,6 +40,9 @@
4340
</button>
4441
</nav>
4542
<nav class="activity-bar-footer">
43+
<button class="activity-item" id="agent-invocation-logs-btn" title="MCP Server (Preview)">
44+
<img id="logs-icon" src="icons/dark/mcp.svg" alt="MCP Icon" class="activity-icon" />
45+
</button>
4646
<button class="activity-item" id="settings-activity-btn" title="Settings">
4747
<img id="settings-icon" src="icons/dark/settings.svg" alt="Settings Icon" class="activity-icon" />
4848
</button>

src/renderer/modules/initialization.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import { initNotificationHistoryPanel, setDefaultNotificationDuration, showPPTBN
3434
import { openSettingsTab } from "./settingsManagement";
3535
import { switchSidebar } from "./sidebarManagement";
3636
import { handleTerminalClosed, handleTerminalCommandCompleted, handleTerminalCreated, handleTerminalError, handleTerminalOutput, setupTerminalPanel } from "./terminalManagement";
37-
import { applyDebugMenuVisibility, applyTerminalFont, applyTheme } from "./themeManagement";
37+
import { applyDebugMenuVisibility, applyPreviewFeaturesVisibility, applyTerminalFont, applyTheme } from "./themeManagement";
3838
import {
3939
applyAppearanceSettings,
4040
closeAllTools,
@@ -646,6 +646,7 @@ async function loadInitialSettings(): Promise<void> {
646646
applyTheme(settings.theme);
647647
applyTerminalFont(settings.terminalFont || DEFAULT_TERMINAL_FONT);
648648
applyDebugMenuVisibility(settings.showDebugMenu ?? false);
649+
applyPreviewFeaturesVisibility(settings.enablePreviewFeatures ?? false);
649650
setDefaultNotificationDuration(settings.notificationDuration ?? DEFAULT_NOTIFICATION_DURATION);
650651
applyAppearanceSettings(
651652
settings.showCategoryColor ?? DEFAULT_SHOW_CATEGORY_COLOR,

src/renderer/modules/settingsManagement.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
import type { SettingsState } from "../types/index";
1818
import { loadMarketplace } from "./marketplaceManagement";
1919
import { setDefaultNotificationDuration } from "./notifications";
20-
import { applyDebugMenuVisibility, applyTerminalFont, applyTheme } from "./themeManagement";
20+
import { applyDebugMenuVisibility, applyPreviewFeaturesVisibility, applyTerminalFont, applyTheme } from "./themeManagement";
2121
import { applyAppearanceSettings, openLocalPageAsTab, registerCloseGuard } from "./toolManagement";
2222
import { loadSidebarTools } from "./toolsSidebarManagement";
2323

@@ -42,6 +42,7 @@ export async function loadSettings(): Promise<void> {
4242
const showEnvironmentColorCheck = document.getElementById("sidebar-show-environment-color-check") as HTMLInputElement | null;
4343
const categoryColorThicknessInput = document.getElementById("sidebar-category-color-thickness") as HTMLInputElement | null;
4444
const environmentColorThicknessInput = document.getElementById("sidebar-environment-color-thickness") as HTMLInputElement | null;
45+
const enablePreviewFeaturesCheck = document.getElementById("sidebar-enable-preview-features-check") as HTMLInputElement | null;
4546

4647
if (themeSelect && autoUpdateCheck && showDebugMenuCheck && deprecatedToolsSelect && toolDisplayModeSelect && terminalFontSelect) {
4748
const settings = await window.toolboxAPI.getUserSettings();
@@ -60,6 +61,7 @@ export async function loadSettings(): Promise<void> {
6061
showEnvironmentColor: settings.showEnvironmentColor ?? DEFAULT_SHOW_ENVIRONMENT_COLOR,
6162
categoryColorThickness: settings.categoryColorThickness ?? DEFAULT_CATEGORY_COLOR_THICKNESS,
6263
environmentColorThickness: settings.environmentColorThickness ?? DEFAULT_ENVIRONMENT_COLOR_THICKNESS,
64+
enablePreviewFeatures: settings.enablePreviewFeatures ?? false,
6365
};
6466

6567
themeSelect.value = settings.theme;
@@ -87,6 +89,9 @@ export async function loadSettings(): Promise<void> {
8789
if (environmentColorThicknessInput) {
8890
environmentColorThicknessInput.value = String(settings.environmentColorThickness ?? DEFAULT_ENVIRONMENT_COLOR_THICKNESS);
8991
}
92+
if (enablePreviewFeaturesCheck) {
93+
enablePreviewFeaturesCheck.checked = settings.enablePreviewFeatures ?? false;
94+
}
9095

9196
const terminalFont = settings.terminalFont || DEFAULT_TERMINAL_FONT;
9297

@@ -132,6 +137,7 @@ export async function saveSettings(): Promise<void> {
132137
const showEnvironmentColorCheck = document.getElementById("sidebar-show-environment-color-check") as HTMLInputElement | null;
133138
const categoryColorThicknessInput = document.getElementById("sidebar-category-color-thickness") as HTMLInputElement | null;
134139
const environmentColorThicknessInput = document.getElementById("sidebar-environment-color-thickness") as HTMLInputElement | null;
140+
const enablePreviewFeaturesCheck = document.getElementById("sidebar-enable-preview-features-check") as HTMLInputElement | null;
135141

136142
if (!themeSelect || !autoUpdateCheck || !showDebugMenuCheck || !deprecatedToolsSelect || !toolDisplayModeSelect || !terminalFontSelect) return;
137143

@@ -151,6 +157,7 @@ export async function saveSettings(): Promise<void> {
151157
const environmentColorThickness = environmentColorThicknessInput
152158
? Math.min(MAX_COLOR_BORDER_THICKNESS, Math.max(MIN_COLOR_BORDER_THICKNESS, Number(environmentColorThicknessInput.value) || DEFAULT_ENVIRONMENT_COLOR_THICKNESS))
153159
: DEFAULT_ENVIRONMENT_COLOR_THICKNESS;
160+
const enablePreviewFeatures = enablePreviewFeaturesCheck ? enablePreviewFeaturesCheck.checked : false;
154161

155162
const currentSettings = {
156163
theme: themeSelect.value,
@@ -165,6 +172,7 @@ export async function saveSettings(): Promise<void> {
165172
showEnvironmentColor,
166173
categoryColorThickness,
167174
environmentColorThickness,
175+
enablePreviewFeatures,
168176
};
169177

170178
// Only include changed settings in the update
@@ -206,6 +214,9 @@ export async function saveSettings(): Promise<void> {
206214
if (currentSettings.environmentColorThickness !== originalSettings.environmentColorThickness) {
207215
changedSettings.environmentColorThickness = currentSettings.environmentColorThickness;
208216
}
217+
if (currentSettings.enablePreviewFeatures !== (originalSettings.enablePreviewFeatures ?? false)) {
218+
changedSettings.enablePreviewFeatures = currentSettings.enablePreviewFeatures;
219+
}
209220

210221
// Only save and emit event if something changed
211222
if (Object.keys(changedSettings).length > 0) {
@@ -215,6 +226,7 @@ export async function saveSettings(): Promise<void> {
215226
applyTheme(currentSettings.theme);
216227
applyTerminalFont(currentSettings.terminalFont);
217228
applyDebugMenuVisibility(currentSettings.showDebugMenu);
229+
applyPreviewFeaturesVisibility(currentSettings.enablePreviewFeatures);
218230
setDefaultNotificationDuration(currentSettings.notificationDuration);
219231
applyAppearanceSettings(currentSettings.showCategoryColor, currentSettings.showEnvironmentColor, currentSettings.categoryColorThickness, currentSettings.environmentColorThickness);
220232

@@ -267,6 +279,7 @@ function hasUnsavedChanges(): boolean {
267279
const showEnvironmentColorCheck = document.getElementById("sidebar-show-environment-color-check") as HTMLInputElement | null;
268280
const categoryColorThicknessInput = document.getElementById("sidebar-category-color-thickness") as HTMLInputElement | null;
269281
const environmentColorThicknessInput = document.getElementById("sidebar-environment-color-thickness") as HTMLInputElement | null;
282+
const enablePreviewFeaturesCheck = document.getElementById("sidebar-enable-preview-features-check") as HTMLInputElement | null;
270283

271284
// If the DOM elements aren't present the settings panel isn't rendered — no unsaved changes
272285
if (!themeSelect || !autoUpdateCheck || !showDebugMenuCheck || !deprecatedToolsSelect || !toolDisplayModeSelect || !terminalFontSelect) {
@@ -296,6 +309,7 @@ function hasUnsavedChanges(): boolean {
296309
const val = Math.min(MAX_COLOR_BORDER_THICKNESS, Math.max(MIN_COLOR_BORDER_THICKNESS, Number(environmentColorThicknessInput.value) || DEFAULT_ENVIRONMENT_COLOR_THICKNESS));
297310
if (val !== (originalSettings.environmentColorThickness ?? DEFAULT_ENVIRONMENT_COLOR_THICKNESS)) return true;
298311
}
312+
if (enablePreviewFeaturesCheck && enablePreviewFeaturesCheck.checked !== (originalSettings.enablePreviewFeatures ?? false)) return true;
299313

300314
return false;
301315
}
@@ -513,6 +527,23 @@ export function renderSettingsContent(panel: HTMLElement): void {
513527
</div>
514528
</section>
515529
530+
<section id="settings-section-preview" class="settings-vscode-section">
531+
<h2 class="settings-vscode-section-title">Preview Features</h2>
532+
533+
<div class="settings-vscode-item">
534+
<div class="settings-vscode-item-info">
535+
<label class="settings-vscode-item-label" for="sidebar-enable-preview-features-check">Enable Preview Features</label>
536+
<p class="settings-vscode-item-description">Show experimental and preview features in the UI. These features are still in development and may change or be removed. Currently includes: MCP Server.</p>
537+
</div>
538+
<div class="settings-vscode-item-control">
539+
<label class="settings-vscode-checkbox-label">
540+
<input type="checkbox" id="sidebar-enable-preview-features-check" class="settings-vscode-checkbox" />
541+
<span>Enable</span>
542+
</label>
543+
</div>
544+
</div>
545+
</section>
546+
516547
<div class="settings-vscode-actions">
517548
<button id="sidebar-save-settings-btn" class="fluent-button fluent-button-primary">Save Settings</button>
518549
<span class="settings-vscode-item-description">Changes apply instantly after saving.</span>

src/renderer/modules/themeManagement.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,3 +317,14 @@ export function applyDebugMenuVisibility(showDebugMenu: boolean): void {
317317
debugActivityItem.style.display = showDebugMenu ? "" : "none";
318318
}
319319
}
320+
321+
/**
322+
* Apply preview features visibility setting
323+
* Controls visibility of preview-gated items (e.g. the MCP Server button)
324+
*/
325+
export function applyPreviewFeaturesVisibility(enablePreviewFeatures: boolean): void {
326+
const mcpButton = document.getElementById("agent-invocation-logs-btn") as HTMLElement | null;
327+
if (mcpButton) {
328+
mcpButton.style.display = enablePreviewFeatures ? "" : "none";
329+
}
330+
}

src/renderer/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export interface SettingsState {
6262
showEnvironmentColor?: boolean;
6363
categoryColorThickness?: number;
6464
environmentColorThickness?: number;
65+
enablePreviewFeatures?: boolean;
6566
}
6667

6768
/**

0 commit comments

Comments
 (0)