From c32fd41f85703695be701f809e16c99296ce7b17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E5=85=AC?= Date: Fri, 11 Sep 2026 15:54:55 +0800 Subject: [PATCH] feat(desktop): hide sources panel add-source button behind launch flag The "+" button in the sources panel header serves no practical purpose in the current product flow, so it is now hidden by default. The code path is kept intact and can be re-enabled at launch with CRAFT_FEATURE_ADD_SOURCE_BUTTON=1. The flag is evaluated in the preload (which can read env vars) and exposed to the renderer as a preload-local API, following the getRuntimeEnvironment precedent. --- .../apps/electron/src/preload/bootstrap.ts | 2 ++ .../components/app-shell/AppShell.tsx | 4 ++-- .../src/renderer/playground/mock-utils.ts | 3 +++ .../desktop/apps/electron/src/shared/types.ts | 2 ++ .../__tests__/channel-map-parity.test.ts | 1 + .../desktop/apps/webui/src/adapter/web-api.ts | 1 + .../packages/shared/src/feature-flags.ts | 19 +++++++++++++++++++ 7 files changed, 30 insertions(+), 2 deletions(-) diff --git a/packages/desktop/apps/electron/src/preload/bootstrap.ts b/packages/desktop/apps/electron/src/preload/bootstrap.ts index fe8184b32d9..8e6b978d9d1 100644 --- a/packages/desktop/apps/electron/src/preload/bootstrap.ts +++ b/packages/desktop/apps/electron/src/preload/bootstrap.ts @@ -23,6 +23,7 @@ import { RoutedClient } from '../transport/routed-client' import { buildClientApi } from '../transport/build-api' import { CHANNEL_MAP } from '../transport/channel-map' import { createCallbackServer } from '@craft-agent/shared/auth/callback-server' +import { isAddSourceButtonEnabled } from '@craft-agent/shared/feature-flags' import { CLIENT_OPEN_EXTERNAL, CLIENT_OPEN_PATH, @@ -187,6 +188,7 @@ client.handleCapability(CLIENT_OPEN_FILE_DIALOG, async (spec: FileDialogSpec) => const api = buildClientApi(client, CHANNEL_MAP, (ch) => client.isChannelAvailable(ch)) ;(api as any).getRuntimeEnvironment = (): 'electron' | 'web' => 'electron' +;(api as any).isAddSourceButtonEnabled = (): boolean => isAddSourceButtonEnabled() // --------------------------------------------------------------------------- // Transport connection state logging (for remote connections) diff --git a/packages/desktop/apps/electron/src/renderer/components/app-shell/AppShell.tsx b/packages/desktop/apps/electron/src/renderer/components/app-shell/AppShell.tsx index f76515b6de2..b784a0fb56e 100644 --- a/packages/desktop/apps/electron/src/renderer/components/app-shell/AppShell.tsx +++ b/packages/desktop/apps/electron/src/renderer/components/app-shell/AppShell.tsx @@ -4970,8 +4970,8 @@ function AppShellContent({ )} - {/* Add Source button (only for sources mode) - uses filter-aware edit config */} - {isSourcesNavigation(navState) && activeWorkspace && ( + {/* Add Source button (only for sources mode) - uses filter-aware edit config. Hidden unless enabled via launch flag. */} + {isSourcesNavigation(navState) && activeWorkspace && window.electronAPI.isAddSourceButtonEnabled() && ( 'electron', + // Keep the sources panel "add source" button visible in the playground. + isAddSourceButtonEnabled: () => true, + openFileDialog: async () => { console.log('[Playground] openFileDialog called') return [] // Let user use file input or drag-drop diff --git a/packages/desktop/apps/electron/src/shared/types.ts b/packages/desktop/apps/electron/src/shared/types.ts index 4d500609818..8048cb570cd 100644 --- a/packages/desktop/apps/electron/src/shared/types.ts +++ b/packages/desktop/apps/electron/src/shared/types.ts @@ -519,6 +519,8 @@ export interface ElectronAPI { getVersions(): { node: string; chrome: string; electron: string }; /** Returns the renderer host environment without going through RPC. */ getRuntimeEnvironment(): 'electron' | 'web'; + /** Whether the sources panel "add source" header button is shown. Preload-local launch flag. */ + isAddSourceButtonEnabled(): boolean; getHomeDir(): Promise; isDebugMode(): Promise; diff --git a/packages/desktop/apps/electron/src/transport/__tests__/channel-map-parity.test.ts b/packages/desktop/apps/electron/src/transport/__tests__/channel-map-parity.test.ts index bb9bb01a7cd..be1ab0ecf13 100644 --- a/packages/desktop/apps/electron/src/transport/__tests__/channel-map-parity.test.ts +++ b/packages/desktop/apps/electron/src/transport/__tests__/channel-map-parity.test.ts @@ -17,6 +17,7 @@ type ApiToChannelMapKeys = Exclude< | 'performOAuth' | 'getTransportConnectionState' | 'getRuntimeEnvironment' + | 'isAddSourceButtonEnabled' // reads launch env var in the preload — no IPC needed | 'onTransportConnectionStateChanged' | 'reconnectTransport' | 'isChannelAvailable' diff --git a/packages/desktop/apps/webui/src/adapter/web-api.ts b/packages/desktop/apps/webui/src/adapter/web-api.ts index dd6324dcba8..12812ca1e98 100644 --- a/packages/desktop/apps/webui/src/adapter/web-api.ts +++ b/packages/desktop/apps/webui/src/adapter/web-api.ts @@ -109,6 +109,7 @@ export function createWebApi(options: WebApiOptions): { // System info getVersions: () => ({ node: 'n/a', chrome: navigator.userAgent, electron: 'web' }), getRuntimeEnvironment: () => 'web', + isAddSourceButtonEnabled: () => false, getSystemWarnings: () => Promise.resolve({ vcredistMissing: false }), isDebugMode: () => Promise.resolve(import.meta.env.DEV), diff --git a/packages/desktop/packages/shared/src/feature-flags.ts b/packages/desktop/packages/shared/src/feature-flags.ts index 60f20820cad..f40387c4d32 100644 --- a/packages/desktop/packages/shared/src/feature-flags.ts +++ b/packages/desktop/packages/shared/src/feature-flags.ts @@ -59,6 +59,17 @@ export function isEmbeddedServerEnabled(): boolean { return false; } +/** + * Runtime-evaluated check for the sources panel "add source" header button. + * + * Defaults to disabled. Override with CRAFT_FEATURE_ADD_SOURCE_BUTTON=1|0. + */ +export function isAddSourceButtonEnabled(): boolean { + const override = parseBooleanEnv(getEnv('CRAFT_FEATURE_ADD_SOURCE_BUTTON')); + if (override !== undefined) return override; + return false; +} + export const FEATURE_FLAGS = { /** Enable Opus 4.7 fast mode (speed:"fast" + beta header). 6x pricing. */ fastMode: false, @@ -89,4 +100,12 @@ export const FEATURE_FLAGS = { get embeddedServer(): boolean { return isEmbeddedServerEnabled(); }, + /** + * Show the "add source" button in the sources panel header. + * + * Defaults to disabled. Override with CRAFT_FEATURE_ADD_SOURCE_BUTTON=1|0. + */ + get addSourceButton(): boolean { + return isAddSourceButtonEnabled(); + }, } as const;