@digilogiclabs/create-saas-app 1.17.1 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/cli/commands/create.d.ts.map +1 -1
  4. package/dist/cli/commands/create.js +6 -2
  5. package/dist/cli/commands/create.js.map +1 -1
  6. package/dist/cli/index.js +1 -1
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/generators/template-generator.d.ts.map +1 -1
  9. package/dist/generators/template-generator.js +13 -7
  10. package/dist/generators/template-generator.js.map +1 -1
  11. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/README.md +655 -0
  12. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/app/(tabs)/ai.tsx +683 -0
  13. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/docs/MOBILE-SETUP.md +787 -0
  14. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/hooks/useRAGSystem.ts +346 -0
  15. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/lib/rag/config.ts +180 -0
  16. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/package.json +113 -0
  17. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/scripts/setup-rag.js +599 -0
  18. package/dist/templates/web/ui-auth-payments-ai-rag/template/README.md +434 -0
  19. package/dist/templates/web/ui-auth-payments-ai-rag/template/components/rag/KnowledgeManager.tsx +642 -0
  20. package/dist/templates/web/ui-auth-payments-ai-rag/template/components/rag/RAGAnalytics.tsx +466 -0
  21. package/dist/templates/web/ui-auth-payments-ai-rag/template/components/rag/RAGChatInterface.tsx +393 -0
  22. package/dist/templates/web/ui-auth-payments-ai-rag/template/docs/GETTING-STARTED.md +457 -0
  23. package/dist/templates/web/ui-auth-payments-ai-rag/template/hooks/useRAGSystem.ts +478 -0
  24. package/dist/templates/web/ui-auth-payments-ai-rag/template/lib/rag/config.ts +250 -0
  25. package/dist/templates/web/ui-auth-payments-ai-rag/template/package.json +74 -0
  26. package/dist/templates/web/ui-auth-payments-ai-rag/template/scripts/setup-rag.js +622 -0
  27. package/dist/templates/web/ui-auth-payments-ai-rag/template/src/app/ai/page.tsx +396 -0
  28. package/package.json +1 -1
  29. package/src/templates/mobile/ui-auth-payments-ai-rag/template/README.md +655 -0
  30. package/src/templates/mobile/ui-auth-payments-ai-rag/template/app/(tabs)/ai.tsx +683 -0
  31. package/src/templates/mobile/ui-auth-payments-ai-rag/template/docs/MOBILE-SETUP.md +787 -0
  32. package/src/templates/mobile/ui-auth-payments-ai-rag/template/hooks/useRAGSystem.ts +346 -0
  33. package/src/templates/mobile/ui-auth-payments-ai-rag/template/lib/rag/config.ts +180 -0
  34. package/src/templates/mobile/ui-auth-payments-ai-rag/template/package.json +113 -0
  35. package/src/templates/mobile/ui-auth-payments-ai-rag/template/scripts/setup-rag.js +599 -0
  36. package/src/templates/web/ui-auth-payments-ai-rag/template/README.md +434 -0
  37. package/src/templates/web/ui-auth-payments-ai-rag/template/components/rag/KnowledgeManager.tsx +642 -0
  38. package/src/templates/web/ui-auth-payments-ai-rag/template/components/rag/RAGAnalytics.tsx +466 -0
  39. package/src/templates/web/ui-auth-payments-ai-rag/template/components/rag/RAGChatInterface.tsx +393 -0
  40. package/src/templates/web/ui-auth-payments-ai-rag/template/docs/GETTING-STARTED.md +457 -0
  41. package/src/templates/web/ui-auth-payments-ai-rag/template/hooks/useRAGSystem.ts +478 -0
  42. package/src/templates/web/ui-auth-payments-ai-rag/template/lib/rag/config.ts +250 -0
  43. package/src/templates/web/ui-auth-payments-ai-rag/template/package.json +74 -0
  44. package/src/templates/web/ui-auth-payments-ai-rag/template/scripts/setup-rag.js +622 -0
  45. package/src/templates/web/ui-auth-payments-ai-rag/template/src/app/ai/page.tsx +396 -0
@@ -0,0 +1,599 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs')
4
+ const path = require('path')
5
+ const { execSync } = require('child_process')
6
+
7
+ console.log('šŸš€ Setting up RAG Knowledge System for React Native...\n')
8
+
9
+ // Colors for console output
10
+ const colors = {
11
+ red: '\x1b[31m',
12
+ green: '\x1b[32m',
13
+ yellow: '\x1b[33m',
14
+ blue: '\x1b[34m',
15
+ magenta: '\x1b[35m',
16
+ cyan: '\x1b[36m',
17
+ white: '\x1b[37m',
18
+ reset: '\x1b[0m'
19
+ }
20
+
21
+ function log(message, color = 'white') {
22
+ console.log(`${colors[color]}${message}${colors.reset}`)
23
+ }
24
+
25
+ function step(number, message) {
26
+ log(`\nšŸ“‹ Step ${number}: ${message}`, 'cyan')
27
+ }
28
+
29
+ function success(message) {
30
+ log(`āœ… ${message}`, 'green')
31
+ }
32
+
33
+ function warning(message) {
34
+ log(`āš ļø ${message}`, 'yellow')
35
+ }
36
+
37
+ function error(message) {
38
+ log(`āŒ ${message}`, 'red')
39
+ }
40
+
41
+ function checkRequirements() {
42
+ step(1, 'Checking React Native requirements')
43
+
44
+ try {
45
+ // Check if we're in an Expo project
46
+ if (!fs.existsSync('package.json')) {
47
+ throw new Error('package.json not found. Please run this script from your project root.')
48
+ }
49
+
50
+ const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'))
51
+
52
+ if (!packageJson.dependencies?.expo && !packageJson.dependencies?.['react-native']) {
53
+ throw new Error('This appears to be not a React Native/Expo project.')
54
+ }
55
+
56
+ if (packageJson.dependencies?.expo) {
57
+ success('Expo project detected')
58
+ } else {
59
+ success('React Native project detected')
60
+ }
61
+
62
+ // Check for required dependencies
63
+ const requiredDeps = [
64
+ '@digilogiclabs/saas-factory-ai',
65
+ '@digilogiclabs/saas-factory-ai-types',
66
+ '@supabase/supabase-js',
67
+ '@react-native-async-storage/async-storage',
68
+ '@react-native-community/netinfo'
69
+ ]
70
+
71
+ const missingDeps = requiredDeps.filter(dep =>
72
+ !packageJson.dependencies?.[dep] && !packageJson.devDependencies?.[dep]
73
+ )
74
+
75
+ if (missingDeps.length > 0) {
76
+ warning(`Missing dependencies: ${missingDeps.join(', ')}`)
77
+ log('Installing missing dependencies...')
78
+
79
+ if (packageJson.dependencies?.expo) {
80
+ execSync(`npx expo install ${missingDeps.join(' ')}`, { stdio: 'inherit' })
81
+ } else {
82
+ execSync(`npm install ${missingDeps.join(' ')}`, { stdio: 'inherit' })
83
+ }
84
+ success('Dependencies installed')
85
+ } else {
86
+ success('All required dependencies found')
87
+ }
88
+
89
+ } catch (err) {
90
+ error(err.message)
91
+ process.exit(1)
92
+ }
93
+ }
94
+
95
+ function setupEnvironmentVariables() {
96
+ step(2, 'Setting up environment variables')
97
+
98
+ const requiredEnvVars = [
99
+ 'EXPO_PUBLIC_SUPABASE_URL',
100
+ 'EXPO_PUBLIC_SUPABASE_ANON_KEY',
101
+ 'EXPO_PUBLIC_OPENAI_API_KEY'
102
+ ]
103
+
104
+ // Check app.config.js/ts or expo config
105
+ const configFiles = ['app.config.js', 'app.config.ts', 'expo.json']
106
+ let configFile = null
107
+
108
+ for (const file of configFiles) {
109
+ if (fs.existsSync(file)) {
110
+ configFile = file
111
+ break
112
+ }
113
+ }
114
+
115
+ if (!configFile) {
116
+ // Create basic app.config.js
117
+ const configContent = `const IS_DEV = process.env.APP_VARIANT === 'development'
118
+ const IS_PREVIEW = process.env.APP_VARIANT === 'preview'
119
+
120
+ const getUniqueIdentifier = () => {
121
+ if (IS_DEV) {
122
+ return '{{bundleId}}.dev'
123
+ }
124
+
125
+ if (IS_PREVIEW) {
126
+ return '{{bundleId}}.preview'
127
+ }
128
+
129
+ return '{{bundleId}}'
130
+ }
131
+
132
+ const getAppName = () => {
133
+ if (IS_DEV) {
134
+ return '{{displayName}} (Dev)'
135
+ }
136
+
137
+ if (IS_PREVIEW) {
138
+ return '{{displayName}} (Preview)'
139
+ }
140
+
141
+ return '{{displayName}}'
142
+ }
143
+
144
+ export default {
145
+ expo: {
146
+ name: getAppName(),
147
+ slug: '{{slug}}',
148
+ version: '1.0.0',
149
+ orientation: 'portrait',
150
+ icon: './assets/icon.png',
151
+ userInterfaceStyle: 'automatic',
152
+ splash: {
153
+ image: './assets/splash.png',
154
+ resizeMode: 'contain',
155
+ backgroundColor: '#ffffff'
156
+ },
157
+ assetBundlePatterns: ['**/*'],
158
+ ios: {
159
+ supportsTablet: true,
160
+ bundleIdentifier: getUniqueIdentifier()
161
+ },
162
+ android: {
163
+ adaptiveIcon: {
164
+ foregroundImage: './assets/adaptive-icon.png',
165
+ backgroundColor: '#ffffff'
166
+ },
167
+ package: getUniqueIdentifier()
168
+ },
169
+ web: {
170
+ favicon: './assets/favicon.png',
171
+ bundler: 'metro'
172
+ },
173
+ extra: {
174
+ supabaseUrl: process.env.EXPO_PUBLIC_SUPABASE_URL,
175
+ supabaseAnonKey: process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY,
176
+ openaiApiKey: process.env.EXPO_PUBLIC_OPENAI_API_KEY,
177
+ eas: {
178
+ projectId: '{{easProjectId}}'
179
+ }
180
+ },
181
+ owner: '{{expoUsername}}'
182
+ }
183
+ }
184
+ `
185
+ fs.writeFileSync('app.config.js', configContent)
186
+ success('Created app.config.js')
187
+ configFile = 'app.config.js'
188
+ }
189
+
190
+ // Check .env files
191
+ const envFiles = ['.env.local', '.env']
192
+ let envFileExists = false
193
+
194
+ for (const envFile of envFiles) {
195
+ if (fs.existsSync(envFile)) {
196
+ envFileExists = true
197
+ success(`Found ${envFile}`)
198
+ break
199
+ }
200
+ }
201
+
202
+ if (!envFileExists) {
203
+ warning('No environment file found. Creating .env.local...')
204
+
205
+ const envTemplate = `# RAG Knowledge System Configuration for React Native
206
+ EXPO_PUBLIC_SUPABASE_URL=your_supabase_url_here
207
+ EXPO_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key_here
208
+
209
+ # OpenAI Configuration (exposed to client - use with caution)
210
+ EXPO_PUBLIC_OPENAI_API_KEY=your_openai_api_key_here
211
+
212
+ # Server-only keys (for API routes if using Expo Router API routes)
213
+ SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key_here
214
+ OPENAI_API_KEY=your_openai_api_key_here
215
+
216
+ # App Configuration
217
+ APP_VARIANT=development
218
+ EAS_PROJECT_ID=your_eas_project_id_here
219
+ `
220
+
221
+ fs.writeFileSync('.env.local', envTemplate)
222
+ success('Created .env.local template')
223
+ warning('Please update .env.local with your actual API keys before proceeding')
224
+ warning('Note: In React Native, environment variables are embedded in the build!')
225
+ } else {
226
+ success('Environment configuration found')
227
+ }
228
+ }
229
+
230
+ function createMobileSpecificConfig() {
231
+ step(3, 'Creating mobile-specific RAG configuration')
232
+
233
+ // Create lib directory structure
234
+ const dirs = ['lib/rag', 'hooks', 'components/rag', 'scripts']
235
+ dirs.forEach(dir => {
236
+ if (!fs.existsSync(dir)) {
237
+ fs.mkdirSync(dir, { recursive: true })
238
+ success(`Created directory: ${dir}`)
239
+ }
240
+ })
241
+
242
+ // Create mobile-specific Supabase configuration
243
+ const supabaseConfig = `import AsyncStorage from '@react-native-async-storage/async-storage'
244
+ import { createClient } from '@supabase/supabase-js'
245
+ import Constants from 'expo-constants'
246
+ import type { Database } from '../types/supabase'
247
+
248
+ const supabaseUrl = Constants.expoConfig?.extra?.supabaseUrl || process.env.EXPO_PUBLIC_SUPABASE_URL
249
+ const supabaseAnonKey = Constants.expoConfig?.extra?.supabaseAnonKey || process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY
250
+
251
+ if (!supabaseUrl || !supabaseAnonKey) {
252
+ throw new Error(
253
+ 'Supabase URL and Anon Key are required. Please check your environment configuration.'
254
+ )
255
+ }
256
+
257
+ export const supabase = createClient<Database>(supabaseUrl, supabaseAnonKey, {
258
+ auth: {
259
+ storage: AsyncStorage,
260
+ autoRefreshToken: true,
261
+ persistSession: true,
262
+ detectSessionInUrl: false,
263
+ },
264
+ })
265
+
266
+ export default supabase
267
+ `
268
+
269
+ fs.writeFileSync('lib/supabase.ts', supabaseConfig)
270
+ success('Created Supabase configuration for React Native')
271
+ }
272
+
273
+ function createSeedScript() {
274
+ step(4, 'Creating knowledge seeding script')
275
+
276
+ const seedScript = `#!/usr/bin/env node
277
+
278
+ const { createClient } = require('@supabase/supabase-js')
279
+ require('dotenv').config({ path: '.env.local' })
280
+
281
+ const supabase = createClient(
282
+ process.env.EXPO_PUBLIC_SUPABASE_URL,
283
+ process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY
284
+ )
285
+
286
+ const sampleMobileDocuments = [
287
+ {
288
+ namespace: '{{packageName}}-mobile',
289
+ category: 'getting-started',
290
+ content: 'Welcome to your mobile AI-powered knowledge app! This React Native app uses RAG to provide intelligent responses based on your knowledge base. Swipe through tabs to explore different features.',
291
+ fields: {
292
+ title: 'Mobile App Welcome',
293
+ difficulty: 'beginner',
294
+ platform: 'mobile'
295
+ },
296
+ metadata: {
297
+ featured: true,
298
+ priority: 1,
299
+ mobileOptimized: true
300
+ },
301
+ source: { type: 'seed', version: '1.0', platform: 'react-native' }
302
+ },
303
+ {
304
+ namespace: '{{packageName}}-mobile',
305
+ category: 'features',
306
+ content: 'Mobile features include: Voice input for queries, offline caching, push notifications for new knowledge, touch-optimized interface, and seamless sync across devices.',
307
+ fields: {
308
+ title: 'Mobile Platform Features',
309
+ difficulty: 'beginner',
310
+ platform: 'mobile'
311
+ },
312
+ metadata: {
313
+ featured: true,
314
+ priority: 2,
315
+ mobileOptimized: true
316
+ },
317
+ source: { type: 'seed', version: '1.0', platform: 'react-native' }
318
+ },
319
+ {
320
+ namespace: '{{packageName}}-mobile',
321
+ category: 'tutorials',
322
+ content: 'To use voice input: 1. Tap the microphone icon in the chat, 2. Speak your question clearly, 3. The app will convert speech to text and process your query, 4. Get AI responses with relevant sources.',
323
+ fields: {
324
+ title: 'Voice Input Tutorial',
325
+ difficulty: 'intermediate',
326
+ platform: 'mobile'
327
+ },
328
+ metadata: {
329
+ tutorial: true,
330
+ priority: 3,
331
+ mobileOptimized: true
332
+ },
333
+ source: { type: 'seed', version: '1.0', platform: 'react-native' }
334
+ },
335
+ {
336
+ namespace: '{{packageName}}-mobile',
337
+ category: 'offline',
338
+ content: 'Offline mode: The app caches recent queries and responses for offline access. When offline, you can still browse cached content and queue new queries that will be processed when connection is restored.',
339
+ fields: {
340
+ title: 'Offline Mode Guide',
341
+ difficulty: 'intermediate',
342
+ platform: 'mobile'
343
+ },
344
+ metadata: {
345
+ featured: true,
346
+ priority: 4,
347
+ mobileOptimized: true,
348
+ offlineCapable: true
349
+ },
350
+ source: { type: 'seed', version: '1.0', platform: 'react-native' }
351
+ }
352
+ ]
353
+
354
+ async function seedMobileKnowledge() {
355
+ console.log('🌱 Seeding mobile knowledge base...')
356
+
357
+ try {
358
+ for (const doc of sampleMobileDocuments) {
359
+ const { data, error } = await supabase
360
+ .from('rag_knowledge_base')
361
+ .insert(doc)
362
+
363
+ if (error) {
364
+ console.error('Error inserting document:', error)
365
+ } else {
366
+ console.log('āœ… Inserted:', doc.fields.title)
367
+ }
368
+ }
369
+
370
+ console.log('šŸŽ‰ Mobile knowledge base seeded successfully!')
371
+ console.log('šŸ“± Next steps for React Native:')
372
+ console.log(' 1. Run: npm start or npx expo start')
373
+ console.log(' 2. Open in Expo Go or simulator')
374
+ console.log(' 3. Navigate to the AI tab')
375
+ console.log(' 4. Start chatting with your knowledge base!')
376
+ console.log(' 5. Test offline mode by disabling network')
377
+
378
+ } catch (error) {
379
+ console.error('āŒ Mobile seeding failed:', error)
380
+ process.exit(1)
381
+ }
382
+ }
383
+
384
+ seedMobileKnowledge()
385
+ `
386
+
387
+ fs.writeFileSync('scripts/seed-mobile-knowledge.js', seedScript)
388
+ fs.chmodSync('scripts/seed-mobile-knowledge.js', 0o755)
389
+ success('Created mobile seed script')
390
+ }
391
+
392
+ function setupTypeScript() {
393
+ step(5, 'Setting up TypeScript types')
394
+
395
+ // Create types directory
396
+ if (!fs.existsSync('types')) {
397
+ fs.mkdirSync('types', { recursive: true })
398
+ }
399
+
400
+ // Create basic RAG types for mobile
401
+ const ragTypes = `// RAG System Types for React Native
402
+ export interface MobileRAGConfig {
403
+ domain: string
404
+ enableOffline: boolean
405
+ cacheSize: number
406
+ syncStrategy: 'immediate' | 'batch' | 'manual'
407
+ voiceInput?: boolean
408
+ hapticFeedback?: boolean
409
+ }
410
+
411
+ export interface OfflineQuery {
412
+ id: string
413
+ query: string
414
+ timestamp: Date
415
+ synced: boolean
416
+ }
417
+
418
+ export interface CachedResponse {
419
+ query: string
420
+ response: string
421
+ sources: any[]
422
+ confidence: number
423
+ timestamp: Date
424
+ expiresAt: Date
425
+ }
426
+
427
+ export interface MobileRAGState {
428
+ isOnline: boolean
429
+ isLoading: boolean
430
+ cacheSize: number
431
+ offlineQueueSize: number
432
+ lastSync: Date | null
433
+ }
434
+ `
435
+
436
+ fs.writeFileSync('types/rag.ts', ragTypes)
437
+ success('Created mobile RAG types')
438
+
439
+ // Create Supabase types placeholder
440
+ const supabaseTypes = `// Basic Supabase types for RAG system
441
+ // Replace with generated types: supabase gen types --local > types/supabase.ts
442
+
443
+ export interface Database {
444
+ public: {
445
+ Tables: {
446
+ rag_knowledge_base: {
447
+ Row: {
448
+ id: string
449
+ namespace: string
450
+ category: string
451
+ content: string
452
+ fields: Record<string, any>
453
+ metadata: Record<string, any>
454
+ source: Record<string, any>
455
+ embedding: number[] | null
456
+ created_at: string
457
+ updated_at: string
458
+ version: number
459
+ }
460
+ Insert: {
461
+ id?: string
462
+ namespace?: string
463
+ category?: string
464
+ content: string
465
+ fields?: Record<string, any>
466
+ metadata?: Record<string, any>
467
+ source?: Record<string, any>
468
+ embedding?: number[] | null
469
+ created_at?: string
470
+ updated_at?: string
471
+ version?: number
472
+ }
473
+ Update: {
474
+ id?: string
475
+ namespace?: string
476
+ category?: string
477
+ content?: string
478
+ fields?: Record<string, any>
479
+ metadata?: Record<string, any>
480
+ source?: Record<string, any>
481
+ embedding?: number[] | null
482
+ created_at?: string
483
+ updated_at?: string
484
+ version?: number
485
+ }
486
+ }
487
+ }
488
+ Views: {
489
+ [_ in never]: never
490
+ }
491
+ Functions: {
492
+ rag_similarity_search: {
493
+ Args: {
494
+ query_embedding: number[]
495
+ search_namespace?: string
496
+ search_category?: string
497
+ similarity_threshold?: number
498
+ max_results?: number
499
+ }
500
+ Returns: {
501
+ id: string
502
+ content: string
503
+ category: string
504
+ fields: Record<string, any>
505
+ metadata: Record<string, any>
506
+ similarity: number
507
+ }[]
508
+ }
509
+ }
510
+ Enums: {
511
+ [_ in never]: never
512
+ }
513
+ }
514
+ }
515
+ `
516
+
517
+ fs.writeFileSync('types/supabase.ts', supabaseTypes)
518
+ success('Created basic Supabase types')
519
+ }
520
+
521
+ function updatePackageJson() {
522
+ step(6, 'Updating package.json scripts')
523
+
524
+ const packageJsonPath = 'package.json'
525
+ if (fs.existsSync(packageJsonPath)) {
526
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
527
+
528
+ packageJson.scripts = {
529
+ ...packageJson.scripts,
530
+ 'setup:rag': 'node scripts/setup-rag.js',
531
+ 'seed:knowledge': 'node scripts/seed-mobile-knowledge.js',
532
+ 'db:types': 'supabase gen types --local > types/supabase.ts'
533
+ }
534
+
535
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2))
536
+ success('Updated package.json scripts')
537
+ }
538
+ }
539
+
540
+ function displayMobileNextSteps() {
541
+ step(7, 'Setup complete! Mobile-specific next steps')
542
+
543
+ log('\nšŸŽ‰ Mobile RAG Knowledge System setup complete!\n', 'green')
544
+
545
+ log('šŸ“± Mobile-specific next steps:', 'cyan')
546
+ log(' 1. Update your .env.local with actual API keys')
547
+ log(' 2. Ensure your Supabase database has the RAG tables')
548
+ log(' 3. Run the mobile seed script: npm run seed:knowledge')
549
+ log(' 4. Start Expo: npx expo start')
550
+ log(' 5. Open in simulator or Expo Go app')
551
+ log(' 6. Test the AI tab with voice input and offline mode')
552
+
553
+ log('\nšŸ”§ Available commands:', 'cyan')
554
+ log(' npm run setup:rag - Run this setup script')
555
+ log(' npm run seed:knowledge - Add mobile-optimized knowledge')
556
+ log(' npm run db:types - Generate TypeScript types')
557
+ log(' npx expo start - Start development server')
558
+ log(' npx expo start --offline - Start in offline mode')
559
+
560
+ log('\nšŸ“š Mobile-specific files:', 'cyan')
561
+ log(' • RAG Hook: hooks/useRAGSystem.ts')
562
+ log(' • AI Screen: app/(tabs)/ai.tsx')
563
+ log(' • Config: lib/rag/config.ts')
564
+ log(' • Supabase: lib/supabase.ts')
565
+ log(' • Types: types/rag.ts, types/supabase.ts')
566
+
567
+ log('\nšŸ’” Mobile tips:', 'yellow')
568
+ log(' • Test offline functionality by disabling network')
569
+ log(' • Voice input works in simulator with computer microphone')
570
+ log(' • Haptic feedback enhances user experience')
571
+ log(' • Cache settings can be adjusted in config')
572
+ log(' • Consider push notifications for knowledge updates')
573
+
574
+ log('\nšŸ“Š Performance considerations:', 'yellow')
575
+ log(' • Embeddings are computed server-side to save battery')
576
+ log(' • Responses are cached locally for offline access')
577
+ log(' • Background sync keeps knowledge base updated')
578
+ log(' • Network requests are debounced to reduce API calls')
579
+
580
+ log('\nšŸš€ Happy building with Mobile RAG!', 'green')
581
+ }
582
+
583
+ // Main execution
584
+ async function main() {
585
+ try {
586
+ checkRequirements()
587
+ setupEnvironmentVariables()
588
+ createMobileSpecificConfig()
589
+ createSeedScript()
590
+ setupTypeScript()
591
+ updatePackageJson()
592
+ displayMobileNextSteps()
593
+ } catch (err) {
594
+ error(`Mobile setup failed: ${err.message}`)
595
+ process.exit(1)
596
+ }
597
+ }
598
+
599
+ main()