vibefast-cli 1.1.5 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/README.md +63 -169
- package/dist/__tests__/recipes.test.js +89 -85
- package/dist/__tests__/recipes.test.js.map +1 -1
- package/dist/commands/add.d.ts +1 -1
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +576 -588
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/checklist.d.ts +1 -1
- package/dist/commands/checklist.d.ts.map +1 -1
- package/dist/commands/checklist.js +40 -39
- package/dist/commands/checklist.js.map +1 -1
- package/dist/commands/doctor.d.ts +1 -1
- package/dist/commands/doctor.js +22 -22
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/env.d.ts +1 -1
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/env.js +58 -53
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/health.d.ts +1 -1
- package/dist/commands/health.d.ts.map +1 -1
- package/dist/commands/health.js +101 -93
- package/dist/commands/health.js.map +1 -1
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +416 -296
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/remove.d.ts +1 -1
- package/dist/commands/remove.d.ts.map +1 -1
- package/dist/commands/remove.js +77 -64
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/status.d.ts +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +15 -14
- package/dist/commands/status.js.map +1 -1
- package/dist/core/__tests__/detect.test.js +68 -34
- package/dist/core/__tests__/detect.test.js.map +1 -1
- package/dist/core/ast.d.ts +14 -0
- package/dist/core/ast.d.ts.map +1 -0
- package/dist/core/ast.js +239 -0
- package/dist/core/ast.js.map +1 -0
- package/dist/core/codemod.d.ts.map +1 -1
- package/dist/core/codemod.js +62 -44
- package/dist/core/codemod.js.map +1 -1
- package/dist/core/config.d.ts +10 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +51 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/detect.d.ts +8 -2
- package/dist/core/detect.d.ts.map +1 -1
- package/dist/core/detect.js +52 -21
- package/dist/core/detect.js.map +1 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +9 -8
- package/dist/core/errors.js.map +1 -1
- package/dist/core/exec.d.ts +16 -0
- package/dist/core/exec.d.ts.map +1 -0
- package/dist/core/exec.js +48 -0
- package/dist/core/exec.js.map +1 -0
- package/dist/core/manualSteps.d.ts +7 -0
- package/dist/core/manualSteps.d.ts.map +1 -0
- package/dist/core/manualSteps.js +59 -0
- package/dist/core/manualSteps.js.map +1 -0
- package/dist/core/paths.d.ts +3 -1
- package/dist/core/paths.d.ts.map +1 -1
- package/dist/core/paths.js +14 -10
- package/dist/core/paths.js.map +1 -1
- package/dist/core/spinner.d.ts +1 -1
- package/dist/core/spinner.d.ts.map +1 -1
- package/dist/core/spinner.js +38 -8
- package/dist/core/spinner.js.map +1 -1
- package/dist/core/vosk.d.ts.map +1 -1
- package/dist/core/vosk.js +50 -39
- package/dist/core/vosk.js.map +1 -1
- package/docs/manual-testing.md +91 -0
- package/package.json +6 -3
- package/recipes/audio-recorder/apps/native/src/app/audio-recorder/index.tsx +5 -0
- package/recipes/audio-recorder/recipe.json +3 -3
- package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/components/audio-player.tsx +301 -0
- package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/components/audio-recorder.tsx +373 -0
- package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/components/audio-waveform.tsx +270 -0
- package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/components/index.ts +4 -0
- package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/components/recording-list.tsx +89 -0
- package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/audio-player-demo.tsx +66 -0
- package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/audio-recorder-cloud.tsx +68 -0
- package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/audio-recorder-interview.tsx +102 -0
- package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/basic.tsx +27 -0
- package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/index.ts +5 -0
- package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/with-recording-list-demo.tsx +82 -0
- package/recipes/audio-recorder-supabase/packages/backend/src/services/recordings.ts +369 -0
- package/recipes/audio-recorder-supabase/packages/backend/supabase/migrations/recordings.sql +70 -0
- package/recipes/audio-recorder-supabase/recipe.json +52 -0
- package/recipes/audio-recorder-supabase@latest.zip +0 -0
- package/recipes/audio-recorder@latest.zip +0 -0
- package/recipes/charts/apps/native/src/features/charts/components/bar-chart.tsx +3 -3
- package/recipes/charts/apps/native/src/features/charts/components/candlestick-chart.tsx +2 -2
- package/recipes/charts/apps/native/src/features/charts/components/chart-card.tsx +5 -5
- package/recipes/charts/apps/native/src/features/charts/components/column-chart.tsx +3 -3
- package/recipes/charts/apps/native/src/features/charts/components/doughnut-chart.tsx +20 -4
- package/recipes/charts/apps/native/src/features/charts/components/line-chart.tsx +7 -6
- package/recipes/charts/apps/native/src/features/charts/components/radar-chart.tsx +6 -4
- package/recipes/charts/apps/native/src/features/charts/components/radial-bar-chart.tsx +1 -1
- package/recipes/charts/apps/native/src/features/charts/components/stacked-bar-chart.tsx +5 -4
- package/recipes/charts/recipe.json +4 -13
- package/recipes/charts@latest.zip +0 -0
- package/recipes/chatbot/apps/native/src/app/chatbot/index.tsx +1 -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 +86 -53
- package/recipes/chatbot/recipe.json +26 -92
- package/recipes/chatbot-supabase/apps/native/src/api-client/supabase/chatbot.ts +515 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/app/index.tsx +257 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/chat-header-buttons.tsx +59 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/chat-input-bar.tsx +485 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/chat-markdown.tsx +575 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/chat-message-bubble.tsx +223 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/chat-settings-modal.tsx +161 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/image-preview-list.tsx +116 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/markdown/code-block.tsx +165 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/markdown/index.ts +10 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/markdown/table-renderer.tsx +129 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/message-error-boundary.tsx +78 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/message-list.tsx +170 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/model-selector.tsx +283 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/report-content-modal.tsx +188 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/suggested-messages.tsx +67 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/constants/models.ts +20 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/constants/report-reasons.ts +9 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-attachment-cache.ts +142 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-chat-config.ts +458 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-chat-handlers.ts +429 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-chatbot-settings.ts +89 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-conversation.ts +90 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-image-picker.ts +122 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-keyboard-coordinator.ts +161 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-smart-scroll-manager.ts +213 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/models/index.ts +86 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/models/models.ts +162 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/models/providers.ts +62 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/models/types.ts +40 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/services/file-uploader.ts +287 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/services/message-handler-service.ts +189 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/types/index.ts +70 -0
- package/recipes/chatbot-supabase/apps/native/src/features/chatbot/utils/chat-telemetry.ts +91 -0
- package/recipes/chatbot-supabase/packages/backend/src/services/conversations.ts +243 -0
- package/recipes/chatbot-supabase/packages/backend/src/services/messages.ts +327 -0
- package/recipes/chatbot-supabase/packages/backend/supabase/functions/chat-stream/index.ts +347 -0
- package/recipes/chatbot-supabase/packages/backend/supabase/migrations/chatbot.sql +104 -0
- package/recipes/chatbot-supabase/recipe.json +106 -0
- package/recipes/chatbot-supabase@latest.zip +0 -0
- package/recipes/chatbot.zip +0 -0
- package/recipes/chatbot@latest.zip +0 -0
- package/recipes/image-analysis/packages/backend/convex/imageAnalysis/index.ts +2 -2
- package/recipes/image-analysis/packages/backend/convex/imageAnalysis.ts +0 -1
- package/recipes/image-analysis/recipe.json +15 -55
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/analysis-options-screen.tsx +304 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/camera.tsx +221 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/image-capture-screen.tsx +333 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/loading-screen.tsx +214 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/loading.tsx +191 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/results.tsx +137 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/trait-details.tsx +172 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/use-analysis-data.ts +160 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/use-results-screen.ts +151 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/achievement-badge.tsx +77 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/achievement-card.tsx +75 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/achievement-unlocked-modal.tsx +162 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/achievements-section.tsx +44 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/advice-list.tsx +42 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/circular-progress.tsx +233 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/content-card.tsx +38 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/error-state.tsx +42 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/index.ts +9 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/loading-state.tsx +26 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/profile-image.tsx +60 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/results-header.tsx +62 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/score-display.tsx +54 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/share-options-modal.tsx +110 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/traits-grid.tsx +74 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/config/analysis-config.ts +80 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/config/master-analysis-config.ts +157 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/hooks/index.ts +1 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/hooks/use-analysis.ts +38 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/hooks/use-image-analysis.ts +208 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/services/analysis-service.ts +262 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/services/share-service.ts +176 -0
- package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/services/trait-details-service.ts +289 -0
- package/recipes/image-analysis-supabase/packages/backend/src/services/image-analyses.ts +132 -0
- package/recipes/image-analysis-supabase/packages/backend/supabase/functions/analyze-image/index.ts +312 -0
- package/recipes/image-analysis-supabase/packages/backend/supabase/migrations/image_analysis.sql +42 -0
- package/recipes/image-analysis-supabase/recipe.json +90 -0
- package/recipes/image-analysis-supabase@latest.zip +0 -0
- package/recipes/image-analysis@latest.zip +0 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/app/index.tsx +16 -2
- package/recipes/image-generator/apps/native/src/features/image-generator/components/image-model-selector.tsx +11 -5
- package/recipes/image-generator/apps/native/src/features/image-generator/hooks/use-image-generator.ts +11 -5
- package/recipes/image-generator/packages/backend/convex/imageGeneration/index.ts +2 -2
- package/recipes/image-generator/recipe.json +16 -39
- package/recipes/image-generator-supabase/apps/native/src/features/image-generator/app/_layout.tsx +26 -0
- package/recipes/image-generator-supabase/apps/native/src/features/image-generator/app/gallery.tsx +217 -0
- package/recipes/image-generator-supabase/apps/native/src/features/image-generator/app/index.tsx +251 -0
- package/recipes/image-generator-supabase/apps/native/src/features/image-generator/components/gallery-image.tsx +25 -0
- package/recipes/image-generator-supabase/apps/native/src/features/image-generator/components/image-detail-modal.tsx +215 -0
- package/recipes/image-generator-supabase/apps/native/src/features/image-generator/components/image-model-selector.tsx +216 -0
- package/recipes/image-generator-supabase/apps/native/src/features/image-generator/components/image-placeholder.tsx +26 -0
- package/recipes/image-generator-supabase/apps/native/src/features/image-generator/hooks/use-image-gallery.ts +71 -0
- package/recipes/image-generator-supabase/apps/native/src/features/image-generator/hooks/use-image-generator-settings.ts +152 -0
- package/recipes/image-generator-supabase/apps/native/src/features/image-generator/hooks/use-image-generator.ts +103 -0
- package/recipes/image-generator-supabase/apps/native/src/features/image-generator/models/models.ts +66 -0
- package/recipes/image-generator-supabase/apps/native/src/features/image-generator/services/image-gallery-service.ts +96 -0
- package/recipes/image-generator-supabase/apps/native/src/features/image-generator/services/image-save-service.ts +120 -0
- package/recipes/image-generator-supabase/packages/backend/supabase/functions/generate-image/index.ts +291 -0
- package/recipes/image-generator-supabase/packages/backend/supabase/migrations/image_generator.sql +71 -0
- package/recipes/image-generator-supabase/recipe.json +86 -0
- package/recipes/image-generator-supabase@latest.zip +0 -0
- package/recipes/image-generator@latest.zip +0 -0
- package/recipes/ios-widget/recipe.json +15 -24
- package/recipes/ios-widget@latest.zip +0 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/analytics/index.ts +9 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/components/onboarding-with-analytics.tsx +141 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/components/onboarding.tsx +173 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/config/onboarding-flow-config.ts +189 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/demo-one/app/index.tsx +42 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/demo-one/data.ts +32 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/app/index.tsx +43 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/interactive-onboarding.tsx +222 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/ai-tone-step.tsx +133 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/currency-step.tsx +165 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-ai-step.tsx +199 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-chatbot-step.tsx +154 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-manual-step.tsx +156 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-scan-step.tsx +158 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/main-reason-step.tsx +139 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/notification-step.tsx +129 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/overspend-step.tsx +138 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/personalizing-step.tsx +190 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/rating-step.tsx +98 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/reminder-step.tsx +181 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/safety-step.tsx +110 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/struggle-step.tsx +139 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/welcome-step.tsx +217 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/ui/onboarding-header.tsx +58 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/constants.ts +179 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/hooks/use-onboarding-analytics.ts +323 -0
- package/recipes/onboarding/apps/native/src/features/onboarding/services/onboarding-analytics.ts +432 -0
- package/recipes/onboarding/recipe.json +15 -0
- package/recipes/onboarding@latest.zip +0 -0
- package/recipes/payments/recipe.json +28 -61
- package/recipes/payments-supabase/apps/native/src/features/payments/README.md +200 -0
- package/recipes/payments-supabase/apps/native/src/features/payments/app/local-paywall.tsx +194 -0
- package/recipes/payments-supabase/apps/native/src/features/payments/app/remote-paywall.tsx +79 -0
- package/recipes/payments-supabase/apps/native/src/features/payments/components/payment-initializer.tsx +95 -0
- package/recipes/payments-supabase/apps/native/src/features/payments/components/paywall-error-state.tsx +60 -0
- package/recipes/payments-supabase/apps/native/src/features/payments/components/paywall-local-mode.tsx +116 -0
- package/recipes/payments-supabase/apps/native/src/features/payments/components/paywall-product-card.tsx +133 -0
- package/recipes/payments-supabase/apps/native/src/features/payments/components/paywall-remote-mode.tsx +146 -0
- package/recipes/payments-supabase/apps/native/src/features/payments/hooks/use-entitlement.ts +63 -0
- package/recipes/payments-supabase/apps/native/src/features/payments/index.ts +8 -0
- package/recipes/payments-supabase/apps/native/src/features/payments/services/revenuecat-adapter.ts +407 -0
- package/recipes/payments-supabase/packages/backend/src/services/payments.ts +201 -0
- package/recipes/payments-supabase/packages/backend/supabase/migrations/payments.sql +35 -0
- package/recipes/payments-supabase/recipe.json +72 -0
- package/recipes/payments-supabase@latest.zip +0 -0
- package/recipes/payments@latest.zip +0 -0
- package/recipes/quiz/apps/native/src/features/quiz/index.tsx +1 -2
- package/recipes/quiz/recipe.json +6 -9
- package/recipes/quiz@latest.zip +0 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/app/index.tsx +1 -2
- package/recipes/tracker-app/recipe.json +7 -10
- package/recipes/tracker-app@latest.zip +0 -0
- package/recipes/voice-bot/recipe.json +8 -68
- package/recipes/voice-bot.zip +0 -0
- package/recipes/voice-bot@latest.zip +0 -0
- package/recipes/wake-word/recipe.json +10 -9
- package/recipes/wake-word.zip +0 -0
- package/recipes/wake-word@latest.zip +0 -0
- package/recipes/charts/apps/native/src/app/(root)/(protected)/charts/index.tsx +0 -3
- package/recipes/chatbot/packages/backend/convex/lib/rateLimit.ts +0 -100
- package/recipes/chatbot/packages/backend/convex/lib/telemetry.ts +0 -29
- package/recipes/chatbot/packages/backend/convex/ragKnowledge.ts +0 -0
- package/recipes/image-analysis/apps/native/assets/features/image-analyzer/front.jpg +0 -0
- package/recipes/image-analysis/apps/native/assets/features/image-analyzer/side.jpg +0 -0
- package/recipes/image-analysis/apps/native/assets/features/image-analyzer/threeQuarter.jpg +0 -0
- package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/_layout.tsx +0 -5
- package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/analysis-options.tsx +0 -50
- package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/camera.tsx +0 -2
- package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/index.tsx +0 -50
- package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/loading.tsx +0 -50
- package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/results.tsx +0 -2
- package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/trait-details.tsx +0 -3
- package/recipes/image-analysis/packages/backend/convex/imageAnalysisFunctions.ts +0 -325
- package/recipes/image-analysis/packages/backend/convex/lib/ai/imageAnalysisAdapter.ts +0 -200
- package/recipes/payments/apps/native/src/app/(root)/(protected)/paywall/index.tsx +0 -74
- package/recipes/payments/apps/native/src/app/(root)/(protected)/paywall/local.tsx +0 -25
- package/recipes/payments/apps/native/src/app/(root)/(protected)/paywall/remote.tsx +0 -23
- package/recipes/quiz/apps/native/src/app/(root)/(protected)/quiz/index.tsx +0 -47
- package/recipes/tracker-app/apps/native/src/app/(root)/(protected)/tracker-app/index.tsx +0 -1
- package/recipes/voice-bot/apps/native/src/app/(root)/(protected)/voice-bot/index.tsx +0 -27
- package/recipes/voice-bot/packages/backend/convex/router.ts +0 -81
- /package/recipes/{chatbot/apps/native/src/app/(root)/(protected) → chatbot-supabase/apps/native/src/app}/chatbot/index.tsx +0 -0
- /package/recipes/{image-generator/apps/native/src/app/(root)/(protected) → image-generator-supabase/apps/native/src/app}/image-generator/gallery.tsx +0 -0
- /package/recipes/{image-generator/apps/native/src/app/(root)/(protected) → image-generator-supabase/apps/native/src/app}/image-generator/index.tsx +0 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { Button, Input, Modal, Select, Text, useModal } from '@/components/ui';
|
|
5
|
+
import type { OptionType } from '@/components/ui/core/select';
|
|
6
|
+
|
|
7
|
+
import { REPORT_REASONS, type ReportReason } from '../constants/report-reasons';
|
|
8
|
+
import type { AppMessage } from '../types';
|
|
9
|
+
|
|
10
|
+
type ReportContentModalProps = {
|
|
11
|
+
message: AppMessage | null;
|
|
12
|
+
onSubmit: (reportData: {
|
|
13
|
+
messageId?: string;
|
|
14
|
+
reason: ReportReason;
|
|
15
|
+
details?: string;
|
|
16
|
+
}) => Promise<boolean>;
|
|
17
|
+
onCancel: () => void;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Modal component for reporting AI-generated content in chat messages.
|
|
22
|
+
* Allows users to select a reason and provide additional details for the report.
|
|
23
|
+
*/
|
|
24
|
+
export const ReportContentModal: React.FC<ReportContentModalProps> = ({
|
|
25
|
+
message,
|
|
26
|
+
onSubmit,
|
|
27
|
+
onCancel,
|
|
28
|
+
}) => {
|
|
29
|
+
const modal = useModal();
|
|
30
|
+
const [selectedReason, setSelectedReason] = useState<
|
|
31
|
+
ReportReason | undefined
|
|
32
|
+
>();
|
|
33
|
+
const [details, setDetails] = useState('');
|
|
34
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
35
|
+
const [error, setError] = useState<string | null>(null);
|
|
36
|
+
|
|
37
|
+
// Convert readonly array to mutable array for Select component
|
|
38
|
+
const reportReasonOptions: OptionType[] = REPORT_REASONS.map((reason) => ({
|
|
39
|
+
label: reason.label,
|
|
40
|
+
value: reason.value,
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
// Handle modal presentation/dismissal without resetting form
|
|
44
|
+
React.useEffect(() => {
|
|
45
|
+
if (message) {
|
|
46
|
+
modal.present();
|
|
47
|
+
} else {
|
|
48
|
+
modal.dismiss();
|
|
49
|
+
}
|
|
50
|
+
}, [message, modal]);
|
|
51
|
+
|
|
52
|
+
// NO automatic form reset - only reset on explicit user actions
|
|
53
|
+
|
|
54
|
+
const handleSubmitReport = async () => {
|
|
55
|
+
if (!message || !selectedReason) {
|
|
56
|
+
setError('Please select a reason for reporting');
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
setIsLoading(true);
|
|
61
|
+
setError(null);
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
const success = await onSubmit({
|
|
65
|
+
messageId: message.id,
|
|
66
|
+
reason: selectedReason,
|
|
67
|
+
details: details.trim() || undefined,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (success) {
|
|
71
|
+
// Reset form and close modal
|
|
72
|
+
setSelectedReason(undefined);
|
|
73
|
+
setDetails('');
|
|
74
|
+
onCancel();
|
|
75
|
+
} else {
|
|
76
|
+
setError('Failed to submit report. Please try again.');
|
|
77
|
+
}
|
|
78
|
+
} catch {
|
|
79
|
+
setError('An error occurred while submitting the report.');
|
|
80
|
+
} finally {
|
|
81
|
+
setIsLoading(false);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const handleCancel = () => {
|
|
86
|
+
setSelectedReason(undefined);
|
|
87
|
+
setDetails('');
|
|
88
|
+
setError(null);
|
|
89
|
+
onCancel();
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// Get message preview text (first 100 characters)
|
|
93
|
+
const getContentPreview = () => {
|
|
94
|
+
if (!message) return '';
|
|
95
|
+
|
|
96
|
+
let text = '';
|
|
97
|
+
if (typeof message.content === 'string') {
|
|
98
|
+
text = message.content;
|
|
99
|
+
} else if (Array.isArray(message.content)) {
|
|
100
|
+
text = message.content
|
|
101
|
+
.filter((part) => part.type === 'text')
|
|
102
|
+
.map((part) => part.text)
|
|
103
|
+
.join('\n');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return text.length > 100 ? `${text.substring(0, 100)}...` : text;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<Modal
|
|
111
|
+
ref={modal.ref}
|
|
112
|
+
title="Report Content"
|
|
113
|
+
snapPoints={['80%']}
|
|
114
|
+
onDismiss={handleCancel}
|
|
115
|
+
>
|
|
116
|
+
<View className="flex-1 px-4 pb-8">
|
|
117
|
+
{/* Message Preview */}
|
|
118
|
+
<View className="mb-6">
|
|
119
|
+
<Text className="mb-2 text-sm font-medium text-neutral-700 dark:text-neutral-300">
|
|
120
|
+
Reporting content:
|
|
121
|
+
</Text>
|
|
122
|
+
<View className="rounded-lg border border-neutral-200 bg-neutral-50 p-3 dark:border-neutral-600 dark:bg-neutral-800">
|
|
123
|
+
<Text
|
|
124
|
+
className="text-sm text-neutral-800 dark:text-neutral-200"
|
|
125
|
+
numberOfLines={3}
|
|
126
|
+
>
|
|
127
|
+
{getContentPreview() || 'Content preview'}
|
|
128
|
+
</Text>
|
|
129
|
+
</View>
|
|
130
|
+
</View>
|
|
131
|
+
|
|
132
|
+
{/* Reason Selection */}
|
|
133
|
+
<View className="mb-4">
|
|
134
|
+
<Select
|
|
135
|
+
label="Reason for reporting"
|
|
136
|
+
placeholder="Select a reason..."
|
|
137
|
+
options={reportReasonOptions}
|
|
138
|
+
value={selectedReason}
|
|
139
|
+
onSelect={(value) => setSelectedReason(value as ReportReason)}
|
|
140
|
+
testID="report-reason-select"
|
|
141
|
+
/>
|
|
142
|
+
</View>
|
|
143
|
+
|
|
144
|
+
{/* Additional Details */}
|
|
145
|
+
<View className="mb-4">
|
|
146
|
+
<Input
|
|
147
|
+
label="Additional details (optional)"
|
|
148
|
+
placeholder="Provide more context about why you're reporting this message..."
|
|
149
|
+
value={details}
|
|
150
|
+
onChangeText={setDetails}
|
|
151
|
+
multiline
|
|
152
|
+
numberOfLines={4}
|
|
153
|
+
testID="report-details-input"
|
|
154
|
+
accessibilityHint="Optional field to provide additional context for the report"
|
|
155
|
+
/>
|
|
156
|
+
</View>
|
|
157
|
+
|
|
158
|
+
{/* Error Message */}
|
|
159
|
+
{error && (
|
|
160
|
+
<View className="mb-4">
|
|
161
|
+
<Text className="text-sm text-red-600 dark:text-red-400">
|
|
162
|
+
{error}
|
|
163
|
+
</Text>
|
|
164
|
+
</View>
|
|
165
|
+
)}
|
|
166
|
+
|
|
167
|
+
{/* Action Buttons */}
|
|
168
|
+
<View className="mt-auto gap-3">
|
|
169
|
+
<Button
|
|
170
|
+
label={isLoading ? 'Submitting...' : 'Submit Report'}
|
|
171
|
+
onPress={handleSubmitReport}
|
|
172
|
+
disabled={isLoading || !selectedReason}
|
|
173
|
+
testID="submit-report-button"
|
|
174
|
+
accessibilityHint="Submit the report for review"
|
|
175
|
+
/>
|
|
176
|
+
<Button
|
|
177
|
+
label="Cancel"
|
|
178
|
+
variant="outline"
|
|
179
|
+
onPress={handleCancel}
|
|
180
|
+
disabled={isLoading}
|
|
181
|
+
testID="cancel-report-button"
|
|
182
|
+
accessibilityHint="Cancel reporting and close modal"
|
|
183
|
+
/>
|
|
184
|
+
</View>
|
|
185
|
+
</View>
|
|
186
|
+
</Modal>
|
|
187
|
+
);
|
|
188
|
+
};
|
package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/suggested-messages.tsx
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import { useCallback } from 'react';
|
|
3
|
+
import { ScrollView, View } from 'react-native';
|
|
4
|
+
|
|
5
|
+
import { Pressable, Text } from '@/components/ui';
|
|
6
|
+
import { translate } from '@/lib';
|
|
7
|
+
import { useThemeConfig } from '@/lib/use-theme-config';
|
|
8
|
+
|
|
9
|
+
type SuggestedMessagesProps = {
|
|
10
|
+
onSelectMessage: (message: string) => void;
|
|
11
|
+
visible?: boolean;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const getSuggestedMessages = () => [
|
|
15
|
+
translate('chatbot.suggested_messages.help_today'),
|
|
16
|
+
translate('chatbot.suggested_messages.weather'),
|
|
17
|
+
translate('chatbot.suggested_messages.fun_fact'),
|
|
18
|
+
translate('chatbot.suggested_messages.brainstorm'),
|
|
19
|
+
translate('chatbot.suggested_messages.explain_concept'),
|
|
20
|
+
translate('chatbot.suggested_messages.capabilities'),
|
|
21
|
+
translate('chatbot.suggested_messages.writing_tips'),
|
|
22
|
+
translate('chatbot.suggested_messages.solve_problem'),
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Component for displaying suggested messages when conversation is empty
|
|
27
|
+
*/
|
|
28
|
+
export const SuggestedMessages: React.FC<SuggestedMessagesProps> = ({
|
|
29
|
+
onSelectMessage,
|
|
30
|
+
visible = false,
|
|
31
|
+
}) => {
|
|
32
|
+
const theme = useThemeConfig();
|
|
33
|
+
|
|
34
|
+
const handleSuggestedMessage = useCallback(
|
|
35
|
+
(message: string) => {
|
|
36
|
+
onSelectMessage(message);
|
|
37
|
+
},
|
|
38
|
+
[onSelectMessage],
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
if (!visible) return null;
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<View className="pb-4 pl-4">
|
|
45
|
+
<ScrollView
|
|
46
|
+
horizontal
|
|
47
|
+
showsHorizontalScrollIndicator={false}
|
|
48
|
+
contentContainerStyle={{ gap: 8, paddingHorizontal: 4 }}
|
|
49
|
+
>
|
|
50
|
+
{getSuggestedMessages().map((message, index) => (
|
|
51
|
+
<Pressable
|
|
52
|
+
key={index}
|
|
53
|
+
onPress={() => handleSuggestedMessage(message)}
|
|
54
|
+
className="rounded-2xl bg-neutral-200 p-4 dark:border-neutral-700 dark:bg-neutral-800"
|
|
55
|
+
style={{ borderColor: theme.colors.border }}
|
|
56
|
+
accessibilityRole="button"
|
|
57
|
+
accessibilityLabel={`Suggested message: ${message}`}
|
|
58
|
+
>
|
|
59
|
+
<Text className="whitespace-nowrap text-base text-neutral-700 dark:text-neutral-300">
|
|
60
|
+
{message}
|
|
61
|
+
</Text>
|
|
62
|
+
</Pressable>
|
|
63
|
+
))}
|
|
64
|
+
</ScrollView>
|
|
65
|
+
</View>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// DEPRECATED: This file has been moved to src/features/chatbot/models/
|
|
2
|
+
// Please import from '@/features/chatbot/models' instead
|
|
3
|
+
// This file is kept for backward compatibility
|
|
4
|
+
|
|
5
|
+
// Type exports for backward compatibility
|
|
6
|
+
export type { ModelType, Provider } from '../models';
|
|
7
|
+
// Re-export from new location for backward compatibility
|
|
8
|
+
export {
|
|
9
|
+
DEFAULT_MODELS,
|
|
10
|
+
getAllProviders,
|
|
11
|
+
getModelById,
|
|
12
|
+
getModelDescription,
|
|
13
|
+
getModelsByProvider,
|
|
14
|
+
getPremiumModels,
|
|
15
|
+
getProviderDisplayName,
|
|
16
|
+
getProviderIcon,
|
|
17
|
+
isPremiumModel,
|
|
18
|
+
MODELS,
|
|
19
|
+
PREMIUM_MODELS,
|
|
20
|
+
} from '../models';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const REPORT_REASONS = [
|
|
2
|
+
{ label: 'Inaccurate Information', value: 'inaccurate' },
|
|
3
|
+
{ label: 'Offensive Content', value: 'offensive' },
|
|
4
|
+
{ label: 'Harmful Content', value: 'harmful' },
|
|
5
|
+
{ label: 'Spam / Irrelevant', value: 'spam' },
|
|
6
|
+
{ label: 'Other', value: 'other' },
|
|
7
|
+
] as const;
|
|
8
|
+
|
|
9
|
+
export type ReportReason = (typeof REPORT_REASONS)[number]['value'];
|
package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-attachment-cache.ts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Attachment type for caching
|
|
5
|
+
*/
|
|
6
|
+
export type AppAttachment = {
|
|
7
|
+
type: 'image';
|
|
8
|
+
storageId: string;
|
|
9
|
+
fileName?: string;
|
|
10
|
+
mimeType?: string;
|
|
11
|
+
url?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Hook to manage attachment caching for chat messages.
|
|
16
|
+
* Prevents image flickering by maintaining stable attachment references across renders.
|
|
17
|
+
*
|
|
18
|
+
* Features:
|
|
19
|
+
* - O(1) lookups using Map data structure
|
|
20
|
+
* - Persistent cache across re-renders using useRef
|
|
21
|
+
* - Automatic cache clearing on conversation switch
|
|
22
|
+
* - Set/get/clear/remove operations with proper TypeScript types
|
|
23
|
+
*
|
|
24
|
+
* Requirements addressed:
|
|
25
|
+
* - 1.1: Display images immediately in optimistic user message
|
|
26
|
+
* - 1.2: Maintain visibility during AI response streaming
|
|
27
|
+
* - 1.3: Seamless transition from optimistic to persisted attachments
|
|
28
|
+
* - 1.4: Preserve display order consistently across render cycles
|
|
29
|
+
* - 1.5: Clear cache on conversation switch to prevent data bleeding
|
|
30
|
+
*
|
|
31
|
+
* @param conversationId - Current conversation ID for cache invalidation
|
|
32
|
+
* @returns Object containing cache operations and state
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```tsx
|
|
36
|
+
* const attachmentCache = useAttachmentCache(conversationId);
|
|
37
|
+
*
|
|
38
|
+
* // Store attachments for a message
|
|
39
|
+
* attachmentCache.set('message-123', [
|
|
40
|
+
* { type: 'image', storageId: 'storage-456', fileName: 'photo.jpg' }
|
|
41
|
+
* ]);
|
|
42
|
+
*
|
|
43
|
+
* // Retrieve cached attachments
|
|
44
|
+
* const cached = attachmentCache.get('message-123');
|
|
45
|
+
*
|
|
46
|
+
* // Clear all cached attachments
|
|
47
|
+
* attachmentCache.clear();
|
|
48
|
+
*
|
|
49
|
+
* // Remove specific message's attachments
|
|
50
|
+
* attachmentCache.remove('message-123');
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export function useAttachmentCache(conversationId: string | null) {
|
|
54
|
+
// Use Map for O(1) lookups instead of plain object
|
|
55
|
+
const cacheRef = useRef<Map<string, AppAttachment[]>>(new Map());
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Store attachments for a specific message ID.
|
|
59
|
+
* Updates cache only if attachments actually changed (deep comparison).
|
|
60
|
+
*
|
|
61
|
+
* @param messageId - Unique message identifier
|
|
62
|
+
* @param attachments - Array of attachments to cache
|
|
63
|
+
*/
|
|
64
|
+
const set = useCallback((messageId: string, attachments: AppAttachment[]) => {
|
|
65
|
+
const cache = cacheRef.current;
|
|
66
|
+
const existing = cache.get(messageId);
|
|
67
|
+
|
|
68
|
+
// Only update if attachments changed
|
|
69
|
+
if (
|
|
70
|
+
!existing ||
|
|
71
|
+
existing.length !== attachments.length ||
|
|
72
|
+
!existing.every((a, i) => a.storageId === attachments[i]?.storageId)
|
|
73
|
+
) {
|
|
74
|
+
cache.set(messageId, attachments);
|
|
75
|
+
}
|
|
76
|
+
}, []);
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Retrieve cached attachments for a specific message ID.
|
|
80
|
+
*
|
|
81
|
+
* @param messageId - Unique message identifier
|
|
82
|
+
* @returns Cached attachments or undefined if not found
|
|
83
|
+
*/
|
|
84
|
+
const get = useCallback((messageId: string): AppAttachment[] | undefined => {
|
|
85
|
+
return cacheRef.current.get(messageId);
|
|
86
|
+
}, []);
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Clear all cached attachments.
|
|
90
|
+
* Useful when clearing chat or switching conversations.
|
|
91
|
+
*/
|
|
92
|
+
const clear = useCallback(() => {
|
|
93
|
+
cacheRef.current.clear();
|
|
94
|
+
}, []);
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Remove cached attachments for a specific message ID.
|
|
98
|
+
*
|
|
99
|
+
* @param messageId - Unique message identifier
|
|
100
|
+
*/
|
|
101
|
+
const remove = useCallback((messageId: string) => {
|
|
102
|
+
cacheRef.current.delete(messageId);
|
|
103
|
+
}, []);
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Get the current cache size (number of cached messages).
|
|
107
|
+
* Useful for debugging and monitoring.
|
|
108
|
+
*
|
|
109
|
+
* @returns Number of messages with cached attachments
|
|
110
|
+
*/
|
|
111
|
+
const size = useCallback((): number => {
|
|
112
|
+
return cacheRef.current.size;
|
|
113
|
+
}, []);
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Check if a message has cached attachments.
|
|
117
|
+
*
|
|
118
|
+
* @param messageId - Unique message identifier
|
|
119
|
+
* @returns True if message has cached attachments
|
|
120
|
+
*/
|
|
121
|
+
const has = useCallback((messageId: string): boolean => {
|
|
122
|
+
return cacheRef.current.has(messageId);
|
|
123
|
+
}, []);
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Clear cache when conversation changes to prevent data bleeding.
|
|
127
|
+
* This ensures attachments from one conversation don't appear in another.
|
|
128
|
+
*/
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
clear();
|
|
131
|
+
}, [conversationId, clear]);
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
set,
|
|
135
|
+
get,
|
|
136
|
+
clear,
|
|
137
|
+
remove,
|
|
138
|
+
size,
|
|
139
|
+
has,
|
|
140
|
+
cacheRef,
|
|
141
|
+
};
|
|
142
|
+
}
|