diff --git a/apps/code/src/renderer/components/GlobalEventHandlers.tsx b/apps/code/src/renderer/components/GlobalEventHandlers.tsx
index e1453521d..f4597643c 100644
--- a/apps/code/src/renderer/components/GlobalEventHandlers.tsx
+++ b/apps/code/src/renderer/components/GlobalEventHandlers.tsx
@@ -8,6 +8,7 @@ import { useSidebarStore } from "@features/sidebar/stores/sidebarStore";
import { useTasks } from "@features/tasks/hooks/useTasks";
import { useFocusWorkspace } from "@features/workspace/hooks/useFocusWorkspace";
import { useWorkspaces } from "@features/workspace/hooks/useWorkspace";
+import { useFeatureFlag } from "@hooks/useFeatureFlag";
import { SHORTCUTS } from "@renderer/constants/keyboard-shortcuts";
import { useTRPC } from "@renderer/trpc";
import type { Task } from "@shared/types";
@@ -170,10 +171,15 @@ export function GlobalEventHandlers({
setReviewMode(currentTaskId, mode === "closed" ? "split" : "closed");
}, [currentTaskId, getReviewMode, setReviewMode]);
+ const inboxHidden = useFeatureFlag("posthog-code-inbox-hidden");
+
useHotkeys(SHORTCUTS.TOGGLE_LEFT_SIDEBAR, toggleLeftSidebar, globalOptions);
useHotkeys(SHORTCUTS.TOGGLE_REVIEW_PANEL, handleToggleReview, globalOptions);
useHotkeys(SHORTCUTS.SHORTCUTS_SHEET, onToggleShortcutsSheet, globalOptions);
- useHotkeys(SHORTCUTS.INBOX, navigateToInbox, globalOptions);
+ useHotkeys(SHORTCUTS.INBOX, navigateToInbox, {
+ ...globalOptions,
+ enabled: !inboxHidden,
+ });
useHotkeys(SHORTCUTS.PREV_TASK, handlePrevTask, globalOptions, [
handlePrevTask,
]);
diff --git a/apps/code/src/renderer/components/KeyboardShortcutsSheet.tsx b/apps/code/src/renderer/components/KeyboardShortcutsSheet.tsx
index 0699109aa..3e59f6984 100644
--- a/apps/code/src/renderer/components/KeyboardShortcutsSheet.tsx
+++ b/apps/code/src/renderer/components/KeyboardShortcutsSheet.tsx
@@ -1,3 +1,4 @@
+import { useFeatureFlag } from "@hooks/useFeatureFlag";
import { Box, Dialog, Flex, Text } from "@radix-ui/themes";
import {
CATEGORY_LABELS,
@@ -130,7 +131,14 @@ function ShortcutsHeader() {
}
export function KeyboardShortcutsList() {
- const shortcutsByCategory = useMemo(() => getShortcutsByCategory(), []);
+ const inboxHidden = useFeatureFlag("posthog-code-inbox-hidden");
+ const shortcutsByCategory = useMemo(() => {
+ const grouped = getShortcutsByCategory();
+ if (inboxHidden) {
+ grouped.navigation = grouped.navigation.filter((s) => s.id !== "inbox");
+ }
+ return grouped;
+ }, [inboxHidden]);
const categoryOrder: ShortcutCategory[] = [
"general",
diff --git a/apps/code/src/renderer/components/MainLayout.tsx b/apps/code/src/renderer/components/MainLayout.tsx
index cfd2f4cb5..901b93ba2 100644
--- a/apps/code/src/renderer/components/MainLayout.tsx
+++ b/apps/code/src/renderer/components/MainLayout.tsx
@@ -51,6 +51,7 @@ export function MainLayout() {
} = useShortcutsSheetStore();
const { data: tasks } = useTasks();
const { showPrompt, isChecking, check, dismiss } = useConnectivity();
+ const inboxHidden = useFeatureFlag("posthog-code-inbox-hidden");
const billingEnabled = useFeatureFlag(BILLING_FLAG);
// Space switcher data
@@ -108,7 +109,7 @@ export function MainLayout() {
{view.type === "folder-settings" && }
- {view.type === "inbox" && }
+ {view.type === "inbox" && !inboxHidden && }
{view.type === "archived" && }
diff --git a/apps/code/src/renderer/features/onboarding/components/OnboardingFlow.tsx b/apps/code/src/renderer/features/onboarding/components/OnboardingFlow.tsx
index 2cb2ef939..c53b38abb 100644
--- a/apps/code/src/renderer/features/onboarding/components/OnboardingFlow.tsx
+++ b/apps/code/src/renderer/features/onboarding/components/OnboardingFlow.tsx
@@ -28,6 +28,7 @@ export function OnboardingFlow() {
const {
currentStep,
activeSteps,
+ isLastStep,
direction,
next,
back,
@@ -46,12 +47,10 @@ export function OnboardingFlow() {
);
usePrefetchSignalData();
- useHotkeys("right", next, { enableOnFormTags: false }, [next]);
- useHotkeys("left", back, { enableOnFormTags: false }, [back]);
+ const handleNext = isLastStep ? completeOnboarding : next;
- const handleComplete = () => {
- completeOnboarding();
- };
+ useHotkeys("right", handleNext, { enableOnFormTags: false }, [handleNext]);
+ useHotkeys("left", back, { enableOnFormTags: false }, [back]);
const footerRight = (
@@ -75,7 +74,7 @@ export function OnboardingFlow() {
size="1"
variant="ghost"
color="gray"
- onClick={handleComplete}
+ onClick={completeOnboarding}
style={{ opacity: 0.5 }}
>
@@ -100,7 +99,7 @@ export function OnboardingFlow() {
transition={{ duration: 0.3 }}
style={{ width: "100%", flex: 1, minHeight: 0 }}
>
-
+
)}
@@ -115,7 +114,7 @@ export function OnboardingFlow() {
transition={{ duration: 0.3 }}
style={{ width: "100%", flex: 1, minHeight: 0 }}
>
-
+
)}
@@ -130,7 +129,7 @@ export function OnboardingFlow() {
transition={{ duration: 0.3 }}
style={{ width: "100%", flex: 1, minHeight: 0 }}
>
-
+
)}
@@ -146,7 +145,7 @@ export function OnboardingFlow() {
style={{ width: "100%", flex: 1, minHeight: 0 }}
>
-
+
)}
@@ -182,7 +181,7 @@ export function OnboardingFlow() {
transition={{ duration: 0.3 }}
style={{ width: "100%", flex: 1, minHeight: 0 }}
>
-
+
)}
diff --git a/apps/code/src/renderer/features/onboarding/components/WelcomeScreen.tsx b/apps/code/src/renderer/features/onboarding/components/WelcomeScreen.tsx
index 0438932de..c10177daf 100644
--- a/apps/code/src/renderer/features/onboarding/components/WelcomeScreen.tsx
+++ b/apps/code/src/renderer/features/onboarding/components/WelcomeScreen.tsx
@@ -1,3 +1,4 @@
+import { useFeatureFlag } from "@hooks/useFeatureFlag";
import {
ArrowRight,
ChartLine,
@@ -8,37 +9,42 @@ import {
} from "@phosphor-icons/react";
import { Button, Flex, Text } from "@radix-ui/themes";
import explorerHog from "@renderer/assets/images/hedgehogs/explorer-hog.png";
-import { useCallback, useEffect, useRef, useState } from "react";
+import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { FeatureListItem } from "./FeatureListItem";
import { OnboardingHogTip } from "./OnboardingHogTip";
import { StepActions } from "./StepActions";
-const FEATURES = [
+const ALL_FEATURES = [
{
+ id: "signals-inbox",
icon: ,
title: "Your signals inbox",
description:
"Automatically surfaces the highest-impact work from your product data so you always know what to do next.",
},
{
+ id: "product-data",
icon: ,
title: "Product data as context",
description:
"Your agents have context from your analytics, session replays and feature flags built in.",
},
{
+ id: "any-model",
icon: ,
title: "Any model, any harness",
description:
"Bring your own agent framework or use our built-in harnesses. Swap models without changing your workflow.",
},
{
+ id: "ship-work",
icon: ,
title: "Ship work, not messages",
description:
"Run tasks in parallel across local and cloud environments. Work gets done whether you're watching or not.",
},
{
+ id: "review-ship",
icon: ,
title: "Review and ship with confidence",
description:
@@ -51,18 +57,26 @@ interface WelcomeScreenProps {
}
const CYCLE_INTERVAL_MS = 2500;
-const CYCLE_START_DELAY_MS = FEATURES.length * 100 + 400;
+const CYCLE_START_DELAY_MS = ALL_FEATURES.length * 100 + 400;
export function WelcomeScreen({ onNext }: WelcomeScreenProps) {
+ const inboxHidden = useFeatureFlag("posthog-code-inbox-hidden");
+ const features = useMemo(
+ () =>
+ inboxHidden
+ ? ALL_FEATURES.filter((f) => f.id !== "signals-inbox")
+ : ALL_FEATURES,
+ [inboxHidden],
+ );
const [activeIndex, setActiveIndex] = useState(-1);
const timerRef = useRef>(null);
const startCycling = useCallback(() => {
if (timerRef.current) clearInterval(timerRef.current);
timerRef.current = setInterval(() => {
- setActiveIndex((prev) => (prev + 1) % FEATURES.length);
+ setActiveIndex((prev) => (prev + 1) % features.length);
}, CYCLE_INTERVAL_MS);
- }, []);
+ }, [features.length]);
useEffect(() => {
const timeout = setTimeout(() => {
@@ -126,7 +140,7 @@ export function WelcomeScreen({ onNext }: WelcomeScreenProps) {
- {FEATURES.map((feature, index) => (
+ {features.map((feature, index) => (
state.hasCodeAccess);
+ const inboxHidden = useFeatureFlag("posthog-code-inbox-hidden");
const activeSteps = useMemo(() => {
+ let steps = ONBOARDING_STEPS as OnboardingStep[];
if (hasCodeAccess === true) {
- return ONBOARDING_STEPS.filter((s) => s !== "invite-code");
+ steps = steps.filter((s) => s !== "invite-code");
}
- return ONBOARDING_STEPS;
- }, [hasCodeAccess]);
+ if (inboxHidden) {
+ steps = steps.filter((s) => s !== "signals");
+ }
+ return steps;
+ }, [hasCodeAccess, inboxHidden]);
useEffect(() => {
if (!activeSteps.includes(currentStep)) {
diff --git a/apps/code/src/renderer/features/settings/components/SettingsDialog.tsx b/apps/code/src/renderer/features/settings/components/SettingsDialog.tsx
index b16165af0..29cbc55ed 100644
--- a/apps/code/src/renderer/features/settings/components/SettingsDialog.tsx
+++ b/apps/code/src/renderer/features/settings/components/SettingsDialog.tsx
@@ -129,15 +129,18 @@ export function SettingsDialog() {
const client = useOptionalAuthenticatedClient();
const { data: user } = useCurrentUser({ client });
const { seat, planLabel } = useSeat();
+ const inboxHidden = useFeatureFlag("posthog-code-inbox-hidden");
const billingEnabled = useFeatureFlag(BILLING_FLAG);
const logoutMutation = useLogoutMutation();
const sidebarItems = useMemo(
() =>
- billingEnabled
- ? SIDEBAR_ITEMS
- : SIDEBAR_ITEMS.filter((item) => item.id !== "plan-usage"),
- [billingEnabled],
+ SIDEBAR_ITEMS.filter((item) => {
+ if (item.id === "plan-usage" && !billingEnabled) return false;
+ if (item.id === "signals" && inboxHidden) return false;
+ return true;
+ }),
+ [billingEnabled, inboxHidden],
);
useHotkeys("escape", close, {
diff --git a/apps/code/src/renderer/features/sidebar/components/SidebarMenu.tsx b/apps/code/src/renderer/features/sidebar/components/SidebarMenu.tsx
index 47222ff98..ce1e2d1e5 100644
--- a/apps/code/src/renderer/features/sidebar/components/SidebarMenu.tsx
+++ b/apps/code/src/renderer/features/sidebar/components/SidebarMenu.tsx
@@ -13,6 +13,7 @@ import {
} from "@features/tasks/hooks/useArchiveTask";
import { useTasks, useUpdateTask } from "@features/tasks/hooks/useTasks";
import { useWorkspaces } from "@features/workspace/hooks/useWorkspace";
+import { useFeatureFlag } from "@hooks/useFeatureFlag";
import { useTaskContextMenu } from "@hooks/useTaskContextMenu";
import { ScrollArea, Separator } from "@posthog/quill";
import { Box, Flex } from "@radix-ui/themes";
@@ -55,10 +56,12 @@ function SidebarMenuComponent() {
const sidebarData = useSidebarData({
activeView: view,
});
+ const inboxHidden = useFeatureFlag("posthog-code-inbox-hidden");
const inboxPollingActive = useRendererWindowFocusStore((s) => s.focused);
const { data: inboxProbe } = useInboxReports(
{ status: INBOX_PIPELINE_STATUS_FILTER },
{
+ enabled: !inboxHidden,
refetchInterval: inboxPollingActive ? INBOX_REFETCH_INTERVAL_MS : false,
refetchIntervalInBackground: false,
staleTime: inboxPollingActive ? INBOX_REFETCH_INTERVAL_MS : 15_000,
@@ -277,13 +280,15 @@ function SidebarMenuComponent() {
/>
-
-
-
+ {!inboxHidden && (
+
+
+
+ )}