From d3cfb3e9dfdfbdcb6221b9324ae5371d0f32e90b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 12 Mar 2026 02:02:31 +0000 Subject: [PATCH 1/4] Initial plan From c3194c9295350115be82694651e901c05922d032 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 12 Mar 2026 02:30:27 +0000 Subject: [PATCH 2/4] feat(buddy): add AI Buddy database schema, types, settings toggle, and tab navigation (#412) - Create migration for ai_buddy_conversations and ai_buddy_messages tables with RLS - Add ai_buddy_enabled feature flag to profiles table - Add AiBuddyConversation and AiBuddyMessage TypeScript types - Add AI Buddy analytics events - Add Sobers Buddy toggle in Settings Features section - Add Buddy tab to navigation (conditionally visible) - Create placeholder Buddy screen Co-authored-by: BillChirico <13951316+BillChirico@users.noreply.github.com> --- app/(app)/(tabs)/_layout.tsx | 26 +++- app/(app)/(tabs)/buddy.tsx | 125 ++++++++++++++++ components/settings/SettingsContent.tsx | 71 +++++++++ .../20260312000001_create_ai_buddy_tables.sql | 139 ++++++++++++++++++ types/analytics.ts | 8 + types/database.ts | 36 +++++ 6 files changed, 401 insertions(+), 4 deletions(-) create mode 100644 app/(app)/(tabs)/buddy.tsx create mode 100644 supabase/migrations/20260312000001_create_ai_buddy_tables.sql diff --git a/app/(app)/(tabs)/_layout.tsx b/app/(app)/(tabs)/_layout.tsx index 1adc5ffd..4d5d82a5 100644 --- a/app/(app)/(tabs)/_layout.tsx +++ b/app/(app)/(tabs)/_layout.tsx @@ -5,7 +5,7 @@ import React, { useMemo } from 'react'; import { Platform } from 'react-native'; import { Tabs } from 'expo-router'; import { NativeTabs } from 'expo-router/unstable-native-tabs'; -import { Home, Compass, TrendingUp, CheckSquare, User } from 'lucide-react-native'; +import { Home, Compass, TrendingUp, CheckSquare, User, Bot } from 'lucide-react-native'; import { useTheme } from '@/contexts/ThemeContext'; import { useAuth } from '@/contexts/AuthContext'; import type { SFSymbol } from 'sf-symbols-typescript'; @@ -38,6 +38,13 @@ const TAB_ROUTES: TabRoute[] = [ mdIcon: 'home', icon: Home, }, + { + name: 'buddy', + title: 'Buddy', + sfSymbol: 'bubble.left.and.text.bubble.right.fill', + mdIcon: 'smart_toy', + icon: Bot, + }, { name: 'program', title: 'Program', @@ -86,10 +93,18 @@ export default function TabLayout(): React.ReactElement { // Show Program tab unless explicitly set to false (treats null/undefined as true for backwards compatibility) const shouldShowProgram = profile?.show_program_content !== false; + // Determine if Buddy tab should be visible + // Show Buddy tab unless explicitly set to false (treats null/undefined as true for new users) + const shouldShowBuddy = profile?.ai_buddy_enabled !== false; + // Filter tab routes for web navigation items only const visibleTabRoutes = useMemo(() => { - return shouldShowProgram ? TAB_ROUTES : TAB_ROUTES.filter((route) => route.name !== 'program'); - }, [shouldShowProgram]); + return TAB_ROUTES.filter((route) => { + if (route.name === 'program' && !shouldShowProgram) return false; + if (route.name === 'buddy' && !shouldShowBuddy) return false; + return true; + }); + }, [shouldShowProgram, shouldShowBuddy]); // Web: Use top navigation instead of bottom tabs if (Platform.OS === 'web') { @@ -135,7 +150,10 @@ export default function TabLayout(): React.ReactElement {