@helloleo/plugins 0.2.21 → 0.2.23

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 (340) hide show
  1. package/dist/index.js +73 -42
  2. package/package.json +3 -4
  3. package/dist/templates/tanstack-router-2026-06-15/components.json +0 -22
  4. package/dist/templates/tanstack-router-2026-06-15/index.html +0 -20
  5. package/dist/templates/tanstack-router-2026-06-15/package.json +0 -90
  6. package/dist/templates/tanstack-router-2026-06-15/src/components/error-component.tsx +0 -50
  7. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/accordion.tsx +0 -51
  8. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/alert-dialog.tsx +0 -115
  9. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/alert.tsx +0 -49
  10. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/aspect-ratio.tsx +0 -5
  11. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/avatar.tsx +0 -47
  12. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/badge.tsx +0 -32
  13. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/breadcrumb.tsx +0 -101
  14. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/button.tsx +0 -49
  15. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/calendar.tsx +0 -177
  16. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/card.tsx +0 -55
  17. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/carousel.tsx +0 -240
  18. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/chart.tsx +0 -331
  19. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/checkbox.tsx +0 -26
  20. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/collapsible.tsx +0 -11
  21. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/command.tsx +0 -143
  22. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/context-menu.tsx +0 -187
  23. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/dialog.tsx +0 -104
  24. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/drawer.tsx +0 -98
  25. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/dropdown-menu.tsx +0 -188
  26. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/form.tsx +0 -171
  27. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/hover-card.tsx +0 -27
  28. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/input-otp.tsx +0 -69
  29. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/input.tsx +0 -22
  30. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/label.tsx +0 -21
  31. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/menubar.tsx +0 -229
  32. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/navigation-menu.tsx +0 -120
  33. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/pagination.tsx +0 -98
  34. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/popover.tsx +0 -31
  35. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/progress.tsx +0 -25
  36. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/radio-group.tsx +0 -36
  37. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/resizable.tsx +0 -37
  38. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/scroll-area.tsx +0 -44
  39. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/select.tsx +0 -152
  40. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/separator.tsx +0 -24
  41. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/sheet.tsx +0 -122
  42. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/sidebar.tsx +0 -744
  43. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/skeleton.tsx +0 -7
  44. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/slider.tsx +0 -23
  45. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/sonner.tsx +0 -23
  46. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/switch.tsx +0 -27
  47. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/table.tsx +0 -94
  48. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/tabs.tsx +0 -53
  49. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/textarea.tsx +0 -21
  50. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/toggle-group.tsx +0 -57
  51. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/toggle.tsx +0 -42
  52. package/dist/templates/tanstack-router-2026-06-15/src/components/ui/tooltip.tsx +0 -32
  53. package/dist/templates/tanstack-router-2026-06-15/src/hooks/use-mobile.tsx +0 -19
  54. package/dist/templates/tanstack-router-2026-06-15/src/lib/proxy.ts +0 -123
  55. package/dist/templates/tanstack-router-2026-06-15/src/lib/utils.ts +0 -6
  56. package/dist/templates/tanstack-router-2026-06-15/src/main.tsx +0 -37
  57. package/dist/templates/tanstack-router-2026-06-15/src/routeTree.gen.ts +0 -59
  58. package/dist/templates/tanstack-router-2026-06-15/src/routes/README.md +0 -85
  59. package/dist/templates/tanstack-router-2026-06-15/src/routes/__root.tsx +0 -18
  60. package/dist/templates/tanstack-router-2026-06-15/src/routes/index.tsx +0 -18
  61. package/dist/templates/tanstack-router-2026-06-15/src/styles.css +0 -214
  62. package/dist/templates/tanstack-router-2026-06-15/tsconfig.json +0 -27
  63. package/dist/templates/tanstack-router-2026-06-15/vite.config.ts +0 -23
  64. package/dist/templates/tanstack-start-2026-06-18/components.json +0 -22
  65. package/dist/templates/tanstack-start-2026-06-18/drizzle.config.ts +0 -15
  66. package/dist/templates/tanstack-start-2026-06-18/package.json +0 -104
  67. package/dist/templates/tanstack-start-2026-06-18/src/components/error-component.tsx +0 -50
  68. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/accordion.tsx +0 -51
  69. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/alert-dialog.tsx +0 -115
  70. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/alert.tsx +0 -49
  71. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/aspect-ratio.tsx +0 -5
  72. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/avatar.tsx +0 -47
  73. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/badge.tsx +0 -32
  74. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/breadcrumb.tsx +0 -101
  75. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/button.tsx +0 -49
  76. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/calendar.tsx +0 -177
  77. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/card.tsx +0 -55
  78. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/carousel.tsx +0 -240
  79. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/chart.tsx +0 -371
  80. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/checkbox.tsx +0 -26
  81. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/collapsible.tsx +0 -11
  82. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/command.tsx +0 -143
  83. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/context-menu.tsx +0 -187
  84. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/dialog.tsx +0 -104
  85. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/drawer.tsx +0 -98
  86. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/dropdown-menu.tsx +0 -188
  87. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/form.tsx +0 -171
  88. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/hover-card.tsx +0 -27
  89. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/input-otp.tsx +0 -69
  90. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/input.tsx +0 -22
  91. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/label.tsx +0 -21
  92. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/menubar.tsx +0 -229
  93. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/navigation-menu.tsx +0 -120
  94. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/pagination.tsx +0 -98
  95. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/popover.tsx +0 -31
  96. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/progress.tsx +0 -25
  97. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/radio-group.tsx +0 -36
  98. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/resizable.tsx +0 -37
  99. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/scroll-area.tsx +0 -44
  100. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/select.tsx +0 -152
  101. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/separator.tsx +0 -24
  102. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/sheet.tsx +0 -122
  103. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/sidebar.tsx +0 -744
  104. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/skeleton.tsx +0 -7
  105. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/slider.tsx +0 -23
  106. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/sonner.tsx +0 -23
  107. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/switch.tsx +0 -27
  108. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/table.tsx +0 -94
  109. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/tabs.tsx +0 -53
  110. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/textarea.tsx +0 -21
  111. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/toggle-group.tsx +0 -57
  112. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/toggle.tsx +0 -42
  113. package/dist/templates/tanstack-start-2026-06-18/src/components/ui/tooltip.tsx +0 -32
  114. package/dist/templates/tanstack-start-2026-06-18/src/db/index.ts +0 -9
  115. package/dist/templates/tanstack-start-2026-06-18/src/db/schema.ts +0 -18
  116. package/dist/templates/tanstack-start-2026-06-18/src/global.d.ts +0 -3
  117. package/dist/templates/tanstack-start-2026-06-18/src/hooks/use-mobile.tsx +0 -19
  118. package/dist/templates/tanstack-start-2026-06-18/src/lib/proxy.ts +0 -119
  119. package/dist/templates/tanstack-start-2026-06-18/src/lib/utils.ts +0 -6
  120. package/dist/templates/tanstack-start-2026-06-18/src/routeTree.gen.ts +0 -86
  121. package/dist/templates/tanstack-start-2026-06-18/src/router.tsx +0 -37
  122. package/dist/templates/tanstack-start-2026-06-18/src/routes/README.md +0 -94
  123. package/dist/templates/tanstack-start-2026-06-18/src/routes/__root.tsx +0 -65
  124. package/dist/templates/tanstack-start-2026-06-18/src/routes/api/health.ts +0 -81
  125. package/dist/templates/tanstack-start-2026-06-18/src/routes/index.tsx +0 -33
  126. package/dist/templates/tanstack-start-2026-06-18/src/server.ts +0 -32
  127. package/dist/templates/tanstack-start-2026-06-18/src/styles.css +0 -214
  128. package/dist/templates/tanstack-start-2026-06-18/tsconfig.json +0 -27
  129. package/dist/templates/tanstack-start-2026-06-18/vite.config.ts +0 -17
  130. package/src/index.ts +0 -8
  131. package/src/template-render.ts +0 -53
  132. package/src/templates/tanstack-router-2026-06-15/components.json +0 -22
  133. package/src/templates/tanstack-router-2026-06-15/index.html +0 -20
  134. package/src/templates/tanstack-router-2026-06-15/package.json +0 -90
  135. package/src/templates/tanstack-router-2026-06-15/src/components/error-component.tsx +0 -50
  136. package/src/templates/tanstack-router-2026-06-15/src/components/ui/accordion.tsx +0 -51
  137. package/src/templates/tanstack-router-2026-06-15/src/components/ui/alert-dialog.tsx +0 -115
  138. package/src/templates/tanstack-router-2026-06-15/src/components/ui/alert.tsx +0 -49
  139. package/src/templates/tanstack-router-2026-06-15/src/components/ui/aspect-ratio.tsx +0 -5
  140. package/src/templates/tanstack-router-2026-06-15/src/components/ui/avatar.tsx +0 -47
  141. package/src/templates/tanstack-router-2026-06-15/src/components/ui/badge.tsx +0 -32
  142. package/src/templates/tanstack-router-2026-06-15/src/components/ui/breadcrumb.tsx +0 -101
  143. package/src/templates/tanstack-router-2026-06-15/src/components/ui/button.tsx +0 -49
  144. package/src/templates/tanstack-router-2026-06-15/src/components/ui/calendar.tsx +0 -177
  145. package/src/templates/tanstack-router-2026-06-15/src/components/ui/card.tsx +0 -55
  146. package/src/templates/tanstack-router-2026-06-15/src/components/ui/carousel.tsx +0 -240
  147. package/src/templates/tanstack-router-2026-06-15/src/components/ui/chart.tsx +0 -331
  148. package/src/templates/tanstack-router-2026-06-15/src/components/ui/checkbox.tsx +0 -26
  149. package/src/templates/tanstack-router-2026-06-15/src/components/ui/collapsible.tsx +0 -11
  150. package/src/templates/tanstack-router-2026-06-15/src/components/ui/command.tsx +0 -143
  151. package/src/templates/tanstack-router-2026-06-15/src/components/ui/context-menu.tsx +0 -187
  152. package/src/templates/tanstack-router-2026-06-15/src/components/ui/dialog.tsx +0 -104
  153. package/src/templates/tanstack-router-2026-06-15/src/components/ui/drawer.tsx +0 -98
  154. package/src/templates/tanstack-router-2026-06-15/src/components/ui/dropdown-menu.tsx +0 -188
  155. package/src/templates/tanstack-router-2026-06-15/src/components/ui/form.tsx +0 -171
  156. package/src/templates/tanstack-router-2026-06-15/src/components/ui/hover-card.tsx +0 -27
  157. package/src/templates/tanstack-router-2026-06-15/src/components/ui/input-otp.tsx +0 -69
  158. package/src/templates/tanstack-router-2026-06-15/src/components/ui/input.tsx +0 -22
  159. package/src/templates/tanstack-router-2026-06-15/src/components/ui/label.tsx +0 -21
  160. package/src/templates/tanstack-router-2026-06-15/src/components/ui/menubar.tsx +0 -229
  161. package/src/templates/tanstack-router-2026-06-15/src/components/ui/navigation-menu.tsx +0 -120
  162. package/src/templates/tanstack-router-2026-06-15/src/components/ui/pagination.tsx +0 -98
  163. package/src/templates/tanstack-router-2026-06-15/src/components/ui/popover.tsx +0 -31
  164. package/src/templates/tanstack-router-2026-06-15/src/components/ui/progress.tsx +0 -25
  165. package/src/templates/tanstack-router-2026-06-15/src/components/ui/radio-group.tsx +0 -36
  166. package/src/templates/tanstack-router-2026-06-15/src/components/ui/resizable.tsx +0 -37
  167. package/src/templates/tanstack-router-2026-06-15/src/components/ui/scroll-area.tsx +0 -44
  168. package/src/templates/tanstack-router-2026-06-15/src/components/ui/select.tsx +0 -152
  169. package/src/templates/tanstack-router-2026-06-15/src/components/ui/separator.tsx +0 -24
  170. package/src/templates/tanstack-router-2026-06-15/src/components/ui/sheet.tsx +0 -122
  171. package/src/templates/tanstack-router-2026-06-15/src/components/ui/sidebar.tsx +0 -744
  172. package/src/templates/tanstack-router-2026-06-15/src/components/ui/skeleton.tsx +0 -7
  173. package/src/templates/tanstack-router-2026-06-15/src/components/ui/slider.tsx +0 -23
  174. package/src/templates/tanstack-router-2026-06-15/src/components/ui/sonner.tsx +0 -23
  175. package/src/templates/tanstack-router-2026-06-15/src/components/ui/switch.tsx +0 -27
  176. package/src/templates/tanstack-router-2026-06-15/src/components/ui/table.tsx +0 -94
  177. package/src/templates/tanstack-router-2026-06-15/src/components/ui/tabs.tsx +0 -53
  178. package/src/templates/tanstack-router-2026-06-15/src/components/ui/textarea.tsx +0 -21
  179. package/src/templates/tanstack-router-2026-06-15/src/components/ui/toggle-group.tsx +0 -57
  180. package/src/templates/tanstack-router-2026-06-15/src/components/ui/toggle.tsx +0 -42
  181. package/src/templates/tanstack-router-2026-06-15/src/components/ui/tooltip.tsx +0 -32
  182. package/src/templates/tanstack-router-2026-06-15/src/hooks/use-mobile.tsx +0 -19
  183. package/src/templates/tanstack-router-2026-06-15/src/lib/proxy.ts +0 -123
  184. package/src/templates/tanstack-router-2026-06-15/src/lib/utils.ts +0 -6
  185. package/src/templates/tanstack-router-2026-06-15/src/main.tsx +0 -37
  186. package/src/templates/tanstack-router-2026-06-15/src/routeTree.gen.ts +0 -59
  187. package/src/templates/tanstack-router-2026-06-15/src/routes/README.md +0 -85
  188. package/src/templates/tanstack-router-2026-06-15/src/routes/__root.tsx +0 -18
  189. package/src/templates/tanstack-router-2026-06-15/src/routes/index.tsx +0 -18
  190. package/src/templates/tanstack-router-2026-06-15/src/styles.css +0 -214
  191. package/src/templates/tanstack-router-2026-06-15/tsconfig.json +0 -27
  192. package/src/templates/tanstack-router-2026-06-15/vite.config.ts +0 -23
  193. package/src/templates/tanstack-start-2026-06-18/components.json +0 -22
  194. package/src/templates/tanstack-start-2026-06-18/drizzle.config.ts +0 -15
  195. package/src/templates/tanstack-start-2026-06-18/package.json +0 -104
  196. package/src/templates/tanstack-start-2026-06-18/src/components/error-component.tsx +0 -50
  197. package/src/templates/tanstack-start-2026-06-18/src/components/ui/accordion.tsx +0 -51
  198. package/src/templates/tanstack-start-2026-06-18/src/components/ui/alert-dialog.tsx +0 -115
  199. package/src/templates/tanstack-start-2026-06-18/src/components/ui/alert.tsx +0 -49
  200. package/src/templates/tanstack-start-2026-06-18/src/components/ui/aspect-ratio.tsx +0 -5
  201. package/src/templates/tanstack-start-2026-06-18/src/components/ui/avatar.tsx +0 -47
  202. package/src/templates/tanstack-start-2026-06-18/src/components/ui/badge.tsx +0 -32
  203. package/src/templates/tanstack-start-2026-06-18/src/components/ui/breadcrumb.tsx +0 -101
  204. package/src/templates/tanstack-start-2026-06-18/src/components/ui/button.tsx +0 -49
  205. package/src/templates/tanstack-start-2026-06-18/src/components/ui/calendar.tsx +0 -177
  206. package/src/templates/tanstack-start-2026-06-18/src/components/ui/card.tsx +0 -55
  207. package/src/templates/tanstack-start-2026-06-18/src/components/ui/carousel.tsx +0 -240
  208. package/src/templates/tanstack-start-2026-06-18/src/components/ui/chart.tsx +0 -371
  209. package/src/templates/tanstack-start-2026-06-18/src/components/ui/checkbox.tsx +0 -26
  210. package/src/templates/tanstack-start-2026-06-18/src/components/ui/collapsible.tsx +0 -11
  211. package/src/templates/tanstack-start-2026-06-18/src/components/ui/command.tsx +0 -143
  212. package/src/templates/tanstack-start-2026-06-18/src/components/ui/context-menu.tsx +0 -187
  213. package/src/templates/tanstack-start-2026-06-18/src/components/ui/dialog.tsx +0 -104
  214. package/src/templates/tanstack-start-2026-06-18/src/components/ui/drawer.tsx +0 -98
  215. package/src/templates/tanstack-start-2026-06-18/src/components/ui/dropdown-menu.tsx +0 -188
  216. package/src/templates/tanstack-start-2026-06-18/src/components/ui/form.tsx +0 -171
  217. package/src/templates/tanstack-start-2026-06-18/src/components/ui/hover-card.tsx +0 -27
  218. package/src/templates/tanstack-start-2026-06-18/src/components/ui/input-otp.tsx +0 -69
  219. package/src/templates/tanstack-start-2026-06-18/src/components/ui/input.tsx +0 -22
  220. package/src/templates/tanstack-start-2026-06-18/src/components/ui/label.tsx +0 -21
  221. package/src/templates/tanstack-start-2026-06-18/src/components/ui/menubar.tsx +0 -229
  222. package/src/templates/tanstack-start-2026-06-18/src/components/ui/navigation-menu.tsx +0 -120
  223. package/src/templates/tanstack-start-2026-06-18/src/components/ui/pagination.tsx +0 -98
  224. package/src/templates/tanstack-start-2026-06-18/src/components/ui/popover.tsx +0 -31
  225. package/src/templates/tanstack-start-2026-06-18/src/components/ui/progress.tsx +0 -25
  226. package/src/templates/tanstack-start-2026-06-18/src/components/ui/radio-group.tsx +0 -36
  227. package/src/templates/tanstack-start-2026-06-18/src/components/ui/resizable.tsx +0 -37
  228. package/src/templates/tanstack-start-2026-06-18/src/components/ui/scroll-area.tsx +0 -44
  229. package/src/templates/tanstack-start-2026-06-18/src/components/ui/select.tsx +0 -152
  230. package/src/templates/tanstack-start-2026-06-18/src/components/ui/separator.tsx +0 -24
  231. package/src/templates/tanstack-start-2026-06-18/src/components/ui/sheet.tsx +0 -122
  232. package/src/templates/tanstack-start-2026-06-18/src/components/ui/sidebar.tsx +0 -744
  233. package/src/templates/tanstack-start-2026-06-18/src/components/ui/skeleton.tsx +0 -7
  234. package/src/templates/tanstack-start-2026-06-18/src/components/ui/slider.tsx +0 -23
  235. package/src/templates/tanstack-start-2026-06-18/src/components/ui/sonner.tsx +0 -23
  236. package/src/templates/tanstack-start-2026-06-18/src/components/ui/switch.tsx +0 -27
  237. package/src/templates/tanstack-start-2026-06-18/src/components/ui/table.tsx +0 -94
  238. package/src/templates/tanstack-start-2026-06-18/src/components/ui/tabs.tsx +0 -53
  239. package/src/templates/tanstack-start-2026-06-18/src/components/ui/textarea.tsx +0 -21
  240. package/src/templates/tanstack-start-2026-06-18/src/components/ui/toggle-group.tsx +0 -57
  241. package/src/templates/tanstack-start-2026-06-18/src/components/ui/toggle.tsx +0 -42
  242. package/src/templates/tanstack-start-2026-06-18/src/components/ui/tooltip.tsx +0 -32
  243. package/src/templates/tanstack-start-2026-06-18/src/db/index.ts +0 -9
  244. package/src/templates/tanstack-start-2026-06-18/src/db/schema.ts +0 -18
  245. package/src/templates/tanstack-start-2026-06-18/src/global.d.ts +0 -3
  246. package/src/templates/tanstack-start-2026-06-18/src/hooks/use-mobile.tsx +0 -19
  247. package/src/templates/tanstack-start-2026-06-18/src/lib/proxy.ts +0 -119
  248. package/src/templates/tanstack-start-2026-06-18/src/lib/utils.ts +0 -6
  249. package/src/templates/tanstack-start-2026-06-18/src/routeTree.gen.ts +0 -86
  250. package/src/templates/tanstack-start-2026-06-18/src/router.tsx +0 -37
  251. package/src/templates/tanstack-start-2026-06-18/src/routes/README.md +0 -94
  252. package/src/templates/tanstack-start-2026-06-18/src/routes/__root.tsx +0 -65
  253. package/src/templates/tanstack-start-2026-06-18/src/routes/api/health.ts +0 -81
  254. package/src/templates/tanstack-start-2026-06-18/src/routes/index.tsx +0 -33
  255. package/src/templates/tanstack-start-2026-06-18/src/server.ts +0 -32
  256. package/src/templates/tanstack-start-2026-06-18/src/styles.css +0 -214
  257. package/src/templates/tanstack-start-2026-06-18/tsconfig.json +0 -27
  258. package/src/templates/tanstack-start-2026-06-18/vite.config.ts +0 -17
  259. package/src/templates/tanstack-start-2026-07-30/components.json +0 -22
  260. package/src/templates/tanstack-start-2026-07-30/drizzle/meta/_journal.json +0 -1
  261. package/src/templates/tanstack-start-2026-07-30/drizzle.config.ts +0 -18
  262. package/src/templates/tanstack-start-2026-07-30/package.json +0 -103
  263. package/src/templates/tanstack-start-2026-07-30/src/components/error-component.tsx +0 -50
  264. package/src/templates/tanstack-start-2026-07-30/src/components/ui/accordion.tsx +0 -51
  265. package/src/templates/tanstack-start-2026-07-30/src/components/ui/alert-dialog.tsx +0 -115
  266. package/src/templates/tanstack-start-2026-07-30/src/components/ui/alert.tsx +0 -49
  267. package/src/templates/tanstack-start-2026-07-30/src/components/ui/aspect-ratio.tsx +0 -5
  268. package/src/templates/tanstack-start-2026-07-30/src/components/ui/avatar.tsx +0 -47
  269. package/src/templates/tanstack-start-2026-07-30/src/components/ui/badge.tsx +0 -32
  270. package/src/templates/tanstack-start-2026-07-30/src/components/ui/breadcrumb.tsx +0 -101
  271. package/src/templates/tanstack-start-2026-07-30/src/components/ui/button.tsx +0 -49
  272. package/src/templates/tanstack-start-2026-07-30/src/components/ui/calendar.tsx +0 -177
  273. package/src/templates/tanstack-start-2026-07-30/src/components/ui/card.tsx +0 -55
  274. package/src/templates/tanstack-start-2026-07-30/src/components/ui/carousel.tsx +0 -240
  275. package/src/templates/tanstack-start-2026-07-30/src/components/ui/chart.tsx +0 -371
  276. package/src/templates/tanstack-start-2026-07-30/src/components/ui/checkbox.tsx +0 -26
  277. package/src/templates/tanstack-start-2026-07-30/src/components/ui/collapsible.tsx +0 -11
  278. package/src/templates/tanstack-start-2026-07-30/src/components/ui/command.tsx +0 -143
  279. package/src/templates/tanstack-start-2026-07-30/src/components/ui/context-menu.tsx +0 -187
  280. package/src/templates/tanstack-start-2026-07-30/src/components/ui/dialog.tsx +0 -104
  281. package/src/templates/tanstack-start-2026-07-30/src/components/ui/drawer.tsx +0 -98
  282. package/src/templates/tanstack-start-2026-07-30/src/components/ui/dropdown-menu.tsx +0 -188
  283. package/src/templates/tanstack-start-2026-07-30/src/components/ui/form.tsx +0 -171
  284. package/src/templates/tanstack-start-2026-07-30/src/components/ui/hover-card.tsx +0 -27
  285. package/src/templates/tanstack-start-2026-07-30/src/components/ui/input-otp.tsx +0 -69
  286. package/src/templates/tanstack-start-2026-07-30/src/components/ui/input.tsx +0 -22
  287. package/src/templates/tanstack-start-2026-07-30/src/components/ui/label.tsx +0 -21
  288. package/src/templates/tanstack-start-2026-07-30/src/components/ui/menubar.tsx +0 -229
  289. package/src/templates/tanstack-start-2026-07-30/src/components/ui/navigation-menu.tsx +0 -120
  290. package/src/templates/tanstack-start-2026-07-30/src/components/ui/pagination.tsx +0 -98
  291. package/src/templates/tanstack-start-2026-07-30/src/components/ui/popover.tsx +0 -31
  292. package/src/templates/tanstack-start-2026-07-30/src/components/ui/progress.tsx +0 -25
  293. package/src/templates/tanstack-start-2026-07-30/src/components/ui/radio-group.tsx +0 -36
  294. package/src/templates/tanstack-start-2026-07-30/src/components/ui/resizable.tsx +0 -37
  295. package/src/templates/tanstack-start-2026-07-30/src/components/ui/scroll-area.tsx +0 -44
  296. package/src/templates/tanstack-start-2026-07-30/src/components/ui/select.tsx +0 -152
  297. package/src/templates/tanstack-start-2026-07-30/src/components/ui/separator.tsx +0 -24
  298. package/src/templates/tanstack-start-2026-07-30/src/components/ui/sheet.tsx +0 -122
  299. package/src/templates/tanstack-start-2026-07-30/src/components/ui/sidebar.tsx +0 -744
  300. package/src/templates/tanstack-start-2026-07-30/src/components/ui/skeleton.tsx +0 -7
  301. package/src/templates/tanstack-start-2026-07-30/src/components/ui/slider.tsx +0 -23
  302. package/src/templates/tanstack-start-2026-07-30/src/components/ui/sonner.tsx +0 -23
  303. package/src/templates/tanstack-start-2026-07-30/src/components/ui/switch.tsx +0 -27
  304. package/src/templates/tanstack-start-2026-07-30/src/components/ui/table.tsx +0 -94
  305. package/src/templates/tanstack-start-2026-07-30/src/components/ui/tabs.tsx +0 -53
  306. package/src/templates/tanstack-start-2026-07-30/src/components/ui/textarea.tsx +0 -21
  307. package/src/templates/tanstack-start-2026-07-30/src/components/ui/toggle-group.tsx +0 -57
  308. package/src/templates/tanstack-start-2026-07-30/src/components/ui/toggle.tsx +0 -42
  309. package/src/templates/tanstack-start-2026-07-30/src/components/ui/tooltip.tsx +0 -32
  310. package/src/templates/tanstack-start-2026-07-30/src/db/index.ts +0 -9
  311. package/src/templates/tanstack-start-2026-07-30/src/db/schema.ts +0 -34
  312. package/src/templates/tanstack-start-2026-07-30/src/global.d.ts +0 -3
  313. package/src/templates/tanstack-start-2026-07-30/src/hooks/use-mobile.tsx +0 -19
  314. package/src/templates/tanstack-start-2026-07-30/src/lib/kv.ts +0 -37
  315. package/src/templates/tanstack-start-2026-07-30/src/lib/proxy.ts +0 -111
  316. package/src/templates/tanstack-start-2026-07-30/src/lib/storage.ts +0 -45
  317. package/src/templates/tanstack-start-2026-07-30/src/lib/utils.ts +0 -6
  318. package/src/templates/tanstack-start-2026-07-30/src/routeTree.gen.ts +0 -86
  319. package/src/templates/tanstack-start-2026-07-30/src/router.tsx +0 -37
  320. package/src/templates/tanstack-start-2026-07-30/src/routes/README.md +0 -94
  321. package/src/templates/tanstack-start-2026-07-30/src/routes/__root.tsx +0 -65
  322. package/src/templates/tanstack-start-2026-07-30/src/routes/api/health.ts +0 -83
  323. package/src/templates/tanstack-start-2026-07-30/src/routes/index.tsx +0 -33
  324. package/src/templates/tanstack-start-2026-07-30/src/server.ts +0 -32
  325. package/src/templates/tanstack-start-2026-07-30/src/styles.css +0 -214
  326. package/src/templates/tanstack-start-2026-07-30/tsconfig.json +0 -27
  327. package/src/templates/tanstack-start-2026-07-30/vite.config.ts +0 -17
  328. package/src/tools/create-plan.ts +0 -61
  329. package/src/tools/inspect-http.ts +0 -276
  330. package/src/tools/list-plans.ts +0 -85
  331. package/src/tools/modify-plan.ts +0 -79
  332. package/src/tools/remove.ts +0 -53
  333. package/src/tools/scaffold.ts +0 -213
  334. package/src/tools/setup-authentication/auth-files.ts +0 -144
  335. package/src/tools/setup-authentication/constants.ts +0 -19
  336. package/src/tools/setup-authentication/db-schema.ts +0 -96
  337. package/src/tools/setup-authentication/index.ts +0 -148
  338. package/src/tools/setup-authentication/package-json.ts +0 -17
  339. package/src/tools/setup-authentication/pages.ts +0 -241
  340. package/src/tools/setup-netsuite.ts +0 -1404
@@ -1,213 +0,0 @@
1
- import { mkdir } from "node:fs/promises";
2
- import path from "node:path";
3
- import type { Plugin } from "@opencode-ai/plugin";
4
- import { tool } from "@opencode-ai/plugin";
5
- import { z } from "zod/v4";
6
- import { renderTemplate } from "../template-render.ts";
7
-
8
- /**
9
- * Scaffold template identifiers, keyed by project type. Each value is the
10
- * directory name under src/templates/ and is written to .leo/project.json so
11
- * the webapp / leo-core can tell which template (and therefore which
12
- * conventions) a workspace was bootstrapped with. Bump a value (and add a new
13
- * templates/<id>/ dir) when that scaffold's shape changes.
14
- *
15
- * - tanstack-start: SSR Worker with file routing, API routes, and a database,
16
- * KV and bucket via @helloleo/runtime.
17
- * - tanstack-router: client-only SPA (Vite + index.html entry), no server and
18
- * no database.
19
- */
20
- export const SCAFFOLD_TEMPLATES = {
21
- "tanstack-start": "tanstack-start-2026-07-30",
22
- "tanstack-router": "tanstack-router-2026-06-15",
23
- } as const;
24
-
25
- export type ScaffoldType = keyof typeof SCAFFOLD_TEMPLATES;
26
-
27
- /**
28
- * Older template ids that still ship under src/templates/ and stay valid
29
- * PLUGINS_SCAFFOLD_VERSION pins (a deployment may hold back a version).
30
- */
31
- export const LEGACY_TEMPLATES = ["tanstack-start-2026-06-18"] as const;
32
-
33
- /** Default template id, kept for callers that predate the `type` param. */
34
- export const SCAFFOLD_VERSION = SCAFFOLD_TEMPLATES["tanstack-start"];
35
-
36
- /**
37
- * Resolve which template to render.
38
- *
39
- * The container can pin the template via PLUGINS_SCAFFOLD_VERSION (a versioned
40
- * template id, e.g. "tanstack-start-2026-06-18"); unknown values are ignored
41
- * so a stale env var can never reproduce the ENOENT-on-missing-template
42
- * failure. An explicit `type` from the tool call wins the FAMILY (start vs
43
- * router); the pin still supplies the version when it points inside that
44
- * family. With neither, the pin decides, falling back to the router template.
45
- */
46
- export function resolveTemplateId(type?: ScaffoldType): string {
47
- const version = process.env.PLUGINS_SCAFFOLD_VERSION;
48
- const known: string[] = [
49
- ...Object.values(SCAFFOLD_TEMPLATES),
50
- ...LEGACY_TEMPLATES,
51
- ];
52
- const pinned = version && known.includes(version) ? version : undefined;
53
- if (type) {
54
- return pinned?.startsWith(type) ? pinned : SCAFFOLD_TEMPLATES[type];
55
- }
56
- return pinned ?? SCAFFOLD_TEMPLATES["tanstack-router"];
57
- }
58
-
59
- /**
60
- * The project workspace directory is named after the project UUID -- the
61
- * webapp generates `<slugified-name>-<uuidv4>` (actions.ts createProject)
62
- * and leo-core mounts the project at /workspace/<uuid>. Baking it into
63
- * proxy.ts at scaffold time removes the VITE_PROJECT_UUID env var, which
64
- * nothing in the infrastructure ever set and which Leo kept mis-generating.
65
- */
66
- export function projectUuidFromDir(dir: string): string {
67
- return path.basename(dir);
68
- }
69
-
70
- /**
71
- * Integration-proxy base URL, provided by the opencode container via
72
- * PLUGINS_INTEGRATION_PROXY_URL (like PLUGINS_SCAFFOLD_VERSION) so each deployment
73
- * (dev | preprod | prod) bakes its own proxy host into proxy.ts at scaffold
74
- * time -- previews and published apps use the same value. Unset falls back
75
- * to prod so a missing env var can never break production scaffolds.
76
- */
77
- export function integrationProxyUrl(projectUuid: string): string {
78
- const base = (
79
- process.env.PLUGINS_INTEGRATION_PROXY_URL || "https://api.app.helloleo.dev"
80
- ).replace(/\/+$/, "");
81
-
82
- return `${base}/api/integration-proxy/${projectUuid}`;
83
- }
84
-
85
- const scaffoldOptionsSchema = z.object({
86
- name: z
87
- .string()
88
- .describe("Human-readable name for SEO, e.g. 'Shipping Platform'"),
89
- description: z
90
- .string()
91
- .describe("One sentence describing the app. Used as the meta description."),
92
- type: z
93
- .enum(["tanstack-start", "tanstack-router"])
94
- .optional()
95
- .describe(
96
- "Project type. 'tanstack-start': SSR app with API routes and a " +
97
- "database, KV and bucket — use it whenever the app needs to " +
98
- "persist data or run server-side code, and always for " +
99
- "setup_authentication (it needs server routes). " +
100
- "'tanstack-router': client-only SPA with no server and no database " +
101
- "— use it only for pure frontends that talk to external APIs. " +
102
- "Omit to use the deployment's default.",
103
- ),
104
- });
105
-
106
- /** Kebab-case slug of the product name, for package.json. */
107
- function slugify(name: string): string {
108
- return (
109
- name
110
- .toLowerCase()
111
- .replace(/[^a-z0-9]+/g, "-")
112
- .replace(/^-+|-+$/g, "") || "leo-project"
113
- );
114
- }
115
-
116
- /**
117
- * Write the base scaffold by rendering the template for the requested type
118
- * into dir, then adding .leo/project.json (template metadata the tool owns,
119
- * not part of the template tree). Returns the relative paths written.
120
- */
121
- export async function writeBaseScaffold(
122
- { name, description, type }: z.infer<typeof scaffoldOptionsSchema>,
123
- dir: string,
124
- ): Promise<string[]> {
125
- const templateId = resolveTemplateId(type);
126
- const projectUuid = projectUuidFromDir(dir);
127
- const created = await renderTemplate(
128
- templateId,
129
- {
130
- LEO_NAME: name,
131
- LEO_SLUG: slugify(name),
132
- LEO_DESCRIPTION: description,
133
- LEO_PROJECT_UUID: projectUuid,
134
- LEO_INTEGRATION_PROXY_URL: integrationProxyUrl(projectUuid),
135
- },
136
- dir,
137
- );
138
-
139
- await mkdir(path.join(dir, ".leo"), { recursive: true });
140
- const leoPath = path.join(".leo", "project.json");
141
- await Bun.write(
142
- path.join(dir, leoPath),
143
- JSON.stringify({ $schema: 1, scaffold: templateId }, null, 2),
144
- );
145
-
146
- return [...created, leoPath];
147
- }
148
-
149
- export const scaffold = tool({
150
- description:
151
- "Scaffold a new project with React 19, file-based routing (TanStack), " +
152
- "Tailwind v4, shadcn/ui, and react-query. Two types: 'tanstack-start' " +
153
- "(SSR, API routes, and a database, KV and bucket via @helloleo/runtime) " +
154
- "or 'tanstack-router' (client-only SPA, no server, no database). Call " +
155
- "this first for any new project, before writing routes or components.",
156
- args: {
157
- name: scaffoldOptionsSchema.shape.name,
158
- description: scaffoldOptionsSchema.shape.description,
159
- type: scaffoldOptionsSchema.shape.type,
160
- },
161
- async execute(args, context) {
162
- const isStart = resolveTemplateId(args.type).startsWith("tanstack-start");
163
- const created = await writeBaseScaffold(args, context.directory);
164
- const uiComponents = created.filter((f) =>
165
- f.startsWith("src/components/ui/"),
166
- );
167
- const rest = created.filter((f) => !f.startsWith("src/components/ui/"));
168
-
169
- const typeNotes = isStart
170
- ? [
171
- "- This is a TanStack Start project. The server entry is src/server.ts. There is no index.html or client entrypoint.",
172
- "- For JSON/CRUD APIs, add server routes under src/routes/api/. Read src/routes/api/health.ts first, add routes as needed.",
173
- "- The database schema lives in src/db/schema.ts and is the single source of truth. Migration files under drizzle/ are generated and applied automatically. Never create, edit or delete them.",
174
- "- Never rename existing tables or columns in schema.ts. Renames cannot be auto-migrated: no migration file is generated, the database keeps the old name, and every query against the new name fails at runtime with a 500. To reshape data, add a new column or table, write to it, and migrate old values in app code (e.g. fall back to the old column on read).",
175
- "- Persistence goes through @helloleo/runtime exclusively: database via #/db (see src/db/index.ts), key-value store via #/lib/kv (see src/lib/kv.ts), file storage via #/lib/storage (see src/lib/storage.ts -- uploads/downloads flow through your API routes; presigned URLs are NOT available), env/secrets via env from @helloleo/runtime. Read those files before server-side data work. Never install another DB/storage client, never import from cloudflare:workers, all of it is server-side only.",
176
- ]
177
- : [
178
- "- This is a TanStack Router SPA. The client entry is index.html -> src/main.tsx. There is no server: no API routes, no server functions, no database.",
179
- "- Fetch data from external APIs only. If the app needs its own persistence or server-side code, it should have been scaffolded as tanstack-start.",
180
- ];
181
-
182
- const nextSteps = isStart
183
- ? [
184
- "Next: read src/routes/index.tsx and continue with the user's request.",
185
- "For authentication (password and/or OAuth), call setup_authentication.",
186
- "For NetSuite projects, call setup_netsuite.",
187
- ]
188
- : [
189
- "Next: read src/routes/index.tsx and continue with the user's request.",
190
- ];
191
-
192
- return [
193
- `Scaffolded ${created.length} files:`,
194
- ...rest.map((f) => ` - ${f}`),
195
- ` - src/components/ui/ (${uiComponents.length} shadcn/ui components)`,
196
- "",
197
- "Notes:",
198
- ...typeNotes,
199
- "- Add routes as files in src/routes/. Do not default export route components. Routing and layout conventions are documented in src/routes/README.md, read it before adding routes.",
200
- "- shadcn/ui components are already in src/components/ui.",
201
- "- Design system: style exclusively with the token utilities, never hardcoded colors. To change the look, edit the token values in src/styles.css (light and dark blocks).",
202
- "- Always fetch data with react-query (useQuery and useMutation).",
203
- "",
204
- ...nextSteps,
205
- ].join("\n");
206
- },
207
- });
208
-
209
- export const ScaffoldPlugin: Plugin = async () => {
210
- return {
211
- tool: { scaffold: scaffold },
212
- };
213
- };
@@ -1,144 +0,0 @@
1
- import type { OAuthProvider, Provider } from "./constants.ts";
2
-
3
- /**
4
- * getAuth() builds the betterAuth instance lazily, on first call from
5
- * INSIDE a request -- never a module-scope `export const auth =
6
- * betterAuth(...)` like better-auth's own docs show. `db` (the app's #/db)
7
- * is a lazy Proxy over the D1 binding, and env.* Worker secrets don't exist
8
- * until a request is in flight; touching either while workerd boots the
9
- * isolate throws. `instance`'s type is inferred from `buildAuth`'s own
10
- * return type (not a hand-written `BetterAuthOptions` annotation) -- with
11
- * secret/clientId/clientSecret resolved to plain `string` at runtime via
12
- * requireEnv, an explicit `ReturnType<typeof betterAuth>` annotation
13
- * mismatches on optionality and fails to typecheck.
14
- */
15
- export function authLibTs(providers: Provider[]): string {
16
- const hasPassword = providers.includes("password");
17
- const oauth = providers.filter((p): p is OAuthProvider => p !== "password");
18
-
19
- const envFields = [
20
- "BETTER_AUTH_SECRET?: string",
21
- "HELLOLEO_URL?: string",
22
- ...oauth.flatMap((p) => {
23
- const prefix = p.toUpperCase();
24
- return [
25
- `${prefix}_CLIENT_ID?: string`,
26
- `${prefix}_CLIENT_SECRET?: string`,
27
- ];
28
- }),
29
- ].join("\n ");
30
-
31
- const socialProvidersBlock = oauth.length
32
- ? `
33
- socialProviders: {
34
- ${oauth
35
- .map((p) => {
36
- const prefix = p.toUpperCase();
37
- return ` ${p}: { clientId: requireEnv(e.${prefix}_CLIENT_ID, '${prefix}_CLIENT_ID'), clientSecret: requireEnv(e.${prefix}_CLIENT_SECRET, '${prefix}_CLIENT_SECRET') },`;
38
- })
39
- .join("\n")}
40
- },`
41
- : "";
42
-
43
- const requireEnvFn = oauth.length
44
- ? `
45
- function requireEnv(value: string | undefined, name: string): string {
46
- if (!value) {
47
- throw new Error(\`\${name} is not set. Add it to .env.\`)
48
- }
49
- return value
50
- }
51
- `
52
- : "";
53
-
54
- return `import { betterAuth } from 'better-auth'
55
- import { drizzleAdapter } from '@better-auth/drizzle-adapter'
56
- import { tanstackStartCookies } from 'better-auth/tanstack-start'
57
- import { db } from '#/db'
58
- import * as schema from '#/db/schema'
59
- import { env } from '@helloleo/runtime'
60
-
61
- /*
62
- * buildAuth() only runs from INSIDE a request (see getAuth() below) --
63
- * never call it at module scope. \`db\` is a lazy Proxy over the D1 binding
64
- * and env.* Worker secrets don't exist until a request is in flight;
65
- * touching either while workerd boots the isolate throws.
66
- */
67
- ${requireEnvFn}
68
- function buildAuth() {
69
- const e = env as {
70
- ${envFields}
71
- }
72
-
73
- // HELLOLEO_URL is injected by the platform as a bare host, no scheme.
74
- return betterAuth({
75
- secret: e.BETTER_AUTH_SECRET,
76
- baseURL: e.HELLOLEO_URL ? \`https://\${e.HELLOLEO_URL}\` : 'http://localhost:3000',
77
- database: drizzleAdapter(db, { provider: 'sqlite', schema }),
78
- emailAndPassword: {
79
- enabled: ${hasPassword},
80
- },${socialProvidersBlock}
81
- // The preview runs inside an iframe on another site, so the session
82
- // cookie lives in a third-party context: it MUST be SameSite=None +
83
- // Secure + Partitioned (CHIPS) or Chrome/Safari silently drop it and
84
- // login never sticks.
85
- advanced: {
86
- defaultCookieAttributes: {
87
- sameSite: 'none',
88
- secure: true,
89
- partitioned: true,
90
- },
91
- },
92
- plugins: [tanstackStartCookies()],
93
- })
94
- }
95
-
96
- let instance: ReturnType<typeof buildAuth> | undefined
97
-
98
- export function getAuth() {
99
- if (!instance) instance = buildAuth()
100
- return instance
101
- }
102
- `;
103
- }
104
-
105
- export function authClientTs(): string {
106
- return `import { createAuthClient } from 'better-auth/react'
107
-
108
- export const authClient = createAuthClient()
109
- `;
110
- }
111
-
112
- export function authServerTs(): string {
113
- return `import { createServerFn } from '@tanstack/react-start'
114
- import { getRequestHeaders } from '@tanstack/react-start/server'
115
- import { getAuth } from '#/lib/auth'
116
-
117
- export const getSession = createServerFn({ method: 'GET' }).handler(async () => {
118
- const headers = getRequestHeaders()
119
- return getAuth().api.getSession({ headers })
120
- })
121
-
122
- export const ensureSession = createServerFn({ method: 'GET' }).handler(async () => {
123
- const headers = getRequestHeaders()
124
- const session = await getAuth().api.getSession({ headers })
125
- if (!session) throw new Error('Unauthorized')
126
- return session
127
- })
128
- `;
129
- }
130
-
131
- export function authRouteTs(): string {
132
- return `import { createFileRoute } from '@tanstack/react-router'
133
- import { getAuth } from '#/lib/auth'
134
-
135
- export const Route = createFileRoute('/api/auth/$')({
136
- server: {
137
- handlers: {
138
- GET: ({ request }: { request: Request }) => getAuth().handler(request),
139
- POST: ({ request }: { request: Request }) => getAuth().handler(request),
140
- },
141
- },
142
- })
143
- `;
144
- }
@@ -1,19 +0,0 @@
1
- export const PROVIDERS = [
2
- "password",
3
- "google",
4
- "github",
5
- "discord",
6
- "microsoft",
7
- ] as const;
8
-
9
- export type Provider = (typeof PROVIDERS)[number];
10
- export type OAuthProvider = Exclude<Provider, "password">;
11
-
12
- export const PROVIDER_LABELS: Record<OAuthProvider, string> = {
13
- google: "Google",
14
- github: "GitHub",
15
- discord: "Discord",
16
- microsoft: "Microsoft",
17
- };
18
-
19
- export const BETTER_AUTH_VERSION = "^1.6.23";
@@ -1,96 +0,0 @@
1
- import { readFile } from "node:fs/promises";
2
- import path from "node:path";
3
-
4
- /**
5
- * user/session/account/verification, hand-written to match better-auth's
6
- * documented drizzle/sqlite schema exactly (text ids, no relations --
7
- * experimental.joins is not enabled). Appended into src/db/schema.ts --
8
- * drizzle.config.ts hardcodes that file as the one schema source, and this
9
- * template's dev/prod pipeline is drizzle-kit push / wrangler d1
10
- * migrations, not better-auth's own Kysely-based migration runner.
11
- */
12
- const SCHEMA_MARKER = "sqliteTable('user'";
13
-
14
- function authTablesBlock(): string {
15
- return `
16
- export const user = sqliteTable('user', {
17
- id: text('id').primaryKey(),
18
- name: text('name').notNull(),
19
- email: text('email').notNull().unique(),
20
- emailVerified: integer('email_verified', { mode: 'boolean' }).default(false).notNull(),
21
- image: text('image'),
22
- createdAt: integer('created_at', { mode: 'timestamp_ms' })
23
- .default(sql\`(cast(unixepoch('subsecond') * 1000 as integer))\`)
24
- .notNull(),
25
- updatedAt: integer('updated_at', { mode: 'timestamp_ms' })
26
- .default(sql\`(cast(unixepoch('subsecond') * 1000 as integer))\`)
27
- .$onUpdate(() => new Date())
28
- .notNull(),
29
- })
30
-
31
- export const session = sqliteTable('session', {
32
- id: text('id').primaryKey(),
33
- expiresAt: integer('expires_at', { mode: 'timestamp_ms' }).notNull(),
34
- token: text('token').notNull().unique(),
35
- createdAt: integer('created_at', { mode: 'timestamp_ms' })
36
- .default(sql\`(cast(unixepoch('subsecond') * 1000 as integer))\`)
37
- .notNull(),
38
- updatedAt: integer('updated_at', { mode: 'timestamp_ms' })
39
- .$onUpdate(() => new Date())
40
- .notNull(),
41
- ipAddress: text('ip_address'),
42
- userAgent: text('user_agent'),
43
- userId: text('user_id')
44
- .notNull()
45
- .references(() => user.id, { onDelete: 'cascade' }),
46
- })
47
-
48
- export const account = sqliteTable('account', {
49
- id: text('id').primaryKey(),
50
- accountId: text('account_id').notNull(),
51
- providerId: text('provider_id').notNull(),
52
- userId: text('user_id')
53
- .notNull()
54
- .references(() => user.id, { onDelete: 'cascade' }),
55
- accessToken: text('access_token'),
56
- refreshToken: text('refresh_token'),
57
- idToken: text('id_token'),
58
- accessTokenExpiresAt: integer('access_token_expires_at', { mode: 'timestamp_ms' }),
59
- refreshTokenExpiresAt: integer('refresh_token_expires_at', { mode: 'timestamp_ms' }),
60
- scope: text('scope'),
61
- password: text('password'),
62
- createdAt: integer('created_at', { mode: 'timestamp_ms' })
63
- .default(sql\`(cast(unixepoch('subsecond') * 1000 as integer))\`)
64
- .notNull(),
65
- updatedAt: integer('updated_at', { mode: 'timestamp_ms' })
66
- .$onUpdate(() => new Date())
67
- .notNull(),
68
- })
69
-
70
- export const verification = sqliteTable('verification', {
71
- id: text('id').primaryKey(),
72
- identifier: text('identifier').notNull(),
73
- value: text('value').notNull(),
74
- expiresAt: integer('expires_at', { mode: 'timestamp_ms' }).notNull(),
75
- createdAt: integer('created_at', { mode: 'timestamp_ms' })
76
- .default(sql\`(cast(unixepoch('subsecond') * 1000 as integer))\`)
77
- .notNull(),
78
- updatedAt: integer('updated_at', { mode: 'timestamp_ms' })
79
- .default(sql\`(cast(unixepoch('subsecond') * 1000 as integer))\`)
80
- .$onUpdate(() => new Date())
81
- .notNull(),
82
- })
83
- `;
84
- }
85
-
86
- /** Appends the auth tables to src/db/schema.ts. Idempotent; returns whether it wrote anything. */
87
- export async function appendAuthTables(dir: string): Promise<boolean> {
88
- const schemaPath = path.join(dir, "src", "db", "schema.ts");
89
- const current = await readFile(schemaPath, "utf8").catch(() => null);
90
- if (current === null) {
91
- throw new Error("src/db/schema.ts not found -- run scaffold first.");
92
- }
93
- if (current.includes(SCHEMA_MARKER)) return false;
94
- await Bun.write(schemaPath, `${current.trimEnd()}\n${authTablesBlock()}`);
95
- return true;
96
- }
@@ -1,148 +0,0 @@
1
- import path from "node:path";
2
- import type { Plugin } from "@opencode-ai/plugin";
3
- import { tool } from "@opencode-ai/plugin";
4
- import { z } from "zod/v4";
5
- import {
6
- authClientTs,
7
- authLibTs,
8
- authRouteTs,
9
- authServerTs,
10
- } from "./auth-files.ts";
11
- import type { OAuthProvider } from "./constants.ts";
12
- import { PROVIDER_LABELS, PROVIDERS } from "./constants.ts";
13
- import { appendAuthTables } from "./db-schema.ts";
14
- import { addAuthDependencies } from "./package-json.ts";
15
- import {
16
- authedLayoutTsx,
17
- dashboardPageTsx,
18
- loginPageTsx,
19
- signupPageTsx,
20
- } from "./pages.ts";
21
-
22
- /**
23
- * Adds authentication on top of an existing scaffold via better-auth:
24
- * email/password and/or social sign-in (google/github/discord/microsoft),
25
- * a drizzle-backed session store, and login/signup routes.
26
- *
27
- * Only additive files are written, except `src/db/schema.ts` (appended,
28
- * never replaced) and `package.json` (two deps added if missing).
29
- *
30
- * Mutually exclusive with setup_netsuite: both own src/routes/login.tsx and
31
- * the app's one auth strategy. Called AFTER `scaffold`, never instead of it.
32
- *
33
- * Only applies to full-stack (tanstack-start) scaffolds: the files it writes
34
- * assume a server (API routes, drizzle schema). On a tanstack-router SPA it
35
- * returns an error instead of writing broken server code.
36
- */
37
-
38
- /**
39
- * Scaffold id recorded by the scaffold tool in .leo/project.json, or null if
40
- * the file is missing/unreadable (pre-project.json workspaces: don't block).
41
- */
42
- async function readScaffoldId(dir: string): Promise<string | null> {
43
- try {
44
- const meta = await Bun.file(path.join(dir, ".leo", "project.json")).json();
45
- return typeof meta?.scaffold === "string" ? meta.scaffold : null;
46
- } catch {
47
- return null;
48
- }
49
- }
50
- export const setupAuthentication = tool({
51
- description:
52
- "Add authentication to an existing project via better-auth. Call scaffold first, " +
53
- "then this. providers: 'password' for email/password, plus any of " +
54
- "'google' | 'github' | 'discord' | 'microsoft' for social sign-in -- pass any " +
55
- "combination. Mutually exclusive with setup_netsuite: an app has one auth " +
56
- "strategy, not two. Only for full-stack (tanstack-start) scaffolds; errors " +
57
- "on client-only SPA projects.",
58
- args: {
59
- providers: z
60
- .array(z.enum(PROVIDERS))
61
- .min(1)
62
- .describe("Auth methods to enable, e.g. ['password', 'google']"),
63
- },
64
- async execute({ providers }, context) {
65
- const dir = context.directory;
66
-
67
- const scaffoldId = await readScaffoldId(dir);
68
- if (scaffoldId !== null && !scaffoldId.startsWith("tanstack-start")) {
69
- return [
70
- "Error: setup_authentication is for full-stack applications and is not applicable to HelloLeo Cloud.",
71
- "This project is a client-only SPA (tanstack-router): no server, no API routes, no database, so the files this tool writes cannot work here.",
72
- "Do not mention this error to the user. Continue by setting up authentication manually by activating HelloLeo Backend and using the MCP.",
73
- ].join("\n");
74
- }
75
-
76
- const hasPassword = providers.includes("password");
77
- const oauth = providers.filter((p): p is OAuthProvider => p !== "password");
78
-
79
- const files: [string, string][] = [
80
- [path.join("src", "lib", "auth.ts"), authLibTs(providers)],
81
- [path.join("src", "lib", "auth-client.ts"), authClientTs()],
82
- [path.join("src", "lib", "auth-server.ts"), authServerTs()],
83
- [path.join("src", "routes", "api", "auth", "$.ts"), authRouteTs()],
84
- [path.join("src", "routes", "_authed.tsx"), authedLayoutTsx()],
85
- [
86
- path.join("src", "routes", "_authed", "dashboard.tsx"),
87
- dashboardPageTsx(),
88
- ],
89
- [
90
- path.join("src", "routes", "login.tsx"),
91
- loginPageTsx(hasPassword, oauth),
92
- ],
93
- ];
94
- if (hasPassword) {
95
- files.push([path.join("src", "routes", "signup.tsx"), signupPageTsx()]);
96
- }
97
-
98
- for (const [filePath, content] of files) {
99
- await Bun.write(path.join(dir, filePath), content);
100
- }
101
-
102
- const schemaAppended = await appendAuthTables(dir);
103
- const depsAdded = await addAuthDependencies(dir);
104
-
105
- const envLines = [
106
- " - dev (.env): BETTER_AUTH_SECRET=<random>",
107
- " - prod: `wrangler secret put BETTER_AUTH_SECRET`",
108
- " - HELLOLEO_URL is auto-injected by the platform (preview + production) -- nothing to set for baseURL",
109
- ];
110
- for (const p of oauth) {
111
- const prefix = p.toUpperCase();
112
- envLines.push(
113
- ` - ${PROVIDER_LABELS[p]}: ${prefix}_CLIENT_ID / ${prefix}_CLIENT_SECRET (dev: .env, prod: wrangler secret put)`,
114
- );
115
- }
116
-
117
- return [
118
- `Wrote authentication (better-auth, providers: ${providers.join(", ")}):`,
119
- " - src/lib/auth.ts (lazy betterAuth instance -- read the comment on why it's not a module-scope export)",
120
- " - src/lib/auth-client.ts (React client -- authClient.signIn.email/social, signUp.email, signOut)",
121
- " - src/lib/auth-server.ts (getSession/ensureSession server functions, for SSR route guards)",
122
- " - src/routes/api/auth/$.ts (catch-all handler)",
123
- " - src/routes/_authed.tsx (pathless guard for protected routes)",
124
- " - src/routes/_authed/dashboard.tsx (example protected page -- _authed needs at least one child route or it collides with index.tsx on '/')",
125
- ` - src/routes/login.tsx${hasPassword ? ", src/routes/signup.tsx" : ""}`,
126
- ` - src/db/schema.ts ${schemaAppended ? "(appended user/session/account/verification tables)" : "(already had a `user` table, left as-is)"}`,
127
- ` - package.json ${depsAdded ? "(added better-auth, @better-auth/drizzle-adapter)" : "(dependencies already present)"}`,
128
- "",
129
- "Run `bun install`, then `bun run db:push` (or just `bun dev`, which runs it first) to create the new tables.",
130
- "",
131
- "Required env vars/secrets:",
132
- ...envLines,
133
- "",
134
- "Add more protected pages under src/routes/_authed/ (e.g. _authed/settings.tsx -> /settings); they inherit the guard.",
135
- "",
136
- "Verify before shipping: password hashing defaults to scrypt via Node's crypto, exposed through the " +
137
- "nodejs_compat flag (already on for this template) -- confirm a real sign-up/login round-trip works in `bun dev`.",
138
- "",
139
- "Mutually exclusive with setup_netsuite -- an app has one auth strategy, not two.",
140
- ].join("\n");
141
- },
142
- });
143
-
144
- export const SetupAuthenticationPlugin: Plugin = async () => {
145
- return {
146
- tool: { setup_authentication: setupAuthentication },
147
- };
148
- };
@@ -1,17 +0,0 @@
1
- import { readFile } from "node:fs/promises";
2
- import path from "node:path";
3
- import { BETTER_AUTH_VERSION } from "./constants.ts";
4
-
5
- /** Adds better-auth + its drizzle adapter to the project's package.json. Idempotent. */
6
- export async function addAuthDependencies(dir: string): Promise<boolean> {
7
- const pkgPath = path.join(dir, "package.json");
8
- const pkg = JSON.parse(await readFile(pkgPath, "utf8")) as {
9
- dependencies?: Record<string, string>;
10
- };
11
- pkg.dependencies ??= {};
12
- if (pkg.dependencies["better-auth"]) return false;
13
- pkg.dependencies["better-auth"] = BETTER_AUTH_VERSION;
14
- pkg.dependencies["@better-auth/drizzle-adapter"] = BETTER_AUTH_VERSION;
15
- await Bun.write(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
16
- return true;
17
- }