vibefast-cli 1.1.3 → 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 (300) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +63 -169
  3. package/dist/__tests__/recipes.test.js +25 -3
  4. package/dist/__tests__/recipes.test.js.map +1 -1
  5. package/dist/commands/add.d.ts +1 -1
  6. package/dist/commands/add.d.ts.map +1 -1
  7. package/dist/commands/add.js +547 -543
  8. package/dist/commands/add.js.map +1 -1
  9. package/dist/commands/checklist.d.ts +1 -1
  10. package/dist/commands/checklist.d.ts.map +1 -1
  11. package/dist/commands/checklist.js +40 -39
  12. package/dist/commands/checklist.js.map +1 -1
  13. package/dist/commands/doctor.d.ts +1 -1
  14. package/dist/commands/doctor.js +22 -22
  15. package/dist/commands/doctor.js.map +1 -1
  16. package/dist/commands/env.d.ts +1 -1
  17. package/dist/commands/env.d.ts.map +1 -1
  18. package/dist/commands/env.js +58 -53
  19. package/dist/commands/env.js.map +1 -1
  20. package/dist/commands/health.d.ts +1 -1
  21. package/dist/commands/health.d.ts.map +1 -1
  22. package/dist/commands/health.js +101 -93
  23. package/dist/commands/health.js.map +1 -1
  24. package/dist/commands/init.d.ts +1 -1
  25. package/dist/commands/init.d.ts.map +1 -1
  26. package/dist/commands/init.js +416 -296
  27. package/dist/commands/init.js.map +1 -1
  28. package/dist/commands/remove.d.ts +1 -1
  29. package/dist/commands/remove.d.ts.map +1 -1
  30. package/dist/commands/remove.js +77 -64
  31. package/dist/commands/remove.js.map +1 -1
  32. package/dist/commands/status.d.ts +1 -1
  33. package/dist/commands/status.d.ts.map +1 -1
  34. package/dist/commands/status.js +15 -14
  35. package/dist/commands/status.js.map +1 -1
  36. package/dist/core/__tests__/detect.test.js +68 -34
  37. package/dist/core/__tests__/detect.test.js.map +1 -1
  38. package/dist/core/ast.d.ts +14 -0
  39. package/dist/core/ast.d.ts.map +1 -0
  40. package/dist/core/ast.js +239 -0
  41. package/dist/core/ast.js.map +1 -0
  42. package/dist/core/codemod.d.ts.map +1 -1
  43. package/dist/core/codemod.js +62 -44
  44. package/dist/core/codemod.js.map +1 -1
  45. package/dist/core/config.d.ts +10 -0
  46. package/dist/core/config.d.ts.map +1 -0
  47. package/dist/core/config.js +51 -0
  48. package/dist/core/config.js.map +1 -0
  49. package/dist/core/detect.d.ts +8 -2
  50. package/dist/core/detect.d.ts.map +1 -1
  51. package/dist/core/detect.js +52 -21
  52. package/dist/core/detect.js.map +1 -1
  53. package/dist/core/errors.d.ts.map +1 -1
  54. package/dist/core/errors.js +9 -8
  55. package/dist/core/errors.js.map +1 -1
  56. package/dist/core/exec.d.ts +16 -0
  57. package/dist/core/exec.d.ts.map +1 -0
  58. package/dist/core/exec.js +48 -0
  59. package/dist/core/exec.js.map +1 -0
  60. package/dist/core/manualSteps.d.ts +7 -0
  61. package/dist/core/manualSteps.d.ts.map +1 -0
  62. package/dist/core/manualSteps.js +59 -0
  63. package/dist/core/manualSteps.js.map +1 -0
  64. package/dist/core/paths.d.ts +3 -1
  65. package/dist/core/paths.d.ts.map +1 -1
  66. package/dist/core/paths.js +14 -10
  67. package/dist/core/paths.js.map +1 -1
  68. package/dist/core/spinner.d.ts +1 -1
  69. package/dist/core/spinner.d.ts.map +1 -1
  70. package/dist/core/spinner.js +38 -8
  71. package/dist/core/spinner.js.map +1 -1
  72. package/dist/core/vosk.d.ts.map +1 -1
  73. package/dist/core/vosk.js +50 -39
  74. package/dist/core/vosk.js.map +1 -1
  75. package/docs/manual-testing.md +91 -0
  76. package/package.json +6 -3
  77. package/recipes/audio-recorder/apps/native/src/app/audio-recorder/index.tsx +5 -0
  78. package/recipes/audio-recorder/recipe.json +3 -3
  79. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/components/audio-player.tsx +301 -0
  80. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/components/audio-recorder.tsx +373 -0
  81. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/components/audio-waveform.tsx +270 -0
  82. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/components/index.ts +4 -0
  83. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/components/recording-list.tsx +89 -0
  84. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/audio-player-demo.tsx +66 -0
  85. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/audio-recorder-cloud.tsx +68 -0
  86. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/audio-recorder-interview.tsx +102 -0
  87. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/basic.tsx +27 -0
  88. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/index.ts +5 -0
  89. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/with-recording-list-demo.tsx +82 -0
  90. package/recipes/audio-recorder-supabase/packages/backend/src/services/recordings.ts +369 -0
  91. package/recipes/audio-recorder-supabase/packages/backend/supabase/migrations/recordings.sql +70 -0
  92. package/recipes/audio-recorder-supabase/recipe.json +35 -0
  93. package/recipes/audio-recorder-supabase@latest.zip +0 -0
  94. package/recipes/audio-recorder@latest.zip +0 -0
  95. package/recipes/charts/apps/native/src/features/charts/components/bar-chart.tsx +3 -3
  96. package/recipes/charts/apps/native/src/features/charts/components/candlestick-chart.tsx +2 -2
  97. package/recipes/charts/apps/native/src/features/charts/components/chart-card.tsx +5 -5
  98. package/recipes/charts/apps/native/src/features/charts/components/column-chart.tsx +3 -3
  99. package/recipes/charts/apps/native/src/features/charts/components/doughnut-chart.tsx +20 -4
  100. package/recipes/charts/apps/native/src/features/charts/components/line-chart.tsx +7 -6
  101. package/recipes/charts/apps/native/src/features/charts/components/radar-chart.tsx +6 -4
  102. package/recipes/charts/apps/native/src/features/charts/components/radial-bar-chart.tsx +1 -1
  103. package/recipes/charts/apps/native/src/features/charts/components/stacked-bar-chart.tsx +5 -4
  104. package/recipes/charts/recipe.json +4 -13
  105. package/recipes/charts@latest.zip +0 -0
  106. package/recipes/chatbot/apps/native/src/app/chatbot/index.tsx +1 -0
  107. package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-markdown.tsx +86 -86
  108. package/recipes/chatbot/apps/native/src/features/chatbot/components/markdown/code-block.tsx +86 -53
  109. package/recipes/chatbot/recipe.json +26 -92
  110. package/recipes/chatbot-supabase/apps/native/src/api-client/supabase/chatbot.ts +515 -0
  111. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/app/index.tsx +257 -0
  112. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/chat-header-buttons.tsx +59 -0
  113. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/chat-input-bar.tsx +485 -0
  114. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/chat-markdown.tsx +575 -0
  115. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/chat-message-bubble.tsx +223 -0
  116. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/chat-settings-modal.tsx +161 -0
  117. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/image-preview-list.tsx +116 -0
  118. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/markdown/code-block.tsx +165 -0
  119. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/markdown/index.ts +10 -0
  120. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/markdown/table-renderer.tsx +129 -0
  121. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/message-error-boundary.tsx +78 -0
  122. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/message-list.tsx +170 -0
  123. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/model-selector.tsx +283 -0
  124. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/report-content-modal.tsx +188 -0
  125. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/suggested-messages.tsx +67 -0
  126. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/constants/models.ts +20 -0
  127. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/constants/report-reasons.ts +9 -0
  128. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-attachment-cache.ts +142 -0
  129. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-chat-config.ts +458 -0
  130. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-chat-handlers.ts +429 -0
  131. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-chatbot-settings.ts +89 -0
  132. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-conversation.ts +90 -0
  133. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-image-picker.ts +122 -0
  134. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-keyboard-coordinator.ts +161 -0
  135. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/hooks/use-smart-scroll-manager.ts +213 -0
  136. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/models/index.ts +86 -0
  137. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/models/models.ts +162 -0
  138. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/models/providers.ts +62 -0
  139. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/models/types.ts +40 -0
  140. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/services/file-uploader.ts +287 -0
  141. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/services/message-handler-service.ts +189 -0
  142. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/types/index.ts +70 -0
  143. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/utils/chat-telemetry.ts +91 -0
  144. package/recipes/chatbot-supabase/packages/backend/src/services/conversations.ts +243 -0
  145. package/recipes/chatbot-supabase/packages/backend/src/services/messages.ts +327 -0
  146. package/recipes/chatbot-supabase/packages/backend/supabase/functions/chat-stream/index.ts +347 -0
  147. package/recipes/chatbot-supabase/packages/backend/supabase/migrations/chatbot.sql +104 -0
  148. package/recipes/chatbot-supabase/recipe.json +79 -0
  149. package/recipes/chatbot-supabase@latest.zip +0 -0
  150. package/recipes/chatbot.zip +0 -0
  151. package/recipes/chatbot@latest.zip +0 -0
  152. package/recipes/image-analysis/packages/backend/convex/imageAnalysis/index.ts +2 -2
  153. package/recipes/image-analysis/packages/backend/convex/{imageAnalysisFunctions.ts → imageAnalysis.ts} +5 -5
  154. package/recipes/image-analysis/recipe.json +15 -55
  155. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/analysis-options-screen.tsx +304 -0
  156. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/camera.tsx +221 -0
  157. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/image-capture-screen.tsx +333 -0
  158. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/loading-screen.tsx +214 -0
  159. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/loading.tsx +191 -0
  160. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/results.tsx +137 -0
  161. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/trait-details.tsx +172 -0
  162. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/use-analysis-data.ts +160 -0
  163. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/app/use-results-screen.ts +151 -0
  164. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/achievement-badge.tsx +77 -0
  165. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/achievement-card.tsx +75 -0
  166. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/achievement-unlocked-modal.tsx +162 -0
  167. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/achievements-section.tsx +44 -0
  168. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/advice-list.tsx +42 -0
  169. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/circular-progress.tsx +233 -0
  170. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/content-card.tsx +38 -0
  171. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/error-state.tsx +42 -0
  172. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/index.ts +9 -0
  173. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/loading-state.tsx +26 -0
  174. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/profile-image.tsx +60 -0
  175. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/results-header.tsx +62 -0
  176. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/score-display.tsx +54 -0
  177. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/share-options-modal.tsx +110 -0
  178. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/components/results/traits-grid.tsx +74 -0
  179. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/config/analysis-config.ts +80 -0
  180. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/config/master-analysis-config.ts +157 -0
  181. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/hooks/index.ts +1 -0
  182. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/hooks/use-analysis.ts +38 -0
  183. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/hooks/use-image-analysis.ts +208 -0
  184. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/services/analysis-service.ts +262 -0
  185. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/services/share-service.ts +176 -0
  186. package/recipes/image-analysis-supabase/apps/native/src/features/image-analyzer/services/trait-details-service.ts +289 -0
  187. package/recipes/image-analysis-supabase/packages/backend/src/services/image-analyses.ts +132 -0
  188. package/recipes/image-analysis-supabase/packages/backend/supabase/functions/analyze-image/index.ts +312 -0
  189. package/recipes/image-analysis-supabase/packages/backend/supabase/migrations/image_analysis.sql +42 -0
  190. package/recipes/image-analysis-supabase/recipe.json +57 -0
  191. package/recipes/image-analysis-supabase@latest.zip +0 -0
  192. package/recipes/image-analysis@latest.zip +0 -0
  193. package/recipes/image-generator/apps/native/src/features/image-generator/app/index.tsx +16 -2
  194. package/recipes/image-generator/apps/native/src/features/image-generator/components/image-model-selector.tsx +11 -5
  195. package/recipes/image-generator/apps/native/src/features/image-generator/hooks/use-image-generator.ts +11 -5
  196. package/recipes/image-generator/packages/backend/convex/imageGeneration/index.ts +2 -2
  197. package/recipes/image-generator/recipe.json +16 -39
  198. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/app/_layout.tsx +26 -0
  199. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/app/gallery.tsx +217 -0
  200. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/app/index.tsx +251 -0
  201. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/components/gallery-image.tsx +25 -0
  202. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/components/image-detail-modal.tsx +215 -0
  203. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/components/image-model-selector.tsx +216 -0
  204. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/components/image-placeholder.tsx +26 -0
  205. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/hooks/use-image-gallery.ts +71 -0
  206. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/hooks/use-image-generator-settings.ts +152 -0
  207. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/hooks/use-image-generator.ts +103 -0
  208. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/models/models.ts +66 -0
  209. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/services/image-gallery-service.ts +96 -0
  210. package/recipes/image-generator-supabase/apps/native/src/features/image-generator/services/image-save-service.ts +120 -0
  211. package/recipes/image-generator-supabase/packages/backend/supabase/functions/generate-image/index.ts +291 -0
  212. package/recipes/image-generator-supabase/packages/backend/supabase/migrations/image_generator.sql +71 -0
  213. package/recipes/image-generator-supabase/recipe.json +59 -0
  214. package/recipes/image-generator-supabase@latest.zip +0 -0
  215. package/recipes/image-generator@latest.zip +0 -0
  216. package/recipes/ios-widget/recipe.json +15 -24
  217. package/recipes/ios-widget@latest.zip +0 -0
  218. package/recipes/onboarding/apps/native/src/features/onboarding/analytics/index.ts +9 -0
  219. package/recipes/onboarding/apps/native/src/features/onboarding/components/onboarding-with-analytics.tsx +141 -0
  220. package/recipes/onboarding/apps/native/src/features/onboarding/components/onboarding.tsx +173 -0
  221. package/recipes/onboarding/apps/native/src/features/onboarding/config/onboarding-flow-config.ts +189 -0
  222. package/recipes/onboarding/apps/native/src/features/onboarding/demo-one/app/index.tsx +42 -0
  223. package/recipes/onboarding/apps/native/src/features/onboarding/demo-one/data.ts +32 -0
  224. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/app/index.tsx +43 -0
  225. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/interactive-onboarding.tsx +222 -0
  226. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/ai-tone-step.tsx +133 -0
  227. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/currency-step.tsx +165 -0
  228. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-ai-step.tsx +199 -0
  229. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-chatbot-step.tsx +154 -0
  230. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-manual-step.tsx +156 -0
  231. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-scan-step.tsx +158 -0
  232. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/main-reason-step.tsx +139 -0
  233. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/notification-step.tsx +129 -0
  234. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/overspend-step.tsx +138 -0
  235. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/personalizing-step.tsx +190 -0
  236. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/rating-step.tsx +98 -0
  237. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/reminder-step.tsx +181 -0
  238. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/safety-step.tsx +110 -0
  239. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/struggle-step.tsx +139 -0
  240. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/welcome-step.tsx +217 -0
  241. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/ui/onboarding-header.tsx +58 -0
  242. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/constants.ts +179 -0
  243. package/recipes/onboarding/apps/native/src/features/onboarding/hooks/use-onboarding-analytics.ts +323 -0
  244. package/recipes/onboarding/apps/native/src/features/onboarding/services/onboarding-analytics.ts +432 -0
  245. package/recipes/onboarding/recipe.json +15 -0
  246. package/recipes/onboarding@latest.zip +0 -0
  247. package/recipes/payments/recipe.json +28 -61
  248. package/recipes/payments-supabase/apps/native/src/features/payments/README.md +200 -0
  249. package/recipes/payments-supabase/apps/native/src/features/payments/app/local-paywall.tsx +194 -0
  250. package/recipes/payments-supabase/apps/native/src/features/payments/app/remote-paywall.tsx +79 -0
  251. package/recipes/payments-supabase/apps/native/src/features/payments/components/payment-initializer.tsx +95 -0
  252. package/recipes/payments-supabase/apps/native/src/features/payments/components/paywall-error-state.tsx +60 -0
  253. package/recipes/payments-supabase/apps/native/src/features/payments/components/paywall-local-mode.tsx +116 -0
  254. package/recipes/payments-supabase/apps/native/src/features/payments/components/paywall-product-card.tsx +133 -0
  255. package/recipes/payments-supabase/apps/native/src/features/payments/components/paywall-remote-mode.tsx +146 -0
  256. package/recipes/payments-supabase/apps/native/src/features/payments/hooks/use-entitlement.ts +63 -0
  257. package/recipes/payments-supabase/apps/native/src/features/payments/index.ts +8 -0
  258. package/recipes/payments-supabase/apps/native/src/features/payments/services/revenuecat-adapter.ts +407 -0
  259. package/recipes/payments-supabase/packages/backend/src/services/payments.ts +201 -0
  260. package/recipes/payments-supabase/packages/backend/supabase/migrations/payments.sql +35 -0
  261. package/recipes/payments-supabase/recipe.json +51 -0
  262. package/recipes/payments-supabase@latest.zip +0 -0
  263. package/recipes/payments@latest.zip +0 -0
  264. package/recipes/quiz/apps/native/src/features/quiz/index.tsx +1 -2
  265. package/recipes/quiz/recipe.json +6 -9
  266. package/recipes/quiz@latest.zip +0 -0
  267. package/recipes/tracker-app/apps/native/src/features/tracker-app/app/index.tsx +1 -2
  268. package/recipes/tracker-app/recipe.json +7 -10
  269. package/recipes/tracker-app@latest.zip +0 -0
  270. package/recipes/voice-bot/recipe.json +8 -68
  271. package/recipes/voice-bot.zip +0 -0
  272. package/recipes/voice-bot@latest.zip +0 -0
  273. package/recipes/wake-word/recipe.json +10 -9
  274. package/recipes/wake-word.zip +0 -0
  275. package/recipes/wake-word@latest.zip +0 -0
  276. package/recipes/charts/apps/native/src/app/(root)/(protected)/charts/index.tsx +0 -3
  277. package/recipes/chatbot/packages/backend/convex/lib/rateLimit.ts +0 -100
  278. package/recipes/chatbot/packages/backend/convex/lib/telemetry.ts +0 -29
  279. package/recipes/chatbot/packages/backend/convex/ragKnowledge.ts +0 -0
  280. package/recipes/image-analysis/apps/native/assets/features/image-analyzer/front.jpg +0 -0
  281. package/recipes/image-analysis/apps/native/assets/features/image-analyzer/side.jpg +0 -0
  282. package/recipes/image-analysis/apps/native/assets/features/image-analyzer/threeQuarter.jpg +0 -0
  283. package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/_layout.tsx +0 -5
  284. package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/analysis-options.tsx +0 -50
  285. package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/camera.tsx +0 -2
  286. package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/index.tsx +0 -50
  287. package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/loading.tsx +0 -50
  288. package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/results.tsx +0 -2
  289. package/recipes/image-analysis/apps/native/src/app/(root)/(protected)/analysis/[type]/trait-details.tsx +0 -3
  290. package/recipes/image-analysis/packages/backend/convex/lib/ai/imageAnalysisAdapter.ts +0 -200
  291. package/recipes/payments/apps/native/src/app/(root)/(protected)/paywall/index.tsx +0 -74
  292. package/recipes/payments/apps/native/src/app/(root)/(protected)/paywall/local.tsx +0 -25
  293. package/recipes/payments/apps/native/src/app/(root)/(protected)/paywall/remote.tsx +0 -23
  294. package/recipes/quiz/apps/native/src/app/(root)/(protected)/quiz/index.tsx +0 -47
  295. package/recipes/tracker-app/apps/native/src/app/(root)/(protected)/tracker-app/index.tsx +0 -1
  296. package/recipes/voice-bot/apps/native/src/app/(root)/(protected)/voice-bot/index.tsx +0 -27
  297. package/recipes/voice-bot/packages/backend/convex/router.ts +0 -81
  298. /package/recipes/{chatbot/apps/native/src/app/(root)/(protected) → chatbot-supabase/apps/native/src/app}/chatbot/index.tsx +0 -0
  299. /package/recipes/{image-generator/apps/native/src/app/(root)/(protected) → image-generator-supabase/apps/native/src/app}/image-generator/gallery.tsx +0 -0
  300. /package/recipes/{image-generator/apps/native/src/app/(root)/(protected) → image-generator-supabase/apps/native/src/app}/image-generator/index.tsx +0 -0
@@ -1,200 +0,0 @@
1
- 'use node';
2
-
3
- import { createGoogleGenerativeAI } from '@ai-sdk/google';
4
- import { createOpenAI } from '@ai-sdk/openai';
5
- import { generateObject } from 'ai';
6
-
7
- import { getAnalysisConfig } from './analysisConfigs';
8
- import { type AIProvider, getAIConfig } from './config';
9
-
10
- /**
11
- * Generic analysis result type
12
- */
13
- export type GenericAnalysisResult = {
14
- overallScore: number;
15
- overallMessage: string;
16
- confidence: number;
17
- traitScores: Record<
18
- string,
19
- {
20
- score: number;
21
- feedback: string;
22
- strengths: string[];
23
- improvements: string[];
24
- }
25
- >;
26
- recommendations: string[];
27
- analysisType: string;
28
- processingTime: number;
29
- };
30
-
31
- /**
32
- * Truncate an oversized base64 string while preserving a valid encoding.
33
- *
34
- * Base64 strings must have a length that is a multiple of 4 and must end with
35
- * optional padding characters ("="). A naive substring can break the encoding
36
- * and lead to downstream "unsupported image" errors from the OpenAI API. This
37
- * helper trims the string **only** when it exceeds the chosen limit and always
38
- * rounds the length down to the nearest multiple of 4 to keep the data valid.
39
- *
40
- * NOTE: The client already compresses/resize images before upload, so the limit
41
- * here is intentionally generous (4 MB of base64 text ≈ 3 MB binary). This
42
- * should fit within OpenAI's 30 MB image cap while safeguarding Convex memory.
43
- */
44
- function optimizeImageForMemory(base64: string): string {
45
- const MAX_CHARS = 4 * 1024 * 1024; // 4 MB worth of base64 characters
46
-
47
- if (base64.length <= MAX_CHARS) {
48
- return base64;
49
- }
50
-
51
- console.log(
52
- `[Memory Optimization] Truncating image from ${base64.length} to ${MAX_CHARS} chars (safe multiple-of-4)`,
53
- );
54
-
55
- // Round down to nearest multiple of 4 to preserve base64 integrity
56
- const safeLength = MAX_CHARS - (MAX_CHARS % 4);
57
- const truncated = base64.substring(0, safeLength);
58
-
59
- // Ensure proper padding – if the truncated string ends with partial padding
60
- // remove it and re-append correct padding.
61
- const withoutPartialPad = truncated.replace(/=+$/, '');
62
- const padNeeded = (4 - (withoutPartialPad.length % 4)) % 4;
63
- return withoutPartialPad + '='.repeat(padNeeded);
64
- }
65
-
66
- /**
67
- * Generate structured analysis using AI SDK (generic for any analysis type)
68
- */
69
- export async function generateImageAnalysis(
70
- imagesAsBase64: string[],
71
- preferences: {
72
- goal: string;
73
- feedbackStyle: string;
74
- },
75
- analysisConfigId = 'face_analysis',
76
- ): Promise<GenericAnalysisResult> {
77
- const config = getAIConfig();
78
- const analysisConfig = getAnalysisConfig(analysisConfigId);
79
- const startTime = Date.now();
80
-
81
- // Memory optimization: Limit to max 3 images and optimize them
82
- const maxImages = 3;
83
- const optimizedImages = imagesAsBase64
84
- .slice(0, maxImages)
85
- .map(optimizeImageForMemory);
86
-
87
- console.log(
88
- `[Memory Optimization] Processing ${optimizedImages.length} images (max ${maxImages})`,
89
- );
90
-
91
- // Create the appropriate AI provider
92
- const provider = createAIProvider(config.provider);
93
- const model = provider(config.model);
94
-
95
- // Build a simpler, shorter prompt to reduce memory usage
96
- const prompt = buildOptimizedPrompt(
97
- analysisConfig,
98
- preferences,
99
- optimizedImages.length,
100
- );
101
-
102
- // Convert base64 images to the format expected by AI SDK
103
- const imageMessages = optimizedImages.map((base64) => ({
104
- type: 'image' as const,
105
- image: `data:image/jpeg;base64,${base64}`,
106
- }));
107
-
108
- try {
109
- // Generate structured output using AI SDK with reduced complexity
110
- const { object } = await generateObject({
111
- model,
112
- schema: analysisConfig.schema,
113
- messages: [
114
- {
115
- role: 'user',
116
- content: [{ type: 'text', text: prompt }, ...imageMessages],
117
- },
118
- ],
119
- temperature: config.temperature,
120
- maxTokens: Math.min(config.maxTokens, 2000), // Reduce max tokens to save memory
121
- });
122
-
123
- // Add processing metadata
124
- const processingTime = Date.now() - startTime;
125
- return {
126
- ...object,
127
- processingTime,
128
- analysisType: `${analysisConfigId}_${preferences.goal}_${preferences.feedbackStyle}`,
129
- } as GenericAnalysisResult;
130
- } catch (error) {
131
- console.error('Error generating analysis:', error);
132
- throw new Error(
133
- `Failed to generate analysis: ${error instanceof Error ? error.message : 'Unknown error'}`,
134
- );
135
- }
136
- }
137
-
138
- /**
139
- * Build optimized, shorter prompt to reduce memory usage
140
- */
141
- function buildOptimizedPrompt(
142
- analysisConfig: any,
143
- preferences: { goal: string; feedbackStyle: string },
144
- imageCount: number,
145
- ): string {
146
- const traitNames = Object.keys(analysisConfig.traits).slice(0, 6); // Limit traits to reduce complexity
147
-
148
- return `Analyze the ${imageCount} image(s) for ${analysisConfig.name.toLowerCase()}.
149
-
150
- Goal: ${preferences.goal}
151
- Style: ${preferences.feedbackStyle}
152
-
153
- Provide scores (0-100) and feedback for: ${traitNames.join(', ')}.
154
-
155
- Include:
156
- - Overall score and message
157
- - Individual trait scores with feedback
158
- - 2-3 recommendations
159
- - Confidence level (0-1)
160
-
161
- Be concise and ${preferences.feedbackStyle}.`;
162
- }
163
-
164
- /**
165
- * Legacy function for backward compatibility (face analysis)
166
- * @deprecated Use generateImageAnalysis instead
167
- */
168
- export async function generateFacialAnalysis(
169
- imagesAsBase64: string[],
170
- preferences: {
171
- goal: string;
172
- feedbackStyle: string;
173
- },
174
- ): Promise<GenericAnalysisResult> {
175
- return generateImageAnalysis(imagesAsBase64, preferences, 'face_analysis');
176
- }
177
-
178
- /**
179
- * Create AI provider based on configuration
180
- */
181
- function createAIProvider(provider: AIProvider) {
182
- switch (provider) {
183
- case 'openai': {
184
- const apiKey = process.env.OPENAI_API_KEY;
185
- if (!apiKey) {
186
- throw new Error('OPENAI_API_KEY environment variable is required');
187
- }
188
- return createOpenAI({ apiKey });
189
- }
190
- case 'gemini': {
191
- const apiKey = process.env.GEMINI_API_KEY;
192
- if (!apiKey) {
193
- throw new Error('GEMINI_API_KEY environment variable is required');
194
- }
195
- return createGoogleGenerativeAI({ apiKey });
196
- }
197
- default:
198
- throw new Error(`Unsupported AI provider: ${provider}`);
199
- }
200
- }
@@ -1,74 +0,0 @@
1
- import { router, Stack } from 'expo-router';
2
- import React, { useMemo } from 'react';
3
- import { ScrollView, View } from 'react-native';
4
-
5
- import { FeatureButton, FocusAwareStatusBar } from '@/components/ui';
6
- import { translate } from '@/lib';
7
- import { useThemeConfig } from '@/lib/use-theme-config';
8
-
9
- export default function PaywallSelection() {
10
- const theme = useThemeConfig();
11
- const optionsTitle = translate('paywall.options_title');
12
- const screenOptions = useMemo(
13
- () => ({
14
- title: optionsTitle,
15
- headerShown: true,
16
- headerBackButtonDisplayMode: 'generic' as const,
17
- }),
18
- [optionsTitle],
19
- );
20
-
21
- const paywallOptions = [
22
- {
23
- id: 'remote',
24
- title: translate('paywall.remote_title'),
25
- icon: '💳',
26
- color: '#FBBF24', // Amber
27
- description: translate('paywall.remote_description'),
28
- route: '/paywall/remote',
29
- testID: 'remote-paywall-option',
30
- },
31
- {
32
- id: 'local',
33
- title: translate('paywall.local_title'),
34
- icon: '🛒',
35
- color: '#10B981', // Emerald
36
- description: translate('paywall.local_description'),
37
- route: '/paywall/local',
38
- testID: 'local-paywall-option',
39
- },
40
- ];
41
-
42
- const handleOptionPress = (route: string) => {
43
- router.push(route as any);
44
- };
45
-
46
- return (
47
- <>
48
- <FocusAwareStatusBar />
49
- <Stack.Screen options={screenOptions} />
50
- <ScrollView
51
- style={{ backgroundColor: theme.colors.background }}
52
- className="flex-1"
53
- showsVerticalScrollIndicator={false}
54
- >
55
- <View className="px-6 py-8">
56
- <View className="-mx-2 flex-row flex-wrap">
57
- {paywallOptions.map((option) => (
58
- <View key={option.id} className="w-1/2 px-2 pb-4">
59
- <FeatureButton
60
- title={option.title}
61
- icon={option.icon}
62
- color={option.color}
63
- description={option.description}
64
- testID={option.testID}
65
- onPress={() => handleOptionPress(option.route)}
66
- />
67
- </View>
68
- ))}
69
- </View>
70
- </View>
71
- </ScrollView>
72
- </>
73
- );
74
- }
@@ -1,25 +0,0 @@
1
- import { Stack } from 'expo-router';
2
- import React, { useMemo } from 'react';
3
-
4
- import LocalPaywall from '@/features/payments/app/local-paywall';
5
- import { RevenueCatAdapter } from '@/features/payments/services/revenuecat-adapter';
6
- import { translate } from '@/lib';
7
-
8
- export default function LocalPaywallScreen() {
9
- const paymentService = useMemo(() => new RevenueCatAdapter(), []);
10
- const localTitle = translate('paywall.local_title');
11
- const screenOptions = useMemo(
12
- () => ({
13
- title: localTitle,
14
- headerShown: false,
15
- }),
16
- [localTitle],
17
- );
18
-
19
- return (
20
- <>
21
- <Stack.Screen options={screenOptions} />
22
- <LocalPaywall paymentService={paymentService} />
23
- </>
24
- );
25
- }
@@ -1,23 +0,0 @@
1
- import { Stack } from 'expo-router';
2
- import React, { useMemo } from 'react';
3
-
4
- import RemotePaywall from '@/features/payments/app/remote-paywall';
5
- import { translate } from '@/lib';
6
-
7
- export default function RemotePaywallScreen() {
8
- const remoteTitle = translate('paywall.remote_title');
9
- const screenOptions = useMemo(
10
- () => ({
11
- title: remoteTitle,
12
- headerShown: true,
13
- }),
14
- [remoteTitle],
15
- );
16
-
17
- return (
18
- <>
19
- <Stack.Screen options={screenOptions} />
20
- <RemotePaywall />
21
- </>
22
- );
23
- }
@@ -1,47 +0,0 @@
1
- import Quiz from '@/features/quiz';
2
- import { QuestionMode } from '@/features/quiz/config';
3
-
4
- const questions = [
5
- {
6
- text: 'What is your favorite color?',
7
- mode: QuestionMode.AutoAdvance,
8
- options: [
9
- { id: 'red', text: 'Red', note: 'Red is the color of passion.' },
10
- { id: 'blue', text: 'Blue', note: 'Blue is the color of calm.' },
11
- { id: 'green', text: 'Green', note: 'Green is the color of nature.' },
12
- ],
13
- },
14
- {
15
- text: 'What is your favorite animal?',
16
- mode: QuestionMode.ManualAdvance,
17
- options: [
18
- { id: 'dog', text: 'Dog', note: 'Dogs are loyal.' },
19
- { id: 'cat', text: 'Cat', note: 'Cats are independent.' },
20
- { id: 'bird', text: 'Bird', note: 'Birds can fly.' },
21
- ],
22
- },
23
- {
24
- text: 'What is your favorite animal?',
25
- mode: QuestionMode.ManualAdvance,
26
- options: [
27
- { id: 'dog', text: 'Dog', note: 'Dogs are loyal.' },
28
- { id: 'cat', text: 'Cat', note: 'Cats are independent.' },
29
- { id: 'bird', text: 'Bird', note: 'Birds can fly.' },
30
- ],
31
- },
32
- {
33
- text: 'What is your favorite animal?',
34
- mode: QuestionMode.ManualAdvance,
35
- options: [
36
- { id: 'dog', text: 'Dog', note: 'Dogs are loyal.' },
37
- { id: 'cat', text: 'Cat', note: 'Cats are independent.' },
38
- { id: 'bird', text: 'Bird', note: 'Birds can fly.' },
39
- ],
40
- },
41
- ];
42
-
43
- const QuizScreen = () => {
44
- return <Quiz questions={questions} />;
45
- };
46
-
47
- export default QuizScreen;
@@ -1 +0,0 @@
1
- export { default } from '@/features/tracker-app/app';
@@ -1,27 +0,0 @@
1
- import { Env } from '@env';
2
- import { Stack } from 'expo-router';
3
- import React, { useMemo } from 'react';
4
-
5
- import { VoiceBotScreen } from '@/features/voice-bot';
6
-
7
- export default function VoiceBotRoute() {
8
- const agentId = Env.ELEVENLABS_AGENT_ID;
9
- const screenOptions = useMemo(
10
- () => ({
11
- title: 'Voice Assistant',
12
- headerShown: true,
13
- }),
14
- [],
15
- );
16
-
17
- return (
18
- <>
19
- <Stack.Screen options={screenOptions} />
20
- <VoiceBotScreen
21
- config={{ agentId }}
22
- title="Voice Assistant"
23
- subtitle="Start a conversation with your AI assistant"
24
- />
25
- </>
26
- );
27
- }
@@ -1,81 +0,0 @@
1
- import { httpRouter } from 'convex/server';
2
-
3
- import { httpAction } from './_generated/server';
4
-
5
- const http = httpRouter();
6
-
7
- const ELEVENLABS_TOKEN_ENDPOINT =
8
- 'https://api.elevenlabs.io/v1/convai/conversation/token';
9
-
10
- const fetchElevenLabsConversationToken = httpAction(
11
- async (_ctx, request): Promise<Response> => {
12
- const apiKey = process.env.ELEVENLABS_API_KEY;
13
- if (!apiKey) {
14
- return new Response(
15
- JSON.stringify({
16
- error: 'ELEVENLABS_API_KEY is not configured on the backend',
17
- }),
18
- {
19
- status: 500,
20
- headers: { 'content-type': 'application/json' },
21
- },
22
- );
23
- }
24
-
25
- const url = new URL(request.url);
26
- const agentId = url.searchParams.get('agent_id');
27
- if (!agentId) {
28
- return new Response(
29
- JSON.stringify({ error: 'agent_id query parameter is required' }),
30
- {
31
- status: 400,
32
- headers: { 'content-type': 'application/json' },
33
- },
34
- );
35
- }
36
-
37
- const upstreamUrl = new URL(ELEVENLABS_TOKEN_ENDPOINT);
38
- url.searchParams.forEach((value, key) => {
39
- upstreamUrl.searchParams.set(key, value);
40
- });
41
-
42
- try {
43
- const upstreamResponse = await fetch(upstreamUrl, {
44
- method: 'GET',
45
- headers: {
46
- 'xi-api-key': apiKey,
47
- accept: 'application/json',
48
- },
49
- });
50
-
51
- const payload = await upstreamResponse.text();
52
- return new Response(payload, {
53
- status: upstreamResponse.status,
54
- headers: {
55
- 'content-type':
56
- upstreamResponse.headers.get('content-type') || 'application/json',
57
- },
58
- });
59
- } catch (error) {
60
- console.error(
61
- '[voice.token] Failed to fetch ElevenLabs conversation token',
62
- error,
63
- );
64
- return new Response(
65
- JSON.stringify({ error: 'Failed to fetch ElevenLabs token' }),
66
- {
67
- status: 502,
68
- headers: { 'content-type': 'application/json' },
69
- },
70
- );
71
- }
72
- },
73
- );
74
-
75
- http.route({
76
- path: '/voice/conversation-token',
77
- method: 'GET',
78
- handler: fetchElevenLabsConversationToken,
79
- });
80
-
81
- export default http;