vibefast-cli 1.2.1 → 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 +94 -91
- package/dist/__tests__/recipes.test.js.map +1 -1
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +301 -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 -16
- 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 -42
- 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 -37
- 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 -35
- 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 -23
- 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
package/recipes/README.md
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
# VibeFast Service Configuration Recipes
|
|
2
|
-
|
|
3
|
-
This directory contains configuration guides for third-party services that are **already integrated** in VibeFast. These services just need your API keys and credentials to work.
|
|
4
|
-
|
|
5
|
-
## What are Recipes?
|
|
6
|
-
|
|
7
|
-
Recipes are JSON files that provide:
|
|
8
|
-
- **Configuration steps** - How to get API keys and set them up
|
|
9
|
-
- **Environment variables** - Which .env vars you need
|
|
10
|
-
- **File locations** - Where to add your credentials in the codebase
|
|
11
|
-
- **Documentation links** - Official service documentation
|
|
12
|
-
|
|
13
|
-
## Available Recipes
|
|
14
|
-
|
|
15
|
-
### Analytics & Monitoring
|
|
16
|
-
- **sentry.json** - Error tracking (already integrated, just add DSN)
|
|
17
|
-
- **posthog.json** - Product analytics (already integrated, just add API key)
|
|
18
|
-
|
|
19
|
-
### Payments & Subscriptions
|
|
20
|
-
- **revenuecat.json** - In-app purchases (already integrated, just add API keys)
|
|
21
|
-
|
|
22
|
-
## Recipe Structure
|
|
23
|
-
|
|
24
|
-
```json
|
|
25
|
-
{
|
|
26
|
-
"name": "service-name",
|
|
27
|
-
"version": "1.0.0",
|
|
28
|
-
"description": "Service description",
|
|
29
|
-
"target": "service",
|
|
30
|
-
"manualSteps": [
|
|
31
|
-
{
|
|
32
|
-
"title": "Step Title",
|
|
33
|
-
"description": "Step description",
|
|
34
|
-
"link": "https://docs.example.com",
|
|
35
|
-
"file": ".env.local",
|
|
36
|
-
"content": "ENV_VAR=value"
|
|
37
|
-
}
|
|
38
|
-
],
|
|
39
|
-
"env": [
|
|
40
|
-
{
|
|
41
|
-
"key": "ENV_VAR_NAME",
|
|
42
|
-
"description": "Variable description",
|
|
43
|
-
"example": "example-value",
|
|
44
|
-
"required": true,
|
|
45
|
-
"link": "https://docs.example.com"
|
|
46
|
-
}
|
|
47
|
-
],
|
|
48
|
-
"postInstall": {
|
|
49
|
-
"message": "Success message"
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## Fields
|
|
55
|
-
|
|
56
|
-
### Root Level
|
|
57
|
-
- `name` - Service identifier (lowercase, no spaces)
|
|
58
|
-
- `version` - Recipe version (semver)
|
|
59
|
-
- `description` - Short description of the service
|
|
60
|
-
- `target` - Type of recipe (usually "service")
|
|
61
|
-
- `manualSteps` - Array of setup steps
|
|
62
|
-
- `env` - Array of environment variables
|
|
63
|
-
- `postInstall` - Post-installation message
|
|
64
|
-
|
|
65
|
-
### Manual Steps
|
|
66
|
-
- `title` - Step title
|
|
67
|
-
- `description` - Step description
|
|
68
|
-
- `link` - (Optional) Documentation link
|
|
69
|
-
- `file` - (Optional) File to edit
|
|
70
|
-
- `content` - (Optional) Content to add
|
|
71
|
-
|
|
72
|
-
### Environment Variables
|
|
73
|
-
- `key` - Variable name
|
|
74
|
-
- `description` - What the variable is for
|
|
75
|
-
- `example` - Example value
|
|
76
|
-
- `required` - Whether it's required
|
|
77
|
-
- `link` - (Optional) Where to get the value
|
|
78
|
-
|
|
79
|
-
## How to Use
|
|
80
|
-
|
|
81
|
-
### View Setup Steps
|
|
82
|
-
```bash
|
|
83
|
-
vf checklist sentry
|
|
84
|
-
vf checklist posthog
|
|
85
|
-
vf checklist stripe
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### List All Services
|
|
89
|
-
```bash
|
|
90
|
-
vf list
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
## Adding New Recipes
|
|
94
|
-
|
|
95
|
-
1. Create a new JSON file in this directory
|
|
96
|
-
2. Follow the recipe structure above
|
|
97
|
-
3. Include clear setup steps and documentation links
|
|
98
|
-
4. Test with `vf checklist <service-name>`
|
|
99
|
-
|
|
100
|
-
## Recipe Guidelines
|
|
101
|
-
|
|
102
|
-
### Setup Steps
|
|
103
|
-
- Keep steps clear and actionable
|
|
104
|
-
- Include links to official documentation
|
|
105
|
-
- Specify which files need to be edited
|
|
106
|
-
- Provide example values
|
|
107
|
-
|
|
108
|
-
### Environment Variables
|
|
109
|
-
- Use clear, descriptive names
|
|
110
|
-
- Include example values
|
|
111
|
-
- Mark required vs optional
|
|
112
|
-
- Provide links to where users can get values
|
|
113
|
-
- Never include actual secrets in examples
|
|
114
|
-
|
|
115
|
-
### Documentation
|
|
116
|
-
- Link to official service documentation
|
|
117
|
-
- Link to relevant setup guides
|
|
118
|
-
- Include links to dashboards/settings pages
|
|
119
|
-
|
|
120
|
-
## Integration with CLI
|
|
121
|
-
|
|
122
|
-
Recipes are automatically discovered by the CLI through the VibeFast API. When users run:
|
|
123
|
-
|
|
124
|
-
```bash
|
|
125
|
-
vf list # Shows all available services
|
|
126
|
-
vf checklist <name> # Shows setup steps for a service
|
|
127
|
-
vf env # Prompts for environment variables
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
The CLI fetches recipe data from the API and displays it to users.
|
|
131
|
-
|
|
132
|
-
## Testing Recipes
|
|
133
|
-
|
|
134
|
-
To test a recipe locally:
|
|
135
|
-
|
|
136
|
-
1. Ensure the recipe JSON is valid
|
|
137
|
-
2. Run `vf checklist <service-name>`
|
|
138
|
-
3. Verify all steps display correctly
|
|
139
|
-
4. Check that environment variables are listed
|
|
140
|
-
5. Verify documentation links work
|
|
141
|
-
|
|
142
|
-
## Best Practices
|
|
143
|
-
|
|
144
|
-
1. **Be Specific** - Clear, actionable steps
|
|
145
|
-
2. **Provide Examples** - Show what values should look like
|
|
146
|
-
3. **Link to Docs** - Always provide official documentation
|
|
147
|
-
4. **Test Thoroughly** - Verify all links work
|
|
148
|
-
5. **Keep Updated** - Update recipes when services change
|
|
149
|
-
6. **Security** - Never include real secrets or API keys
|
|
150
|
-
|
|
151
|
-
## Support
|
|
152
|
-
|
|
153
|
-
For issues or questions about recipes:
|
|
154
|
-
- 📧 Email: support@vibefast.pro
|
|
155
|
-
- 📚 Docs: https://vibefast.pro/docs
|
|
156
|
-
- 🐛 Issues: https://github.com/vibefast/vibefast-cli/issues
|
|
@@ -1,369 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Recordings Service
|
|
3
|
-
*
|
|
4
|
-
* Handles recording operations including createRecordingDraft, finalizeRecording,
|
|
5
|
-
* listRecordings, updateRecordingName, and deleteRecording.
|
|
6
|
-
*
|
|
7
|
-
* Requirements: 12.1, 12.2, 12.3, 12.4, 12.5
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import type { SupabaseClientType } from '../lib/supabase';
|
|
11
|
-
import type { Recording } from '../types';
|
|
12
|
-
import type { Json } from '../types/database';
|
|
13
|
-
|
|
14
|
-
export interface CreateRecordingDraftInput {
|
|
15
|
-
name?: string | null;
|
|
16
|
-
fileUri: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface CreateRecordingDraftResult {
|
|
20
|
-
success: boolean;
|
|
21
|
-
recording?: Recording;
|
|
22
|
-
error?: string;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface FinalizeRecordingInput {
|
|
26
|
-
recordingId: string;
|
|
27
|
-
duration: number;
|
|
28
|
-
fileUri: string;
|
|
29
|
-
metering?: Json | null;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface FinalizeRecordingResult {
|
|
33
|
-
success: boolean;
|
|
34
|
-
recording?: Recording;
|
|
35
|
-
error?: string;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface ListRecordingsResult {
|
|
39
|
-
success: boolean;
|
|
40
|
-
recordings?: Recording[];
|
|
41
|
-
hasMore?: boolean;
|
|
42
|
-
error?: string;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export interface UpdateRecordingNameResult {
|
|
46
|
-
success: boolean;
|
|
47
|
-
recording?: Recording;
|
|
48
|
-
error?: string;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export interface DeleteRecordingResult {
|
|
52
|
-
success: boolean;
|
|
53
|
-
error?: string;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const DEFAULT_PAGE_SIZE = 50;
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Create a recording draft
|
|
60
|
-
*
|
|
61
|
-
* Creates a new recording with status "draft". The recording can be finalized
|
|
62
|
-
* later with duration and metering data.
|
|
63
|
-
*
|
|
64
|
-
* @param supabase - Supabase client (authenticated)
|
|
65
|
-
* @param input - Recording draft data
|
|
66
|
-
* @returns The created recording draft
|
|
67
|
-
*
|
|
68
|
-
* Requirements: 12.1
|
|
69
|
-
*/
|
|
70
|
-
export async function createRecordingDraft(
|
|
71
|
-
supabase: SupabaseClientType,
|
|
72
|
-
input: CreateRecordingDraftInput
|
|
73
|
-
): Promise<CreateRecordingDraftResult> {
|
|
74
|
-
// Get the current auth user
|
|
75
|
-
const { data: authData, error: authError } = await supabase.auth.getUser();
|
|
76
|
-
|
|
77
|
-
if (authError || !authData.user) {
|
|
78
|
-
return { success: false, error: 'Not authenticated' };
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (!input.fileUri) {
|
|
82
|
-
return { success: false, error: 'File URI is required' };
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Create the recording draft
|
|
86
|
-
const { data: recording, error: createError } = await supabase
|
|
87
|
-
.from('recordings')
|
|
88
|
-
.insert({
|
|
89
|
-
user_id: authData.user.id,
|
|
90
|
-
name: input.name || null,
|
|
91
|
-
file_uri: input.fileUri,
|
|
92
|
-
duration: 0, // Will be updated when finalized
|
|
93
|
-
status: 'draft',
|
|
94
|
-
metering: null,
|
|
95
|
-
})
|
|
96
|
-
.select()
|
|
97
|
-
.single();
|
|
98
|
-
|
|
99
|
-
if (createError) {
|
|
100
|
-
return { success: false, error: `Failed to create recording draft: ${createError.message}` };
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return { success: true, recording };
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Finalize a recording
|
|
109
|
-
*
|
|
110
|
-
* Updates a draft recording with duration, file URI, and metering data,
|
|
111
|
-
* then sets status to "completed".
|
|
112
|
-
*
|
|
113
|
-
* @param supabase - Supabase client (authenticated)
|
|
114
|
-
* @param input - Finalization data
|
|
115
|
-
* @returns The finalized recording
|
|
116
|
-
*
|
|
117
|
-
* Requirements: 12.2
|
|
118
|
-
*/
|
|
119
|
-
export async function finalizeRecording(
|
|
120
|
-
supabase: SupabaseClientType,
|
|
121
|
-
input: FinalizeRecordingInput
|
|
122
|
-
): Promise<FinalizeRecordingResult> {
|
|
123
|
-
// Get the current auth user
|
|
124
|
-
const { data: authData, error: authError } = await supabase.auth.getUser();
|
|
125
|
-
|
|
126
|
-
if (authError || !authData.user) {
|
|
127
|
-
return { success: false, error: 'Not authenticated' };
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (!input.recordingId) {
|
|
131
|
-
return { success: false, error: 'Recording ID is required' };
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (input.duration < 0) {
|
|
135
|
-
return { success: false, error: 'Duration must be non-negative' };
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (!input.fileUri) {
|
|
139
|
-
return { success: false, error: 'File URI is required' };
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Update the recording (RLS + user_id check ensures ownership)
|
|
143
|
-
const { data: recording, error: updateError } = await supabase
|
|
144
|
-
.from('recordings')
|
|
145
|
-
.update({
|
|
146
|
-
duration: input.duration,
|
|
147
|
-
file_uri: input.fileUri,
|
|
148
|
-
metering: input.metering || null,
|
|
149
|
-
status: 'completed',
|
|
150
|
-
})
|
|
151
|
-
.eq('id', input.recordingId)
|
|
152
|
-
.eq('user_id', authData.user.id)
|
|
153
|
-
.eq('status', 'draft') // Can only finalize drafts
|
|
154
|
-
.select()
|
|
155
|
-
.single();
|
|
156
|
-
|
|
157
|
-
if (updateError) {
|
|
158
|
-
if (updateError.code === 'PGRST116') {
|
|
159
|
-
return { success: false, error: 'Recording not found, not owned by user, or already finalized' };
|
|
160
|
-
}
|
|
161
|
-
return { success: false, error: `Failed to finalize recording: ${updateError.message}` };
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return { success: true, recording };
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* List recordings for the current user
|
|
169
|
-
*
|
|
170
|
-
* Returns only completed recordings, ordered by creation time (newest first).
|
|
171
|
-
*
|
|
172
|
-
* @param supabase - Supabase client (authenticated)
|
|
173
|
-
* @param options - Pagination options
|
|
174
|
-
* @returns Paginated list of completed recordings
|
|
175
|
-
*
|
|
176
|
-
* Requirements: 12.3
|
|
177
|
-
*/
|
|
178
|
-
export async function listRecordings(
|
|
179
|
-
supabase: SupabaseClientType,
|
|
180
|
-
options?: {
|
|
181
|
-
limit?: number;
|
|
182
|
-
cursor?: string; // created_at timestamp for cursor-based pagination
|
|
183
|
-
}
|
|
184
|
-
): Promise<ListRecordingsResult> {
|
|
185
|
-
// Get the current auth user
|
|
186
|
-
const { data: authData, error: authError } = await supabase.auth.getUser();
|
|
187
|
-
|
|
188
|
-
if (authError || !authData.user) {
|
|
189
|
-
return { success: false, error: 'Not authenticated' };
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
const limit = options?.limit || DEFAULT_PAGE_SIZE;
|
|
193
|
-
|
|
194
|
-
// Build query - only return completed recordings
|
|
195
|
-
let query = supabase
|
|
196
|
-
.from('recordings')
|
|
197
|
-
.select('*')
|
|
198
|
-
.eq('user_id', authData.user.id)
|
|
199
|
-
.eq('status', 'completed')
|
|
200
|
-
.order('created_at', { ascending: false })
|
|
201
|
-
.limit(limit + 1); // Fetch one extra to check if there are more
|
|
202
|
-
|
|
203
|
-
// Apply cursor if provided
|
|
204
|
-
if (options?.cursor) {
|
|
205
|
-
query = query.lt('created_at', options.cursor);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const { data: recordings, error: listError } = await query;
|
|
209
|
-
|
|
210
|
-
if (listError) {
|
|
211
|
-
return { success: false, error: `Failed to list recordings: ${listError.message}` };
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Check if there are more results
|
|
215
|
-
const hasMore = recordings && recordings.length > limit;
|
|
216
|
-
const resultRecordings = hasMore ? recordings.slice(0, limit) : (recordings || []);
|
|
217
|
-
|
|
218
|
-
return {
|
|
219
|
-
success: true,
|
|
220
|
-
recordings: resultRecordings,
|
|
221
|
-
hasMore,
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Update a recording's name
|
|
228
|
-
*
|
|
229
|
-
* Only allows update if the user owns the recording.
|
|
230
|
-
*
|
|
231
|
-
* @param supabase - Supabase client (authenticated)
|
|
232
|
-
* @param recordingId - The ID of the recording to update
|
|
233
|
-
* @param name - The new name for the recording
|
|
234
|
-
* @returns The updated recording
|
|
235
|
-
*
|
|
236
|
-
* Requirements: 12.4
|
|
237
|
-
*/
|
|
238
|
-
export async function updateRecordingName(
|
|
239
|
-
supabase: SupabaseClientType,
|
|
240
|
-
recordingId: string,
|
|
241
|
-
name: string | null
|
|
242
|
-
): Promise<UpdateRecordingNameResult> {
|
|
243
|
-
// Get the current auth user
|
|
244
|
-
const { data: authData, error: authError } = await supabase.auth.getUser();
|
|
245
|
-
|
|
246
|
-
if (authError || !authData.user) {
|
|
247
|
-
return { success: false, error: 'Not authenticated' };
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
if (!recordingId) {
|
|
251
|
-
return { success: false, error: 'Recording ID is required' };
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
// Update the recording name (RLS + user_id check ensures ownership)
|
|
255
|
-
const { data: recording, error: updateError } = await supabase
|
|
256
|
-
.from('recordings')
|
|
257
|
-
.update({ name })
|
|
258
|
-
.eq('id', recordingId)
|
|
259
|
-
.eq('user_id', authData.user.id)
|
|
260
|
-
.select()
|
|
261
|
-
.single();
|
|
262
|
-
|
|
263
|
-
if (updateError) {
|
|
264
|
-
if (updateError.code === 'PGRST116') {
|
|
265
|
-
return { success: false, error: 'Recording not found or access denied' };
|
|
266
|
-
}
|
|
267
|
-
return { success: false, error: `Failed to update recording: ${updateError.message}` };
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
return { success: true, recording };
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* Delete a recording
|
|
275
|
-
*
|
|
276
|
-
* Removes the recording record. Note: This does not delete the associated
|
|
277
|
-
* file from storage - that should be handled separately.
|
|
278
|
-
*
|
|
279
|
-
* @param supabase - Supabase client (authenticated)
|
|
280
|
-
* @param recordingId - The ID of the recording to delete
|
|
281
|
-
* @returns Success or error
|
|
282
|
-
*
|
|
283
|
-
* Requirements: 12.5
|
|
284
|
-
*/
|
|
285
|
-
export async function deleteRecording(
|
|
286
|
-
supabase: SupabaseClientType,
|
|
287
|
-
recordingId: string
|
|
288
|
-
): Promise<DeleteRecordingResult> {
|
|
289
|
-
// Get the current auth user
|
|
290
|
-
const { data: authData, error: authError } = await supabase.auth.getUser();
|
|
291
|
-
|
|
292
|
-
if (authError || !authData.user) {
|
|
293
|
-
return { success: false, error: 'Not authenticated' };
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
if (!recordingId) {
|
|
297
|
-
return { success: false, error: 'Recording ID is required' };
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
// Delete the recording (RLS + user_id check ensures ownership)
|
|
301
|
-
const { data, error: deleteError } = await supabase
|
|
302
|
-
.from('recordings')
|
|
303
|
-
.delete()
|
|
304
|
-
.eq('id', recordingId)
|
|
305
|
-
.eq('user_id', authData.user.id)
|
|
306
|
-
.select('id')
|
|
307
|
-
.single();
|
|
308
|
-
|
|
309
|
-
if (deleteError) {
|
|
310
|
-
if (deleteError.code === 'PGRST116') {
|
|
311
|
-
return { success: false, error: 'Recording not found or access denied' };
|
|
312
|
-
}
|
|
313
|
-
return { success: false, error: `Failed to delete recording: ${deleteError.message}` };
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
if (!data) {
|
|
317
|
-
return { success: false, error: 'Recording not found or access denied' };
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
return { success: true };
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Get a recording by ID
|
|
325
|
-
*
|
|
326
|
-
* @param supabase - Supabase client (authenticated)
|
|
327
|
-
* @param recordingId - The ID of the recording
|
|
328
|
-
* @returns The recording or error
|
|
329
|
-
*/
|
|
330
|
-
export async function getRecordingById(
|
|
331
|
-
supabase: SupabaseClientType,
|
|
332
|
-
recordingId: string
|
|
333
|
-
): Promise<{ success: boolean; recording?: Recording; error?: string }> {
|
|
334
|
-
// Get the current auth user
|
|
335
|
-
const { data: authData, error: authError } = await supabase.auth.getUser();
|
|
336
|
-
|
|
337
|
-
if (authError || !authData.user) {
|
|
338
|
-
return { success: false, error: 'Not authenticated' };
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
if (!recordingId) {
|
|
342
|
-
return { success: false, error: 'Recording ID is required' };
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
const { data: recording, error: getError } = await supabase
|
|
346
|
-
.from('recordings')
|
|
347
|
-
.select('*')
|
|
348
|
-
.eq('id', recordingId)
|
|
349
|
-
.eq('user_id', authData.user.id)
|
|
350
|
-
.single();
|
|
351
|
-
|
|
352
|
-
if (getError) {
|
|
353
|
-
if (getError.code === 'PGRST116') {
|
|
354
|
-
return { success: false, error: 'Recording not found' };
|
|
355
|
-
}
|
|
356
|
-
return { success: false, error: `Failed to get recording: ${getError.message}` };
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
return { success: true, recording };
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
export const recordingsService = {
|
|
363
|
-
createRecordingDraft,
|
|
364
|
-
finalizeRecording,
|
|
365
|
-
listRecordings,
|
|
366
|
-
updateRecordingName,
|
|
367
|
-
deleteRecording,
|
|
368
|
-
getRecordingById,
|
|
369
|
-
};
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { api } from '@vibefast/backend/_generated/api';
|
|
2
|
-
import type { Id } from '@vibefast/backend/_generated/dataModel';
|
|
3
|
-
import { useMutation, useQuery } from 'convex/react';
|
|
4
|
-
|
|
5
|
-
type ConversationId = Id<'conversations'>;
|
|
6
|
-
|
|
7
|
-
const skipToken = 'skip' as const;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Chatbot API Gateway
|
|
11
|
-
*
|
|
12
|
-
* This gateway provides typed wrappers around Convex chatbot functions.
|
|
13
|
-
* It decouples the frontend from the backend file structure by using
|
|
14
|
-
* the chatbot domain aggregator (convex/chatbot/index.ts).
|
|
15
|
-
*
|
|
16
|
-
* Usage:
|
|
17
|
-
* - Import this gateway in feature code: `import { chatbotApi } from '@/platform/api/chatbot'`
|
|
18
|
-
* - Never import from `@vibefast/backend/_generated/api` directly in feature code
|
|
19
|
-
* - All chatbot-related Convex calls should go through this gateway
|
|
20
|
-
*/
|
|
21
|
-
export const chatbotApi = {
|
|
22
|
-
useAgentSession(conversationId?: ConversationId | null) {
|
|
23
|
-
return useQuery(
|
|
24
|
-
api['chatbot/index'].getAgentSession,
|
|
25
|
-
conversationId ? { conversationId } : skipToken,
|
|
26
|
-
);
|
|
27
|
-
},
|
|
28
|
-
|
|
29
|
-
useAgentStreamBody(
|
|
30
|
-
conversationId?: ConversationId | null,
|
|
31
|
-
streamId?: string | null,
|
|
32
|
-
) {
|
|
33
|
-
return useQuery(
|
|
34
|
-
api['chatbot/index'].getAgentStreamBody,
|
|
35
|
-
conversationId && streamId
|
|
36
|
-
? {
|
|
37
|
-
conversationId,
|
|
38
|
-
streamId,
|
|
39
|
-
}
|
|
40
|
-
: skipToken,
|
|
41
|
-
);
|
|
42
|
-
},
|
|
43
|
-
|
|
44
|
-
useStartAgentStream() {
|
|
45
|
-
return useMutation(api['chatbot/index'].startAgentStream);
|
|
46
|
-
},
|
|
47
|
-
|
|
48
|
-
useListMessages(
|
|
49
|
-
conversationId?: ConversationId | null,
|
|
50
|
-
paginationOpts: { numItems: number; cursor: string | null } = {
|
|
51
|
-
numItems: 50,
|
|
52
|
-
cursor: null,
|
|
53
|
-
},
|
|
54
|
-
) {
|
|
55
|
-
return useQuery(
|
|
56
|
-
api['chatbot/index'].listMessages,
|
|
57
|
-
conversationId
|
|
58
|
-
? {
|
|
59
|
-
conversationId,
|
|
60
|
-
paginationOpts,
|
|
61
|
-
}
|
|
62
|
-
: skipToken,
|
|
63
|
-
);
|
|
64
|
-
},
|
|
65
|
-
|
|
66
|
-
useGetOrCreateConversation() {
|
|
67
|
-
return useMutation(api['chatbot/index'].getOrCreateDefaultConversation);
|
|
68
|
-
},
|
|
69
|
-
|
|
70
|
-
useStoreMessage() {
|
|
71
|
-
return useMutation(api['chatbot/index'].storeMessage);
|
|
72
|
-
},
|
|
73
|
-
|
|
74
|
-
useClearConversation() {
|
|
75
|
-
return useMutation(api['chatbot/index'].clearConversationMessages);
|
|
76
|
-
},
|
|
77
|
-
|
|
78
|
-
useDeleteUserMessage() {
|
|
79
|
-
return useMutation(api['chatbot/index'].deleteUserMessage);
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
export type ChatbotApi = typeof chatbotApi;
|