vibefast-cli 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (348) hide show
  1. package/README.md +30 -95
  2. package/dist/__tests__/recipes.test.js +8 -9
  3. package/dist/__tests__/recipes.test.js.map +1 -1
  4. package/dist/commands/add.d.ts.map +1 -1
  5. package/dist/commands/add.js +271 -125
  6. package/dist/commands/add.js.map +1 -1
  7. package/dist/commands/checklist.d.ts.map +1 -1
  8. package/dist/commands/checklist.js +85 -44
  9. package/dist/commands/checklist.js.map +1 -1
  10. package/dist/commands/health.d.ts.map +1 -1
  11. package/dist/commands/health.js +13 -4
  12. package/dist/commands/health.js.map +1 -1
  13. package/dist/commands/init.d.ts.map +1 -1
  14. package/dist/commands/init.js +118 -26
  15. package/dist/commands/init.js.map +1 -1
  16. package/dist/commands/migrate.d.ts +3 -0
  17. package/dist/commands/migrate.d.ts.map +1 -0
  18. package/dist/commands/migrate.js +202 -0
  19. package/dist/commands/migrate.js.map +1 -0
  20. package/dist/commands/remove.d.ts.map +1 -1
  21. package/dist/commands/remove.js +61 -3
  22. package/dist/commands/remove.js.map +1 -1
  23. package/dist/core/auth.d.ts.map +1 -1
  24. package/dist/core/auth.js +20 -18
  25. package/dist/core/auth.js.map +1 -1
  26. package/dist/core/codemod.d.ts +33 -0
  27. package/dist/core/codemod.d.ts.map +1 -1
  28. package/dist/core/codemod.js +116 -0
  29. package/dist/core/codemod.js.map +1 -1
  30. package/dist/core/detect.d.ts.map +1 -1
  31. package/dist/core/detect.js +24 -7
  32. package/dist/core/detect.js.map +1 -1
  33. package/dist/core/journal.d.ts +1 -0
  34. package/dist/core/journal.d.ts.map +1 -1
  35. package/dist/core/journal.js.map +1 -1
  36. package/dist/core/recipes.d.ts.map +1 -1
  37. package/dist/core/recipes.js +25 -7
  38. package/dist/core/recipes.js.map +1 -1
  39. package/dist/index.js +2 -2
  40. package/dist/index.js.map +1 -1
  41. package/docs/architecture.md +50 -0
  42. package/docs/commands.md +78 -0
  43. package/docs/contributing.md +27 -0
  44. package/docs/quickstart.md +50 -0
  45. package/docs/recipes.md +57 -0
  46. package/docs/troubleshooting.md +31 -0
  47. package/package.json +2 -2
  48. package/recipes/0/apps/native/src/components/advanced-ui/timeline/demo.tsx +445 -0
  49. package/recipes/0/apps/native/src/components/advanced-ui/timeline/timeline-view.tsx +355 -0
  50. package/recipes/0/apps/native/src/components/advanced-ui/timeline/types.ts +31 -0
  51. package/recipes/0/recipe.json +18 -0
  52. package/recipes/animated-chip/apps/native/src/components/advanced-ui/chip/demo.tsx +2 -1
  53. package/recipes/animated-chip/recipe.json +5 -2
  54. package/recipes/animated-chip-native@latest.zip +0 -0
  55. package/recipes/animated-chip@latest.zip +0 -0
  56. package/recipes/animated-switch/apps/native/src/components/advanced-ui/switch/demo.tsx +1 -1
  57. package/recipes/animated-switch/recipe.json +5 -2
  58. package/recipes/animated-switch-native@latest.zip +0 -0
  59. package/recipes/animated-switch@latest.zip +0 -0
  60. package/recipes/audio-recorder/apps/native/src/features/audio-recorder/components/audio-recorder.tsx +2 -1
  61. package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/with-recording-list-demo.tsx +2 -2
  62. package/recipes/audio-recorder/recipe.json +7 -2
  63. package/recipes/audio-recorder-native@latest.zip +0 -0
  64. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/components/audio-recorder.tsx +2 -1
  65. package/recipes/audio-recorder-supabase/apps/native/src/features/audio-recorder/demo/with-recording-list-demo.tsx +2 -1
  66. package/recipes/audio-recorder-supabase/recipe.json +12 -33
  67. package/recipes/audio-recorder-supabase-native@latest.zip +0 -0
  68. package/recipes/audio-recorder-supabase@latest.zip +0 -0
  69. package/recipes/audio-recorder@latest.zip +0 -0
  70. package/recipes/charts/apps/native/src/app/charts/index.tsx +3 -0
  71. package/recipes/charts/apps/native/src/features/charts/components/bar-chart.tsx +3 -1
  72. package/recipes/charts/apps/native/src/features/charts/components/candlestick-chart.tsx +3 -1
  73. package/recipes/charts/apps/native/src/features/charts/components/column-chart.tsx +3 -1
  74. package/recipes/charts/apps/native/src/features/charts/components/doughnut-chart.tsx +3 -1
  75. package/recipes/charts/apps/native/src/features/charts/components/line-chart.tsx +3 -1
  76. package/recipes/charts/apps/native/src/features/charts/components/radar-chart.tsx +3 -1
  77. package/recipes/charts/apps/native/src/features/charts/components/stacked-bar-chart.tsx +3 -1
  78. package/recipes/charts/recipe.json +13 -4
  79. package/recipes/charts-native@latest.zip +0 -0
  80. package/recipes/charts@latest.zip +0 -0
  81. package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-markdown.tsx +86 -86
  82. package/recipes/chatbot/apps/native/src/features/chatbot/components/markdown/code-block.tsx +4 -4
  83. package/recipes/chatbot/recipe.json +3 -40
  84. package/recipes/chatbot-native@latest.zip +0 -0
  85. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/chat-markdown.tsx +4 -1
  86. package/recipes/chatbot-supabase/apps/native/src/features/chatbot/components/markdown/code-block.tsx +86 -53
  87. package/recipes/chatbot-supabase/recipe.json +3 -69
  88. package/recipes/chatbot-supabase-native@latest.zip +0 -0
  89. package/recipes/chatbot-supabase@latest.zip +0 -0
  90. package/recipes/chatbot@latest.zip +0 -0
  91. package/recipes/glowing-button/recipe.json +6 -2
  92. package/recipes/glowing-button-native@latest.zip +0 -0
  93. package/recipes/glowing-button@latest.zip +0 -0
  94. package/recipes/image-analysis/apps/native/src/app/analysis/[type]/_layout.tsx +5 -0
  95. package/recipes/image-analysis/apps/native/src/app/analysis/[type]/analysis-options.tsx +50 -0
  96. package/recipes/image-analysis/apps/native/src/app/analysis/[type]/camera.tsx +2 -0
  97. package/recipes/image-analysis/apps/native/src/app/analysis/[type]/index.tsx +50 -0
  98. package/recipes/image-analysis/apps/native/src/app/analysis/[type]/loading.tsx +50 -0
  99. package/recipes/image-analysis/apps/native/src/app/analysis/[type]/results.tsx +2 -0
  100. package/recipes/image-analysis/apps/native/src/app/analysis/[type]/trait-details.tsx +3 -0
  101. package/recipes/image-analysis/apps/native/src/features/image-analyzer/app/analysis-options-screen.tsx +2 -2
  102. package/recipes/image-analysis/apps/native/src/features/image-analyzer/app/camera.tsx +72 -65
  103. package/recipes/image-analysis/apps/native/src/features/image-analyzer/app/image-capture-screen.tsx +65 -47
  104. package/recipes/image-analysis/apps/native/src/features/image-analyzer/app/loading-screen.tsx +43 -2
  105. package/recipes/image-analysis/apps/native/src/features/image-analyzer/app/loading.tsx +34 -1
  106. package/recipes/image-analysis/apps/native/src/features/image-analyzer/hooks/use-image-analysis.ts +83 -2
  107. package/recipes/image-analysis/recipe.json +11 -19
  108. package/recipes/image-analysis-native@latest.zip +0 -0
  109. package/recipes/image-analysis-supabase/apps/native/src/app/analysis/[type]/_layout.tsx +5 -0
  110. package/recipes/image-analysis-supabase/apps/native/src/app/analysis/[type]/analysis-options.tsx +50 -0
  111. package/recipes/image-analysis-supabase/apps/native/src/app/analysis/[type]/camera.tsx +2 -0
  112. package/recipes/image-analysis-supabase/apps/native/src/app/analysis/[type]/index.tsx +50 -0
  113. package/recipes/image-analysis-supabase/apps/native/src/app/analysis/[type]/loading.tsx +50 -0
  114. package/recipes/image-analysis-supabase/apps/native/src/app/analysis/[type]/results.tsx +2 -0
  115. package/recipes/image-analysis-supabase/apps/native/src/app/analysis/[type]/trait-details.tsx +3 -0
  116. package/recipes/image-analysis-supabase/recipe.json +10 -70
  117. package/recipes/image-analysis-supabase-native@latest.zip +0 -0
  118. package/recipes/image-analysis-supabase@latest.zip +0 -0
  119. package/recipes/image-analysis@latest.zip +0 -0
  120. package/recipes/image-analyzer/apps/native/src/app/(root)/(protected)/image-analyzer/index.tsx +2 -0
  121. package/recipes/image-generator/apps/native/src/app/image-generator/gallery.tsx +3 -0
  122. package/recipes/image-generator/apps/native/src/app/image-generator/index.tsx +3 -0
  123. package/recipes/image-generator/recipe.json +8 -18
  124. package/recipes/image-generator-native@latest.zip +0 -0
  125. package/recipes/image-generator-supabase/recipe.json +6 -62
  126. package/recipes/image-generator-supabase-native@latest.zip +0 -0
  127. package/recipes/image-generator-supabase@latest.zip +0 -0
  128. package/recipes/image-generator@latest.zip +0 -0
  129. package/recipes/ios-widget/recipe.json +18 -119
  130. package/recipes/ios-widget-native@latest.zip +0 -0
  131. package/recipes/ios-widget@latest.zip +0 -0
  132. package/recipes/number-stepper/apps/native/src/components/advanced-ui/stepper/demo.tsx +1 -1
  133. package/recipes/number-stepper/recipe.json +5 -2
  134. package/recipes/number-stepper-native@latest.zip +0 -0
  135. package/recipes/number-stepper@latest.zip +0 -0
  136. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/interactive-onboarding.tsx +11 -18
  137. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/ai-tone-step.tsx +5 -7
  138. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/currency-step.tsx +9 -7
  139. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-ai-step.tsx +8 -7
  140. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-chatbot-step.tsx +6 -5
  141. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-manual-step.tsx +4 -3
  142. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/feature-scan-step.tsx +6 -5
  143. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/main-reason-step.tsx +5 -7
  144. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/notification-step.tsx +7 -6
  145. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/overspend-step.tsx +5 -7
  146. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/personalizing-step.tsx +8 -7
  147. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/rating-step.tsx +6 -5
  148. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/reminder-step.tsx +5 -6
  149. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/safety-step.tsx +5 -4
  150. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/struggle-step.tsx +5 -7
  151. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/steps/welcome-step.tsx +7 -6
  152. package/recipes/onboarding/apps/native/src/features/onboarding/expense-tracker/components/ui/onboarding-header.tsx +4 -3
  153. package/recipes/onboarding/recipe.json +9 -6
  154. package/recipes/onboarding-native@latest.zip +0 -0
  155. package/recipes/onboarding@latest.zip +0 -0
  156. package/recipes/payments/apps/native/src/app/paywall/index.tsx +74 -0
  157. package/recipes/payments/apps/native/src/app/paywall/local.tsx +25 -0
  158. package/recipes/payments/apps/native/src/app/paywall/remote.tsx +23 -0
  159. package/recipes/payments/packages/backend/convex/payments.ts +21 -3
  160. package/recipes/payments/recipe.json +14 -34
  161. package/recipes/payments-native@latest.zip +0 -0
  162. package/recipes/payments-supabase/apps/native/src/app/paywall/index.tsx +74 -0
  163. package/recipes/payments-supabase/apps/native/src/app/paywall/local.tsx +25 -0
  164. package/recipes/payments-supabase/apps/native/src/app/paywall/remote.tsx +23 -0
  165. package/recipes/payments-supabase/recipe.json +16 -44
  166. package/recipes/payments-supabase-native@latest.zip +0 -0
  167. package/recipes/payments-supabase@latest.zip +0 -0
  168. package/recipes/payments@latest.zip +0 -0
  169. package/recipes/posthog/apps/native/src/components/analytics/navigation-tracker.tsx +14 -0
  170. package/recipes/posthog/apps/native/src/lib/hooks/use-navigation-analytics.ts +44 -0
  171. package/recipes/posthog/apps/native/src/providers/posthog-provider.tsx +51 -0
  172. package/recipes/posthog/recipe.json +60 -0
  173. package/recipes/posthog-native@latest.zip +0 -0
  174. package/recipes/progress-circle/apps/native/src/components/advanced-ui/progress-bars/progress-circle-page.tsx +1 -1
  175. package/recipes/progress-circle/recipe.json +5 -2
  176. package/recipes/progress-circle-native@latest.zip +0 -0
  177. package/recipes/progress-circle@latest.zip +0 -0
  178. package/recipes/quiz/apps/native/src/app/quiz/index.tsx +47 -0
  179. package/recipes/quiz/recipe.json +9 -6
  180. package/recipes/quiz-native@latest.zip +0 -0
  181. package/recipes/quiz@latest.zip +0 -0
  182. package/recipes/screen-kits/apps/native/src/app/screen-kits/_layout.tsx +12 -0
  183. package/recipes/screen-kits/apps/native/src/app/screen-kits/index.tsx +114 -0
  184. package/recipes/screen-kits/apps/native/src/features/screen-kits/index.ts +1 -0
  185. package/recipes/screen-kits/apps/native/src/features/screen-kits/types.ts +28 -0
  186. package/recipes/screen-kits/recipe.json +26 -0
  187. package/recipes/screen-kits-duolingo/apps/native/src/app/screen-kits/duolingo/_layout.tsx +12 -0
  188. package/recipes/screen-kits-duolingo/apps/native/src/app/screen-kits/duolingo/home.tsx +5 -0
  189. package/recipes/screen-kits-duolingo/apps/native/src/app/screen-kits/duolingo/index.tsx +5 -0
  190. package/recipes/screen-kits-duolingo/apps/native/src/app/screen-kits/duolingo/lesson-complete.tsx +5 -0
  191. package/recipes/screen-kits-duolingo/apps/native/src/app/screen-kits/duolingo/lesson-fail.tsx +5 -0
  192. package/recipes/screen-kits-duolingo/apps/native/src/app/screen-kits/duolingo/lesson.tsx +5 -0
  193. package/recipes/screen-kits-duolingo/apps/native/src/app/screen-kits/duolingo/skill-tree.tsx +5 -0
  194. package/recipes/screen-kits-duolingo/apps/native/src/features/screen-kits/duolingo/components/duo-button.tsx +174 -0
  195. package/recipes/screen-kits-duolingo/apps/native/src/features/screen-kits/duolingo/components/skill-button.tsx +186 -0
  196. package/recipes/screen-kits-duolingo/apps/native/src/features/screen-kits/duolingo/components/xp-header.tsx +115 -0
  197. package/recipes/screen-kits-duolingo/apps/native/src/features/screen-kits/duolingo/constants.ts +89 -0
  198. package/recipes/screen-kits-duolingo/apps/native/src/features/screen-kits/duolingo/index.ts +3 -0
  199. package/recipes/screen-kits-duolingo/apps/native/src/features/screen-kits/duolingo/screens/home-screen.tsx +225 -0
  200. package/recipes/screen-kits-duolingo/apps/native/src/features/screen-kits/duolingo/screens/lesson-complete-screen.tsx +485 -0
  201. package/recipes/screen-kits-duolingo/apps/native/src/features/screen-kits/duolingo/screens/lesson-fail-screen.tsx +105 -0
  202. package/recipes/screen-kits-duolingo/apps/native/src/features/screen-kits/duolingo/screens/lesson-screen.tsx +384 -0
  203. package/recipes/screen-kits-duolingo/recipe.json +58 -0
  204. package/recipes/screen-kits-duolingo-native@latest.zip +0 -0
  205. package/recipes/screen-kits-finance/apps/native/src/app/screen-kits/finance/_layout.tsx +45 -0
  206. package/recipes/screen-kits-finance/apps/native/src/app/screen-kits/finance/asset-detail.tsx +3 -0
  207. package/recipes/screen-kits-finance/apps/native/src/app/screen-kits/finance/notifications.tsx +3 -0
  208. package/recipes/screen-kits-finance/apps/native/src/app/screen-kits/finance/receive.tsx +3 -0
  209. package/recipes/screen-kits-finance/apps/native/src/app/screen-kits/finance/send.tsx +3 -0
  210. package/recipes/screen-kits-finance/apps/native/src/app/screen-kits/finance/swap.tsx +3 -0
  211. package/recipes/screen-kits-finance/apps/native/src/app/screen-kits/finance/wallet.tsx +3 -0
  212. package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/components/ActionButtons.tsx +78 -0
  213. package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/components/AssetRow.tsx +94 -0
  214. package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/components/BalanceCard.tsx +118 -0
  215. package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/constants.ts +85 -0
  216. package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/screens/asset-detail.tsx +378 -0
  217. package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/screens/notifications.tsx +210 -0
  218. package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/screens/receive-modal.tsx +317 -0
  219. package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/screens/send-modal.tsx +420 -0
  220. package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/screens/swap-modal.tsx +363 -0
  221. package/recipes/screen-kits-finance/apps/native/src/features/screen-kits/finance/screens/wallet-dashboard.tsx +281 -0
  222. package/recipes/screen-kits-finance/recipe.json +46 -0
  223. package/recipes/screen-kits-finance-native@latest.zip +0 -0
  224. package/recipes/screen-kits-fitness/apps/native/assets/sounds/timer-beep.wav +0 -0
  225. package/recipes/screen-kits-fitness/apps/native/src/app/screen-kits/fitness/_layout.tsx +10 -0
  226. package/recipes/screen-kits-fitness/apps/native/src/app/screen-kits/fitness/index.tsx +6 -0
  227. package/recipes/screen-kits-fitness/apps/native/src/app/screen-kits/fitness/timer.tsx +3 -0
  228. package/recipes/screen-kits-fitness/apps/native/src/app/screen-kits/fitness/workout.tsx +3 -0
  229. package/recipes/screen-kits-fitness/apps/native/src/features/screen-kits/fitness/components/timer-components.tsx +500 -0
  230. package/recipes/screen-kits-fitness/apps/native/src/features/screen-kits/fitness/components/timer-settings-modal.tsx +352 -0
  231. package/recipes/screen-kits-fitness/apps/native/src/features/screen-kits/fitness/components/workout-card.tsx +105 -0
  232. package/recipes/screen-kits-fitness/apps/native/src/features/screen-kits/fitness/constants.ts +189 -0
  233. package/recipes/screen-kits-fitness/apps/native/src/features/screen-kits/fitness/hooks/use-timer.ts +307 -0
  234. package/recipes/screen-kits-fitness/apps/native/src/features/screen-kits/fitness/index.ts +1 -0
  235. package/recipes/screen-kits-fitness/apps/native/src/features/screen-kits/fitness/screens/timer-screen.tsx +278 -0
  236. package/recipes/screen-kits-fitness/apps/native/src/features/screen-kits/fitness/screens/workout-dashboard.tsx +350 -0
  237. package/recipes/screen-kits-fitness/recipe.json +63 -0
  238. package/recipes/screen-kits-fitness-native@latest.zip +0 -0
  239. package/recipes/screen-kits-habits/apps/native/src/app/screen-kits/productivity/habits.tsx +1 -0
  240. package/recipes/screen-kits-habits/apps/native/src/app/screen-kits/productivity/kanban.tsx +1 -0
  241. package/recipes/screen-kits-habits/apps/native/src/app/screen-kits/productivity/routes.ts +4 -0
  242. package/recipes/screen-kits-habits/apps/native/src/features/screen-kits/productivity/components/AddTaskModal.tsx +246 -0
  243. package/recipes/screen-kits-habits/apps/native/src/features/screen-kits/productivity/components/DraggableTaskCard.tsx +92 -0
  244. package/recipes/screen-kits-habits/apps/native/src/features/screen-kits/productivity/components/KanbanColumn.tsx +238 -0
  245. package/recipes/screen-kits-habits/apps/native/src/features/screen-kits/productivity/components/TaskCard.tsx +144 -0
  246. package/recipes/screen-kits-habits/apps/native/src/features/screen-kits/productivity/components/add-habit-modal.tsx +271 -0
  247. package/recipes/screen-kits-habits/apps/native/src/features/screen-kits/productivity/constants.ts +295 -0
  248. package/recipes/screen-kits-habits/apps/native/src/features/screen-kits/productivity/kanban-utils.ts +62 -0
  249. package/recipes/screen-kits-habits/apps/native/src/features/screen-kits/productivity/screens/habit-tracker.tsx +1160 -0
  250. package/recipes/screen-kits-habits/apps/native/src/features/screen-kits/productivity/screens/kanban-board.tsx +432 -0
  251. package/recipes/screen-kits-habits/recipe.json +52 -0
  252. package/recipes/screen-kits-habits-native@latest.zip +0 -0
  253. package/recipes/screen-kits-native@latest.zip +0 -0
  254. package/recipes/sentry/apps/native/src/providers/sentry-provider.tsx +64 -0
  255. package/recipes/sentry/recipe.json +39 -0
  256. package/recipes/sentry-native@latest.zip +0 -0
  257. package/recipes/swipe-slider/apps/native/src/components/advanced-ui/sliders/swipe-slider-page.tsx +1 -1
  258. package/recipes/swipe-slider/recipe.json +5 -2
  259. package/recipes/swipe-slider-native@latest.zip +0 -0
  260. package/recipes/swipe-slider@latest.zip +0 -0
  261. package/recipes/timeline/apps/native/src/components/advanced-ui/timeline/demo.tsx +2 -1
  262. package/recipes/timeline/recipe.json +5 -2
  263. package/recipes/timeline-native@latest.zip +0 -0
  264. package/recipes/timeline@latest.zip +0 -0
  265. package/recipes/tracker-app/apps/native/src/app/tracker-app/index.tsx +1 -0
  266. package/recipes/tracker-app/recipe.json +10 -7
  267. package/recipes/tracker-app-native@latest.zip +0 -0
  268. package/recipes/tracker-app@latest.zip +0 -0
  269. package/recipes/upload-all.sh +8 -31
  270. package/recipes/voice-bot/apps/native/src/app/voice-bot/index.tsx +56 -0
  271. package/recipes/voice-bot/recipe.json +31 -7
  272. package/recipes/voice-bot-native@latest.zip +0 -0
  273. package/recipes/voice-bot@latest.zip +0 -0
  274. package/recipes/wake-word/apps/native/src/app/{(root)/(protected)/test-wake-word.tsx → test-wake-word.tsx} +43 -4
  275. package/recipes/wake-word/recipe.json +16 -26
  276. package/recipes/wake-word-native@latest.zip +0 -0
  277. package/recipes/wake-word@latest.zip +0 -0
  278. package/scripts/create-advanced-ui-recipes.sh +46 -19
  279. package/scripts/create-recipes.mjs +471 -117
  280. package/scripts/package-recipes.mjs +76 -0
  281. package/scripts/publish-all.sh +6 -2
  282. package/CHANGELOG.md +0 -198
  283. package/docs/archive/AUTO-DETECT-DEPS.md +0 -607
  284. package/docs/archive/FINAL-PACKAGE-STRATEGY.md +0 -583
  285. package/docs/archive/FINAL-SIMPLE-PLAN.md +0 -487
  286. package/docs/archive/FINAL-STATUS.md +0 -144
  287. package/docs/archive/FLOW-DIAGRAM.md +0 -1629
  288. package/docs/archive/GOTCHAS-AND-RISKS.md +0 -801
  289. package/docs/archive/IMPLEMENTATION-PLAN.md +0 -1360
  290. package/docs/archive/PLAN.md +0 -453
  291. package/docs/archive/PRODUCTION-READINESS.md +0 -684
  292. package/docs/archive/PRODUCTION-TEST-RESULTS.md +0 -465
  293. package/docs/archive/SIMPLIFIED-PLAN.md +0 -578
  294. package/docs/archive/STATUS.md +0 -199
  295. package/docs/archive/SUCCESS.md +0 -259
  296. package/docs/archive/TEST-SUMMARY.md +0 -261
  297. package/docs/archive/TESTING-CHECKLIST.md +0 -450
  298. package/docs/archive/USER-MODIFICATIONS.md +0 -448
  299. package/docs/decisions.md +0 -55
  300. package/docs/manual-testing.md +0 -91
  301. package/docs/next-steps.md +0 -12
  302. package/recipes/README.md +0 -156
  303. package/recipes/audio-recorder-supabase/packages/backend/src/services/recordings.ts +0 -369
  304. package/recipes/chatbot/apps/native/src/api-client/chatbot.ts +0 -83
  305. package/recipes/chatbot/packages/backend/convex/agents.ts +0 -115
  306. package/recipes/chatbot/packages/backend/convex/tools/index.ts +0 -18
  307. package/recipes/chatbot/packages/backend/convex/tools/knowledgeRetrieval.ts +0 -97
  308. package/recipes/chatbot/packages/backend/convex/tools/tavilySearch.ts +0 -83
  309. package/recipes/chatbot/packages/backend/convex/tools/userProfile.ts +0 -72
  310. package/recipes/chatbot-supabase/apps/native/src/api-client/supabase/chatbot.ts +0 -515
  311. package/recipes/chatbot-supabase/packages/backend/src/services/conversations.ts +0 -243
  312. package/recipes/chatbot-supabase/packages/backend/src/services/messages.ts +0 -327
  313. package/recipes/image-analysis/apps/native/src/api-client/image-analyzer.ts +0 -62
  314. package/recipes/image-analysis-supabase/packages/backend/src/services/image-analyses.ts +0 -132
  315. package/recipes/image-generator/apps/native/src/api-client/image-generator.ts +0 -34
  316. package/recipes/payments/apps/native/src/api-client/payments.ts +0 -44
  317. package/recipes/payments-supabase/packages/backend/src/services/payments.ts +0 -201
  318. package/recipes/posthog.json +0 -47
  319. package/recipes/revenuecat.json +0 -43
  320. package/recipes/sentry.json +0 -47
  321. package/recipes/wake-word/apps/native/assets/vosk-model/README.md +0 -103
  322. package/recipes/wake-word/apps/native/scripts/download-vosk-model.mjs +0 -127
  323. /package/recipes/{audio-recorder/apps/native/src/app/(root)/(protected) → audio-recorder-supabase/apps/native/src/app}/audio-recorder/index.tsx +0 -0
  324. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/AppIntent.swift +0 -0
  325. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@1x.png +0 -0
  326. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@2x.png +0 -0
  327. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@3x.png +0 -0
  328. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@1x.png +0 -0
  329. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@2x.png +0 -0
  330. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@3x.png +0 -0
  331. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@1x.png +0 -0
  332. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@2x.png +0 -0
  333. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@3x.png +0 -0
  334. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-60x60@2x.png +0 -0
  335. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-60x60@3x.png +0 -0
  336. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-76x76@1x.png +0 -0
  337. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-76x76@2x.png +0 -0
  338. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-83.5x83.5@2x.png +0 -0
  339. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -0
  340. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png +0 -0
  341. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/CalorieTrackerWidget.swift +0 -0
  342. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/HabitTrackerWidget.swift +0 -0
  343. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/Info.plist +0 -0
  344. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/WidgetLiveActivity.swift +0 -0
  345. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/expo-target.config.js +0 -0
  346. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/generated.entitlements +0 -0
  347. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/index.swift +0 -0
  348. /package/recipes/ios-widget/{targets → apps/native/targets}/widget/widgets.swift +0 -0
@@ -1,607 +0,0 @@
1
- # 🔍 Auto-Detecting Missing Dependencies
2
-
3
- ## The Problem
4
-
5
- When we install a feature, we copy files that import packages:
6
- following is an example we aint using that pck name in reality:
7
- ```typescript
8
- // apps/native/src/features/charts/index.tsx
9
- import { LineChart } from 'react-native-chart-kit'; // ← Package not installed!
10
- import { Dimensions } from 'react-native';
11
- ```
12
-
13
- If `react-native-chart-kit` isn't installed, the app will crash or fail to build.
14
-
15
- ## The Question
16
-
17
- Can we **automatically detect** what packages are missing instead of manually specifying them in recipe.json?
18
-
19
- **Answer: YES!** Multiple approaches:
20
-
21
- ---
22
-
23
- ## Approach 1: Run TypeScript Type Checking ✅ BEST
24
-
25
- ### How It Works
26
-
27
- TypeScript will error on missing packages:
28
-
29
- ```bash
30
- $ pnpm tsc --noEmit
31
- # Output:
32
- # error TS2307: Cannot find module 'react-native-chart-kit' or its corresponding type declarations.
33
- ```
34
-
35
- ### Implementation
36
-
37
- **File:** `src/core/typecheck.ts` (NEW)
38
-
39
- ```typescript
40
- import { executeBash } from './shell.js';
41
- import { log } from './log.js';
42
-
43
- export interface TypeCheckResult {
44
- success: boolean;
45
- missingPackages: string[];
46
- errors: string[];
47
- }
48
-
49
- export async function runTypeCheck(cwd: string): Promise<TypeCheckResult> {
50
- log.info('Running type check to detect missing packages...');
51
-
52
- // Try different type checkers in order of preference
53
- const checkers = [
54
- { cmd: 'pnpm tsc --noEmit', name: 'pnpm' },
55
- { cmd: 'yarn tsc --noEmit', name: 'yarn' },
56
- { cmd: 'npx tsc --noEmit', name: 'npm' },
57
- ];
58
-
59
- let result;
60
- for (const checker of checkers) {
61
- result = await executeBash(checker.cmd, { cwd });
62
- if (result.exitCode !== 127) { // 127 = command not found
63
- break;
64
- }
65
- }
66
-
67
- if (!result || result.exitCode === 127) {
68
- log.warn('TypeScript not found, skipping type check');
69
- return { success: true, missingPackages: [], errors: [] };
70
- }
71
-
72
- // Parse TypeScript errors
73
- const missingPackages = new Set<string>();
74
- const errors: string[] = [];
75
-
76
- const lines = result.stderr.split('\n');
77
-
78
- for (const line of lines) {
79
- // Match: error TS2307: Cannot find module 'package-name'
80
- const match = line.match(/error TS2307: Cannot find module '([^']+)'/);
81
- if (match) {
82
- const moduleName = match[1];
83
-
84
- // Extract package name (handle scoped packages and subpaths)
85
- const packageName = extractPackageName(moduleName);
86
-
87
- if (packageName && !isBuiltInModule(packageName)) {
88
- missingPackages.add(packageName);
89
- }
90
- }
91
-
92
- // Collect all errors for debugging
93
- if (line.includes('error TS')) {
94
- errors.push(line);
95
- }
96
- }
97
-
98
- return {
99
- success: result.exitCode === 0,
100
- missingPackages: Array.from(missingPackages),
101
- errors,
102
- };
103
- }
104
-
105
- function extractPackageName(modulePath: string): string | null {
106
- // Handle different import patterns:
107
- // 'react-native-chart-kit' → 'react-native-chart-kit'
108
- // 'react-native-chart-kit/dist/LineChart' → 'react-native-chart-kit'
109
- // '@react-navigation/native' → '@react-navigation/native'
110
- // '@react-navigation/native/lib/index' → '@react-navigation/native'
111
-
112
- if (modulePath.startsWith('@')) {
113
- // Scoped package: @scope/package
114
- const parts = modulePath.split('/');
115
- if (parts.length >= 2) {
116
- return `${parts[0]}/${parts[1]}`;
117
- }
118
- } else {
119
- // Regular package: package-name
120
- const parts = modulePath.split('/');
121
- return parts[0];
122
- }
123
-
124
- return null;
125
- }
126
-
127
- function isBuiltInModule(packageName: string): boolean {
128
- // Node.js built-in modules
129
- const builtIns = [
130
- 'fs', 'path', 'crypto', 'http', 'https', 'url', 'util',
131
- 'stream', 'events', 'buffer', 'process', 'os', 'child_process',
132
- ];
133
-
134
- // React Native built-ins
135
- const rnBuiltIns = [
136
- 'react-native',
137
- 'react',
138
- ];
139
-
140
- return builtIns.includes(packageName) || rnBuiltIns.includes(packageName);
141
- }
142
- ```
143
-
144
- ### Usage in add command
145
-
146
- **File:** `src/commands/add.ts`
147
-
148
- ```typescript
149
- // After copying files, BEFORE adding watermarks
150
-
151
- if (!options.dryRun && !options.skipTypeCheck) {
152
- log.plain('');
153
- log.info('🔍 Checking for missing dependencies...');
154
-
155
- const typeCheckResult = await runTypeCheck(paths.cwd);
156
-
157
- if (typeCheckResult.missingPackages.length > 0) {
158
- log.plain('');
159
- log.warn('⚠ Missing packages detected:');
160
- log.plain('');
161
-
162
- typeCheckResult.missingPackages.forEach(pkg => {
163
- log.plain(` • ${pkg}`);
164
- });
165
-
166
- log.plain('');
167
-
168
- // Try to find versions from recipe.json if available
169
- const packagesWithVersions: Record<string, string> = {};
170
-
171
- if (manifest.dependencies?.npm) {
172
- typeCheckResult.missingPackages.forEach(pkg => {
173
- if (manifest.dependencies.npm[pkg]) {
174
- packagesWithVersions[pkg] = manifest.dependencies.npm[pkg];
175
- } else {
176
- // Default to latest
177
- packagesWithVersions[pkg] = 'latest';
178
- }
179
- });
180
- } else {
181
- // No recipe dependencies, use latest for all
182
- typeCheckResult.missingPackages.forEach(pkg => {
183
- packagesWithVersions[pkg] = 'latest';
184
- });
185
- }
186
-
187
- // Show install command
188
- const pm = await detectPackageManager(paths.cwd);
189
- const pkgList = Object.entries(packagesWithVersions)
190
- .map(([name, version]) => version === 'latest' ? name : `${name}@${version}`)
191
- .join(' ');
192
- const installCmd = getInstallCommand(pm, pkgList.split(' '));
193
-
194
- log.info('📦 Install with:');
195
- log.plain(` ${installCmd}`);
196
- log.plain('');
197
-
198
- // Ask to install
199
- if (!options.yes) {
200
- const shouldInstall = promptYesNo(
201
- 'Install missing packages now? (Y/n): ',
202
- true
203
- );
204
-
205
- if (shouldInstall) {
206
- log.info('Installing packages...');
207
- const result = await installPackages(packagesWithVersions, paths.cwd);
208
-
209
- if (result.success) {
210
- log.success('✓ Packages installed successfully!');
211
-
212
- // Run type check again to verify
213
- log.info('Verifying installation...');
214
- const verifyResult = await runTypeCheck(paths.cwd);
215
-
216
- if (verifyResult.missingPackages.length > 0) {
217
- log.warn('⚠ Some packages are still missing:');
218
- verifyResult.missingPackages.forEach(pkg => {
219
- log.plain(` • ${pkg}`);
220
- });
221
- } else {
222
- log.success('✓ All dependencies resolved!');
223
- }
224
- } else {
225
- log.error(`✗ Installation failed: ${result.error}`);
226
- }
227
- }
228
- } else {
229
- // Auto-install in --yes mode
230
- log.info('Installing packages...');
231
- const result = await installPackages(packagesWithVersions, paths.cwd);
232
-
233
- if (!result.success) {
234
- log.error(`✗ Installation failed: ${result.error}`);
235
- process.exit(1);
236
- }
237
- }
238
- } else if (typeCheckResult.success) {
239
- log.success('✓ No missing dependencies detected');
240
- } else {
241
- log.warn('⚠ Type check completed with errors (but no missing packages)');
242
- if (typeCheckResult.errors.length > 0 && process.env.DEBUG) {
243
- log.plain('');
244
- log.plain('Errors:');
245
- typeCheckResult.errors.slice(0, 5).forEach(err => {
246
- log.plain(` ${err}`);
247
- });
248
- }
249
- }
250
- }
251
- ```
252
-
253
- ### Add CLI flag
254
-
255
- ```typescript
256
- export const addCommand = new Command('add')
257
- .description('Add a VibeFast feature to your project')
258
- .argument('<feature>', 'Feature name to install')
259
- .option('--target <target>', 'Target platform (native or web)', 'native')
260
- .option('--dry-run', 'Preview changes without applying')
261
- .option('--force', 'Overwrite existing files without asking')
262
- .option('--yes', 'Answer yes to all prompts')
263
- .option('--skip-install', 'Skip package installation')
264
- .option('--skip-type-check', 'Skip type checking for missing packages') // NEW
265
- .action(async (feature: string, options) => {
266
- // ...
267
- });
268
- ```
269
-
270
- ---
271
-
272
- ## Approach 2: Parse Import Statements 🟡 FALLBACK
273
-
274
- If TypeScript isn't available, parse imports manually.
275
-
276
- ### Implementation
277
-
278
- **File:** `src/core/importParser.ts` (NEW)
279
-
280
- ```typescript
281
- import { readFile } from 'fs/promises';
282
- import { join } from 'path';
283
-
284
- export async function extractImports(filePath: string): Promise<string[]> {
285
- const content = await readFile(filePath, 'utf-8');
286
- const imports = new Set<string>();
287
-
288
- // Match various import patterns
289
- const patterns = [
290
- // import X from 'package'
291
- /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g,
292
- // import 'package'
293
- /import\s+['"]([^'"]+)['"]/g,
294
- // require('package')
295
- /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g,
296
- // import('package')
297
- /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g,
298
- ];
299
-
300
- for (const pattern of patterns) {
301
- let match;
302
- while ((match = pattern.exec(content)) !== null) {
303
- const importPath = match[1];
304
-
305
- // Skip relative imports
306
- if (importPath.startsWith('.') || importPath.startsWith('/')) {
307
- continue;
308
- }
309
-
310
- imports.add(importPath);
311
- }
312
- }
313
-
314
- return Array.from(imports);
315
- }
316
-
317
- export async function extractImportsFromFiles(
318
- filePaths: string[]
319
- ): Promise<string[]> {
320
- const allImports = new Set<string>();
321
-
322
- for (const filePath of filePaths) {
323
- // Only parse JS/TS files
324
- if (!/\.(js|jsx|ts|tsx)$/.test(filePath)) {
325
- continue;
326
- }
327
-
328
- try {
329
- const imports = await extractImports(filePath);
330
- imports.forEach(imp => allImports.add(imp));
331
- } catch (error) {
332
- // Skip files that can't be read
333
- continue;
334
- }
335
- }
336
-
337
- return Array.from(allImports).map(extractPackageName).filter(Boolean) as string[];
338
- }
339
- ```
340
-
341
- ### Check Against Installed Packages
342
-
343
- **File:** `src/core/packageChecker.ts` (NEW)
344
-
345
- ```typescript
346
- import { readFile } from 'fs/promises';
347
- import { join } from 'path';
348
- import { exists } from './fsx.js';
349
-
350
- export async function getInstalledPackages(cwd: string): Promise<Set<string>> {
351
- const packageJsonPath = join(cwd, 'package.json');
352
-
353
- if (!await exists(packageJsonPath)) {
354
- return new Set();
355
- }
356
-
357
- const content = await readFile(packageJsonPath, 'utf-8');
358
- const packageJson = JSON.parse(content);
359
-
360
- const installed = new Set<string>();
361
-
362
- // Add dependencies
363
- if (packageJson.dependencies) {
364
- Object.keys(packageJson.dependencies).forEach(pkg => installed.add(pkg));
365
- }
366
-
367
- // Add devDependencies
368
- if (packageJson.devDependencies) {
369
- Object.keys(packageJson.devDependencies).forEach(pkg => installed.add(pkg));
370
- }
371
-
372
- return installed;
373
- }
374
-
375
- export async function findMissingPackages(
376
- requiredPackages: string[],
377
- cwd: string
378
- ): Promise<string[]> {
379
- const installed = await getInstalledPackages(cwd);
380
-
381
- return requiredPackages.filter(pkg => !installed.has(pkg));
382
- }
383
- ```
384
-
385
- ### Usage
386
-
387
- ```typescript
388
- // After copying files
389
-
390
- // Extract imports from copied files
391
- const imports = await extractImportsFromFiles(copiedFiles);
392
-
393
- // Check which are missing
394
- const missing = await findMissingPackages(imports, paths.cwd);
395
-
396
- if (missing.length > 0) {
397
- log.warn('⚠ Missing packages detected:');
398
- missing.forEach(pkg => log.plain(` • ${pkg}`));
399
- // ... prompt to install
400
- }
401
- ```
402
-
403
- ---
404
-
405
- ## Approach 3: Run ESLint 🟢 BONUS
406
-
407
- If the project has ESLint configured:
408
-
409
- ```typescript
410
- export async function runESLint(cwd: string): Promise<string[]> {
411
- const result = await executeBash('npx eslint . --format json', { cwd });
412
-
413
- if (result.exitCode === 0) {
414
- return [];
415
- }
416
-
417
- try {
418
- const eslintOutput = JSON.parse(result.stdout);
419
- const missingPackages = new Set<string>();
420
-
421
- eslintOutput.forEach((file: any) => {
422
- file.messages.forEach((msg: any) => {
423
- // ESLint rule: import/no-unresolved
424
- if (msg.ruleId === 'import/no-unresolved') {
425
- const match = msg.message.match(/Unable to resolve path to module '([^']+)'/);
426
- if (match) {
427
- const packageName = extractPackageName(match[1]);
428
- if (packageName) {
429
- missingPackages.add(packageName);
430
- }
431
- }
432
- }
433
- });
434
- });
435
-
436
- return Array.from(missingPackages);
437
- } catch (error) {
438
- return [];
439
- }
440
- }
441
- ```
442
-
443
- ---
444
-
445
- ## Recommended Strategy: Hybrid Approach
446
-
447
- ### Step 1: Try TypeScript (Most Accurate)
448
- ```typescript
449
- const typeCheckResult = await runTypeCheck(paths.cwd);
450
- if (typeCheckResult.missingPackages.length > 0) {
451
- return typeCheckResult.missingPackages;
452
- }
453
- ```
454
-
455
- ### Step 2: Fallback to Import Parsing
456
- ```typescript
457
- if (!typeCheckResult.success && typeCheckResult.missingPackages.length === 0) {
458
- // TypeScript failed or not available, try parsing
459
- const imports = await extractImportsFromFiles(copiedFiles);
460
- const missing = await findMissingPackages(imports, paths.cwd);
461
- return missing;
462
- }
463
- ```
464
-
465
- ### Step 3: Use Recipe as Source of Truth
466
- ```typescript
467
- // If detection fails, fall back to recipe.json
468
- if (manifest.dependencies?.npm) {
469
- return Object.keys(manifest.dependencies.npm);
470
- }
471
- ```
472
-
473
- ---
474
-
475
- ## Complete Flow
476
-
477
- ```
478
- ┌─────────────────────────────────────────────────────────────────┐
479
- │ DEPENDENCY DETECTION FLOW │
480
- └─────────────────────────────────────────────────────────────────┘
481
-
482
- Step 1: Install Feature Files
483
- ┌──────────────────────────────────────────────────────────────┐
484
- │ $ vf add charts │
485
- │ ✓ Files copied: 17 │
486
- └──────────────────────────────────────────────────────────────┘
487
-
488
-
489
- Step 2: Run Type Check
490
- ┌──────────────────────────────────────────────────────────────┐
491
- │ $ pnpm tsc --noEmit │
492
- │ │
493
- │ Output: │
494
- │ error TS2307: Cannot find module 'react-native-chart-kit' │
495
- │ error TS2307: Cannot find module 'react-native-svg' │
496
- └──────────────────────────────────────────────────────────────┘
497
-
498
-
499
- Step 3: Parse Errors
500
- ┌──────────────────────────────────────────────────────────────┐
501
- │ Detected missing packages: │
502
- │ • react-native-chart-kit │
503
- │ • react-native-svg │
504
- └──────────────────────────────────────────────────────────────┘
505
-
506
-
507
- Step 4: Check Recipe for Versions
508
- ┌──────────────────────────────────────────────────────────────┐
509
- │ recipe.json has: │
510
- │ { │
511
- │ "dependencies": { │
512
- │ "npm": { │
513
- │ "react-native-chart-kit": "^6.12.0", │
514
- │ "react-native-svg": "^13.9.0" │
515
- │ } │
516
- │ } │
517
- │ } │
518
- │ │
519
- │ Use these versions ✓ │
520
- └──────────────────────────────────────────────────────────────┘
521
-
522
-
523
- Step 5: Prompt User
524
- ┌──────────────────────────────────────────────────────────────┐
525
- │ ⚠ Missing packages detected: │
526
- │ • react-native-chart-kit@^6.12.0 │
527
- │ • react-native-svg@^13.9.0 │
528
- │ │
529
- │ 📦 Install with: │
530
- │ pnpm add react-native-chart-kit@^6.12.0 react-native-svg@^13.9.0
531
- │ │
532
- │ Install missing packages now? (Y/n): _ │
533
- └──────────────────────────────────────────────────────────────┘
534
-
535
-
536
- Step 6: Install Packages
537
- ┌──────────────────────────────────────────────────────────────┐
538
- │ $ pnpm add react-native-chart-kit@^6.12.0 react-native-svg@^13.9.0
539
- │ ✓ Packages installed │
540
- └──────────────────────────────────────────────────────────────┘
541
-
542
-
543
- Step 7: Verify
544
- ┌──────────────────────────────────────────────────────────────┐
545
- │ $ pnpm tsc --noEmit │
546
- │ ✓ No errors │
547
- │ ✓ All dependencies resolved! │
548
- └──────────────────────────────────────────────────────────────┘
549
- ```
550
-
551
- ---
552
-
553
- ## Advantages of This Approach
554
-
555
- 1. **Automatic Detection** - No need to manually specify in recipe.json
556
- 2. **Accurate** - TypeScript knows exactly what's missing
557
- 3. **Version Aware** - Can still use recipe.json for specific versions
558
- 4. **Fallback** - Import parsing if TypeScript not available
559
- 5. **Verification** - Can re-run type check after install to confirm
560
-
561
- ## Disadvantages
562
-
563
- 1. **Slower** - Type checking takes 5-30 seconds
564
- 2. **Requires TypeScript** - Not all projects have it
565
- 3. **False Positives** - Might detect unrelated errors
566
- 4. **Version Guessing** - If not in recipe.json, defaults to 'latest'
567
-
568
- ---
569
-
570
- ## Recommendation
571
-
572
- **Use BOTH approaches:**
573
-
574
- 1. **Recipe.json as primary** (fast, explicit, version-controlled)
575
- 2. **Type checking as verification** (catch missing deps in recipe.json)
576
-
577
- ```typescript
578
- // After copying files
579
-
580
- // 1. Check recipe.json first
581
- if (manifest.dependencies?.npm) {
582
- const recipeDeps = manifest.dependencies.npm;
583
- // Show and install these
584
- }
585
-
586
- // 2. Run type check to verify
587
- const typeCheckResult = await runTypeCheck(paths.cwd);
588
- if (typeCheckResult.missingPackages.length > 0) {
589
- log.warn('⚠ Additional missing packages detected:');
590
- // Show packages not in recipe.json
591
- const additional = typeCheckResult.missingPackages.filter(
592
- pkg => !recipeDeps[pkg]
593
- );
594
-
595
- if (additional.length > 0) {
596
- log.warn('These packages are missing from recipe.json:');
597
- additional.forEach(pkg => log.plain(` • ${pkg}`));
598
- log.info('Consider updating the recipe to include these.');
599
- }
600
- }
601
- ```
602
-
603
- This gives us:
604
- - ✅ Fast installation (recipe.json)
605
- - ✅ Verification (type check)
606
- - ✅ Catches recipe mistakes
607
- - ✅ Best of both worlds