vibefast-cli 1.1.5 → 1.2.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.
Files changed (299) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +63 -169
  3. package/dist/commands/add.d.ts +1 -1
  4. package/dist/commands/add.d.ts.map +1 -1
  5. package/dist/commands/add.js +547 -589
  6. package/dist/commands/add.js.map +1 -1
  7. package/dist/commands/checklist.d.ts +1 -1
  8. package/dist/commands/checklist.d.ts.map +1 -1
  9. package/dist/commands/checklist.js +40 -39
  10. package/dist/commands/checklist.js.map +1 -1
  11. package/dist/commands/doctor.d.ts +1 -1
  12. package/dist/commands/doctor.js +22 -22
  13. package/dist/commands/doctor.js.map +1 -1
  14. package/dist/commands/env.d.ts +1 -1
  15. package/dist/commands/env.d.ts.map +1 -1
  16. package/dist/commands/env.js +58 -53
  17. package/dist/commands/env.js.map +1 -1
  18. package/dist/commands/health.d.ts +1 -1
  19. package/dist/commands/health.d.ts.map +1 -1
  20. package/dist/commands/health.js +101 -93
  21. package/dist/commands/health.js.map +1 -1
  22. package/dist/commands/init.d.ts +1 -1
  23. package/dist/commands/init.d.ts.map +1 -1
  24. package/dist/commands/init.js +416 -296
  25. package/dist/commands/init.js.map +1 -1
  26. package/dist/commands/remove.d.ts +1 -1
  27. package/dist/commands/remove.d.ts.map +1 -1
  28. package/dist/commands/remove.js +77 -64
  29. package/dist/commands/remove.js.map +1 -1
  30. package/dist/commands/status.d.ts +1 -1
  31. package/dist/commands/status.d.ts.map +1 -1
  32. package/dist/commands/status.js +15 -14
  33. package/dist/commands/status.js.map +1 -1
  34. package/dist/core/__tests__/detect.test.js +68 -34
  35. package/dist/core/__tests__/detect.test.js.map +1 -1
  36. package/dist/core/ast.d.ts +14 -0
  37. package/dist/core/ast.d.ts.map +1 -0
  38. package/dist/core/ast.js +239 -0
  39. package/dist/core/ast.js.map +1 -0
  40. package/dist/core/codemod.d.ts.map +1 -1
  41. package/dist/core/codemod.js +62 -44
  42. package/dist/core/codemod.js.map +1 -1
  43. package/dist/core/config.d.ts +10 -0
  44. package/dist/core/config.d.ts.map +1 -0
  45. package/dist/core/config.js +51 -0
  46. package/dist/core/config.js.map +1 -0
  47. package/dist/core/detect.d.ts +8 -2
  48. package/dist/core/detect.d.ts.map +1 -1
  49. package/dist/core/detect.js +52 -21
  50. package/dist/core/detect.js.map +1 -1
  51. package/dist/core/errors.d.ts.map +1 -1
  52. package/dist/core/errors.js +9 -8
  53. package/dist/core/errors.js.map +1 -1
  54. package/dist/core/exec.d.ts +16 -0
  55. package/dist/core/exec.d.ts.map +1 -0
  56. package/dist/core/exec.js +48 -0
  57. package/dist/core/exec.js.map +1 -0
  58. package/dist/core/manualSteps.d.ts +7 -0
  59. package/dist/core/manualSteps.d.ts.map +1 -0
  60. package/dist/core/manualSteps.js +59 -0
  61. package/dist/core/manualSteps.js.map +1 -0
  62. package/dist/core/paths.d.ts +3 -1
  63. package/dist/core/paths.d.ts.map +1 -1
  64. package/dist/core/paths.js +14 -10
  65. package/dist/core/paths.js.map +1 -1
  66. package/dist/core/spinner.d.ts +1 -1
  67. package/dist/core/spinner.d.ts.map +1 -1
  68. package/dist/core/spinner.js +38 -8
  69. package/dist/core/spinner.js.map +1 -1
  70. package/dist/core/vosk.d.ts.map +1 -1
  71. package/dist/core/vosk.js +50 -39
  72. package/dist/core/vosk.js.map +1 -1
  73. package/docs/manual-testing.md +91 -0
  74. package/package.json +6 -3
  75. package/recipes/audio-recorder/apps/native/src/app/audio-recorder/index.tsx +5 -0
  76. package/recipes/audio-recorder/recipe.json +3 -3
  77. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/components/audio-player.tsx +301 -0
  78. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/components/audio-recorder.tsx +373 -0
  79. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/components/audio-waveform.tsx +270 -0
  80. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/components/index.ts +4 -0
  81. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/components/recording-list.tsx +89 -0
  82. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/audio-player-demo.tsx +66 -0
  83. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/audio-recorder-cloud.tsx +68 -0
  84. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/audio-recorder-interview.tsx +102 -0
  85. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/basic.tsx +27 -0
  86. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/index.ts +5 -0
  87. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/with-recording-list-demo.tsx +82 -0
  88. package/recipes/audio-recorder-supabase/packages/backend/src/services/recordings.ts +369 -0
  89. package/recipes/audio-recorder-supabase/packages/backend/supabase/migrations/recordings.sql +70 -0
  90. package/recipes/audio-recorder-supabase/recipe.json +35 -0
  91. package/recipes/audio-recorder-supabase@latest.zip +0 -0
  92. package/recipes/audio-recorder@latest.zip +0 -0
  93. package/recipes/charts/apps/native/src/features/charts/components/bar-chart.tsx +3 -3
  94. package/recipes/charts/apps/native/src/features/charts/components/candlestick-chart.tsx +2 -2
  95. package/recipes/charts/apps/native/src/features/charts/components/chart-card.tsx +5 -5
  96. package/recipes/charts/apps/native/src/features/charts/components/column-chart.tsx +3 -3
  97. package/recipes/charts/apps/native/src/features/charts/components/doughnut-chart.tsx +20 -4
  98. package/recipes/charts/apps/native/src/features/charts/components/line-chart.tsx +7 -6
  99. package/recipes/charts/apps/native/src/features/charts/components/radar-chart.tsx +6 -4
  100. package/recipes/charts/apps/native/src/features/charts/components/radial-bar-chart.tsx +1 -1
  101. package/recipes/charts/apps/native/src/features/charts/components/stacked-bar-chart.tsx +5 -4
  102. package/recipes/charts/recipe.json +4 -13
  103. package/recipes/charts@latest.zip +0 -0
  104. package/recipes/chatbot/apps/native/src/app/chatbot/index.tsx +1 -0
  105. package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-markdown.tsx +86 -86
  106. package/recipes/chatbot/apps/native/src/features/chatbot/components/markdown/code-block.tsx +86 -53
  107. package/recipes/chatbot/recipe.json +26 -92
  108. package/recipes/chatbot-supabase/apps/native/src/api-client/supabase/chatbot.ts +515 -0
  109. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/app/index.tsx +257 -0
  110. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/chat-header-buttons.tsx +59 -0
  111. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/chat-input-bar.tsx +485 -0
  112. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/chat-markdown.tsx +575 -0
  113. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/chat-message-bubble.tsx +223 -0
  114. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/chat-settings-modal.tsx +161 -0
  115. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/image-preview-list.tsx +116 -0
  116. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/markdown/code-block.tsx +165 -0
  117. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/markdown/index.ts +10 -0
  118. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/markdown/table-renderer.tsx +129 -0
  119. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/message-error-boundary.tsx +78 -0
  120. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/message-list.tsx +170 -0
  121. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/model-selector.tsx +283 -0
  122. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/report-content-modal.tsx +188 -0
  123. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/suggested-messages.tsx +67 -0
  124. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/constants/models.ts +20 -0
  125. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/constants/report-reasons.ts +9 -0
  126. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-attachment-cache.ts +142 -0
  127. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-chat-config.ts +458 -0
  128. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-chat-handlers.ts +429 -0
  129. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-chatbot-settings.ts +89 -0
  130. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-conversation.ts +90 -0
  131. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-image-picker.ts +122 -0
  132. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-keyboard-coordinator.ts +161 -0
  133. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-smart-scroll-manager.ts +213 -0
  134. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/models/index.ts +86 -0
  135. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/models/models.ts +162 -0
  136. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/models/providers.ts +62 -0
  137. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/models/types.ts +40 -0
  138. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/services/file-uploader.ts +287 -0
  139. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/services/message-handler-service.ts +189 -0
  140. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/types/index.ts +70 -0
  141. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/utils/chat-telemetry.ts +91 -0
  142. package/recipes/chatbot-supabase/packages/backend/src/services/conversations.ts +243 -0
  143. package/recipes/chatbot-supabase/packages/backend/src/services/messages.ts +327 -0
  144. package/recipes/chatbot-supabase/packages/backend/supabase/functions/chat-stream/index.ts +347 -0
  145. package/recipes/chatbot-supabase/packages/backend/supabase/migrations/chatbot.sql +104 -0
  146. package/recipes/chatbot-supabase/recipe.json +79 -0
  147. package/recipes/chatbot-supabase@latest.zip +0 -0
  148. package/recipes/chatbot.zip +0 -0
  149. package/recipes/chatbot@latest.zip +0 -0
  150. package/recipes/image-analysis/packages/backend/convex/imageAnalysis/index.ts +2 -2
  151. package/recipes/image-analysis/packages/backend/convex/imageAnalysis.ts +0 -1
  152. package/recipes/image-analysis/recipe.json +15 -55
  153. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/analysis-options-screen.tsx +304 -0
  154. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/camera.tsx +221 -0
  155. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/image-capture-screen.tsx +333 -0
  156. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/loading-screen.tsx +214 -0
  157. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/loading.tsx +191 -0
  158. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/results.tsx +137 -0
  159. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/trait-details.tsx +172 -0
  160. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/use-analysis-data.ts +160 -0
  161. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/use-results-screen.ts +151 -0
  162. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/achievement-badge.tsx +77 -0
  163. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/achievement-card.tsx +75 -0
  164. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/achievement-unlocked-modal.tsx +162 -0
  165. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/achievements-section.tsx +44 -0
  166. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/advice-list.tsx +42 -0
  167. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/circular-progress.tsx +233 -0
  168. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/content-card.tsx +38 -0
  169. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/error-state.tsx +42 -0
  170. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/index.ts +9 -0
  171. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/loading-state.tsx +26 -0
  172. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/profile-image.tsx +60 -0
  173. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/results-header.tsx +62 -0
  174. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/score-display.tsx +54 -0
  175. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/share-options-modal.tsx +110 -0
  176. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/traits-grid.tsx +74 -0
  177. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/config/analysis-config.ts +80 -0
  178. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/config/master-analysis-config.ts +157 -0
  179. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/hooks/index.ts +1 -0
  180. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/hooks/use-analysis.ts +38 -0
  181. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/hooks/use-image-analysis.ts +208 -0
  182. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/services/analysis-service.ts +262 -0
  183. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/services/share-service.ts +176 -0
  184. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/services/trait-details-service.ts +289 -0
  185. package/recipes/image-analysis-supabase/packages/backend/src/services/image-analyses.ts +132 -0
  186. package/recipes/image-analysis-supabase/packages/backend/supabase/functions/analyze-image/index.ts +312 -0
  187. package/recipes/image-analysis-supabase/packages/backend/supabase/migrations/image_analysis.sql +42 -0
  188. package/recipes/image-analysis-supabase/recipe.json +57 -0
  189. package/recipes/image-analysis-supabase@latest.zip +0 -0
  190. package/recipes/image-analysis@latest.zip +0 -0
  191. package/recipes/image-generator/apps/native/src/features/image-generator/app/index.tsx +16 -2
  192. package/recipes/image-generator/apps/native/src/features/image-generator/components/image-model-selector.tsx +11 -5
  193. package/recipes/image-generator/apps/native/src/features/image-generator/hooks/use-image-generator.ts +11 -5
  194. package/recipes/image-generator/packages/backend/convex/imageGeneration/index.ts +2 -2
  195. package/recipes/image-generator/recipe.json +16 -39
  196. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/app/_layout.tsx +26 -0
  197. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/app/gallery.tsx +217 -0
  198. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/app/index.tsx +251 -0
  199. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/components/gallery-image.tsx +25 -0
  200. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/components/image-detail-modal.tsx +215 -0
  201. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/components/image-model-selector.tsx +216 -0
  202. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/components/image-placeholder.tsx +26 -0
  203. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/hooks/use-image-gallery.ts +71 -0
  204. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/hooks/use-image-generator-settings.ts +152 -0
  205. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/hooks/use-image-generator.ts +103 -0
  206. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/models/models.ts +66 -0
  207. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/services/image-gallery-service.ts +96 -0
  208. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/services/image-save-service.ts +120 -0
  209. package/recipes/image-generator-supabase/packages/backend/supabase/functions/generate-image/index.ts +291 -0
  210. package/recipes/image-generator-supabase/packages/backend/supabase/migrations/image_generator.sql +71 -0
  211. package/recipes/image-generator-supabase/recipe.json +59 -0
  212. package/recipes/image-generator-supabase@latest.zip +0 -0
  213. package/recipes/image-generator@latest.zip +0 -0
  214. package/recipes/ios-widget/recipe.json +15 -24
  215. package/recipes/ios-widget@latest.zip +0 -0
  216. package/recipes/onboarding/apps/native/src/features/onboarding/analytics/index.ts +9 -0
  217. package/recipes/onboarding/apps/native/src/features/onboarding/components/onboarding-with-analytics.tsx +141 -0
  218. package/recipes/onboarding/apps/native/src/features/onboarding/components/onboarding.tsx +173 -0
  219. package/recipes/onboarding/apps/native/src/features/onboarding/config/onboarding-flow-config.ts +189 -0
  220. package/recipes/onboarding/apps/native/src/features/onboarding/demo-one/app/index.tsx +42 -0
  221. package/recipes/onboarding/apps/native/src/features/onboarding/demo-one/data.ts +32 -0
  222. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/app/index.tsx +43 -0
  223. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/interactive-onboarding.tsx +222 -0
  224. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/ai-tone-step.tsx +133 -0
  225. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/currency-step.tsx +165 -0
  226. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-ai-step.tsx +199 -0
  227. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-chatbot-step.tsx +154 -0
  228. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-manual-step.tsx +156 -0
  229. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-scan-step.tsx +158 -0
  230. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/main-reason-step.tsx +139 -0
  231. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/notification-step.tsx +129 -0
  232. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/overspend-step.tsx +138 -0
  233. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/personalizing-step.tsx +190 -0
  234. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/rating-step.tsx +98 -0
  235. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/reminder-step.tsx +181 -0
  236. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/safety-step.tsx +110 -0
  237. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/struggle-step.tsx +139 -0
  238. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/welcome-step.tsx +217 -0
  239. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/ui/onboarding-header.tsx +58 -0
  240. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/constants.ts +179 -0
  241. package/recipes/onboarding/apps/native/src/features/onboarding/hooks/use-onboarding-analytics.ts +323 -0
  242. package/recipes/onboarding/apps/native/src/features/onboarding/services/onboarding-analytics.ts +432 -0
  243. package/recipes/onboarding/recipe.json +15 -0
  244. package/recipes/onboarding@latest.zip +0 -0
  245. package/recipes/payments/recipe.json +28 -61
  246. package/recipes/payments-supabase/apps/native/src/features/payments/README.md +200 -0
  247. package/recipes/payments-supabase/apps/native/src/features/payments/app/local-paywall.tsx +194 -0
  248. package/recipes/payments-supabase/apps/native/src/features/payments/app/remote-paywall.tsx +79 -0
  249. package/recipes/payments-supabase/apps/native/src/features/payments/components/payment-initializer.tsx +95 -0
  250. package/recipes/payments-supabase/apps/native/src/features/payments/components/paywall-error-state.tsx +60 -0
  251. package/recipes/payments-supabase/apps/native/src/features/payments/components/paywall-local-mode.tsx +116 -0
  252. package/recipes/payments-supabase/apps/native/src/features/payments/components/paywall-product-card.tsx +133 -0
  253. package/recipes/payments-supabase/apps/native/src/features/payments/components/paywall-remote-mode.tsx +146 -0
  254. package/recipes/payments-supabase/apps/native/src/features/payments/hooks/use-entitlement.ts +63 -0
  255. package/recipes/payments-supabase/apps/native/src/features/payments/index.ts +8 -0
  256. package/recipes/payments-supabase/apps/native/src/features/payments/services/revenuecat-adapter.ts +407 -0
  257. package/recipes/payments-supabase/packages/backend/src/services/payments.ts +201 -0
  258. package/recipes/payments-supabase/packages/backend/supabase/migrations/payments.sql +35 -0
  259. package/recipes/payments-supabase/recipe.json +51 -0
  260. package/recipes/payments-supabase@latest.zip +0 -0
  261. package/recipes/payments@latest.zip +0 -0
  262. package/recipes/quiz/apps/native/src/features/quiz/index.tsx +1 -2
  263. package/recipes/quiz/recipe.json +6 -9
  264. package/recipes/quiz@latest.zip +0 -0
  265. package/recipes/tracker-app/apps/native/src/features/tracker-app/app/index.tsx +1 -2
  266. package/recipes/tracker-app/recipe.json +7 -10
  267. package/recipes/tracker-app@latest.zip +0 -0
  268. package/recipes/voice-bot/recipe.json +8 -68
  269. package/recipes/voice-bot.zip +0 -0
  270. package/recipes/voice-bot@latest.zip +0 -0
  271. package/recipes/wake-word/recipe.json +10 -9
  272. package/recipes/wake-word.zip +0 -0
  273. package/recipes/wake-word@latest.zip +0 -0
  274. package/recipes/charts/apps/native/src/app/(root)/(protected)/charts/index.tsx +0 -3
  275. package/recipes/chatbot/packages/backend/convex/lib/rateLimit.ts +0 -100
  276. package/recipes/chatbot/packages/backend/convex/lib/telemetry.ts +0 -29
  277. package/recipes/chatbot/packages/backend/convex/ragKnowledge.ts +0 -0
  278. package/recipes/image-analysis/apps/native/assets/features/image-analyzer/front.jpg +0 -0
  279. package/recipes/image-analysis/apps/native/assets/features/image-analyzer/side.jpg +0 -0
  280. package/recipes/image-analysis/apps/native/assets/features/image-analyzer/threeQuarter.jpg +0 -0
  281. package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/_layout.tsx +0 -5
  282. package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/analysis-options.tsx +0 -50
  283. package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/camera.tsx +0 -2
  284. package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/index.tsx +0 -50
  285. package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/loading.tsx +0 -50
  286. package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/results.tsx +0 -2
  287. package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/trait-details.tsx +0 -3
  288. package/recipes/image-analysis/packages/backend/convex/imageAnalysisFunctions.ts +0 -325
  289. package/recipes/image-analysis/packages/backend/convex/lib/ai/imageAnalysisAdapter.ts +0 -200
  290. package/recipes/payments/apps/native/src/app/(root)/(protected)/paywall/index.tsx +0 -74
  291. package/recipes/payments/apps/native/src/app/(root)/(protected)/paywall/local.tsx +0 -25
  292. package/recipes/payments/apps/native/src/app/(root)/(protected)/paywall/remote.tsx +0 -23
  293. package/recipes/quiz/apps/native/src/app/(root)/(protected)/quiz/index.tsx +0 -47
  294. package/recipes/tracker-app/apps/native/src/app/(root)/(protected)/tracker-app/index.tsx +0 -1
  295. package/recipes/voice-bot/apps/native/src/app/(root)/(protected)/voice-bot/index.tsx +0 -27
  296. package/recipes/voice-bot/packages/backend/convex/router.ts +0 -81
  297. /package/recipes/{chatbot/apps/native/src/app/(root)/(protected) → chatbot-supabase/apps/native/src/app}/chatbot/index.tsx +0 -0
  298. /package/recipes/{image-generator/apps/native/src/app/(root)/(protected) → image-generator-supabase/apps/native/src/app}/image-generator/gallery.tsx +0 -0
  299. /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
+ };
@@ -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'];
@@ -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
+ }