vibefast-cli 1.3.0 → 1.3.1
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.
- package/README.md +30 -95
- package/dist/__tests__/recipes.test.js +8 -9
- package/dist/__tests__/recipes.test.js.map +1 -1
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +271 -125
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/checklist.d.ts.map +1 -1
- package/dist/commands/checklist.js +85 -44
- package/dist/commands/checklist.js.map +1 -1
- package/dist/commands/health.d.ts.map +1 -1
- package/dist/commands/health.js +13 -4
- package/dist/commands/health.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +118 -26
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/migrate.d.ts +3 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +202 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/remove.d.ts.map +1 -1
- package/dist/commands/remove.js +61 -3
- package/dist/commands/remove.js.map +1 -1
- package/dist/core/auth.d.ts.map +1 -1
- package/dist/core/auth.js +20 -18
- package/dist/core/auth.js.map +1 -1
- package/dist/core/codemod.d.ts +33 -0
- package/dist/core/codemod.d.ts.map +1 -1
- package/dist/core/codemod.js +116 -0
- package/dist/core/codemod.js.map +1 -1
- package/dist/core/detect.d.ts.map +1 -1
- package/dist/core/detect.js +24 -7
- package/dist/core/detect.js.map +1 -1
- package/dist/core/journal.d.ts +1 -0
- package/dist/core/journal.d.ts.map +1 -1
- package/dist/core/journal.js.map +1 -1
- package/dist/core/recipes.d.ts.map +1 -1
- package/dist/core/recipes.js +25 -7
- package/dist/core/recipes.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/docs/architecture.md +50 -0
- package/docs/commands.md +78 -0
- package/docs/contributing.md +27 -0
- package/docs/quickstart.md +50 -0
- package/docs/recipes.md +57 -0
- package/docs/troubleshooting.md +31 -0
- package/package.json +2 -2
- package/recipes/0/apps/native/src/components/advanced-ui/timeline/demo.tsx +445 -0
- package/recipes/0/apps/native/src/components/advanced-ui/timeline/timeline-view.tsx +355 -0
- package/recipes/0/apps/native/src/components/advanced-ui/timeline/types.ts +31 -0
- package/recipes/0/recipe.json +18 -0
- package/recipes/animated-chip/apps/native/src/components/advanced-ui/chip/demo.tsx +2 -1
- package/recipes/animated-chip/recipe.json +5 -2
- package/recipes/animated-chip-native@latest.zip +0 -0
- package/recipes/animated-chip@latest.zip +0 -0
- package/recipes/animated-switch/apps/native/src/components/advanced-ui/switch/demo.tsx +1 -1
- package/recipes/animated-switch/recipe.json +5 -2
- package/recipes/animated-switch-native@latest.zip +0 -0
- package/recipes/animated-switch@latest.zip +0 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/components/audio-recorder.tsx +2 -1
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/with-recording-list-demo.tsx +2 -2
- package/recipes/audio-recorder/recipe.json +7 -2
- package/recipes/audio-recorder-native@latest.zip +0 -0
- package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/components/audio-recorder.tsx +2 -1
- package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/with-recording-list-demo.tsx +2 -1
- package/recipes/audio-recorder-supabase/recipe.json +12 -33
- package/recipes/audio-recorder-supabase-native@latest.zip +0 -0
- package/recipes/audio-recorder-supabase@latest.zip +0 -0
- package/recipes/audio-recorder@latest.zip +0 -0
- package/recipes/charts/apps/native/src/app/charts/index.tsx +3 -0
- package/recipes/charts/apps/native/src/features/charts/components/bar-chart.tsx +3 -1
- package/recipes/charts/apps/native/src/features/charts/components/candlestick-chart.tsx +3 -1
- package/recipes/charts/apps/native/src/features/charts/components/column-chart.tsx +3 -1
- package/recipes/charts/apps/native/src/features/charts/components/doughnut-chart.tsx +3 -1
- package/recipes/charts/apps/native/src/features/charts/components/line-chart.tsx +3 -1
- package/recipes/charts/apps/native/src/features/charts/components/radar-chart.tsx +3 -1
- package/recipes/charts/apps/native/src/features/charts/components/stacked-bar-chart.tsx +3 -1
- package/recipes/charts/recipe.json +13 -4
- package/recipes/charts-native@latest.zip +0 -0
- package/recipes/charts@latest.zip +0 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-markdown.tsx +86 -86
- package/recipes/chatbot/apps/native/src/features/chatbot/components/markdown/code-block.tsx +4 -4
- package/recipes/chatbot/recipe.json +3 -40
- package/recipes/chatbot-native@latest.zip +0 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/chat-markdown.tsx +4 -1
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/markdown/code-block.tsx +86 -53
- package/recipes/chatbot-supabase/recipe.json +3 -69
- package/recipes/chatbot-supabase-native@latest.zip +0 -0
- package/recipes/chatbot-supabase@latest.zip +0 -0
- package/recipes/chatbot@latest.zip +0 -0
- package/recipes/glowing-button/recipe.json +6 -2
- package/recipes/glowing-button-native@latest.zip +0 -0
- package/recipes/glowing-button@latest.zip +0 -0
- package/recipes/image-analysis/apps/native/src/app/analysis/[type]/_layout.tsx +5 -0
- package/recipes/image-analysis/apps/native/src/app/analysis/[type]/analysis-options.tsx +50 -0
- package/recipes/image-analysis/apps/native/src/app/analysis/[type]/camera.tsx +2 -0
- package/recipes/image-analysis/apps/native/src/app/analysis/[type]/index.tsx +50 -0
- package/recipes/image-analysis/apps/native/src/app/analysis/[type]/loading.tsx +50 -0
- package/recipes/image-analysis/apps/native/src/app/analysis/[type]/results.tsx +2 -0
- package/recipes/image-analysis/apps/native/src/app/analysis/[type]/trait-details.tsx +3 -0
- package/recipes/image-analysis/apps/native/src/features/image-analyzer/app/analysis-options-screen.tsx +2 -2
- package/recipes/image-analysis/apps/native/src/features/image-analyzer/app/camera.tsx +72 -65
- package/recipes/image-analysis/apps/native/src/features/image-analyzer/app/image-capture-screen.tsx +65 -47
- package/recipes/image-analysis/apps/native/src/features/image-analyzer/app/loading-screen.tsx +43 -2
- package/recipes/image-analysis/apps/native/src/features/image-analyzer/app/loading.tsx +34 -1
- package/recipes/image-analysis/apps/native/src/features/image-analyzer/hooks/use-image-analysis.ts +83 -2
- package/recipes/image-analysis/recipe.json +11 -19
- package/recipes/image-analysis-native@latest.zip +0 -0
- package/recipes/image-analysis-supabase/apps/native/src/app/analysis/[type]/_layout.tsx +5 -0
- package/recipes/image-analysis-supabase/apps/native/src/app/analysis/[type]/analysis-options.tsx +50 -0
- package/recipes/image-analysis-supabase/apps/native/src/app/analysis/[type]/camera.tsx +2 -0
- package/recipes/image-analysis-supabase/apps/native/src/app/analysis/[type]/index.tsx +50 -0
- package/recipes/image-analysis-supabase/apps/native/src/app/analysis/[type]/loading.tsx +50 -0
- package/recipes/image-analysis-supabase/apps/native/src/app/analysis/[type]/results.tsx +2 -0
- package/recipes/image-analysis-supabase/apps/native/src/app/analysis/[type]/trait-details.tsx +3 -0
- package/recipes/image-analysis-supabase/recipe.json +10 -70
- package/recipes/image-analysis-supabase-native@latest.zip +0 -0
- package/recipes/image-analysis-supabase@latest.zip +0 -0
- package/recipes/image-analysis@latest.zip +0 -0
- package/recipes/image-analyzer/apps/native/src/app/(root)/(protected)/image-analyzer/index.tsx +2 -0
- package/recipes/image-generator/apps/native/src/app/image-generator/gallery.tsx +3 -0
- package/recipes/image-generator/apps/native/src/app/image-generator/index.tsx +3 -0
- package/recipes/image-generator/recipe.json +8 -18
- package/recipes/image-generator-native@latest.zip +0 -0
- package/recipes/image-generator-supabase/recipe.json +6 -62
- package/recipes/image-generator-supabase-native@latest.zip +0 -0
- package/recipes/image-generator-supabase@latest.zip +0 -0
- package/recipes/image-generator@latest.zip +0 -0
- package/recipes/ios-widget/recipe.json +18 -119
- package/recipes/ios-widget-native@latest.zip +0 -0
- package/recipes/ios-widget@latest.zip +0 -0
- package/recipes/number-stepper/apps/native/src/components/advanced-ui/stepper/demo.tsx +1 -1
- package/recipes/number-stepper/recipe.json +5 -2
- package/recipes/number-stepper-native@latest.zip +0 -0
- package/recipes/number-stepper@latest.zip +0 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/interactive-onboarding.tsx +11 -18
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/ai-tone-step.tsx +5 -7
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/currency-step.tsx +9 -7
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-ai-step.tsx +8 -7
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-chatbot-step.tsx +6 -5
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-manual-step.tsx +4 -3
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-scan-step.tsx +6 -5
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/main-reason-step.tsx +5 -7
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/notification-step.tsx +7 -6
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/overspend-step.tsx +5 -7
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/personalizing-step.tsx +8 -7
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/rating-step.tsx +6 -5
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/reminder-step.tsx +5 -6
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/safety-step.tsx +5 -4
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/struggle-step.tsx +5 -7
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/welcome-step.tsx +7 -6
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/ui/onboarding-header.tsx +4 -3
- package/recipes/onboarding/recipe.json +9 -6
- package/recipes/onboarding-native@latest.zip +0 -0
- package/recipes/onboarding@latest.zip +0 -0
- package/recipes/payments/apps/native/src/app/paywall/index.tsx +74 -0
- package/recipes/payments/apps/native/src/app/paywall/local.tsx +25 -0
- package/recipes/payments/apps/native/src/app/paywall/remote.tsx +23 -0
- package/recipes/payments/packages/backend/convex/payments.ts +21 -3
- package/recipes/payments/recipe.json +14 -34
- package/recipes/payments-native@latest.zip +0 -0
- package/recipes/payments-supabase/apps/native/src/app/paywall/index.tsx +74 -0
- package/recipes/payments-supabase/apps/native/src/app/paywall/local.tsx +25 -0
- package/recipes/payments-supabase/apps/native/src/app/paywall/remote.tsx +23 -0
- package/recipes/payments-supabase/recipe.json +16 -44
- package/recipes/payments-supabase-native@latest.zip +0 -0
- package/recipes/payments-supabase@latest.zip +0 -0
- package/recipes/payments@latest.zip +0 -0
- package/recipes/posthog/apps/native/src/components/analytics/navigation-tracker.tsx +14 -0
- package/recipes/posthog/apps/native/src/lib/hooks/use-navigation-analytics.ts +44 -0
- package/recipes/posthog/apps/native/src/providers/posthog-provider.tsx +51 -0
- package/recipes/posthog/recipe.json +60 -0
- package/recipes/posthog-native@latest.zip +0 -0
- package/recipes/progress-circle/apps/native/src/components/advanced-ui/progress-bars/progress-circle-page.tsx +1 -1
- package/recipes/progress-circle/recipe.json +5 -2
- package/recipes/progress-circle-native@latest.zip +0 -0
- package/recipes/progress-circle@latest.zip +0 -0
- package/recipes/quiz/apps/native/src/app/quiz/index.tsx +47 -0
- package/recipes/quiz/recipe.json +9 -6
- package/recipes/quiz-native@latest.zip +0 -0
- package/recipes/quiz@latest.zip +0 -0
- package/recipes/screen-kits/apps/native/src/app/screen-kits/_layout.tsx +12 -0
- package/recipes/screen-kits/apps/native/src/app/screen-kits/index.tsx +114 -0
- package/recipes/screen-kits/apps/native/src/features/screen-kits/index.ts +1 -0
- package/recipes/screen-kits/apps/native/src/features/screen-kits/types.ts +28 -0
- package/recipes/screen-kits/recipe.json +26 -0
- package/recipes/screen-kits-duolingo/apps/native/src/app/screen-kits/duolingo/_layout.tsx +12 -0
- package/recipes/screen-kits-duolingo/apps/native/src/app/screen-kits/duolingo/home.tsx +5 -0
- package/recipes/screen-kits-duolingo/apps/native/src/app/screen-kits/duolingo/index.tsx +5 -0
- package/recipes/screen-kits-duolingo/apps/native/src/app/screen-kits/duolingo/lesson-complete.tsx +5 -0
- package/recipes/screen-kits-duolingo/apps/native/src/app/screen-kits/duolingo/lesson-fail.tsx +5 -0
- package/recipes/screen-kits-duolingo/apps/native/src/app/screen-kits/duolingo/lesson.tsx +5 -0
- package/recipes/screen-kits-duolingo/apps/native/src/app/screen-kits/duolingo/skill-tree.tsx +5 -0
- package/recipes/screen-kits-duolingo/apps/native/src/features/screen-kits/duolingo/components/duo-button.tsx +174 -0
- package/recipes/screen-kits-duolingo/apps/native/src/features/screen-kits/duolingo/components/skill-button.tsx +186 -0
- package/recipes/screen-kits-duolingo/apps/native/src/features/screen-kits/duolingo/components/xp-header.tsx +115 -0
- package/recipes/screen-kits-duolingo/apps/native/src/features/screen-kits/duolingo/constants.ts +89 -0
- package/recipes/screen-kits-duolingo/apps/native/src/features/screen-kits/duolingo/index.ts +3 -0
- package/recipes/screen-kits-duolingo/apps/native/src/features/screen-kits/duolingo/screens/home-screen.tsx +225 -0
- package/recipes/screen-kits-duolingo/apps/native/src/features/screen-kits/duolingo/screens/lesson-complete-screen.tsx +485 -0
- package/recipes/screen-kits-duolingo/apps/native/src/features/screen-kits/duolingo/screens/lesson-fail-screen.tsx +105 -0
- package/recipes/screen-kits-duolingo/apps/native/src/features/screen-kits/duolingo/screens/lesson-screen.tsx +384 -0
- package/recipes/screen-kits-duolingo/recipe.json +58 -0
- package/recipes/screen-kits-duolingo-native@latest.zip +0 -0
- package/recipes/screen-kits-finance/apps/native/src/app/screen-kits/finance/_layout.tsx +45 -0
- package/recipes/screen-kits-finance/apps/native/src/app/screen-kits/finance/asset-detail.tsx +3 -0
- package/recipes/screen-kits-finance/apps/native/src/app/screen-kits/finance/notifications.tsx +3 -0
- package/recipes/screen-kits-finance/apps/native/src/app/screen-kits/finance/receive.tsx +3 -0
- package/recipes/screen-kits-finance/apps/native/src/app/screen-kits/finance/send.tsx +3 -0
- package/recipes/screen-kits-finance/apps/native/src/app/screen-kits/finance/swap.tsx +3 -0
- package/recipes/screen-kits-finance/apps/native/src/app/screen-kits/finance/wallet.tsx +3 -0
- package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/components/ActionButtons.tsx +78 -0
- package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/components/AssetRow.tsx +94 -0
- package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/components/BalanceCard.tsx +118 -0
- package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/constants.ts +85 -0
- package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/screens/asset-detail.tsx +378 -0
- package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/screens/notifications.tsx +210 -0
- package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/screens/receive-modal.tsx +317 -0
- package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/screens/send-modal.tsx +420 -0
- package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/screens/swap-modal.tsx +363 -0
- package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/screens/wallet-dashboard.tsx +281 -0
- package/recipes/screen-kits-finance/recipe.json +46 -0
- package/recipes/screen-kits-finance-native@latest.zip +0 -0
- package/recipes/screen-kits-fitness/apps/native/assets/sounds/timer-beep.wav +0 -0
- package/recipes/screen-kits-fitness/apps/native/src/app/screen-kits/fitness/_layout.tsx +10 -0
- package/recipes/screen-kits-fitness/apps/native/src/app/screen-kits/fitness/index.tsx +6 -0
- package/recipes/screen-kits-fitness/apps/native/src/app/screen-kits/fitness/timer.tsx +3 -0
- package/recipes/screen-kits-fitness/apps/native/src/app/screen-kits/fitness/workout.tsx +3 -0
- package/recipes/screen-kits-fitness/apps/native/src/features/screen-kits/fitness/components/timer-components.tsx +500 -0
- package/recipes/screen-kits-fitness/apps/native/src/features/screen-kits/fitness/components/timer-settings-modal.tsx +352 -0
- package/recipes/screen-kits-fitness/apps/native/src/features/screen-kits/fitness/components/workout-card.tsx +105 -0
- package/recipes/screen-kits-fitness/apps/native/src/features/screen-kits/fitness/constants.ts +189 -0
- package/recipes/screen-kits-fitness/apps/native/src/features/screen-kits/fitness/hooks/use-timer.ts +307 -0
- package/recipes/screen-kits-fitness/apps/native/src/features/screen-kits/fitness/index.ts +1 -0
- package/recipes/screen-kits-fitness/apps/native/src/features/screen-kits/fitness/screens/timer-screen.tsx +278 -0
- package/recipes/screen-kits-fitness/apps/native/src/features/screen-kits/fitness/screens/workout-dashboard.tsx +350 -0
- package/recipes/screen-kits-fitness/recipe.json +63 -0
- package/recipes/screen-kits-fitness-native@latest.zip +0 -0
- package/recipes/screen-kits-habits/apps/native/src/app/screen-kits/productivity/habits.tsx +1 -0
- package/recipes/screen-kits-habits/apps/native/src/app/screen-kits/productivity/kanban.tsx +1 -0
- package/recipes/screen-kits-habits/apps/native/src/app/screen-kits/productivity/routes.ts +4 -0
- package/recipes/screen-kits-habits/apps/native/src/features/screen-kits/productivity/components/AddTaskModal.tsx +246 -0
- package/recipes/screen-kits-habits/apps/native/src/features/screen-kits/productivity/components/DraggableTaskCard.tsx +92 -0
- package/recipes/screen-kits-habits/apps/native/src/features/screen-kits/productivity/components/KanbanColumn.tsx +238 -0
- package/recipes/screen-kits-habits/apps/native/src/features/screen-kits/productivity/components/TaskCard.tsx +144 -0
- package/recipes/screen-kits-habits/apps/native/src/features/screen-kits/productivity/components/add-habit-modal.tsx +271 -0
- package/recipes/screen-kits-habits/apps/native/src/features/screen-kits/productivity/constants.ts +295 -0
- package/recipes/screen-kits-habits/apps/native/src/features/screen-kits/productivity/kanban-utils.ts +62 -0
- package/recipes/screen-kits-habits/apps/native/src/features/screen-kits/productivity/screens/habit-tracker.tsx +1160 -0
- package/recipes/screen-kits-habits/apps/native/src/features/screen-kits/productivity/screens/kanban-board.tsx +432 -0
- package/recipes/screen-kits-habits/recipe.json +52 -0
- package/recipes/screen-kits-habits-native@latest.zip +0 -0
- package/recipes/screen-kits-native@latest.zip +0 -0
- package/recipes/sentry/apps/native/src/providers/sentry-provider.tsx +64 -0
- package/recipes/sentry/recipe.json +39 -0
- package/recipes/sentry-native@latest.zip +0 -0
- package/recipes/swipe-slider/apps/native/src/components/advanced-ui/sliders/swipe-slider-page.tsx +1 -1
- package/recipes/swipe-slider/recipe.json +5 -2
- package/recipes/swipe-slider-native@latest.zip +0 -0
- package/recipes/swipe-slider@latest.zip +0 -0
- package/recipes/timeline/apps/native/src/components/advanced-ui/timeline/demo.tsx +2 -1
- package/recipes/timeline/recipe.json +5 -2
- package/recipes/timeline-native@latest.zip +0 -0
- package/recipes/timeline@latest.zip +0 -0
- package/recipes/tracker-app/apps/native/src/app/tracker-app/index.tsx +1 -0
- package/recipes/tracker-app/recipe.json +10 -7
- package/recipes/tracker-app-native@latest.zip +0 -0
- package/recipes/tracker-app@latest.zip +0 -0
- package/recipes/upload-all.sh +8 -31
- package/recipes/voice-bot/apps/native/src/app/voice-bot/index.tsx +56 -0
- package/recipes/voice-bot/recipe.json +31 -7
- package/recipes/voice-bot-native@latest.zip +0 -0
- package/recipes/voice-bot@latest.zip +0 -0
- package/recipes/wake-word/apps/native/src/app/{(root)/(protected)/test-wake-word.tsx → test-wake-word.tsx} +43 -4
- package/recipes/wake-word/recipe.json +16 -26
- package/recipes/wake-word-native@latest.zip +0 -0
- package/recipes/wake-word@latest.zip +0 -0
- package/scripts/create-advanced-ui-recipes.sh +46 -19
- package/scripts/create-recipes.mjs +471 -117
- package/scripts/package-recipes.mjs +76 -0
- package/scripts/publish-all.sh +6 -2
- package/CHANGELOG.md +0 -198
- package/docs/archive/AUTO-DETECT-DEPS.md +0 -607
- package/docs/archive/FINAL-PACKAGE-STRATEGY.md +0 -583
- package/docs/archive/FINAL-SIMPLE-PLAN.md +0 -487
- package/docs/archive/FINAL-STATUS.md +0 -144
- package/docs/archive/FLOW-DIAGRAM.md +0 -1629
- package/docs/archive/GOTCHAS-AND-RISKS.md +0 -801
- package/docs/archive/IMPLEMENTATION-PLAN.md +0 -1360
- package/docs/archive/PLAN.md +0 -453
- package/docs/archive/PRODUCTION-READINESS.md +0 -684
- package/docs/archive/PRODUCTION-TEST-RESULTS.md +0 -465
- package/docs/archive/SIMPLIFIED-PLAN.md +0 -578
- package/docs/archive/STATUS.md +0 -199
- package/docs/archive/SUCCESS.md +0 -259
- package/docs/archive/TEST-SUMMARY.md +0 -261
- package/docs/archive/TESTING-CHECKLIST.md +0 -450
- package/docs/archive/USER-MODIFICATIONS.md +0 -448
- package/docs/decisions.md +0 -55
- package/docs/manual-testing.md +0 -91
- package/docs/next-steps.md +0 -12
- package/recipes/README.md +0 -156
- package/recipes/audio-recorder-supabase/packages/backend/src/services/recordings.ts +0 -369
- package/recipes/chatbot/apps/native/src/api-client/chatbot.ts +0 -83
- package/recipes/chatbot/packages/backend/convex/agents.ts +0 -115
- package/recipes/chatbot/packages/backend/convex/tools/index.ts +0 -18
- package/recipes/chatbot/packages/backend/convex/tools/knowledgeRetrieval.ts +0 -97
- package/recipes/chatbot/packages/backend/convex/tools/tavilySearch.ts +0 -83
- package/recipes/chatbot/packages/backend/convex/tools/userProfile.ts +0 -72
- package/recipes/chatbot-supabase/apps/native/src/api-client/supabase/chatbot.ts +0 -515
- package/recipes/chatbot-supabase/packages/backend/src/services/conversations.ts +0 -243
- package/recipes/chatbot-supabase/packages/backend/src/services/messages.ts +0 -327
- package/recipes/image-analysis/apps/native/src/api-client/image-analyzer.ts +0 -62
- package/recipes/image-analysis-supabase/packages/backend/src/services/image-analyses.ts +0 -132
- package/recipes/image-generator/apps/native/src/api-client/image-generator.ts +0 -34
- package/recipes/payments/apps/native/src/api-client/payments.ts +0 -44
- package/recipes/payments-supabase/packages/backend/src/services/payments.ts +0 -201
- package/recipes/posthog.json +0 -47
- package/recipes/revenuecat.json +0 -43
- package/recipes/sentry.json +0 -47
- package/recipes/wake-word/apps/native/assets/vosk-model/README.md +0 -103
- package/recipes/wake-word/apps/native/scripts/download-vosk-model.mjs +0 -127
- /package/recipes/{audio-recorder/apps/native/src/app/(root)/(protected) → audio-recorder-supabase/apps/native/src/app}/audio-recorder/index.tsx +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/AppIntent.swift +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@1x.png +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@2x.png +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@3x.png +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@1x.png +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@2x.png +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@3x.png +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@1x.png +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@2x.png +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@3x.png +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-60x60@2x.png +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-60x60@3x.png +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-76x76@1x.png +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-76x76@2x.png +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-83.5x83.5@2x.png +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/CalorieTrackerWidget.swift +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/HabitTrackerWidget.swift +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Info.plist +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/WidgetLiveActivity.swift +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/expo-target.config.js +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/generated.entitlements +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/index.swift +0 -0
- /package/recipes/ios-widget/{targets → apps/native/targets}/widget/widgets.swift +0 -0
|
@@ -1,801 +0,0 @@
|
|
|
1
|
-
# ⚠️ Gotchas, Risks, and Difficult Problems
|
|
2
|
-
|
|
3
|
-
## 🔴 HIGH RISK Issues
|
|
4
|
-
|
|
5
|
-
### 1. Monorepo Package Installation - VERY TRICKY
|
|
6
|
-
|
|
7
|
-
**The Problem:**
|
|
8
|
-
VibeFast is a monorepo with multiple workspaces:
|
|
9
|
-
```
|
|
10
|
-
vibefast-monorepo/
|
|
11
|
-
├── package.json (root)
|
|
12
|
-
├── apps/
|
|
13
|
-
│ ├── native/
|
|
14
|
-
│ │ └── package.json (workspace)
|
|
15
|
-
│ └── web/
|
|
16
|
-
│ └── package.json (workspace)
|
|
17
|
-
└── packages/
|
|
18
|
-
└── ui/
|
|
19
|
-
└── package.json (workspace)
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
**Where do we install packages?**
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
# If we run this in apps/native/:
|
|
26
|
-
$ pnpm add react-native-chart-kit
|
|
27
|
-
|
|
28
|
-
# It might:
|
|
29
|
-
# ❌ Install in apps/native/node_modules (wrong!)
|
|
30
|
-
# ❌ Install in root node_modules (maybe wrong!)
|
|
31
|
-
# ✅ Install in root + update apps/native/package.json (correct!)
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
**The Issue:**
|
|
35
|
-
- pnpm workspaces install at ROOT but update workspace package.json
|
|
36
|
-
- yarn workspaces behave differently
|
|
37
|
-
- npm workspaces behave differently again
|
|
38
|
-
- Turborepo adds another layer of complexity
|
|
39
|
-
|
|
40
|
-
**Example of What Can Go Wrong:**
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
# User is in: /Users/john/vibefast-monorepo/apps/native/
|
|
44
|
-
$ vf add charts
|
|
45
|
-
|
|
46
|
-
# CLI detects: pnpm
|
|
47
|
-
# CLI runs: pnpm add react-native-chart-kit
|
|
48
|
-
|
|
49
|
-
# What happens?
|
|
50
|
-
# - pnpm sees we're in a workspace
|
|
51
|
-
# - pnpm installs at ROOT
|
|
52
|
-
# - pnpm updates apps/native/package.json
|
|
53
|
-
# - BUT: If we run from wrong directory, it fails!
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
**Solution (Complex):**
|
|
57
|
-
|
|
58
|
-
```typescript
|
|
59
|
-
export async function installInMonorepo(
|
|
60
|
-
packages: Record<string, string>,
|
|
61
|
-
currentDir: string
|
|
62
|
-
): Promise<{ success: boolean; error?: string }> {
|
|
63
|
-
// 1. Find workspace root
|
|
64
|
-
const workspaceRoot = await findWorkspaceRoot(currentDir);
|
|
65
|
-
|
|
66
|
-
// 2. Find which workspace we're in
|
|
67
|
-
const workspaceName = await findWorkspaceName(currentDir, workspaceRoot);
|
|
68
|
-
|
|
69
|
-
// 3. Detect package manager
|
|
70
|
-
const pm = await detectPackageManager(workspaceRoot);
|
|
71
|
-
|
|
72
|
-
// 4. Build correct command based on PM
|
|
73
|
-
let command: string;
|
|
74
|
-
|
|
75
|
-
if (pm === 'pnpm') {
|
|
76
|
-
// pnpm needs --filter flag for workspaces
|
|
77
|
-
command = `pnpm add ${pkgList} --filter ${workspaceName}`;
|
|
78
|
-
} else if (pm === 'yarn') {
|
|
79
|
-
// yarn workspaces needs to run from workspace dir
|
|
80
|
-
command = `yarn workspace ${workspaceName} add ${pkgList}`;
|
|
81
|
-
} else if (pm === 'npm') {
|
|
82
|
-
// npm workspaces needs -w flag
|
|
83
|
-
command = `npm install ${pkgList} -w ${workspaceName}`;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// 5. Run from workspace root
|
|
87
|
-
return await executeBash(command, { cwd: workspaceRoot });
|
|
88
|
-
}
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
**Gotchas:**
|
|
92
|
-
- Different package managers have different workspace commands
|
|
93
|
-
- Need to detect workspace name (from package.json name field)
|
|
94
|
-
- Need to run from correct directory
|
|
95
|
-
- Turborepo might interfere
|
|
96
|
-
- User might have custom workspace config
|
|
97
|
-
|
|
98
|
-
**Risk Level:** 🔴 HIGH - This WILL cause issues for some users
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
### 2. TypeScript Configuration Variations - MESSY
|
|
103
|
-
|
|
104
|
-
**The Problem:**
|
|
105
|
-
|
|
106
|
-
Every project has different tsconfig.json:
|
|
107
|
-
|
|
108
|
-
```json
|
|
109
|
-
// Project A
|
|
110
|
-
{
|
|
111
|
-
"extends": "@tsconfig/react-native/tsconfig.json",
|
|
112
|
-
"compilerOptions": {
|
|
113
|
-
"paths": {
|
|
114
|
-
"@/*": ["./src/*"]
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Project B
|
|
120
|
-
{
|
|
121
|
-
"compilerOptions": {
|
|
122
|
-
"baseUrl": ".",
|
|
123
|
-
"paths": {
|
|
124
|
-
"@/features/*": ["src/features/*"],
|
|
125
|
-
"@/components/*": ["src/components/*"]
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Project C (broken)
|
|
131
|
-
{
|
|
132
|
-
"extends": "./tsconfig.base.json", // File doesn't exist!
|
|
133
|
-
"compilerOptions": {}
|
|
134
|
-
}
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
**What Can Go Wrong:**
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
$ vf add charts
|
|
141
|
-
🔍 Running type check...
|
|
142
|
-
$ pnpm tsc --noEmit
|
|
143
|
-
|
|
144
|
-
# Error 1: tsconfig.json not found
|
|
145
|
-
# Error 2: tsconfig.json extends missing file
|
|
146
|
-
# Error 3: Type check takes 5 minutes (huge project)
|
|
147
|
-
# Error 4: Type check fails for unrelated reasons
|
|
148
|
-
# Error 5: Multiple tsconfig files (which one to use?)
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
**Real Example:**
|
|
152
|
-
|
|
153
|
-
```typescript
|
|
154
|
-
// User's project has this:
|
|
155
|
-
// tsconfig.json (for IDE)
|
|
156
|
-
// tsconfig.build.json (for building)
|
|
157
|
-
// apps/native/tsconfig.json (for native app)
|
|
158
|
-
// apps/web/tsconfig.json (for web app)
|
|
159
|
-
|
|
160
|
-
// Which one do we run?
|
|
161
|
-
$ tsc --noEmit // Uses tsconfig.json (might be wrong one!)
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
**Solution (Defensive):**
|
|
165
|
-
|
|
166
|
-
```typescript
|
|
167
|
-
export async function runTypeCheck(cwd: string): Promise<TypeCheckResult> {
|
|
168
|
-
// 1. Find the right tsconfig
|
|
169
|
-
const tsconfigPath = await findTsConfig(cwd);
|
|
170
|
-
|
|
171
|
-
if (!tsconfigPath) {
|
|
172
|
-
log.warn('No tsconfig.json found, skipping type check');
|
|
173
|
-
return { success: true, missingPackages: [], errors: [] };
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// 2. Set timeout (don't hang forever)
|
|
177
|
-
const timeout = 60000; // 60 seconds max
|
|
178
|
-
|
|
179
|
-
// 3. Run with timeout
|
|
180
|
-
try {
|
|
181
|
-
const result = await executeBashWithTimeout(
|
|
182
|
-
`tsc --noEmit --project ${tsconfigPath}`,
|
|
183
|
-
{ cwd, timeout }
|
|
184
|
-
);
|
|
185
|
-
|
|
186
|
-
// 4. Handle timeout
|
|
187
|
-
if (result.timedOut) {
|
|
188
|
-
log.warn('Type check timed out (project too large)');
|
|
189
|
-
log.info('Skipping automatic dependency detection');
|
|
190
|
-
return { success: true, missingPackages: [], errors: [] };
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// 5. Parse errors (but ignore non-dependency errors)
|
|
194
|
-
return parseTypeScriptErrors(result.stderr);
|
|
195
|
-
|
|
196
|
-
} catch (error) {
|
|
197
|
-
// Don't fail the whole installation if type check fails
|
|
198
|
-
log.warn('Type check failed, skipping dependency detection');
|
|
199
|
-
return { success: true, missingPackages: [], errors: [] };
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
**Risk Level:** 🟡 MEDIUM - Can be handled with good error handling
|
|
205
|
-
|
|
206
|
-
---
|
|
207
|
-
|
|
208
|
-
### 3. File Hashing Performance - SLOW
|
|
209
|
-
|
|
210
|
-
**The Problem:**
|
|
211
|
-
|
|
212
|
-
Hashing 100+ files can be slow:
|
|
213
|
-
|
|
214
|
-
```typescript
|
|
215
|
-
// Feature with 150 files
|
|
216
|
-
const files = [
|
|
217
|
-
'file1.tsx', 'file2.tsx', ... // 150 files
|
|
218
|
-
];
|
|
219
|
-
|
|
220
|
-
// Hash each file
|
|
221
|
-
for (const file of files) {
|
|
222
|
-
const hash = await hashFile(file); // 10-50ms per file
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Total: 1.5 - 7.5 seconds just for hashing!
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
**What Makes It Worse:**
|
|
229
|
-
|
|
230
|
-
```typescript
|
|
231
|
-
// Large files are slow
|
|
232
|
-
const largeFile = 'bundle.js'; // 5MB
|
|
233
|
-
await hashFile(largeFile); // 500ms+
|
|
234
|
-
|
|
235
|
-
// Binary files are pointless to hash
|
|
236
|
-
const image = 'logo.png';
|
|
237
|
-
await hashFile(image); // Waste of time
|
|
238
|
-
|
|
239
|
-
// Many files = many disk reads
|
|
240
|
-
// On slow HDDs: 100ms+ per file
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
**Solution (Optimized):**
|
|
244
|
-
|
|
245
|
-
```typescript
|
|
246
|
-
export async function hashFiles(
|
|
247
|
-
filePaths: string[],
|
|
248
|
-
options?: { showProgress?: boolean }
|
|
249
|
-
): Promise<Map<string, string>> {
|
|
250
|
-
const hashes = new Map<string, string>();
|
|
251
|
-
|
|
252
|
-
// 1. Filter out files we don't need to hash
|
|
253
|
-
const filesToHash = filePaths.filter(path => {
|
|
254
|
-
// Skip binary files
|
|
255
|
-
if (/\.(png|jpg|jpeg|gif|ico|woff|woff2|ttf|eot)$/.test(path)) {
|
|
256
|
-
return false;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// Skip large files (>1MB)
|
|
260
|
-
try {
|
|
261
|
-
const stats = statSync(path);
|
|
262
|
-
if (stats.size > 1024 * 1024) {
|
|
263
|
-
return false;
|
|
264
|
-
}
|
|
265
|
-
} catch {
|
|
266
|
-
return false;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
return true;
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
// 2. Process in parallel batches
|
|
273
|
-
const batchSize = 10;
|
|
274
|
-
const batches = [];
|
|
275
|
-
|
|
276
|
-
for (let i = 0; i < filesToHash.length; i += batchSize) {
|
|
277
|
-
batches.push(filesToHash.slice(i, i + batchSize));
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
// 3. Process batches with progress
|
|
281
|
-
for (let i = 0; i < batches.length; i++) {
|
|
282
|
-
const batch = batches[i];
|
|
283
|
-
|
|
284
|
-
await Promise.all(
|
|
285
|
-
batch.map(async (path) => {
|
|
286
|
-
const hash = await hashFile(path);
|
|
287
|
-
hashes.set(path, hash);
|
|
288
|
-
})
|
|
289
|
-
);
|
|
290
|
-
|
|
291
|
-
if (options?.showProgress && filesToHash.length > 20) {
|
|
292
|
-
const progress = Math.min((i + 1) * batchSize, filesToHash.length);
|
|
293
|
-
process.stdout.write(`\r Hashing files: ${progress}/${filesToHash.length}`);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
if (options?.showProgress && filesToHash.length > 20) {
|
|
298
|
-
process.stdout.write('\n');
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
return hashes;
|
|
302
|
-
}
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
**Risk Level:** 🟡 MEDIUM - Solvable with optimization
|
|
306
|
-
|
|
307
|
-
---
|
|
308
|
-
|
|
309
|
-
### 4. Journal Migration - BREAKING CHANGE
|
|
310
|
-
|
|
311
|
-
**The Problem:**
|
|
312
|
-
|
|
313
|
-
Existing journals look like this:
|
|
314
|
-
|
|
315
|
-
```json
|
|
316
|
-
{
|
|
317
|
-
"entries": [
|
|
318
|
-
{
|
|
319
|
-
"feature": "charts",
|
|
320
|
-
"files": [
|
|
321
|
-
"/path/to/file1.tsx",
|
|
322
|
-
"/path/to/file2.tsx"
|
|
323
|
-
]
|
|
324
|
-
}
|
|
325
|
-
]
|
|
326
|
-
}
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
New format needs hashes:
|
|
330
|
-
|
|
331
|
-
```json
|
|
332
|
-
{
|
|
333
|
-
"entries": [
|
|
334
|
-
{
|
|
335
|
-
"feature": "charts",
|
|
336
|
-
"files": [
|
|
337
|
-
{ "path": "/path/to/file1.tsx", "hash": "abc123..." },
|
|
338
|
-
{ "path": "/path/to/file2.tsx", "hash": "def456..." }
|
|
339
|
-
]
|
|
340
|
-
}
|
|
341
|
-
]
|
|
342
|
-
}
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
**What Can Go Wrong:**
|
|
346
|
-
|
|
347
|
-
```bash
|
|
348
|
-
# User has old journal
|
|
349
|
-
$ vf remove charts
|
|
350
|
-
|
|
351
|
-
# CLI tries to read journal
|
|
352
|
-
# Expects: files[0].path
|
|
353
|
-
# Gets: files[0] (string)
|
|
354
|
-
# Result: CRASH!
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
**Solution (Migration):**
|
|
358
|
-
|
|
359
|
-
```typescript
|
|
360
|
-
export async function readJournal(path: string): Promise<Journal> {
|
|
361
|
-
try {
|
|
362
|
-
const content = await readFileContent(path);
|
|
363
|
-
const journal = JSON.parse(content) as any;
|
|
364
|
-
|
|
365
|
-
// Detect old format
|
|
366
|
-
const needsMigration = journal.entries.some((entry: any) => {
|
|
367
|
-
return entry.files.length > 0 && typeof entry.files[0] === 'string';
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
if (needsMigration) {
|
|
371
|
-
log.info('Migrating journal to new format...');
|
|
372
|
-
|
|
373
|
-
// Migrate each entry
|
|
374
|
-
for (const entry of journal.entries) {
|
|
375
|
-
if (typeof entry.files[0] === 'string') {
|
|
376
|
-
// Old format: array of strings
|
|
377
|
-
const oldFiles = entry.files as string[];
|
|
378
|
-
|
|
379
|
-
// Hash existing files
|
|
380
|
-
const newFiles = [];
|
|
381
|
-
for (const filePath of oldFiles) {
|
|
382
|
-
const hash = await hashFile(filePath);
|
|
383
|
-
newFiles.push({ path: filePath, hash });
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
entry.files = newFiles;
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
// Save migrated journal
|
|
391
|
-
await writeJournal(path, journal);
|
|
392
|
-
log.success('Journal migrated successfully');
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
return journal;
|
|
396
|
-
|
|
397
|
-
} catch (err: any) {
|
|
398
|
-
if (err.code === 'ENOENT') {
|
|
399
|
-
return { entries: [] };
|
|
400
|
-
}
|
|
401
|
-
throw err;
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
**Gotcha:**
|
|
407
|
-
- Migration happens on first read
|
|
408
|
-
- If files were deleted, we can't hash them (use empty hash)
|
|
409
|
-
- Need to handle corrupted journals
|
|
410
|
-
|
|
411
|
-
**Risk Level:** 🟡 MEDIUM - Need careful migration logic
|
|
412
|
-
|
|
413
|
-
---
|
|
414
|
-
|
|
415
|
-
### 5. Interactive Prompts in CI/CD - HANGS
|
|
416
|
-
|
|
417
|
-
**The Problem:**
|
|
418
|
-
|
|
419
|
-
```bash
|
|
420
|
-
# In CI/CD (GitHub Actions, etc.)
|
|
421
|
-
$ vf add charts
|
|
422
|
-
|
|
423
|
-
# CLI tries to prompt:
|
|
424
|
-
Overwrite file? (y/N): _
|
|
425
|
-
|
|
426
|
-
# But there's no TTY!
|
|
427
|
-
# Result: Hangs forever, CI times out
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
**What Happens:**
|
|
431
|
-
|
|
432
|
-
```typescript
|
|
433
|
-
// This hangs in CI:
|
|
434
|
-
const answer = readlineSync.question('Continue? (y/N): ');
|
|
435
|
-
|
|
436
|
-
// Because:
|
|
437
|
-
// - process.stdin.isTTY === false
|
|
438
|
-
// - No user to answer
|
|
439
|
-
// - readline waits forever
|
|
440
|
-
```
|
|
441
|
-
|
|
442
|
-
**Solution (Detection):**
|
|
443
|
-
|
|
444
|
-
```typescript
|
|
445
|
-
export function promptUser(question: string): string {
|
|
446
|
-
// Check if we're in a non-interactive environment
|
|
447
|
-
if (!process.stdin.isTTY) {
|
|
448
|
-
// CI/CD, piped input, etc.
|
|
449
|
-
log.warn('Non-interactive environment detected');
|
|
450
|
-
log.info('Use --yes flag to auto-confirm or --force to skip prompts');
|
|
451
|
-
return 'n'; // Default to safe option
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
// Check for CI environment variables
|
|
455
|
-
const isCI = process.env.CI === 'true' ||
|
|
456
|
-
process.env.GITHUB_ACTIONS === 'true' ||
|
|
457
|
-
process.env.GITLAB_CI === 'true' ||
|
|
458
|
-
process.env.CIRCLECI === 'true';
|
|
459
|
-
|
|
460
|
-
if (isCI) {
|
|
461
|
-
log.warn('CI environment detected');
|
|
462
|
-
return 'n';
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
return readlineSync.question(question);
|
|
466
|
-
}
|
|
467
|
-
```
|
|
468
|
-
|
|
469
|
-
**Risk Level:** 🟡 MEDIUM - Easy to detect and handle
|
|
470
|
-
|
|
471
|
-
---
|
|
472
|
-
|
|
473
|
-
### 6. Navigation Markers Missing or Modified - BREAKS INJECTION
|
|
474
|
-
|
|
475
|
-
**The Problem:**
|
|
476
|
-
|
|
477
|
-
CLI expects these markers:
|
|
478
|
-
|
|
479
|
-
```typescript
|
|
480
|
-
// apps/native/src/app/(root)/(protected)/(tabs)/index.tsx
|
|
481
|
-
|
|
482
|
-
const features = [
|
|
483
|
-
// --- @vibefast:navigation:start ---
|
|
484
|
-
// --- @vibefast:navigation:end ---
|
|
485
|
-
];
|
|
486
|
-
```
|
|
487
|
-
|
|
488
|
-
**What If User:**
|
|
489
|
-
|
|
490
|
-
1. **Deletes markers:**
|
|
491
|
-
```typescript
|
|
492
|
-
const features = [
|
|
493
|
-
// User removed the markers!
|
|
494
|
-
];
|
|
495
|
-
```
|
|
496
|
-
|
|
497
|
-
2. **Modifies markers:**
|
|
498
|
-
```typescript
|
|
499
|
-
const features = [
|
|
500
|
-
// --- @vibefast:navigation:start --- (extra space)
|
|
501
|
-
// --- @vibefast:navigation:end ---
|
|
502
|
-
];
|
|
503
|
-
```
|
|
504
|
-
|
|
505
|
-
3. **Moves markers:**
|
|
506
|
-
```typescript
|
|
507
|
-
// Markers are now in a different file!
|
|
508
|
-
```
|
|
509
|
-
|
|
510
|
-
**Result:**
|
|
511
|
-
|
|
512
|
-
```bash
|
|
513
|
-
$ vf add charts
|
|
514
|
-
✗ Navigation markers not found!
|
|
515
|
-
✗ Cannot inject navigation link
|
|
516
|
-
```
|
|
517
|
-
|
|
518
|
-
**Solution (Defensive):**
|
|
519
|
-
|
|
520
|
-
```typescript
|
|
521
|
-
export async function insertNavLinkNative(
|
|
522
|
-
navFile: string,
|
|
523
|
-
navData: any,
|
|
524
|
-
options?: { dryRun?: boolean }
|
|
525
|
-
): Promise<boolean> {
|
|
526
|
-
// 1. Check if file exists
|
|
527
|
-
if (!await exists(navFile)) {
|
|
528
|
-
log.error(`Navigation file not found: ${navFile}`);
|
|
529
|
-
log.info('This feature requires navigation injection');
|
|
530
|
-
log.info('You may need to add the navigation link manually');
|
|
531
|
-
return false;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
// 2. Read file
|
|
535
|
-
const content = await readFileContent(navFile);
|
|
536
|
-
|
|
537
|
-
// 3. Find markers (flexible regex)
|
|
538
|
-
const startMarker = /\/\/\s*---\s*@vibefast:navigation:start\s*---/;
|
|
539
|
-
const endMarker = /\/\/\s*---\s*@vibefast:navigation:end\s*---/;
|
|
540
|
-
|
|
541
|
-
const hasStart = startMarker.test(content);
|
|
542
|
-
const hasEnd = endMarker.test(content);
|
|
543
|
-
|
|
544
|
-
if (!hasStart || !hasEnd) {
|
|
545
|
-
log.error('Navigation markers not found in file');
|
|
546
|
-
log.info('Expected markers:');
|
|
547
|
-
log.plain(' // --- @vibefast:navigation:start ---');
|
|
548
|
-
log.plain(' // --- @vibefast:navigation:end ---');
|
|
549
|
-
log.plain('');
|
|
550
|
-
log.warn('⚠ Navigation link will NOT be added automatically');
|
|
551
|
-
log.info('You can add it manually:');
|
|
552
|
-
log.plain('');
|
|
553
|
-
log.plain(JSON.stringify(navData, null, 2));
|
|
554
|
-
log.plain('');
|
|
555
|
-
|
|
556
|
-
// Don't fail the installation, just skip nav injection
|
|
557
|
-
return false;
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
// 4. Inject navigation
|
|
561
|
-
// ... rest of logic
|
|
562
|
-
|
|
563
|
-
return true;
|
|
564
|
-
}
|
|
565
|
-
```
|
|
566
|
-
|
|
567
|
-
**Risk Level:** 🟢 LOW - Can be handled gracefully
|
|
568
|
-
|
|
569
|
-
---
|
|
570
|
-
|
|
571
|
-
### 7. Package Version Conflicts - DEPENDENCY HELL
|
|
572
|
-
|
|
573
|
-
**The Problem:**
|
|
574
|
-
|
|
575
|
-
```bash
|
|
576
|
-
# User's project has:
|
|
577
|
-
"react-native-svg": "^12.0.0"
|
|
578
|
-
|
|
579
|
-
# Feature needs:
|
|
580
|
-
"react-native-svg": "^13.9.0"
|
|
581
|
-
|
|
582
|
-
# What happens?
|
|
583
|
-
$ pnpm add react-native-svg@^13.9.0
|
|
584
|
-
|
|
585
|
-
# Result: Upgrades to 13.9.0
|
|
586
|
-
# But: User's other code might break!
|
|
587
|
-
```
|
|
588
|
-
|
|
589
|
-
**Real Example:**
|
|
590
|
-
|
|
591
|
-
```json
|
|
592
|
-
// User's package.json
|
|
593
|
-
{
|
|
594
|
-
"dependencies": {
|
|
595
|
-
"react-native-reanimated": "^2.0.0",
|
|
596
|
-
"react-native-svg": "^12.0.0"
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
// Feature needs:
|
|
601
|
-
{
|
|
602
|
-
"dependencies": {
|
|
603
|
-
"react-native-svg": "^13.9.0"
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
// After install:
|
|
608
|
-
{
|
|
609
|
-
"dependencies": {
|
|
610
|
-
"react-native-reanimated": "^2.0.0", // Might break with svg 13!
|
|
611
|
-
"react-native-svg": "^13.9.0"
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
```
|
|
615
|
-
|
|
616
|
-
**Solution (Detection + Warning):**
|
|
617
|
-
|
|
618
|
-
```typescript
|
|
619
|
-
export async function checkVersionConflicts(
|
|
620
|
-
newPackages: Record<string, string>,
|
|
621
|
-
cwd: string
|
|
622
|
-
): Promise<Array<{ package: string; current: string; new: string }>> {
|
|
623
|
-
const conflicts = [];
|
|
624
|
-
|
|
625
|
-
const installed = await getInstalledPackages(cwd);
|
|
626
|
-
const packageJson = await readPackageJson(cwd);
|
|
627
|
-
|
|
628
|
-
for (const [pkg, newVersion] of Object.entries(newPackages)) {
|
|
629
|
-
const currentVersion = packageJson.dependencies?.[pkg] ||
|
|
630
|
-
packageJson.devDependencies?.[pkg];
|
|
631
|
-
|
|
632
|
-
if (currentVersion && currentVersion !== newVersion) {
|
|
633
|
-
// Check if it's a major version change
|
|
634
|
-
const currentMajor = currentVersion.match(/\d+/)?.[0];
|
|
635
|
-
const newMajor = newVersion.match(/\d+/)?.[0];
|
|
636
|
-
|
|
637
|
-
if (currentMajor !== newMajor) {
|
|
638
|
-
conflicts.push({
|
|
639
|
-
package: pkg,
|
|
640
|
-
current: currentVersion,
|
|
641
|
-
new: newVersion,
|
|
642
|
-
});
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
return conflicts;
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
// Usage:
|
|
651
|
-
const conflicts = await checkVersionConflicts(manifest.dependencies.npm, paths.cwd);
|
|
652
|
-
|
|
653
|
-
if (conflicts.length > 0) {
|
|
654
|
-
log.warn('⚠ VERSION CONFLICTS DETECTED:');
|
|
655
|
-
log.plain('');
|
|
656
|
-
|
|
657
|
-
conflicts.forEach(c => {
|
|
658
|
-
log.plain(` ${c.package}`);
|
|
659
|
-
log.plain(` Current: ${c.current}`);
|
|
660
|
-
log.plain(` Required: ${c.new}`);
|
|
661
|
-
});
|
|
662
|
-
|
|
663
|
-
log.plain('');
|
|
664
|
-
log.warn('Installing this feature will UPGRADE these packages');
|
|
665
|
-
log.warn('This might break existing code!');
|
|
666
|
-
log.plain('');
|
|
667
|
-
|
|
668
|
-
const shouldContinue = promptYesNo('Continue anyway? (y/N): ', false);
|
|
669
|
-
if (!shouldContinue) {
|
|
670
|
-
log.info('Installation cancelled');
|
|
671
|
-
return;
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
```
|
|
675
|
-
|
|
676
|
-
**Risk Level:** 🔴 HIGH - Can break user's app
|
|
677
|
-
|
|
678
|
-
---
|
|
679
|
-
|
|
680
|
-
## 🟡 MEDIUM RISK Issues
|
|
681
|
-
|
|
682
|
-
### 8. Watermark Breaks Syntax
|
|
683
|
-
|
|
684
|
-
**Problem:**
|
|
685
|
-
|
|
686
|
-
```typescript
|
|
687
|
-
// Original file:
|
|
688
|
-
export default function Chart() {
|
|
689
|
-
return <View />;
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
// After watermark:
|
|
693
|
-
// vibefast license: abc-123
|
|
694
|
-
export default function Chart() {
|
|
695
|
-
return <View />;
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
// Result: Syntax error! (no import for comment)
|
|
699
|
-
```
|
|
700
|
-
|
|
701
|
-
**Solution:** Always add watermark as first line
|
|
702
|
-
|
|
703
|
-
---
|
|
704
|
-
|
|
705
|
-
### 9. Git Conflicts
|
|
706
|
-
|
|
707
|
-
**Problem:**
|
|
708
|
-
|
|
709
|
-
```bash
|
|
710
|
-
# User has uncommitted changes
|
|
711
|
-
$ vf add charts
|
|
712
|
-
|
|
713
|
-
# CLI copies files
|
|
714
|
-
# User's git status is now messy
|
|
715
|
-
```
|
|
716
|
-
|
|
717
|
-
**Solution:** Check git status first, warn user
|
|
718
|
-
|
|
719
|
-
---
|
|
720
|
-
|
|
721
|
-
### 10. Disk Space
|
|
722
|
-
|
|
723
|
-
**Problem:**
|
|
724
|
-
|
|
725
|
-
```bash
|
|
726
|
-
# Feature is 50MB
|
|
727
|
-
# User has 10MB free
|
|
728
|
-
$ vf add large-feature
|
|
729
|
-
|
|
730
|
-
# Result: Disk full error mid-installation
|
|
731
|
-
```
|
|
732
|
-
|
|
733
|
-
**Solution:** Check available space before downloading
|
|
734
|
-
|
|
735
|
-
---
|
|
736
|
-
|
|
737
|
-
## Summary: What's Actually Difficult?
|
|
738
|
-
|
|
739
|
-
### 🔴 VERY DIFFICULT (Need Careful Implementation)
|
|
740
|
-
|
|
741
|
-
1. **Monorepo package installation** - Different PMs, different commands
|
|
742
|
-
2. **Version conflicts** - Can break user's app
|
|
743
|
-
|
|
744
|
-
### 🟡 MODERATELY DIFFICULT (Need Good Error Handling)
|
|
745
|
-
|
|
746
|
-
3. **TypeScript config variations** - Many edge cases
|
|
747
|
-
4. **File hashing performance** - Need optimization
|
|
748
|
-
5. **Journal migration** - Breaking change
|
|
749
|
-
|
|
750
|
-
### 🟢 EASY (Standard Error Handling)
|
|
751
|
-
|
|
752
|
-
6. **CI/CD detection** - Check TTY
|
|
753
|
-
7. **Missing markers** - Graceful degradation
|
|
754
|
-
8. **Watermark syntax** - Always prepend
|
|
755
|
-
9. **Git conflicts** - Warn user
|
|
756
|
-
10. **Disk space** - Check before download
|
|
757
|
-
|
|
758
|
-
---
|
|
759
|
-
|
|
760
|
-
## Mitigation Strategy
|
|
761
|
-
|
|
762
|
-
### For High-Risk Issues:
|
|
763
|
-
|
|
764
|
-
1. **Extensive testing** with different monorepo setups
|
|
765
|
-
2. **Dry-run mode** to preview changes
|
|
766
|
-
3. **Clear warnings** about version conflicts
|
|
767
|
-
4. **Rollback capability** (future feature)
|
|
768
|
-
5. **Good documentation** for edge cases
|
|
769
|
-
|
|
770
|
-
### For Medium-Risk Issues:
|
|
771
|
-
|
|
772
|
-
1. **Defensive programming** (try/catch everywhere)
|
|
773
|
-
2. **Graceful degradation** (skip features that fail)
|
|
774
|
-
3. **Clear error messages** with solutions
|
|
775
|
-
4. **Timeout handling** for slow operations
|
|
776
|
-
|
|
777
|
-
### For Low-Risk Issues:
|
|
778
|
-
|
|
779
|
-
1. **Standard error handling**
|
|
780
|
-
2. **User-friendly messages**
|
|
781
|
-
3. **Fallback options**
|
|
782
|
-
|
|
783
|
-
---
|
|
784
|
-
|
|
785
|
-
## Recommendation
|
|
786
|
-
|
|
787
|
-
**Start with MVP that avoids the hardest problems:**
|
|
788
|
-
|
|
789
|
-
1. ✅ Require recipe.json dependencies (skip auto-detection initially)
|
|
790
|
-
2. ✅ Warn about monorepos (let user install packages manually)
|
|
791
|
-
3. ✅ Skip type checking if it fails (don't block installation)
|
|
792
|
-
4. ✅ Gracefully handle missing markers (manual nav injection)
|
|
793
|
-
|
|
794
|
-
**Then add advanced features:**
|
|
795
|
-
|
|
796
|
-
1. Auto-detection with type checking
|
|
797
|
-
2. Smart monorepo handling
|
|
798
|
-
3. Version conflict detection
|
|
799
|
-
4. Automatic rollback
|
|
800
|
-
|
|
801
|
-
This way we ship fast and iterate based on real user feedback.
|