### Start Expo Development Server Source: https://github.com/agomezguemes-afk/kairos/blob/main/CLAUDE.md Use this command to start the Expo development server for the project. Ensure you have Expo CLI installed. ```bash npm start # Start Expo dev server ``` -------------------------------- ### Install Dependencies with Legacy Peer Deps Source: https://github.com/agomezguemes-afk/kairos/blob/main/CLAUDE.md Use this command to resolve dependency conflicts by allowing older versions of peer dependencies. ```bash # Fix dependency conflicts npm install --legacy-peer-deps ``` -------------------------------- ### Build and Deploy to iPhone Source: https://github.com/agomezguemes-afk/kairos/blob/main/CLAUDE.md Commands to build a release version of the app, install it on a physical iPhone, and launch it. Ensure the device ID is correctly specified. ```bash # Build Release (standalone, no Metro required) xcodebuild -workspace ios/Kairos.xcworkspace -scheme Kairos \ -configuration Release -destination 'id=00008101-00051D4C3C51003A' \ CODE_SIGN_STYLE=Automatic DEVELOPMENT_TEAM=FH6BYZT9F3 ``` ```bash # Install on device xcrun devicectl device install app --device 00008101-00051D4C3C51003A \ path/to/Kairos.app ``` ```bash # Launch on device xcrun devicectl device process launch --device 00008101-00051D4C3C51003A \ com.alvaro.kairos ``` -------------------------------- ### Clean Project Dependencies and Cache Source: https://github.com/agomezguemes-afk/kairos/blob/main/CLAUDE.md Use this command to remove all node_modules, package-lock.json, and clear the Expo cache for a clean start. ```bash # Clean everything rm -rf node_modules .expo package-lock.json npx expo start --clear --reset-cache ``` -------------------------------- ### Integrating Gesture Handler Source: https://github.com/agomezguemes-afk/kairos/blob/main/CLAUDE.md Example of integrating react-native-reanimated-gesture-handler for advanced gesture control. This library is recommended for creating smooth and interactive UI elements. ```javascript import "react-native-reanimated"; import { GestureHandlerRootView } from "react-native-gesture-handler"; function App() { return ( {/* Your app content */} ); } ``` -------------------------------- ### Supabase Authentication and Profile Operations Source: https://context7.com/agomezguemes-afk/kairos/llms.txt Handles user authentication (sign-up, session management) and profile data operations (fetching, updating) using the Supabase client. Requires Supabase client import and RLS setup for profiles table. ```typescript import { supabase } from './src/lib/supabase'; // Authentication const { data, error } = await supabase.auth.signUp({ email: 'user@example.com', password: 'password123', }); const { data: session } = await supabase.auth.getSession(); // Profile operations (with RLS) const { data: profile } = await supabase .from('profiles') .select('*') .eq('id', userId) .single(); await supabase.from('profiles').upsert({ id: userId, display_name: 'John Doe', fitness_level: 'intermediate', primary_goal: 'muscle_gain', disciplines: ['strength', 'running'], weekly_frequency: 4, updated_at: new Date().toISOString(), }); // Required SQL setup for profiles table: /* create table public.profiles ( id uuid references auth.users on delete cascade primary key, display_name text, fitness_level text, primary_goal text, disciplines jsonb default '[]', weekly_frequency integer, age integer, weight_kg numeric, height_cm numeric, injuries text, workout_place text, onboarding_completed_at timestamptz, created_at timestamptz default now(), updated_at timestamptz default now() ); */ ``` -------------------------------- ### Build Workout Interfaces with Content Nodes Source: https://context7.com/agomezguemes-afk/kairos/llms.txt Utilize factory functions to create various content nodes for flexible workout layouts. Requires importing types from './src/types/content'. ```typescript import { createTextNode, createExerciseNode, createDividerNode, createTimerNode, createDashboardNode, createColumnSectionNode, buildRenderGroups, type ContentNode, type TextFormat, } from './src/types/content'; // Create text nodes with different formats const heading = createTextNode(0, 'h1', 'Warm-up Section'); const bullet = createTextNode(1, 'bullet', '5 minutes light cardio'); const checklist = createTextNode(2, 'checklist', 'Stretch quads'); // Create exercise node const exerciseNode = createExerciseNode(3, exerciseCard); // Create divider const divider = createDividerNode(4); // Create countdown timer const restTimer = createTimerNode(5, 'countdown', 90, 'Rest Period'); // Create dashboard widget const volumeWidget = createDashboardNode(6, 'total_volume', 'counter', 'Total Volume', '#C9A96E'); // Create multi-column section const twoColSection = createColumnSectionNode(7, 2); // Build render groups for layout const groups = buildRenderGroups(block.content); // Returns: [{ type: 'fullWidth', nodes }, { type: 'section', sectionNode, children }] ``` -------------------------------- ### Manage Training Context with TrainingProvider Source: https://context7.com/agomezguemes-afk/kairos/llms.txt Wrap your application with `TrainingProvider` to manage training sessions, streaks, and progress. Access state and actions via the `useTraining` hook. ```typescript import { TrainingProvider, useTraining } from './src/context/TrainingContext'; // Wrap app with provider function App() { return ( ); } // Access training state and actions function WorkoutScreen() { const { stats, // { totalSessions, currentStreak, totalMinutes, lastSession } sessions, // Array of training sessions streak, // { currentStreak, longestStreak, lastTrainingDate } currentWeek, // { weekNumber, startDate, days, totalTrainings, totalMinutes } dayEntries, // Array of daily entries addSession, // Add a training session registerDay, // Register activity for today markRestDay, // Mark today as rest day } = useTraining(); // Register a training session addSession({ id: 'session_123', date: new Date(), muscleGroups: ['chest', 'shoulders', 'triceps'], trainingType: 'strength', duration: 60, timestamp: Date.now(), }); // Mark rest day markRestDay(); } ``` -------------------------------- ### Workout Store with Persistence Source: https://github.com/agomezguemes-afk/kairos/blob/main/CLAUDE.md Implements the Zustand store for managing workout data, including hydration with AsyncStorage for persistence. This is crucial for saving user progress. ```typescript src/store/workoutStore.ts ``` -------------------------------- ### Rebuild Native Code and Run on iOS Source: https://github.com/agomezguemes-afk/kairos/blob/main/CLAUDE.md Commands to clean and rebuild native project files, useful when compilation fails, followed by running the app on an iOS simulator or device. ```bash # Rebuild native (if compilation fails) npx expo prebuild --clean npx expo run:ios ``` -------------------------------- ### Create Workout Entities with Core Types Source: https://context7.com/agomezguemes-afk/kairos/llms.txt Use factory functions to create workout blocks and exercise cards with discipline-specific defaults. Requires importing types from './src/types/core'. ```typescript import { createWorkoutBlock, createExerciseCard, createEmptySet, calculateBlockStats, getBlockExercises, DISCIPLINE_CONFIGS, type WorkoutBlock, type ExerciseCard, type Discipline, } from './src/types/core'; // Available disciplines with their configs const disciplines: Discipline[] = [ 'strength', // weight, reps, RIR 'running', // distance, duration, pace, heart rate 'calisthenics', // reps, hold time, progression 'mobility', // duration, perceived effort 'team_sport', // duration, intensity, calories 'cycling', // distance, duration, heart rate 'swimming', // distance, duration 'general', // duration, effort ]; // Create a workout block const block = createWorkoutBlock('user_001', 0, 'strength', { name: 'Upper Body', icon: 'weightlifting', color: '#E84545', }); // Create an exercise card with discipline-specific fields const exercise = createExerciseCard(block.id, 0, 'strength', { name: 'Barbell Squat', }); // exercise.fields: [{ id: 'weight', isPrimary: true }, { id: 'reps' }, { id: 'rir' }] // exercise.sets: [4 empty sets with field placeholders] // Create additional sets const newSet = createEmptySet(exercise.id, exercise.sets.length, exercise.fields); // Calculate block statistics const stats = calculateBlockStats(block); // { total_exercises, total_sets, completed_sets, total_volume, completion_percentage, estimated_duration } // Extract exercises from block content const exercises = getBlockExercises(block); ``` -------------------------------- ### Workout Store API with Zustand Source: https://context7.com/agomezguemes-afk/kairos/llms.txt Manage workout blocks, exercises, and sets using the `useWorkoutStore` hook. Includes actions for adding, updating, deleting, and toggling set completion, with automatic AsyncStorage persistence. ```typescript import { useWorkoutStore } from './src/store/workoutStore'; // Access store state and actions const { blocks, addBlock, updateBlock, deleteBlock, addExercise, updateExercise, toggleSetComplete, dispatchAIActions, } = useWorkoutStore(); // Create a new workout block const blockId = addBlock('strength', { name: 'Push Day', icon: 'weightlifting', color: '#E84545', }); // Add an exercise to the block addExercise(blockId, { name: 'Bench Press', icon: 'weightlifting', color: '#E84545', discipline: 'strength', }); // Update exercise properties updateExercise(blockId, exerciseId, { rest_seconds: 120, default_sets_count: 5, }); // Toggle set completion (returns completion data for gamification) const result = toggleSetComplete(blockId, exerciseId, setIndex); // result: { exercise, set, wasCompleted: true } // Update a specific set value updateSetValue(blockId, exerciseId, 0, 'weight', 80); updateSetValue(blockId, exerciseId, 0, 'reps', 8); ``` -------------------------------- ### Create Supabase Profiles Table and Policies Source: https://github.com/agomezguemes-afk/kairos/blob/main/README.md SQL script to create the 'profiles' table in Supabase and define row-level security policies for user data access. Ensure users can only view, insert, and update their own profiles. ```sql create table if not exists public.profiles ( id uuid references auth.users on delete cascade primary key, display_name text, fitness_level text, primary_goal text, disciplines jsonb default '[]', weekly_frequency integer, age integer, weight_kg numeric, height_cm numeric, injuries text, workout_place text, onboarding_completed_at timestamptz, created_at timestamptz default now(), updated_at timestamptz default now() ); -- Row-level security: users can only read/write their own row alter table public.profiles enable row level security; create policy "Users can view own profile" on public.profiles for select using (auth.uid() = id); create policy "Users can insert own profile" on public.profiles for insert with check (auth.uid() = id); create policy "Users can update own profile" on public.profiles for update using (auth.uid() = id); ``` -------------------------------- ### Run Expo App on Web Source: https://github.com/agomezguemes-afk/kairos/blob/main/CLAUDE.md Command to run the Expo application in a web browser. This is useful for quick testing and development. ```bash npm run web # Run on web ``` -------------------------------- ### Run Expo App on Android Emulator Source: https://github.com/agomezguemes-afk/kairos/blob/main/CLAUDE.md Command to run the Expo application on an Android emulator. Requires Android Studio and a configured emulator. ```bash npm run android # Run on Android emulator ``` -------------------------------- ### Define Navigation Types with TypeScript Source: https://context7.com/agomezguemes-afk/kairos/llms.txt Sets up type definitions for the root stack and dashboard tab navigators using TypeScript. Ensure these types accurately reflect all possible routes and their parameters. ```typescript import { NavigationContainer, } from '@react-navigation/native'; import { createNativeStackNavigator, } from '@react-navigation/native-stack'; import { createBottomTabNavigator, } from '@react-navigation/bottom-tabs'; // Navigation type definitions type RootStackParamList = { Welcome: undefined; Auth: undefined; ProfileSetup: undefined; Onboarding: undefined; Dashboard: undefined; BlockDetail: { blockId: string }; Badges: undefined; PRCards: undefined; ProgressTree: undefined; AIChat: undefined; }; type DashboardTabParamList = { HomeTab: undefined; WorkoutTab: undefined; AchievementsTab: undefined; AILabTab: undefined; ProfileTab: undefined; }; // Navigation flow: // 1. !session → Welcome → Auth // 2. session && !onboarding → ProfileSetup → Onboarding // 3. session && onboarding → Dashboard (tabs) → detail screens // Navigating to screens navigation.navigate('BlockDetail', { blockId: 'block_123' }); navigation.navigate('AIChat'); navigation.navigate('Dashboard'); ``` -------------------------------- ### Workout Store API Source: https://context7.com/agomezguemes-afk/kairos/llms.txt The `useWorkoutStore` hook provides centralized state management for workout blocks, exercises, and sets with automatic persistence to AsyncStorage. ```APIDOC ## Workout Store API ### Description Manages workout blocks, exercises, and sets with persistence. ### Methods - `addBlock(discipline, data)`: Adds a new workout block. - `updateBlock(blockId, data)`: Updates an existing workout block. - `deleteBlock(blockId)`: Deletes a workout block. - `addExercise(blockId, data)`: Adds an exercise to a block. - `updateExercise(blockId, exerciseId, data)`: Updates an exercise. - `toggleSetComplete(blockId, exerciseId, setIndex)`: Toggles the completion status of a set. - `updateSetValue(blockId, exerciseId, setIndex, field, value)`: Updates a specific value for a set. ### State - `blocks`: Array of workout blocks. ### Example Usage ```typescript import { useWorkoutStore } from './src/store/workoutStore'; const { blocks, addBlock, updateBlock, deleteBlock, addExercise, updateExercise, toggleSetComplete, updateSetValue } = useWorkoutStore(); // Create a new block const blockId = addBlock('strength', { name: 'Push Day', icon: 'weightlifting', color: '#E84545' }); // Add an exercise addExercise(blockId, { name: 'Bench Press', icon: 'weightlifting', color: '#E84545', discipline: 'strength' }); // Update exercise updateExercise(blockId, exerciseId, { rest_seconds: 120, default_sets_count: 5 }); // Toggle set completion const result = toggleSetComplete(blockId, exerciseId, 0); // Update set value updateSetValue(blockId, exerciseId, 0, 'weight', 80); updateSetValue(blockId, exerciseId, 0, 'reps', 8); ``` ``` -------------------------------- ### Run Expo App on iOS Simulator Source: https://github.com/agomezguemes-afk/kairos/blob/main/CLAUDE.md Command to run the Expo application on an iOS simulator. Requires Xcode and a configured simulator. ```bash npm run ios # Run on iOS simulator ``` -------------------------------- ### Authentication Store API with Supabase Source: https://context7.com/agomezguemes-afk/kairos/llms.txt Manage Supabase authentication sessions and user profiles using the `useAuthStore` hook. Includes functions for sign-up, sign-in, profile updates, and sign-out, with automatic session persistence. ```typescript import { useAuthStore, startAuthListener } from './src/store/useAuthStore'; // Initialize auth listener in App.tsx useEffect(() => { const unsubscribe = startAuthListener(); useAuthStore.getState().initialize(); return unsubscribe; }, []); // Access auth state const { session, profile, isLoading, error } = useAuthStore(); // Sign up a new user const signUpError = await useAuthStore.getState().signUp( 'user@example.com', 'securePassword123' ); // Sign in existing user const signInError = await useAuthStore.getState().signIn( 'user@example.com', 'securePassword123' ); // Update user profile await useAuthStore.getState().upsertProfile({ displayName: 'John Doe', fitnessLevel: 'intermediate', primaryGoal: 'muscle_gain', disciplines: ['strength', 'running'], weeklyFrequency: 4, }); // Sign out await useAuthStore.getState().signOut(); ``` -------------------------------- ### Enable Verbose Expo Logs Source: https://github.com/agomezguemes-afk/kairos/blob/main/CLAUDE.md Redirects all Expo logs to a file named 'expo.log' for detailed debugging. ```bash # Verbose logs npx expo start --verbose 2>&1 | tee expo.log ``` -------------------------------- ### Theme Tokens for Design System Source: https://github.com/agomezguemes-afk/kairos/blob/main/CLAUDE.md Defines theme tokens for the design system, including background and accent colors. Use these tokens to ensure consistency across the application. ```typescript src/theme/tokens.ts ``` -------------------------------- ### Authentication Store API Source: https://context7.com/agomezguemes-afk/kairos/llms.txt The `useAuthStore` hook manages Supabase authentication sessions and user profiles with automatic session persistence. ```APIDOC ## Authentication Store API ### Description Manages user authentication and profile data using Supabase, with persistent session storage. ### Initialization Initialize the auth listener in your main application file (e.g., `App.tsx`). ```typescript import { useAuthStore, startAuthListener } from './src/store/useAuthStore'; import { useEffect } from 'react'; useEffect(() => { const unsubscribe = startAuthListener(); useAuthStore.getState().initialize(); return unsubscribe; }, []); ``` ### State - `session`: Current authentication session object. - `profile`: User profile data. - `isLoading`: Boolean indicating if authentication is in progress. - `error`: Any authentication-related error. ### Methods - `signUp(email, password)`: Creates a new user account. - `signIn(email, password)`: Authenticates an existing user. - `upsertProfile(profileData)`: Updates or inserts user profile information. - `signOut()`: Logs the user out. ### Example Usage ```typescript import { useAuthStore } from './src/store/useAuthStore'; const { session, profile, isLoading, error, signUp, signIn, upsertProfile, signOut } = useAuthStore(); // Sign up const signUpError = await signUp('user@example.com', 'securePassword123'); // Sign in const signInError = await signIn('user@example.com', 'securePassword123'); // Update profile await upsertProfile({ displayName: 'John Doe', fitnessLevel: 'intermediate', primaryGoal: 'muscle_gain', disciplines: ['strength', 'running'], weeklyFrequency: 4, }); // Sign out await signOut(); ``` ``` -------------------------------- ### Gamification Context and Services Source: https://context7.com/agomezguemes-afk/kairos/llms.txt Accesses gamification state and handles events like completing sets, creating blocks, and finishing missions. It also defines available badge IDs. ```typescript import { GamificationProvider, useGamification } from './src/context/GamificationContext'; import { updateStreak, checkBadges, checkForPR, computeStats } from './src/services/gamificationService'; // Access gamification state const { streak, badges, prCards, onSetCompleted, onBlockCreated, onMissionCompleted } = useGamification(); // When user completes a set const { newBadges, prCard } = await onSetCompleted(exercise, completedSet, allBlocks); if (prCard) { // Show PR celebration console.log(`New PR: ${prCard.exerciseName} - ${prCard.value}${prCard.unit}`); } if (newBadges.length > 0) { // Show badge unlock animation newBadges.forEach(b => console.log(`Badge unlocked: ${b.id}`)); } // When user creates a block const { newBadges: blockBadges } = await onBlockCreated(allBlocks); // When user completes a mission const { newBadges: missionBadges } = await onMissionCompleted(allBlocks); // Available badge IDs type BadgeId = | 'first_step' // Complete first set | 'streak_7' // 7-day streak | 'streak_30' // 30-day streak | 'volume_100' // 100 total sets | 'explorer_5' // Use 5 different exercises | 'block_creator' // Create first block | 'mission_complete'; // Complete first mission ``` -------------------------------- ### Design System Tokens Source: https://context7.com/agomezguemes-afk/kairos/llms.txt Utilizes design system tokens for consistent styling of colors, typography, spacing, and animations. Imports are required from the theme tokens. ```typescript import { Colors, Typography, Spacing, Radius, Shadows, Animation } from './src/theme/tokens'; // Color palette const styles = { container: { backgroundColor: Colors.background.void, // #F7F7F5 warm off-white borderColor: Colors.border.warm, // #EFECE8 }, card: { backgroundColor: Colors.background.surface, // #FFFFFF ...Shadows.card, // Subtle elevation }, accentButton: { backgroundColor: Colors.accent.primary, // #C9A96E gold color: Colors.text.onAccent, // #FFFFFF }, disciplineIndicator: { backgroundColor: Colors.discipline.strength, // #E84545 }, }; // Typography scale const textStyles = { hero: { fontSize: Typography.size.hero, fontWeight: Typography.weight.bold }, // 34px title: { fontSize: Typography.size.title, fontWeight: Typography.weight.semibold }, // 28px body: { fontSize: Typography.size.body, fontWeight: Typography.weight.regular }, // 15px caption: { fontSize: Typography.size.caption, color: Colors.text.secondary }, // 13px }; // Spacing system (base unit: 4px) const layout = { padding: Spacing.lg, // 16 gap: Spacing.gap.cards, // 10 screenHorizontal: Spacing.screen.horizontal, // 20 }; // Animation springs for Reanimated const springConfig = Animation.spring.snappy; // { damping: 15, stiffness: 260, mass: 0.8 } ``` -------------------------------- ### AI Chat Service for Workout Management Source: https://context7.com/agomezguemes-afk/kairos/llms.txt Process natural language messages to generate structured actions for workout management using `aiChatService`. Supports mock responses and real Groq/Llama 3 integration via `aiService`. ```typescript import { processMessage, getInitialGreeting, resetSession } from './src/services/aiChatService'; import { processWithGroq, isGroqConfigured } from './src/services/aiService'; // Context for AI responses const context = { blocks: workoutBlocks, streak: { current: 5, longest: 12, lastActivityDate: '2024-01-15' }, badges: [], prCards: [], activeMission: null, }; // Get initial greeting const greeting = getInitialGreeting(context); // "¡Hola! Soy Kai, tu asistente de entrenamiento..." // Process user message (mock service) const response = await processMessage( 'Créame un bloque de fuerza para principiantes en casa', context ); // response.content: "¡Listo! He creado 'Bloque Fuerza Principiante' con 5 ejercicios..." // response.actions: [{ type: 'create_block', payload: { name, discipline, exercises } }] // Process with Groq (if configured) if (isGroqConfigured()) { const groqResponse = await processWithGroq(userMessage, rawContext, conversationHistory); // Dispatch actions to store const createdBlockId = useWorkoutStore.getState().dispatchAIActions(groqResponse.actions); } // Reset conversation session resetSession(); ``` -------------------------------- ### Implementing a Draggable Grid Source: https://github.com/agomezguemes-afk/kairos/blob/main/CLAUDE.md Shows how to use react-native-draggable-grid to implement a widget-style layout with drag and resize capabilities. This is useful for the canvas layout feature. ```javascript import DraggableGrid from "react-native-draggable-grid"; // ... component implementation using DraggableGrid ``` -------------------------------- ### Babel Configuration Note Source: https://github.com/agomezguemes-afk/kairos/blob/main/CLAUDE.md Important: Ensure that `react-native-reanimated/plugin` is the last plugin listed in your `babel.config.js` file to avoid configuration issues. ```javascript > **Important:** `react-native-reanimated/plugin` must remain the **last** plugin in `babel.config.js`. ``` -------------------------------- ### Core Type Definitions Source: https://github.com/agomezguemes-afk/kairos/blob/main/CLAUDE.md Defines the fundamental types used across the application for exercises, blocks, and workouts. ```typescript src/types/ ├── core.ts ← Discipline, ExerciseCard, WorkoutBlock, Sets ├── training.ts ← TrainingSession, MuscleGroup, TrainingType ├── progress.ts ← DayEntry, StreakData, WeeklyLog ├── legacy.ts ← Deprecated — avoid └── index.ts ← Barrel re-exports from core.ts ``` -------------------------------- ### App Navigation Structure Source: https://github.com/agomezguemes-afk/kairos/blob/main/CLAUDE.md This outlines the primary navigation flow of the KAIROS app, including the native stack and bottom tab navigator. ```plaintext AppNavigator (native stack) ├── WelcomeScreen ├── SetupScreen ← 4-step onboarding form └── Dashboard (bottom tabs) ├── HomeTab ├── BlockLibraryScreen ├── ProgressTab └── ProfileTab ``` -------------------------------- ### AI Chat Service API Source: https://context7.com/agomezguemes-afk/kairos/llms.txt The AI chat service processes natural language messages and returns structured actions for workout management. It supports both mock responses and real Groq/Llama 3 integration. ```APIDOC ## AI Chat Service API ### Description Processes natural language input to generate workout management actions, with options for mock or real AI integration (Groq/Llama 3). ### Context Provides necessary data for AI processing, such as workout blocks, user stats, and achievements. ```typescript const context = { blocks: workoutBlocks, streak: { current: 5, longest: 12, lastActivityDate: '2024-01-15' }, badges: [], prCards: [], activeMission: null, }; ``` ### Methods - `getInitialGreeting(context)`: Retrieves an initial greeting message from the AI. - `processMessage(message, context)`: Processes a user message using the mock AI service and returns content and actions. - `processWithGroq(userMessage, rawContext, conversationHistory)`: Processes a user message using the Groq API (if configured). - `resetSession()`: Resets the AI chat conversation session. ### Response Format (from `processMessage` and `processWithGroq`) - `content`: The AI's textual response. - `actions`: An array of structured actions to be performed (e.g., creating a block, adding an exercise). ### Example Usage ```typescript import { processMessage, getInitialGreeting, resetSession, processWithGroq, isGroqConfigured } from './src/services/aiChatService'; // Get initial greeting const greeting = getInitialGreeting(context); // Process message with mock service const response = await processMessage( 'Créame un bloque de fuerza para principiantes en casa', context ); // response.content: "¡Listo! He creado 'Bloque Fuerza Principiante' con 5 ejercicios..." // response.actions: [{ type: 'create_block', payload: { name, discipline, exercises } }] // Process message with Groq (if configured) if (isGroqConfigured()) { const groqResponse = await processWithGroq(userMessage, rawContext, conversationHistory); // Dispatch actions to workout store const createdBlockId = useWorkoutStore.getState().dispatchAIActions(groqResponse.actions); } // Reset session resetSession(); ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.