diff --git a/apps/studio/e2e/e2e-helpers.ts b/apps/studio/e2e/e2e-helpers.ts index 146309359a..d9998ddb1a 100644 --- a/apps/studio/e2e/e2e-helpers.ts +++ b/apps/studio/e2e/e2e-helpers.ts @@ -1,7 +1,6 @@ import { randomUUID } from 'crypto'; import { tmpdir } from 'os'; import path from 'path'; -import { isErrnoException } from '@studio/common/lib/is-errno-exception'; import { findLatestBuild, parseElectronApp } from 'electron-playwright-helpers'; import fs from 'fs-extra'; import { _electron as electron, Page, ElectronApplication } from 'playwright'; diff --git a/apps/studio/src/components/content-tab-assistant.tsx b/apps/studio/src/components/content-tab-assistant.tsx index e9d121f27c..ce006b75c3 100644 --- a/apps/studio/src/components/content-tab-assistant.tsx +++ b/apps/studio/src/components/content-tab-assistant.tsx @@ -20,7 +20,6 @@ import { StudioCodeSession } from 'src/components/studio-code-session'; import WelcomeComponent from 'src/components/welcome-message-prompt'; import { LIMIT_OF_PROMPTS_PER_USER, TELEX_HOSTNAME, TELEX_UTM_PARAMS } from 'src/constants'; import { useAuth } from 'src/hooks/use-auth'; -import { useFeatureFlags } from 'src/hooks/use-feature-flags'; import { useOffline } from 'src/hooks/use-offline'; import { useThemeDetails } from 'src/hooks/use-theme-details'; import { cx } from 'src/lib/cx'; @@ -359,7 +358,9 @@ const UnauthenticatedView = ( { onAuthenticate }: { onAuthenticate: () => void } ); export function ContentTabAssistant( { selectedSite }: ContentTabAssistantProps ) { - const { enableStudioCodeUi } = useFeatureFlags(); + const enableStudioCodeUi = useRootSelector( + ( state ) => state.betaFeatures.features.enableStudioCodeUi + ); if ( enableStudioCodeUi ) { return ; diff --git a/apps/studio/src/components/site-content-tabs.tsx b/apps/studio/src/components/site-content-tabs.tsx index 0522fc6529..5fb60adcd5 100644 --- a/apps/studio/src/components/site-content-tabs.tsx +++ b/apps/studio/src/components/site-content-tabs.tsx @@ -9,9 +9,9 @@ import { ContentTabSettings } from 'src/components/content-tab-settings'; import Header from 'src/components/header'; import { SiteIsBeingCreated } from 'src/components/site-is-being-created'; import { MIN_WIDTH_CLASS_TO_MEASURE } from 'src/constants'; +import { useBetaFeatures } from 'src/hooks/use-beta-features'; import { TabName } from 'src/hooks/use-content-tabs'; import { useEffectiveTab } from 'src/hooks/use-effective-tab'; -import { useFeatureFlags } from 'src/hooks/use-feature-flags'; import { useImportExport } from 'src/hooks/use-import-export'; import { useSiteDetails } from 'src/hooks/use-site-details'; import { cx } from 'src/lib/cx'; @@ -21,7 +21,7 @@ export function SiteContentTabs() { const { selectedSite, siteCreationMessages } = useSiteDetails(); const { importState } = useImportExport(); const { effectiveTab, selectedTab, setSelectedTab, tabs } = useEffectiveTab(); - const { enableStudioCodeUi } = useFeatureFlags(); + const { enableStudioCodeUi } = useBetaFeatures(); const { __ } = useI18n(); // Remount: Avoid focus loss on user tab changes (no remount), diff --git a/apps/studio/src/components/tests/content-tab-settings.test.tsx b/apps/studio/src/components/tests/content-tab-settings.test.tsx index 04e86020ca..96de8946ce 100644 --- a/apps/studio/src/components/tests/content-tab-settings.test.tsx +++ b/apps/studio/src/components/tests/content-tab-settings.test.tsx @@ -38,7 +38,7 @@ const snapshotTestActions = { let testStore = createTestStore( { preloadedState: { betaFeatures: { - features: { remoteSession: false, nativePhpRuntime: false }, + features: { enableStudioCodeUi: false, remoteSession: false, nativePhpRuntime: false }, loading: false, }, }, @@ -49,7 +49,7 @@ function createCustomTestStore( nativePhpRuntime = false ) { const store = createTestStore( { preloadedState: { betaFeatures: { - features: { remoteSession: false, nativePhpRuntime }, + features: { enableStudioCodeUi: false, remoteSession: false, nativePhpRuntime }, loading: false, }, }, diff --git a/apps/studio/src/components/tests/remote-session-indicator.test.tsx b/apps/studio/src/components/tests/remote-session-indicator.test.tsx index c0ec034575..2024e13c83 100644 --- a/apps/studio/src/components/tests/remote-session-indicator.test.tsx +++ b/apps/studio/src/components/tests/remote-session-indicator.test.tsx @@ -32,7 +32,7 @@ function setupHooks( { isRunning: boolean; isLoading?: boolean; } ) { - vi.mocked( useBetaFeatures ).mockReturnValue( { remoteSession } ); + vi.mocked( useBetaFeatures ).mockReturnValue( { enableStudioCodeUi: false, remoteSession } ); vi.mocked( useAuth, { partial: true } ).mockReturnValue( { isAuthenticated } ); vi.mocked( useRemoteSessionStatus ).mockReturnValue( { status: isRunning ? { running: true } : undefined, diff --git a/apps/studio/src/ipc-types.d.ts b/apps/studio/src/ipc-types.d.ts index 7f519ea262..3cf17ede31 100644 --- a/apps/studio/src/ipc-types.d.ts +++ b/apps/studio/src/ipc-types.d.ts @@ -99,11 +99,11 @@ type IpcApi = { interface FeatureFlags { enableBlueprints: boolean; - enableStudioCodeUi: boolean; enableDesksUiSwitch: boolean; } interface BetaFeatures { + enableStudioCodeUi: boolean; remoteSession: boolean; nativePhpRuntime?: boolean; } diff --git a/apps/studio/src/lib/beta-features.ts b/apps/studio/src/lib/beta-features.ts index 45a07ed2f8..5ec6677a7d 100644 --- a/apps/studio/src/lib/beta-features.ts +++ b/apps/studio/src/lib/beta-features.ts @@ -13,6 +13,7 @@ export interface BetaFeatureDefinition { * Default values for beta features. */ const BETA_FEATURE_DEFAULTS: Record< keyof BetaFeatures, boolean > = { + enableStudioCodeUi: false, remoteSession: false, nativePhpRuntime: false, }; @@ -23,6 +24,12 @@ const BETA_FEATURE_DEFAULTS: Record< keyof BetaFeatures, boolean > = { */ export function getBetaFeaturesDefinition(): Record< keyof BetaFeatures, BetaFeatureDefinition > { return { + enableStudioCodeUi: { + label: __( 'Studio Code Desktop' ), + key: 'enableStudioCodeUi', + default: BETA_FEATURE_DEFAULTS.enableStudioCodeUi, + description: __( 'Try the new Studio Code Desktop assistant.' ), + }, remoteSession: { label: __( 'Remote Session' ), key: 'remoteSession', diff --git a/apps/studio/src/lib/feature-flags.ts b/apps/studio/src/lib/feature-flags.ts index a8facdbfbc..8a00304887 100644 --- a/apps/studio/src/lib/feature-flags.ts +++ b/apps/studio/src/lib/feature-flags.ts @@ -12,12 +12,6 @@ export const FEATURE_FLAGS: Record< keyof FeatureFlags, FeatureFlagDefinition > flag: 'enableBlueprints', default: true, }, - enableStudioCodeUi: { - label: 'Enable Studio Code UI', - env: 'ENABLE_STUDIO_CODE_UI', - flag: 'enableStudioCodeUi', - default: false, - }, enableDesksUiSwitch: { label: 'Enable Studio UI Switcher', env: 'ENABLE_DESKS_UI_SWITCH', diff --git a/apps/studio/src/modules/site-settings/tests/edit-site-details.test.tsx b/apps/studio/src/modules/site-settings/tests/edit-site-details.test.tsx index 38ddf58ddf..50100c7a4f 100644 --- a/apps/studio/src/modules/site-settings/tests/edit-site-details.test.tsx +++ b/apps/studio/src/modules/site-settings/tests/edit-site-details.test.tsx @@ -73,7 +73,7 @@ const renderWithProvider = ( children: React.ReactElement, nativePhpRuntime = fa const store = createTestStore( { preloadedState: { betaFeatures: { - features: { remoteSession: false, nativePhpRuntime }, + features: { enableStudioCodeUi: false, remoteSession: false, nativePhpRuntime }, loading: false, }, }, diff --git a/apps/studio/src/stores/beta-features-slice.ts b/apps/studio/src/stores/beta-features-slice.ts index 5706690120..cb8745c2b3 100644 --- a/apps/studio/src/stores/beta-features-slice.ts +++ b/apps/studio/src/stores/beta-features-slice.ts @@ -8,7 +8,7 @@ type BetaFeaturesState = { }; const initialState: BetaFeaturesState = { - features: { remoteSession: false, nativePhpRuntime: false }, + features: { enableStudioCodeUi: false, remoteSession: false, nativePhpRuntime: false }, loading: false, };