From 4d922da2a6a29fdf49287176bae11401aaf02b75 Mon Sep 17 00:00:00 2001 From: Alejandro Bailo <59607668+alejandrobailo@users.noreply.github.com> Date: Mon, 19 Oct 2026 20:19:07 +0200 Subject: [PATCH] refactor(ui): remove the skill launcher flag and keep the chip rail (#13097) --- .../lighthouse-skills-block.test.tsx | 90 -------------- .../lighthouse-skills-block.tsx | 92 -------------- .../lighthouse-skills-rail.tsx | 6 +- .../resource-detail-drawer-content.test.tsx | 113 ++---------------- .../resource-detail-drawer-content.tsx | 32 +---- .../use-skill-launcher-variant.test.ts | 44 ------- .../use-skill-launcher-variant.ts | 17 --- ui/lib/feature-flags/client.test.ts | 74 ++---------- ui/lib/feature-flags/client.ts | 17 +-- ui/lib/feature-flags/shared.test.ts | 1 - ui/lib/feature-flags/shared.ts | 3 - ui/types/lighthouse-skills.ts | 10 -- 12 files changed, 22 insertions(+), 477 deletions(-) delete mode 100644 ui/components/findings/table/resource-detail-drawer/lighthouse-skills-block.test.tsx delete mode 100644 ui/components/findings/table/resource-detail-drawer/lighthouse-skills-block.tsx delete mode 100644 ui/components/findings/table/resource-detail-drawer/use-skill-launcher-variant.test.ts delete mode 100644 ui/components/findings/table/resource-detail-drawer/use-skill-launcher-variant.ts diff --git a/ui/components/findings/table/resource-detail-drawer/lighthouse-skills-block.test.tsx b/ui/components/findings/table/resource-detail-drawer/lighthouse-skills-block.test.tsx deleted file mode 100644 index 53e8362757..0000000000 --- a/ui/components/findings/table/resource-detail-drawer/lighthouse-skills-block.test.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { render, screen } from "@testing-library/react"; -import userEvent from "@testing-library/user-event"; -import { describe, expect, it, vi } from "vitest"; - -import { LighthouseSkillsBlock } from "./lighthouse-skills-block"; - -describe("LighthouseSkillsBlock", () => { - it("should render every skill with its description", () => { - // Given / When - render( - , - ); - - // Then - expect(screen.getByText("Lighthouse AI Skills")).toBeInTheDocument(); - expect(screen.getByText("Contextual Fix")).toBeInTheDocument(); - expect(screen.getByText("Triage Decision")).toBeInTheDocument(); - expect(screen.getByText("Systemic Scope")).toBeInTheDocument(); - expect(screen.getByText("Compliance Impact")).toBeInTheDocument(); - expect( - screen.getByText("Is this real, and if not, close it out"), - ).toBeInTheDocument(); - }); - - it("should launch the clicked skill", async () => { - // Given - const user = userEvent.setup(); - const onLaunchSkill = vi.fn(); - render( - , - ); - - // When - await user.click(screen.getByRole("button", { name: /Triage Decision/ })); - - // Then - expect(onLaunchSkill).toHaveBeenCalledOnce(); - expect(onLaunchSkill.mock.calls[0][0]).toMatchObject({ - id: "triage-decision", - }); - }); - - it("should render disabled skills as coming soon and not launch them", async () => { - // Given - const user = userEvent.setup(); - const onLaunchSkill = vi.fn(); - render( - , - ); - - // Then - const card = screen.getByRole("button", { name: /Compliance Impact/ }); - expect(card).toBeDisabled(); - expect(screen.getByText("Coming soon")).toBeInTheDocument(); - - // When - await user.click(card); - - // Then - expect(onLaunchSkill).not.toHaveBeenCalled(); - }); - - it("should keep the free-form fallback available", async () => { - // Given - const user = userEvent.setup(); - const onAskAnything = vi.fn(); - render( - , - ); - - // When - await user.click( - screen.getByRole("button", { - name: /ask Lighthouse anything about this finding/i, - }), - ); - - // Then - expect(onAskAnything).toHaveBeenCalledOnce(); - }); -}); diff --git a/ui/components/findings/table/resource-detail-drawer/lighthouse-skills-block.tsx b/ui/components/findings/table/resource-detail-drawer/lighthouse-skills-block.tsx deleted file mode 100644 index 073c7fb2ef..0000000000 --- a/ui/components/findings/table/resource-detail-drawer/lighthouse-skills-block.tsx +++ /dev/null @@ -1,92 +0,0 @@ -"use client"; - -import { ArrowRight } from "lucide-react"; - -import { LighthouseIcon } from "@/components/icons"; -import { Card } from "@/components/shadcn/card/card"; -import { getAllSkills } from "@/lib/lighthouse/skills/registry"; -import type { LighthouseSkillDefinition } from "@/types/lighthouse-skills"; - -interface LighthouseSkillsBlockProps { - onLaunchSkill: (skill: LighthouseSkillDefinition) => void; - onAskAnything: () => void; -} - -// Finding-detail CTA: a grid of launchable agentic workflows plus -// the free-form "ask anything" fallback that the old gradient banner offered. -export function LighthouseSkillsBlock({ - onLaunchSkill, - onAskAnything, -}: LighthouseSkillsBlockProps) { - return ( - -
- - - Lighthouse AI Skills - - - Run in chat - -
-
- {getAllSkills().map((skill) => ( - onLaunchSkill(skill)} - /> - ))} -
- -
- ); -} - -function SkillCard({ - skill, - onLaunch, -}: { - skill: LighthouseSkillDefinition; - onLaunch: () => void; -}) { - const Icon = skill.icon; - - return ( - - ); -} diff --git a/ui/components/findings/table/resource-detail-drawer/lighthouse-skills-rail.tsx b/ui/components/findings/table/resource-detail-drawer/lighthouse-skills-rail.tsx index 8a9abd7331..1b5eb28ea0 100644 --- a/ui/components/findings/table/resource-detail-drawer/lighthouse-skills-rail.tsx +++ b/ui/components/findings/table/resource-detail-drawer/lighthouse-skills-rail.tsx @@ -24,9 +24,9 @@ interface LighthouseSkillsRailProps { onSubmitPrompt: (text: string) => void; } -// Finding-detail skill launcher, "dropdown" experiment variant (chip rail): -// one compact row under the finding title — direct-launch chips plus a +N -// trigger opening the same skills menu used by the table row surfaces. +// Finding-detail skill launcher (chip rail): one compact row under the +// finding title — direct-launch chips plus a +N trigger opening the same +// skills menu used by the table row surfaces. export function LighthouseSkillsRail({ onLaunchSkill, onSubmitPrompt, diff --git a/ui/components/findings/table/resource-detail-drawer/resource-detail-drawer-content.test.tsx b/ui/components/findings/table/resource-detail-drawer/resource-detail-drawer-content.test.tsx index a8a55195fb..e9eae3ee65 100644 --- a/ui/components/findings/table/resource-detail-drawer/resource-detail-drawer-content.test.tsx +++ b/ui/components/findings/table/resource-detail-drawer/resource-detail-drawer-content.test.tsx @@ -28,7 +28,6 @@ const { mockRequestPanelChatMessage, mockRequestPanelSkillLaunch, mockIsCloud, - mockUseSkillLauncherVariant, mockCurrentLighthouseContext, } = vi.hoisted(() => ({ mockGetComplianceIcon: vi.fn((_: string) => null as string | null), @@ -43,7 +42,6 @@ const { mockRequestPanelChatMessage: vi.fn(), mockRequestPanelSkillLaunch: vi.fn(), mockIsCloud: vi.fn(() => true), - mockUseSkillLauncherVariant: vi.fn(() => "card"), mockCurrentLighthouseContext: { schemaVersion: 1, transport: "inline", @@ -310,10 +308,6 @@ vi.mock("@/components/icons", () => ({ LighthouseIcon: () => null, })); -vi.mock("./use-skill-launcher-variant", () => ({ - useSkillLauncherVariant: mockUseSkillLauncherVariant, -})); - vi.mock("@/components/icons/services/IconServices", () => ({ JiraIcon: () => null, })); @@ -571,7 +565,6 @@ afterEach(() => { (_: string) => null as string | null, ); mockIsCloud.mockReturnValue(true); - mockUseSkillLauncherVariant.mockReturnValue("card"); useSidePanelStore.setState({ isOpen: false, selectedTab: SIDE_PANEL_TAB.AI_CHAT, @@ -840,82 +833,7 @@ const mockResourceRow: FindingResourceRow = { lastSeenAt: null, }; -describe("ResourceDetailDrawerContent — Lighthouse AI", () => { - it("should open the Lighthouse tab without starting a conversation", async () => { - // Given - const user = userEvent.setup(); - useSidePanelStore.setState({ - isOpen: true, - selectedTab: SIDE_PANEL_TAB.CONTEXT, - }); - render( - , - ); - - // When: the free-form fallback only navigates to the chat tab - await user.click( - screen.getByRole("button", { - name: /ask Lighthouse anything about this finding/i, - }), - ); - - // Then — no conversation is started on the user's behalf - expect(mockRequestPanelChatMessage).not.toHaveBeenCalled(); - expect(useSidePanelStore.getState()).toMatchObject({ - isOpen: true, - selectedTab: SIDE_PANEL_TAB.AI_CHAT, - }); - - // And launching a skill goes through the skill launcher with the context - await user.click(screen.getByRole("button", { name: /Triage Decision/ })); - expect(mockRequestPanelSkillLaunch).toHaveBeenCalledWith( - expect.objectContaining({ id: "triage-decision" }), - mockCurrentLighthouseContext, - ); - }); - - it("should hide the action when the Lighthouse panel tab is unavailable", () => { - // Given - mockIsCloud.mockReturnValue(false); - - // When - render( - , - ); - - // Then - expect(screen.queryByText("Lighthouse AI Skills")).not.toBeInTheDocument(); - expect( - screen.queryByRole("button", { - name: /ask Lighthouse anything about this finding/i, - }), - ).not.toBeInTheDocument(); - }); -}); - -describe("ResourceDetailDrawerContent — skill launcher experiment", () => { +describe("ResourceDetailDrawerContent — Lighthouse skills rail", () => { const renderDrawer = (overrides: { isNavigating?: boolean } = {}) => render( { />, ); - it("should swap the footer card for the header chip rail on the dropdown variant", async () => { + it("should launch a skill from the header chip rail", async () => { // Given const user = userEvent.setup(); - mockUseSkillLauncherVariant.mockReturnValue("dropdown"); renderDrawer(); - // Then — control card gone, rail chips present. The always-open dropdown - // mock repeats every skill as a menu button, hence getAllByRole. - expect(screen.queryByText("Lighthouse AI Skills")).not.toBeInTheDocument(); + // Then — rail chips present. The always-open dropdown mock repeats every + // skill as a menu button, hence getAllByRole. expect( screen.getAllByRole("button", { name: "Contextual Fix" }).length, ).toBeGreaterThan(0); @@ -964,7 +880,6 @@ describe("ResourceDetailDrawerContent — skill launcher experiment", () => { it("should start a fresh conversation from the rail prompt", async () => { // Given const user = userEvent.setup(); - mockUseSkillLauncherVariant.mockReturnValue("dropdown"); renderDrawer(); // When @@ -989,7 +904,6 @@ describe("ResourceDetailDrawerContent — skill launcher experiment", () => { it("should hide the rail outside cloud and while navigating", () => { // Given - mockUseSkillLauncherVariant.mockReturnValue("dropdown"); mockIsCloud.mockReturnValue(false); // When @@ -1012,21 +926,6 @@ describe("ResourceDetailDrawerContent — skill launcher experiment", () => { screen.queryByRole("button", { name: "Contextual Fix" }), ).not.toBeInTheDocument(); }); - - it("should keep the card control for unresolved or unknown variants", () => { - // Given — the hook already collapses those to "card"; the drawer treats - // anything that is not exactly "dropdown" as control. - mockUseSkillLauncherVariant.mockReturnValue("card"); - - // When - renderDrawer(); - - // Then - expect(screen.getByText("Lighthouse AI Skills")).toBeInTheDocument(); - expect( - screen.queryByRole("button", { name: "More Lighthouse skills" }), - ).not.toBeInTheDocument(); - }); }); describe("ResourceDetailDrawerContent — remediation code editors", () => { @@ -1914,7 +1813,9 @@ describe("ResourceDetailDrawerContent — header skeleton while navigating", () expect(screen.getByText("security")).toBeInTheDocument(); expect(screen.queryByText("Status Extended:")).not.toBeInTheDocument(); expect(screen.queryByText("uid-1")).not.toBeInTheDocument(); - expect(screen.queryByText("Lighthouse AI Skills")).not.toBeInTheDocument(); + expect( + screen.queryByRole("button", { name: "More Lighthouse skills" }), + ).not.toBeInTheDocument(); }); it("should keep the overview tab shell visible with section skeletons when navigating to a different check", () => { diff --git a/ui/components/findings/table/resource-detail-drawer/resource-detail-drawer-content.tsx b/ui/components/findings/table/resource-detail-drawer/resource-detail-drawer-content.tsx index a02617e3c1..24fff8df1c 100644 --- a/ui/components/findings/table/resource-detail-drawer/resource-detail-drawer-content.tsx +++ b/ui/components/findings/table/resource-detail-drawer/resource-detail-drawer-content.tsx @@ -91,10 +91,7 @@ import type { UpdateFindingTriageInput, } from "@/types/findings-triage"; import { JIRA_DISPATCH_TARGET } from "@/types/integrations"; -import { - SKILL_LAUNCHER_VARIANT, - type LighthouseSkillDefinition, -} from "@/types/lighthouse-skills"; +import type { LighthouseSkillDefinition } from "@/types/lighthouse-skills"; import { Muted } from "../../muted"; import { DeltaIndicator } from "../delta-indicator"; @@ -105,11 +102,9 @@ import { } from "../finding-triage-cells"; import { DeltaValues, NotificationIndicator } from "../notification-indicator"; -import { LighthouseSkillsBlock } from "./lighthouse-skills-block"; import { LighthouseSkillsRail } from "./lighthouse-skills-rail"; import { ResourceDetailSkeleton } from "./resource-detail-skeleton"; import type { CheckMeta } from "./use-resource-detail-drawer"; -import { useSkillLauncherVariant } from "./use-skill-launcher-variant"; const OTHER_FINDINGS_ACTION_CELL_CLASS = "sticky right-0 z-20 min-w-12 last:rounded-r-none! overflow-visible bg-bg-neutral-secondary before:pointer-events-none before:absolute before:inset-y-0 before:-left-8 before:w-8 before:bg-gradient-to-r before:from-transparent before:to-bg-neutral-secondary before:content-[''] group-hover:bg-bg-neutral-tertiary group-hover:before:to-bg-neutral-tertiary"; @@ -322,10 +317,6 @@ export function ResourceDetailDrawerContent({ const searchParams = useSearchParams(); const openSidePanel = useSidePanelStore((state) => state.openPanel); const lighthouseContext = useLighthouseCurrentContext(); - // A/B experiment: PostHog decides between the footer card (control) and - // the header chip rail. Falls back to the card until the flag resolves. - const isDropdownLauncher = - useSkillLauncherVariant() === SKILL_LAUNCHER_VARIANT.DROPDOWN; const [isMuteModalOpen, setIsMuteModalOpen] = useState(false); const [optimisticallyMutedIds, setOptimisticallyMutedIds] = useState< Set @@ -471,19 +462,11 @@ export function ResourceDetailDrawerContent({ return result; }; - // Navigation only: the panel picks up the focused finding as context on its - // own, so no conversation is started on the user's behalf. - const handleOpenLighthouseChat = () => { - openSidePanel(SIDE_PANEL_TAB.AI_CHAT); - }; - const handleLaunchSkill = (skill: LighthouseSkillDefinition) => { openSidePanel(SIDE_PANEL_TAB.AI_CHAT); requestPanelSkillLaunch(skill, lighthouseContext.context); }; - // TODO(experiment): capture launch origin + skill id via cloud's - // trackEvent/ANALYTICS_EVENTS once the flag readout event lands. const handleSubmitPrompt = (text: string) => { openSidePanel(SIDE_PANEL_TAB.AI_CHAT); requestPanelChatMessage(text, lighthouseContext.context); @@ -596,9 +579,8 @@ export function ResourceDetailDrawerContent({ )} - {/* Skill launcher experiment, "dropdown" variant: chip rail under the - title instead of the footer card. */} - {isCloud() && !isNavigating && isDropdownLauncher && ( + {/* Lighthouse skill launcher: chip rail under the title. */} + {isCloud() && !isNavigating && ( - - {/* Lighthouse AI Skills (design 1d) — the experiment's card control */} - {isCloud() && !isNavigating && !isDropdownLauncher && ( - - )} ); } diff --git a/ui/components/findings/table/resource-detail-drawer/use-skill-launcher-variant.test.ts b/ui/components/findings/table/resource-detail-drawer/use-skill-launcher-variant.test.ts deleted file mode 100644 index d20ef45f97..0000000000 --- a/ui/components/findings/table/resource-detail-drawer/use-skill-launcher-variant.test.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { renderHook } from "@testing-library/react"; -import { beforeEach, describe, expect, it, vi } from "vitest"; - -const { useFeatureFlagVariantMock } = vi.hoisted(() => ({ - useFeatureFlagVariantMock: vi.fn(), -})); - -vi.mock("@/lib/feature-flags/client", () => ({ - useFeatureFlagVariant: useFeatureFlagVariantMock, -})); - -import { useSkillLauncherVariant } from "./use-skill-launcher-variant"; - -describe("useSkillLauncherVariant", () => { - beforeEach(() => { - useFeatureFlagVariantMock.mockReset(); - }); - - it("should read the skill launcher flag with card as the fallback", () => { - useFeatureFlagVariantMock.mockReturnValue("card"); - - renderHook(() => useSkillLauncherVariant()); - - expect(useFeatureFlagVariantMock).toHaveBeenCalledWith( - "finding-detail-skill-launcher", - ["card", "dropdown"], - "card", - ); - }); - - it.each([ - ["dropdown", "dropdown"], - ["card", "card"], - ])( - "should return the %s variant the flag module resolves", - (_label, variant) => { - useFeatureFlagVariantMock.mockReturnValue(variant); - - const { result } = renderHook(() => useSkillLauncherVariant()); - - expect(result.current).toBe(variant); - }, - ); -}); diff --git a/ui/components/findings/table/resource-detail-drawer/use-skill-launcher-variant.ts b/ui/components/findings/table/resource-detail-drawer/use-skill-launcher-variant.ts deleted file mode 100644 index a4599ec6a9..0000000000 --- a/ui/components/findings/table/resource-detail-drawer/use-skill-launcher-variant.ts +++ /dev/null @@ -1,17 +0,0 @@ -"use client"; - -import { FEATURE_FLAG, useFeatureFlagVariant } from "@/lib/feature-flags"; -import { - SKILL_LAUNCHER_VARIANT, - type SkillLauncherVariant, -} from "@/types/lighthouse-skills"; - -// Unresolved or unknown variants (including OSS builds that never init -// PostHog) fall back to the card control. -export function useSkillLauncherVariant(): SkillLauncherVariant { - return useFeatureFlagVariant( - FEATURE_FLAG.SKILL_LAUNCHER, - Object.values(SKILL_LAUNCHER_VARIANT), - SKILL_LAUNCHER_VARIANT.CARD, - ); -} diff --git a/ui/lib/feature-flags/client.test.ts b/ui/lib/feature-flags/client.test.ts index 8a9e0829ed..3591a68a5c 100644 --- a/ui/lib/feature-flags/client.test.ts +++ b/ui/lib/feature-flags/client.test.ts @@ -1,27 +1,17 @@ import { renderHook } from "@testing-library/react"; import { beforeEach, describe, expect, it, vi } from "vitest"; -const { useFeatureFlagEnabledMock, useFeatureFlagVariantKeyMock } = vi.hoisted( - () => ({ - useFeatureFlagEnabledMock: vi.fn(), - useFeatureFlagVariantKeyMock: vi.fn(), - }), -); +const { useFeatureFlagEnabledMock } = vi.hoisted(() => ({ + useFeatureFlagEnabledMock: vi.fn(), +})); vi.mock("posthog-js/react", () => ({ useFeatureFlagEnabled: useFeatureFlagEnabledMock, - useFeatureFlagVariantKey: useFeatureFlagVariantKeyMock, })); -import { - useFeatureFlag, - useFeatureFlagState, - useFeatureFlagVariant, -} from "./client"; +import { useFeatureFlag, useFeatureFlagState } from "./client"; import { FEATURE_FLAG, FEATURE_FLAG_STATE } from "./shared"; -const VARIANTS = ["card", "dropdown"] as const; - describe("useFeatureFlagState", () => { beforeEach(() => { useFeatureFlagEnabledMock.mockReset(); @@ -62,19 +52,15 @@ describe("useFeatureFlag", () => { it("should pass the flag key through to PostHog", () => { useFeatureFlagEnabledMock.mockReturnValue(undefined); - renderHook(() => useFeatureFlag(FEATURE_FLAG.SKILL_LAUNCHER)); + renderHook(() => useFeatureFlag(FEATURE_FLAG.ISSUES)); - expect(useFeatureFlagEnabledMock).toHaveBeenCalledWith( - "finding-detail-skill-launcher", - ); + expect(useFeatureFlagEnabledMock).toHaveBeenCalledWith("issues-feature"); }); it("should return true when the flag is enabled", () => { useFeatureFlagEnabledMock.mockReturnValue(true); - const { result } = renderHook(() => - useFeatureFlag(FEATURE_FLAG.SKILL_LAUNCHER), - ); + const { result } = renderHook(() => useFeatureFlag(FEATURE_FLAG.ISSUES)); expect(result.current).toBe(true); }); @@ -85,52 +71,8 @@ describe("useFeatureFlag", () => { ])("should return false when the flag is %s", (_label, flagValue) => { useFeatureFlagEnabledMock.mockReturnValue(flagValue); - const { result } = renderHook(() => - useFeatureFlag(FEATURE_FLAG.SKILL_LAUNCHER), - ); + const { result } = renderHook(() => useFeatureFlag(FEATURE_FLAG.ISSUES)); expect(result.current).toBe(false); }); }); - -describe("useFeatureFlagVariant", () => { - beforeEach(() => { - useFeatureFlagVariantKeyMock.mockReset(); - }); - - it("should pass the flag key through to PostHog", () => { - useFeatureFlagVariantKeyMock.mockReturnValue(undefined); - - renderHook(() => - useFeatureFlagVariant(FEATURE_FLAG.SKILL_LAUNCHER, VARIANTS, "card"), - ); - - expect(useFeatureFlagVariantKeyMock).toHaveBeenCalledWith( - "finding-detail-skill-launcher", - ); - }); - - it("should return the resolved key when it is a known variant", () => { - useFeatureFlagVariantKeyMock.mockReturnValue("dropdown"); - - const { result } = renderHook(() => - useFeatureFlagVariant(FEATURE_FLAG.SKILL_LAUNCHER, VARIANTS, "card"), - ); - - expect(result.current).toBe("dropdown"); - }); - - it.each([ - ["an unknown variant", "weird"], - ["unresolved", undefined], - ["a boolean value", true], - ])("should fall back when the flag resolves to %s", (_label, flagValue) => { - useFeatureFlagVariantKeyMock.mockReturnValue(flagValue); - - const { result } = renderHook(() => - useFeatureFlagVariant(FEATURE_FLAG.SKILL_LAUNCHER, VARIANTS, "card"), - ); - - expect(result.current).toBe("card"); - }); -}); diff --git a/ui/lib/feature-flags/client.ts b/ui/lib/feature-flags/client.ts index 6d3eca1d6f..2c737d1f18 100644 --- a/ui/lib/feature-flags/client.ts +++ b/ui/lib/feature-flags/client.ts @@ -1,9 +1,6 @@ "use client"; -import { - useFeatureFlagEnabled, - useFeatureFlagVariantKey, -} from "posthog-js/react"; +import { useFeatureFlagEnabled } from "posthog-js/react"; import { FEATURE_FLAG_STATE, @@ -31,15 +28,3 @@ export function useFeatureFlagState(flag: FeatureFlag): FeatureFlagState { export function useFeatureFlag(flag: FeatureFlag): boolean { return useFeatureFlagState(flag) === FEATURE_FLAG_STATE.ON; } - -// Multivariate flag. Returns the resolved key when it is one of `variants`; -// unresolved, boolean or unknown values fall back to `fallback`. -export function useFeatureFlagVariant( - flag: FeatureFlag, - variants: readonly T[], - fallback: T, -): T { - const value = useFeatureFlagVariantKey(flag); - const match = variants.find((variant) => variant === value); - return match ?? fallback; -} diff --git a/ui/lib/feature-flags/shared.test.ts b/ui/lib/feature-flags/shared.test.ts index e134cb41a7..cd453a9f5d 100644 --- a/ui/lib/feature-flags/shared.test.ts +++ b/ui/lib/feature-flags/shared.test.ts @@ -5,7 +5,6 @@ import { FEATURE_FLAG, FEATURE_FLAG_STATE } from "./shared"; describe("FEATURE_FLAG", () => { it("should map each flag to the key PostHog knows it by", () => { expect(FEATURE_FLAG).toEqual({ - SKILL_LAUNCHER: "finding-detail-skill-launcher", ISSUES: "issues-feature", BILLING_SYSTEM_METRONOME: "BILLING_SYSTEM_METRONOME", }); diff --git a/ui/lib/feature-flags/shared.ts b/ui/lib/feature-flags/shared.ts index 9828d00e5c..7e54f06bf5 100644 --- a/ui/lib/feature-flags/shared.ts +++ b/ui/lib/feature-flags/shared.ts @@ -3,9 +3,6 @@ // lives here, including the ones only the cloud fork reads, so the registry // never diverges between repos. export const FEATURE_FLAG = { - // Multivariate flag deciding which skill launcher the finding detail drawer - // renders ("card" | "dropdown"). - SKILL_LAUNCHER: "finding-detail-skill-launcher", // Boolean flag gating the experimental Issues feature (contextual findings). // Read by cloud only. ISSUES: "issues-feature", diff --git a/ui/types/lighthouse-skills.ts b/ui/types/lighthouse-skills.ts index 4ec121b1ea..8121ed02b6 100644 --- a/ui/types/lighthouse-skills.ts +++ b/ui/types/lighthouse-skills.ts @@ -1,15 +1,5 @@ import type { LucideIcon } from "lucide-react"; -// Variants of the FEATURE_FLAG.SKILL_LAUNCHER experiment (see -// lib/feature-flags). Anything other than "dropdown" renders the card control. -export const SKILL_LAUNCHER_VARIANT = { - CARD: "card", - DROPDOWN: "dropdown", -} as const; - -export type SkillLauncherVariant = - (typeof SKILL_LAUNCHER_VARIANT)[keyof typeof SKILL_LAUNCHER_VARIANT]; - export const LIGHTHOUSE_SKILL_ID = { CONTEXTUAL_FIX: "contextual-fix", TRIAGE_DECISION: "triage-decision",