@tanstack/cta-engine 0.10.0-alpha.21 → 0.10.0-alpha.25

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/add-ons.js +91 -5
  2. package/dist/add.js +125 -0
  3. package/dist/cli.js +132 -0
  4. package/dist/config-file.js +9 -14
  5. package/dist/constants.js +2 -0
  6. package/dist/create-app.js +451 -142
  7. package/dist/custom-add-on.js +254 -0
  8. package/dist/environment.js +32 -64
  9. package/dist/file-helper.js +18 -0
  10. package/dist/index.js +1 -17
  11. package/dist/mcp.js +229 -0
  12. package/dist/options.js +333 -9
  13. package/dist/package-manager.js +6 -51
  14. package/dist/templates.js +6 -0
  15. package/dist/toolchain.js +6 -0
  16. package/dist/types/add-ons.d.ts +8 -3
  17. package/dist/types/add.d.ts +3 -0
  18. package/dist/types/cli.d.ts +7 -0
  19. package/dist/types/config-file.d.ts +4 -6
  20. package/dist/types/constants.d.ts +3 -0
  21. package/dist/types/create-app.d.ts +7 -1
  22. package/dist/types/custom-add-on.d.ts +3 -0
  23. package/dist/types/environment.d.ts +1 -2
  24. package/dist/types/file-helper.d.ts +2 -0
  25. package/dist/types/index.d.ts +1 -20
  26. package/dist/types/mcp.d.ts +7 -0
  27. package/dist/types/options.d.ts +6 -2
  28. package/dist/types/package-manager.d.ts +1 -18
  29. package/dist/types/templates.d.ts +1 -0
  30. package/dist/types/toolchain.d.ts +3 -0
  31. package/dist/types/types.d.ts +85 -788
  32. package/dist/types/utils.d.ts +0 -5
  33. package/dist/types.js +1 -65
  34. package/dist/utils.js +0 -9
  35. package/package.json +12 -9
  36. package/src/add-ons.ts +123 -7
  37. package/src/add.ts +186 -0
  38. package/src/cli.ts +210 -0
  39. package/src/config-file.ts +17 -26
  40. package/src/constants.ts +5 -0
  41. package/src/create-app.ts +730 -180
  42. package/src/custom-add-on.ts +325 -0
  43. package/src/environment.ts +33 -77
  44. package/src/file-helper.ts +20 -0
  45. package/src/index.ts +1 -77
  46. package/src/mcp.ts +302 -0
  47. package/src/options.ts +409 -8
  48. package/src/package-manager.ts +9 -80
  49. package/src/templates.ts +7 -0
  50. package/src/toolchain.ts +7 -0
  51. package/src/types.ts +87 -175
  52. package/src/utils.ts +0 -17
  53. package/templates/react/add-on/clerk/README.md +3 -0
  54. package/templates/react/add-on/clerk/assets/_dot_env.local.append +2 -0
  55. package/templates/react/add-on/clerk/assets/src/integrations/clerk/header-user.tsx +19 -0
  56. package/templates/react/add-on/clerk/assets/src/integrations/clerk/provider.tsx +18 -0
  57. package/templates/react/add-on/clerk/assets/src/routes/demo.clerk.tsx +20 -0
  58. package/templates/react/add-on/clerk/info.json +13 -0
  59. package/templates/react/add-on/clerk/package.json +5 -0
  60. package/templates/react/add-on/convex/README.md +4 -0
  61. package/templates/react/add-on/convex/assets/_dot_cursorrules.append +93 -0
  62. package/templates/react/add-on/convex/assets/_dot_env.local.append +3 -0
  63. package/templates/react/add-on/convex/assets/convex/products.ts +8 -0
  64. package/templates/react/add-on/convex/assets/convex/schema.ts +10 -0
  65. package/templates/react/add-on/convex/assets/src/integrations/convex/provider.tsx +20 -0
  66. package/templates/react/add-on/convex/assets/src/routes/demo.convex.tsx +33 -0
  67. package/templates/react/add-on/convex/info.json +13 -0
  68. package/templates/react/add-on/convex/package.json +6 -0
  69. package/templates/react/add-on/form/assets/src/components/demo.FormComponents.tsx.ejs +300 -0
  70. package/templates/react/add-on/form/assets/src/hooks/demo.form-context.ts +4 -0
  71. package/templates/react/add-on/form/assets/src/hooks/demo.form.ts +22 -0
  72. package/templates/react/add-on/form/assets/src/routes/demo.form.address.tsx.ejs +213 -0
  73. package/templates/react/add-on/form/assets/src/routes/demo.form.simple.tsx.ejs +77 -0
  74. package/templates/react/add-on/form/info.json +26 -0
  75. package/templates/react/add-on/form/package.json +6 -0
  76. package/templates/react/add-on/module-federation/assets/module-federation.config.js.ejs +31 -0
  77. package/templates/react/add-on/module-federation/assets/src/demo-mf-component.tsx +3 -0
  78. package/templates/react/add-on/module-federation/assets/src/demo-mf-self-contained.tsx +11 -0
  79. package/templates/react/add-on/module-federation/info.json +7 -0
  80. package/templates/react/add-on/module-federation/package.json +5 -0
  81. package/templates/react/add-on/netlify/README.md +11 -0
  82. package/templates/react/add-on/netlify/info.json +7 -0
  83. package/templates/react/add-on/sentry/assets/_dot_cursorrules.append +22 -0
  84. package/templates/react/add-on/sentry/assets/_dot_env.local.append +11 -0
  85. package/templates/react/add-on/sentry/assets/src/app/global-middleware.ts +11 -0
  86. package/templates/react/add-on/sentry/assets/src/routes/demo.sentry.testing.tsx +489 -0
  87. package/templates/react/add-on/sentry/info.json +14 -0
  88. package/templates/react/add-on/sentry/package.json +5 -0
  89. package/templates/react/add-on/shadcn/README.md +7 -0
  90. package/templates/react/add-on/shadcn/assets/_dot_cursorrules.append +7 -0
  91. package/templates/react/add-on/shadcn/assets/components.json +21 -0
  92. package/templates/react/add-on/shadcn/assets/src/lib/utils.ts +6 -0
  93. package/templates/react/add-on/shadcn/assets/src/styles.css +138 -0
  94. package/templates/react/add-on/shadcn/info.json +7 -0
  95. package/templates/react/add-on/shadcn/package.json +9 -0
  96. package/templates/react/add-on/start/assets/_dot_gitignore.append +2 -0
  97. package/templates/react/add-on/start/assets/app.config.ts.ejs +32 -0
  98. package/templates/react/add-on/start/assets/src/api.ts +6 -0
  99. package/templates/react/add-on/start/assets/src/client.tsx.ejs +33 -0
  100. package/templates/react/add-on/start/assets/src/router.tsx.ejs +48 -0
  101. package/templates/react/add-on/start/assets/src/routes/api.demo-names.ts +11 -0
  102. package/templates/react/add-on/start/assets/src/routes/demo.start.api-request.tsx.ejs +33 -0
  103. package/templates/react/add-on/start/assets/src/routes/demo.start.server-funcs.tsx +50 -0
  104. package/templates/react/add-on/start/assets/src/ssr.tsx.ejs +30 -0
  105. package/templates/react/add-on/start/info.json +18 -0
  106. package/templates/react/add-on/start/package.json +13 -0
  107. package/templates/react/add-on/store/assets/src/lib/demo-store.ts +13 -0
  108. package/templates/react/add-on/store/assets/src/routes/demo.store.tsx.ejs +75 -0
  109. package/templates/react/add-on/store/info.json +13 -0
  110. package/templates/react/add-on/store/package.json +6 -0
  111. package/templates/react/add-on/t3env/README.md +16 -0
  112. package/templates/react/add-on/t3env/assets/src/env.ts +39 -0
  113. package/templates/react/add-on/t3env/info.json +10 -0
  114. package/templates/react/add-on/t3env/package.json +6 -0
  115. package/templates/react/add-on/tRPC/assets/src/integrations/trpc/init.ts +9 -0
  116. package/templates/react/add-on/tRPC/assets/src/integrations/trpc/react.ts +4 -0
  117. package/templates/react/add-on/tRPC/assets/src/integrations/trpc/router.ts +18 -0
  118. package/templates/react/add-on/tRPC/assets/src/routes/api.trpc.$.tsx +16 -0
  119. package/templates/react/add-on/tRPC/info.json +9 -0
  120. package/templates/react/add-on/tRPC/package.json +9 -0
  121. package/templates/react/add-on/table/assets/src/data/demo-table-data.ts +50 -0
  122. package/templates/react/add-on/table/assets/src/routes/demo.table.tsx.ejs +373 -0
  123. package/templates/react/add-on/table/info.json +13 -0
  124. package/templates/react/add-on/table/package.json +7 -0
  125. package/templates/react/add-on/tanstack-query/assets/src/integrations/tanstack-query/layout.tsx +5 -0
  126. package/templates/react/add-on/tanstack-query/assets/src/integrations/tanstack-query/root-provider.tsx.ejs +70 -0
  127. package/templates/react/add-on/tanstack-query/assets/src/routes/demo.tanstack-query.tsx.ejs +53 -0
  128. package/templates/react/add-on/tanstack-query/info.json +13 -0
  129. package/templates/react/add-on/tanstack-query/package.json +6 -0
  130. package/templates/react/base/README.md.ejs +558 -0
  131. package/templates/react/base/_dot_gitignore +5 -0
  132. package/templates/react/base/_dot_vscode/settings.biome.json +35 -0
  133. package/templates/react/base/_dot_vscode/settings.json +11 -0
  134. package/templates/react/base/index.html.ejs +20 -0
  135. package/templates/react/base/package.biome.json +10 -0
  136. package/templates/react/base/package.eslintprettier.json +11 -0
  137. package/templates/react/base/package.json +30 -0
  138. package/templates/react/base/package.ts.json +7 -0
  139. package/templates/react/base/package.tw.json +6 -0
  140. package/templates/react/base/public/favicon.ico +0 -0
  141. package/templates/react/base/public/logo192.png +0 -0
  142. package/templates/react/base/public/logo512.png +0 -0
  143. package/templates/react/base/public/manifest.json +25 -0
  144. package/templates/react/base/public/robots.txt +3 -0
  145. package/templates/react/base/src/App.css +38 -0
  146. package/templates/react/base/src/App.test.tsx.ejs +10 -0
  147. package/templates/react/base/src/App.tsx.ejs +74 -0
  148. package/templates/react/base/src/components/Header.tsx.ejs +27 -0
  149. package/templates/react/base/src/logo.svg +44 -0
  150. package/templates/react/base/src/reportWebVitals.ts.ejs +28 -0
  151. package/templates/react/base/src/styles.css.ejs +15 -0
  152. package/templates/react/base/toolchain/.prettierignore +3 -0
  153. package/templates/react/base/toolchain/biome.json +31 -0
  154. package/templates/react/base/toolchain/eslint.config.js +5 -0
  155. package/templates/react/base/toolchain/prettier.config.js +10 -0
  156. package/templates/react/base/tsconfig.json.ejs +29 -0
  157. package/templates/react/base/vite.config.js.ejs +23 -0
  158. package/templates/react/code-router/src/main.tsx.ejs +92 -0
  159. package/templates/react/example/tanchat/README.md +37 -0
  160. package/templates/react/example/tanchat/assets/_dot_env.local.append +2 -0
  161. package/templates/react/example/tanchat/assets/public/example-guitar-flowers.jpg +0 -0
  162. package/templates/react/example/tanchat/assets/public/example-guitar-motherboard.jpg +0 -0
  163. package/templates/react/example/tanchat/assets/public/example-guitar-racing.jpg +0 -0
  164. package/templates/react/example/tanchat/assets/public/example-guitar-steamer-trunk.jpg +0 -0
  165. package/templates/react/example/tanchat/assets/public/example-guitar-superhero.jpg +0 -0
  166. package/templates/react/example/tanchat/assets/public/example-guitar-traveling.jpg +0 -0
  167. package/templates/react/example/tanchat/assets/public/example-guitar-video-games.jpg +0 -0
  168. package/templates/react/example/tanchat/assets/src/components/example-AIAssistant.tsx +173 -0
  169. package/templates/react/example/tanchat/assets/src/components/example-GuitarRecommendation.tsx +47 -0
  170. package/templates/react/example/tanchat/assets/src/data/example-guitars.ts +83 -0
  171. package/templates/react/example/tanchat/assets/src/demo.index.css +220 -0
  172. package/templates/react/example/tanchat/assets/src/integrations/tanchat/header-user.tsx +5 -0
  173. package/templates/react/example/tanchat/assets/src/routes/api.messages.ts +24 -0
  174. package/templates/react/example/tanchat/assets/src/routes/api.sse.ts +23 -0
  175. package/templates/react/example/tanchat/assets/src/routes/example.chat.tsx +159 -0
  176. package/templates/react/example/tanchat/assets/src/routes/example.guitars/$guitarId.tsx +50 -0
  177. package/templates/react/example/tanchat/assets/src/routes/example.guitars/index.tsx +54 -0
  178. package/templates/react/example/tanchat/assets/src/store/example-assistant.ts +3 -0
  179. package/templates/react/example/tanchat/assets/src/utils/demo.ai.ts +62 -0
  180. package/templates/react/example/tanchat/assets/src/utils/demo.sse.ts +31 -0
  181. package/templates/react/example/tanchat/assets/src/utils/demo.tools.ts +47 -0
  182. package/templates/react/example/tanchat/info.json +19 -0
  183. package/templates/react/example/tanchat/package.json +16 -0
  184. package/templates/react/file-router/package.fr.json +5 -0
  185. package/templates/react/file-router/src/main.tsx.ejs +55 -0
  186. package/templates/react/file-router/src/routes/__root.tsx.ejs +82 -0
  187. package/templates/solid/add-on/form/assets/src/routes/demo.form.tsx.ejs +352 -0
  188. package/templates/solid/add-on/form/info.json +13 -0
  189. package/templates/solid/add-on/form/package.json +5 -0
  190. package/templates/solid/add-on/module-federation/assets/module-federation.config.js.ejs +27 -0
  191. package/templates/solid/add-on/module-federation/assets/src/demo-mf-component.tsx +3 -0
  192. package/templates/solid/add-on/module-federation/assets/src/demo-mf-self-contained.tsx +9 -0
  193. package/templates/solid/add-on/module-federation/info.json +7 -0
  194. package/templates/solid/add-on/module-federation/package.json +5 -0
  195. package/templates/solid/add-on/sentry/assets/_dot_cursorrules.append +22 -0
  196. package/templates/solid/add-on/sentry/assets/_dot_env.local.append +2 -0
  197. package/templates/solid/add-on/sentry/assets/src/routes/demo.sentry.bad-event-handler.tsx +20 -0
  198. package/templates/solid/add-on/sentry/info.json +13 -0
  199. package/templates/solid/add-on/sentry/package.json +5 -0
  200. package/templates/solid/add-on/solid-ui/README.md +9 -0
  201. package/templates/solid/add-on/solid-ui/assets/src/lib/utils.ts +6 -0
  202. package/templates/solid/add-on/solid-ui/assets/src/styles.css +138 -0
  203. package/templates/solid/add-on/solid-ui/assets/ui.config.json +13 -0
  204. package/templates/solid/add-on/solid-ui/info.json +11 -0
  205. package/templates/solid/add-on/solid-ui/package.json +9 -0
  206. package/templates/solid/add-on/start/assets/app.config.ts +16 -0
  207. package/templates/solid/add-on/start/assets/src/api.ts +6 -0
  208. package/templates/solid/add-on/start/assets/src/client.tsx +7 -0
  209. package/templates/solid/add-on/start/assets/src/router.tsx.ejs +24 -0
  210. package/templates/solid/add-on/start/assets/src/routes/demo.start.server-funcs.tsx +49 -0
  211. package/templates/solid/add-on/start/assets/src/ssr.tsx +12 -0
  212. package/templates/solid/add-on/start/info.json +14 -0
  213. package/templates/solid/add-on/start/package.json +12 -0
  214. package/templates/solid/add-on/store/assets/src/lib/demo-store.ts +13 -0
  215. package/templates/solid/add-on/store/assets/src/routes/demo.store.tsx.ejs +77 -0
  216. package/templates/solid/add-on/store/info.json +13 -0
  217. package/templates/solid/add-on/store/package.json +6 -0
  218. package/templates/solid/add-on/t3env/README.md +16 -0
  219. package/templates/solid/add-on/t3env/assets/src/env.ts +39 -0
  220. package/templates/solid/add-on/t3env/info.json +10 -0
  221. package/templates/solid/add-on/t3env/package.json +6 -0
  222. package/templates/solid/add-on/tanstack-query/assets/src/integrations/tanstack-query/header-user.tsx +5 -0
  223. package/templates/solid/add-on/tanstack-query/assets/src/integrations/tanstack-query/provider.tsx +15 -0
  224. package/templates/solid/add-on/tanstack-query/assets/src/routes/demo.tanstack-query.tsx +30 -0
  225. package/templates/solid/add-on/tanstack-query/info.json +13 -0
  226. package/templates/solid/add-on/tanstack-query/package.json +6 -0
  227. package/templates/solid/base/README.md.ejs +215 -0
  228. package/templates/solid/base/_dot_cursorrules.append +35 -0
  229. package/templates/solid/base/_dot_gitignore +5 -0
  230. package/templates/solid/base/_dot_vscode/settings.biome.json +35 -0
  231. package/templates/solid/base/_dot_vscode/settings.json +11 -0
  232. package/templates/solid/base/index.html.ejs +20 -0
  233. package/templates/solid/base/package.biome.json +10 -0
  234. package/templates/solid/base/package.eslintprettier.json +11 -0
  235. package/templates/solid/base/package.json +23 -0
  236. package/templates/solid/base/package.ts.json +5 -0
  237. package/templates/solid/base/package.tw.json +6 -0
  238. package/templates/solid/base/public/favicon.ico +0 -0
  239. package/templates/solid/base/public/logo192.png +0 -0
  240. package/templates/solid/base/public/logo512.png +0 -0
  241. package/templates/solid/base/public/manifest.json +25 -0
  242. package/templates/solid/base/public/robots.txt +3 -0
  243. package/templates/solid/base/src/App.css +0 -0
  244. package/templates/solid/base/src/App.tsx.ejs +47 -0
  245. package/templates/solid/base/src/components/Header.tsx.ejs +26 -0
  246. package/templates/solid/base/src/logo.svg +120 -0
  247. package/templates/solid/base/src/styles.css.ejs +15 -0
  248. package/templates/solid/base/toolchain/.prettierignore +3 -0
  249. package/templates/solid/base/toolchain/biome.json +31 -0
  250. package/templates/solid/base/toolchain/eslint.config.js +5 -0
  251. package/templates/solid/base/toolchain/prettier.config.js +10 -0
  252. package/templates/solid/base/tsconfig.json.ejs +31 -0
  253. package/templates/solid/base/vite.config.js.ejs +22 -0
  254. package/templates/solid/code-router/src/main.tsx.ejs +71 -0
  255. package/templates/solid/example/tanchat/README.md +52 -0
  256. package/templates/solid/example/tanchat/assets/ai-streaming-server/README.md +110 -0
  257. package/templates/solid/example/tanchat/assets/ai-streaming-server/_dot_env.example +1 -0
  258. package/templates/solid/example/tanchat/assets/ai-streaming-server/package.json +26 -0
  259. package/templates/solid/example/tanchat/assets/ai-streaming-server/src/index.ts +102 -0
  260. package/templates/solid/example/tanchat/assets/ai-streaming-server/tsconfig.json +15 -0
  261. package/templates/solid/example/tanchat/assets/src/components/demo.SettingsDialog.tsx +149 -0
  262. package/templates/solid/example/tanchat/assets/src/demo.index.css +227 -0
  263. package/templates/solid/example/tanchat/assets/src/lib/demo-store.ts +13 -0
  264. package/templates/solid/example/tanchat/assets/src/routes/example.chat.tsx +435 -0
  265. package/templates/solid/example/tanchat/assets/src/store/demo.hooks.ts +17 -0
  266. package/templates/solid/example/tanchat/assets/src/store/demo.store.ts +133 -0
  267. package/templates/solid/example/tanchat/info.json +14 -0
  268. package/templates/solid/example/tanchat/package.json +7 -0
  269. package/templates/solid/file-router/package.fr.json +5 -0
  270. package/templates/solid/file-router/src/main.tsx.ejs +47 -0
  271. package/templates/solid/file-router/src/routes/__root.tsx.ejs +41 -0
  272. package/templates/solid/file-router/src/routes/index.tsx +43 -0
  273. package/tests/cra.test.ts +293 -0
  274. package/tests/snapshots/cra/cr-js-npm.json +33 -0
  275. package/tests/snapshots/cra/cr-ts-npm.json +34 -0
  276. package/tests/snapshots/cra/cr-ts-start-npm.json +38 -0
  277. package/tests/snapshots/cra/fr-ts-npm.json +34 -0
  278. package/tests/snapshots/cra/fr-ts-tw-npm.json +33 -0
  279. package/tests/snapshots/cra/solid-cr-js-npm.json +31 -0
  280. package/tests/snapshots/cra/solid-cr-ts-npm.json +32 -0
  281. package/tests/snapshots/cra/solid-cr-ts-start-npm.json +36 -0
  282. package/tests/snapshots/cra/solid-fr-ts-npm.json +33 -0
  283. package/tests/snapshots/cra/solid-fr-ts-tw-npm.json +32 -0
  284. package/tests/test-utilities.ts +87 -0
  285. package/dist/add-to-app.js +0 -169
  286. package/dist/custom-add-ons/add-on.js +0 -175
  287. package/dist/custom-add-ons/shared.js +0 -117
  288. package/dist/custom-add-ons/starter.js +0 -84
  289. package/dist/file-helpers.js +0 -165
  290. package/dist/frameworks.js +0 -92
  291. package/dist/integrations/git.js +0 -4
  292. package/dist/integrations/shadcn.js +0 -33
  293. package/dist/package-json.js +0 -48
  294. package/dist/special-steps/index.js +0 -24
  295. package/dist/special-steps/rimraf-node-modules.js +0 -16
  296. package/dist/template-file.js +0 -112
  297. package/dist/types/add-to-app.d.ts +0 -17
  298. package/dist/types/custom-add-ons/add-on.d.ts +0 -69
  299. package/dist/types/custom-add-ons/shared.d.ts +0 -15
  300. package/dist/types/custom-add-ons/starter.d.ts +0 -7
  301. package/dist/types/file-helpers.d.ts +0 -15
  302. package/dist/types/frameworks.d.ts +0 -7
  303. package/dist/types/integrations/git.d.ts +0 -2
  304. package/dist/types/integrations/shadcn.d.ts +0 -2
  305. package/dist/types/package-json.d.ts +0 -7
  306. package/dist/types/special-steps/index.d.ts +0 -2
  307. package/dist/types/special-steps/rimraf-node-modules.d.ts +0 -2
  308. package/dist/types/template-file.d.ts +0 -2
  309. package/src/add-to-app.ts +0 -274
  310. package/src/custom-add-ons/add-on.ts +0 -261
  311. package/src/custom-add-ons/shared.ts +0 -161
  312. package/src/custom-add-ons/starter.ts +0 -126
  313. package/src/file-helpers.ts +0 -235
  314. package/src/frameworks.ts +0 -134
  315. package/src/integrations/git.ts +0 -7
  316. package/src/integrations/shadcn.ts +0 -54
  317. package/src/package-json.ts +0 -69
  318. package/src/special-steps/index.ts +0 -36
  319. package/src/special-steps/rimraf-node-modules.ts +0 -25
  320. package/src/template-file.ts +0 -150
  321. package/tests/add-ons.test.ts +0 -67
  322. package/tests/add-to-app.test.ts +0 -358
  323. package/tests/config-file.test.ts +0 -68
  324. package/tests/create-app.test.ts +0 -120
  325. package/tests/custom-add-ons/add-on.test.ts +0 -12
  326. package/tests/custom-add-ons/shared.test.ts +0 -257
  327. package/tests/custom-add-ons/starter.test.ts +0 -58
  328. package/tests/environment.test.ts +0 -115
  329. package/tests/file-helper.test.ts +0 -90
  330. package/tests/frameworks.test.ts +0 -95
  331. package/tests/index.test.ts +0 -9
  332. package/tests/integrations/git.test.ts +0 -20
  333. package/tests/integrations/shadcn.test.ts +0 -91
  334. package/tests/options.test.ts +0 -42
  335. package/tests/package-json.test.ts +0 -63
  336. package/tests/package-manager.test.ts +0 -154
  337. package/tests/setupVitest.ts +0 -6
  338. package/tests/template-file.test.ts +0 -178
  339. package/tests/utils.test.ts +0 -23
  340. package/vitest.config.ts +0 -21
package/src/mcp.ts ADDED
@@ -0,0 +1,302 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
2
+ import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js'
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
4
+ import express from 'express'
5
+ import { z } from 'zod'
6
+
7
+ import { createApp } from './create-app.js'
8
+ import { finalizeAddOns } from './add-ons.js'
9
+ import { createDefaultEnvironment } from './environment.js'
10
+
11
+ import type { TemplateOptions } from './types.js'
12
+
13
+ const tanStackReactAddOns = [
14
+ {
15
+ id: 'clerk',
16
+ description: 'Enable authentication with Clerk',
17
+ },
18
+ {
19
+ id: 'convex',
20
+ description: 'Enable a database using Convex',
21
+ },
22
+ {
23
+ id: 'form',
24
+ description: 'Form handling library',
25
+ },
26
+ {
27
+ id: 'netlify',
28
+ description: 'Enable deployments to Netlify',
29
+ },
30
+ {
31
+ id: 'sentry',
32
+ description: 'Enable Sentry error tracking',
33
+ },
34
+ {
35
+ id: 'shadcn',
36
+ description: 'Enable integration of the Shadcn UI component library',
37
+ },
38
+ {
39
+ id: 'start',
40
+ description:
41
+ 'Set this if you want a TanStack Start application that supports server functions or APIs',
42
+ },
43
+ {
44
+ id: 'tanstack-query',
45
+ description: 'Enable TanStack Query for data fetching',
46
+ },
47
+ {
48
+ id: 'store',
49
+ description: 'Enable the TanStack Store state management library',
50
+ },
51
+ {
52
+ id: 'tanchat',
53
+ description: 'Add an AI chatbot example to the application',
54
+ },
55
+ ]
56
+
57
+ const tanStackSolidAddOns = [
58
+ {
59
+ id: 'solid-ui',
60
+ description: 'Enable integration of the Solid UI component library',
61
+ },
62
+ {
63
+ id: 'form',
64
+ description: 'Form handling library',
65
+ },
66
+ {
67
+ id: 'sentry',
68
+ description: 'Enable Sentry error tracking',
69
+ },
70
+ {
71
+ id: 'store',
72
+ description: 'Enable the TanStack Store state management library',
73
+ },
74
+ {
75
+ id: 'start',
76
+ description:
77
+ 'Set this if you want a TanStack Start application that supports server functions or APIs',
78
+ },
79
+ {
80
+ id: 'tanstack-query',
81
+ description: 'Enable TanStack Query for data fetching',
82
+ },
83
+ {
84
+ id: 'tanchat',
85
+ description: 'Add an AI chatbot example to the application',
86
+ },
87
+ ]
88
+
89
+ function createServer({
90
+ appName,
91
+ forcedAddOns = [],
92
+ name,
93
+ }: {
94
+ appName?: string
95
+ forcedAddOns?: Array<string>
96
+ name?: string
97
+ }) {
98
+ const server = new McpServer({
99
+ name: `${appName} Application Builder`,
100
+ version: '1.0.0',
101
+ })
102
+
103
+ server.tool('listTanStackReactAddOns', {}, () => {
104
+ return {
105
+ content: [{ type: 'text', text: JSON.stringify(tanStackReactAddOns) }],
106
+ }
107
+ })
108
+
109
+ server.tool(
110
+ 'createTanStackReactApplication',
111
+ {
112
+ projectName: z
113
+ .string()
114
+ .describe(
115
+ 'The package.json module name of the application (will also be the directory name)',
116
+ ),
117
+ cwd: z.string().describe('The directory to create the application in'),
118
+ addOns: z
119
+ .array(
120
+ z.enum([
121
+ 'clerk',
122
+ 'convex',
123
+ 'form',
124
+ 'netlify',
125
+ 'sentry',
126
+ 'shadcn',
127
+ 'start',
128
+ 'store',
129
+ 'tanstack-query',
130
+ 'tanchat',
131
+ ]),
132
+ )
133
+ .describe('The IDs of the add-ons to install'),
134
+ targetDir: z
135
+ .string()
136
+ .describe(
137
+ 'The directory to create the application in. Use the absolute path of the directory you want the application to be created in',
138
+ ),
139
+ },
140
+ async ({ projectName, addOns, cwd, targetDir }) => {
141
+ try {
142
+ process.chdir(cwd)
143
+ const chosenAddOns = await finalizeAddOns(
144
+ 'react',
145
+ 'file-router',
146
+ Array.from(
147
+ new Set([...(addOns as unknown as Array<string>), ...forcedAddOns]),
148
+ ),
149
+ )
150
+ await createApp(
151
+ {
152
+ projectName: projectName.replace(/^\//, './'),
153
+ framework: 'react',
154
+ typescript: true,
155
+ tailwind: true,
156
+ packageManager: 'pnpm',
157
+ toolchain: 'none',
158
+ mode: 'file-router',
159
+ addOns: true,
160
+ chosenAddOns,
161
+ git: true,
162
+ variableValues: {},
163
+ },
164
+ {
165
+ silent: true,
166
+ environment: createDefaultEnvironment(),
167
+ name,
168
+ cwd: targetDir,
169
+ },
170
+ )
171
+ return {
172
+ content: [{ type: 'text', text: 'Application created successfully' }],
173
+ }
174
+ } catch (error) {
175
+ return {
176
+ content: [
177
+ { type: 'text', text: `Error creating application: ${error}` },
178
+ ],
179
+ }
180
+ }
181
+ },
182
+ )
183
+
184
+ server.tool('listTanStackSolidAddOns', {}, () => {
185
+ return {
186
+ content: [{ type: 'text', text: JSON.stringify(tanStackSolidAddOns) }],
187
+ }
188
+ })
189
+
190
+ server.tool(
191
+ 'createTanStackSolidApplication',
192
+ {
193
+ projectName: z
194
+ .string()
195
+ .describe(
196
+ 'The package.json module name of the application (will also be the directory name)',
197
+ ),
198
+ cwd: z.string().describe('The directory to create the application in'),
199
+ addOns: z
200
+ .array(
201
+ z.enum([
202
+ 'solid-ui',
203
+ 'form',
204
+ 'sentry',
205
+ 'store',
206
+ 'tanstack-query',
207
+ 'tanchat',
208
+ ]),
209
+ )
210
+ .describe('The IDs of the add-ons to install'),
211
+ targetDir: z
212
+ .string()
213
+ .describe(
214
+ 'The directory to create the application in. Use the absolute path of the directory you want the application to be created in',
215
+ ),
216
+ },
217
+ async ({ projectName, addOns, cwd, targetDir }) => {
218
+ try {
219
+ process.chdir(cwd)
220
+ const chosenAddOns = await finalizeAddOns(
221
+ 'solid',
222
+ 'file-router',
223
+ Array.from(
224
+ new Set([...(addOns as unknown as Array<string>), ...forcedAddOns]),
225
+ ),
226
+ )
227
+ await createApp(
228
+ {
229
+ projectName: projectName.replace(/^\//, './'),
230
+ framework: 'solid',
231
+ typescript: true,
232
+ tailwind: true,
233
+ packageManager: 'pnpm',
234
+ toolchain: 'none',
235
+ mode: 'file-router',
236
+ addOns: true,
237
+ chosenAddOns,
238
+ git: true,
239
+ variableValues: {},
240
+ },
241
+ {
242
+ silent: true,
243
+ environment: createDefaultEnvironment(),
244
+ name,
245
+ cwd: targetDir,
246
+ },
247
+ )
248
+ return {
249
+ content: [{ type: 'text', text: 'Application created successfully' }],
250
+ }
251
+ } catch (error) {
252
+ return {
253
+ content: [
254
+ { type: 'text', text: `Error creating application: ${error}` },
255
+ ],
256
+ }
257
+ }
258
+ },
259
+ )
260
+
261
+ return server
262
+ }
263
+
264
+ export default async function runServer(
265
+ sse: boolean,
266
+ {
267
+ forcedAddOns,
268
+ appName,
269
+ name,
270
+ }: {
271
+ forcedMode?: TemplateOptions
272
+ forcedAddOns?: Array<string>
273
+ appName?: string
274
+ name?: string
275
+ },
276
+ ) {
277
+ let transport: SSEServerTransport | null = null
278
+
279
+ const server = createServer({ appName, forcedAddOns, name })
280
+ if (sse) {
281
+ const app = express()
282
+
283
+ app.get('/sse', (req, res) => {
284
+ transport = new SSEServerTransport('/messages', res)
285
+ server.connect(transport)
286
+ })
287
+
288
+ app.post('/messages', (req, res) => {
289
+ if (transport) {
290
+ transport.handlePostMessage(req, res)
291
+ }
292
+ })
293
+
294
+ const port = process.env.PORT || 8080
295
+ app.listen(port, () => {
296
+ console.log(`Server is running on port http://localhost:${port}/sse`)
297
+ })
298
+ } else {
299
+ const transport = new StdioServerTransport()
300
+ await server.connect(transport)
301
+ }
302
+ }
package/src/options.ts CHANGED
@@ -1,11 +1,412 @@
1
- import type { Options, SerializedOptions } from './types'
1
+ import {
2
+ cancel,
3
+ confirm,
4
+ isCancel,
5
+ multiselect,
6
+ select,
7
+ text,
8
+ } from '@clack/prompts'
2
9
 
3
- export const createSerializedOptions = (options: Options) => {
4
- const serializedOptions: SerializedOptions = {
5
- ...options,
6
- chosenAddOns: options.chosenAddOns.map((addOn) => addOn.id),
7
- framework: options.framework.id,
8
- starter: options.starter?.id,
10
+ import {
11
+ DEFAULT_PACKAGE_MANAGER,
12
+ SUPPORTED_PACKAGE_MANAGERS,
13
+ getPackageManager,
14
+ } from './package-manager.js'
15
+ import { DEFAULT_TOOLCHAIN, SUPPORTED_TOOLCHAINS } from './toolchain.js'
16
+ import { CODE_ROUTER, DEFAULT_FRAMEWORK, FILE_ROUTER } from './constants.js'
17
+ import { finalizeAddOns, getAllAddOns, loadRemoteAddOn } from './add-ons.js'
18
+
19
+ import type {
20
+ AddOn,
21
+ CliOptions,
22
+ Mode,
23
+ Options,
24
+ Overlay,
25
+ TemplateOptions,
26
+ Variable,
27
+ } from './types.js'
28
+
29
+ // If all CLI options are provided, use them directly
30
+ export async function normalizeOptions(
31
+ cliOptions: CliOptions,
32
+ forcedMode?: Mode,
33
+ forcedAddOns?: Array<string>,
34
+ ): Promise<Options | undefined> {
35
+ // in some cases, if you use windows/powershell, the argument for addons
36
+ // if sepparated by comma is not really passed as an array, but as a string
37
+ // with spaces, We need to normalize this edge case.
38
+ if (Array.isArray(cliOptions.addOns) && cliOptions.addOns.length === 1) {
39
+ const parseSeparatedArgs = cliOptions.addOns[0].split(' ')
40
+ if (parseSeparatedArgs.length > 1) {
41
+ cliOptions.addOns = parseSeparatedArgs
42
+ }
43
+ }
44
+
45
+ if (cliOptions.projectName) {
46
+ let typescript =
47
+ cliOptions.template === 'typescript' ||
48
+ cliOptions.template === 'file-router' ||
49
+ cliOptions.framework === 'solid'
50
+
51
+ let tailwind = !!cliOptions.tailwind
52
+ if (cliOptions.framework === 'solid') {
53
+ tailwind = true
54
+ }
55
+
56
+ let mode: typeof FILE_ROUTER | typeof CODE_ROUTER =
57
+ cliOptions.template === 'file-router' ? FILE_ROUTER : CODE_ROUTER
58
+
59
+ const overlay = cliOptions.overlay
60
+ ? ((await loadRemoteAddOn(cliOptions.overlay)) as Overlay)
61
+ : undefined
62
+
63
+ if (overlay) {
64
+ tailwind = overlay.tailwind
65
+ typescript = overlay.typescript
66
+ cliOptions.framework = overlay.framework
67
+ mode = overlay.mode
68
+ }
69
+
70
+ let addOns = false
71
+ let chosenAddOns: Array<AddOn> = []
72
+ if (
73
+ Array.isArray(cliOptions.addOns) ||
74
+ overlay?.dependsOn ||
75
+ forcedAddOns
76
+ ) {
77
+ addOns = true
78
+ let finalAddOns = Array.from(
79
+ new Set([...(overlay?.dependsOn || []), ...(forcedAddOns || [])]),
80
+ )
81
+ if (cliOptions.addOns && Array.isArray(cliOptions.addOns)) {
82
+ finalAddOns = Array.from(
83
+ new Set([
84
+ ...(forcedAddOns || []),
85
+ ...finalAddOns,
86
+ ...cliOptions.addOns,
87
+ ]),
88
+ )
89
+ }
90
+ chosenAddOns = await finalizeAddOns(
91
+ cliOptions.framework || DEFAULT_FRAMEWORK,
92
+ forcedMode || cliOptions.template === 'file-router'
93
+ ? FILE_ROUTER
94
+ : CODE_ROUTER,
95
+ finalAddOns,
96
+ )
97
+ tailwind = true
98
+ typescript = true
99
+ }
100
+
101
+ return {
102
+ framework: cliOptions.framework || 'react',
103
+ projectName: cliOptions.projectName,
104
+ typescript,
105
+ tailwind,
106
+ packageManager:
107
+ cliOptions.packageManager ||
108
+ getPackageManager() ||
109
+ DEFAULT_PACKAGE_MANAGER,
110
+ toolchain: cliOptions.toolchain || DEFAULT_TOOLCHAIN,
111
+ mode,
112
+ git: !!cliOptions.git,
113
+ addOns,
114
+ chosenAddOns,
115
+ variableValues: {},
116
+ overlay,
117
+ }
118
+ }
119
+ }
120
+
121
+ async function collectVariables(
122
+ variables: Array<Variable>,
123
+ ): Promise<Record<string, string | number | boolean>> {
124
+ const responses: Record<string, string | number | boolean> = {}
125
+ for (const variable of variables) {
126
+ if (variable.type === 'string') {
127
+ const response = await text({
128
+ message: variable.description,
129
+ initialValue: variable.default,
130
+ })
131
+ if (isCancel(response)) {
132
+ cancel('Operation cancelled.')
133
+ process.exit(0)
134
+ }
135
+ responses[variable.name] = response
136
+ } else if (variable.type === 'number') {
137
+ const response = await text({
138
+ message: variable.description,
139
+ initialValue: variable.default.toString(),
140
+ })
141
+ if (isCancel(response)) {
142
+ cancel('Operation cancelled.')
143
+ process.exit(0)
144
+ }
145
+ responses[variable.name] = Number(response)
146
+ } else {
147
+ const response = await confirm({
148
+ message: variable.description,
149
+ initialValue: variable.default === true,
150
+ })
151
+ if (isCancel(response)) {
152
+ cancel('Operation cancelled.')
153
+ process.exit(0)
154
+ }
155
+ responses[variable.name] = response
156
+ }
157
+ }
158
+ return responses
159
+ }
160
+
161
+ export async function promptForOptions(
162
+ cliOptions: CliOptions,
163
+ {
164
+ forcedAddOns = [],
165
+ forcedMode,
166
+ }: {
167
+ forcedAddOns?: Array<string>
168
+ forcedMode?: TemplateOptions
169
+ },
170
+ ): Promise<Required<Options> | undefined> {
171
+ const options = {} as Required<Options>
172
+
173
+ options.framework = cliOptions.framework || DEFAULT_FRAMEWORK
174
+ if (options.framework === 'solid') {
175
+ options.typescript = true
176
+ options.tailwind = true
177
+ }
178
+
179
+ if (cliOptions.addOns) {
180
+ options.typescript = true
181
+ }
182
+
183
+ if (!cliOptions.projectName) {
184
+ const value = await text({
185
+ message: 'What would you like to name your project?',
186
+ defaultValue: 'my-app',
187
+ validate(value) {
188
+ if (!value) {
189
+ return 'Please enter a name'
190
+ }
191
+ },
192
+ })
193
+ if (isCancel(value)) {
194
+ cancel('Operation cancelled.')
195
+ process.exit(0)
196
+ }
197
+ options.projectName = value
198
+ } else {
199
+ options.projectName = cliOptions.projectName
9
200
  }
10
- return serializedOptions
201
+
202
+ // Router type selection
203
+ if (!cliOptions.template && !forcedMode) {
204
+ const routerType = await select({
205
+ message: 'Select the router type:',
206
+ options: [
207
+ {
208
+ value: FILE_ROUTER,
209
+ label: 'File Router - File-based routing structure',
210
+ },
211
+ {
212
+ value: CODE_ROUTER,
213
+ label: 'Code Router - Traditional code-based routing',
214
+ },
215
+ ],
216
+ initialValue: FILE_ROUTER,
217
+ })
218
+ if (isCancel(routerType)) {
219
+ cancel('Operation cancelled.')
220
+ process.exit(0)
221
+ }
222
+ options.mode = routerType as typeof CODE_ROUTER | typeof FILE_ROUTER
223
+ } else if (forcedMode) {
224
+ options.mode = forcedMode === 'file-router' ? FILE_ROUTER : CODE_ROUTER
225
+ options.typescript = options.mode === FILE_ROUTER
226
+ } else {
227
+ options.mode =
228
+ cliOptions.template === 'file-router' ? FILE_ROUTER : CODE_ROUTER
229
+ if (options.mode === FILE_ROUTER) {
230
+ options.typescript = true
231
+ }
232
+ }
233
+
234
+ // TypeScript selection (if using Code Router)
235
+ if (!options.typescript) {
236
+ if (options.mode === CODE_ROUTER) {
237
+ const typescriptEnable = await confirm({
238
+ message: 'Would you like to use TypeScript?',
239
+ initialValue: true,
240
+ })
241
+ if (isCancel(typescriptEnable)) {
242
+ cancel('Operation cancelled.')
243
+ process.exit(0)
244
+ }
245
+ options.typescript = typescriptEnable
246
+ } else {
247
+ options.typescript = true
248
+ }
249
+ }
250
+
251
+ // Tailwind selection
252
+ if (!cliOptions.tailwind && options.framework === 'react') {
253
+ const tailwind = await confirm({
254
+ message: 'Would you like to use Tailwind CSS?',
255
+ initialValue: true,
256
+ })
257
+ if (isCancel(tailwind)) {
258
+ cancel('Operation cancelled.')
259
+ process.exit(0)
260
+ }
261
+ options.tailwind = tailwind
262
+ } else {
263
+ options.tailwind = options.framework === 'solid' || !!cliOptions.tailwind
264
+ }
265
+
266
+ // Package manager selection
267
+ if (cliOptions.packageManager === undefined) {
268
+ const detectedPackageManager = getPackageManager()
269
+ if (!detectedPackageManager) {
270
+ const pm = await select({
271
+ message: 'Select package manager:',
272
+ options: SUPPORTED_PACKAGE_MANAGERS.map((pm) => ({
273
+ value: pm,
274
+ label: pm,
275
+ })),
276
+ initialValue: DEFAULT_PACKAGE_MANAGER,
277
+ })
278
+ if (isCancel(pm)) {
279
+ cancel('Operation cancelled.')
280
+ process.exit(0)
281
+ }
282
+ options.packageManager = pm
283
+ } else {
284
+ options.packageManager = detectedPackageManager
285
+ }
286
+ } else {
287
+ options.packageManager = cliOptions.packageManager
288
+ }
289
+
290
+ // Toolchain selection
291
+ if (cliOptions.toolchain === undefined) {
292
+ const tc = await select({
293
+ message: 'Select toolchain',
294
+ options: SUPPORTED_TOOLCHAINS.map((tc) => ({
295
+ value: tc,
296
+ label: tc,
297
+ })),
298
+ initialValue: DEFAULT_TOOLCHAIN,
299
+ })
300
+ if (isCancel(tc)) {
301
+ cancel('Operation cancelled.')
302
+ process.exit(0)
303
+ }
304
+ options.toolchain = tc
305
+ } else {
306
+ options.toolchain = cliOptions.toolchain
307
+ }
308
+
309
+ options.chosenAddOns = []
310
+ if (Array.isArray(cliOptions.addOns)) {
311
+ options.chosenAddOns = await finalizeAddOns(
312
+ options.framework,
313
+ options.mode,
314
+ Array.from(new Set([...cliOptions.addOns, ...forcedAddOns])),
315
+ )
316
+ options.tailwind = true
317
+ } else if (cliOptions.addOns) {
318
+ // Select any add-ons
319
+ const allAddOns = await getAllAddOns(options.framework, options.mode)
320
+ const addOns = allAddOns.filter((addOn) => addOn.type === 'add-on')
321
+ let selectedAddOns: Array<string> = []
322
+ if (options.typescript && addOns.length > 0) {
323
+ const value = await multiselect({
324
+ message: 'What add-ons would you like for your project:',
325
+ options: addOns
326
+ .filter((addOn) => !forcedAddOns.includes(addOn.id))
327
+ .map((addOn) => ({
328
+ value: addOn.id,
329
+ label: addOn.name,
330
+ hint: addOn.description,
331
+ })),
332
+ required: false,
333
+ })
334
+
335
+ if (isCancel(value)) {
336
+ cancel('Operation cancelled.')
337
+ process.exit(0)
338
+ }
339
+ selectedAddOns = value
340
+ }
341
+
342
+ // Select any examples
343
+ let selectedExamples: Array<string> = []
344
+ const examples = allAddOns.filter((addOn) => addOn.type === 'example')
345
+ if (options.typescript && examples.length > 0) {
346
+ const value = await multiselect({
347
+ message: 'Would you like any examples?',
348
+ options: examples
349
+ .filter((addOn) => !forcedAddOns.includes(addOn.id))
350
+ .map((addOn) => ({
351
+ value: addOn.id,
352
+ label: addOn.name,
353
+ hint: addOn.description,
354
+ })),
355
+ required: false,
356
+ })
357
+
358
+ if (isCancel(value)) {
359
+ cancel('Operation cancelled.')
360
+ process.exit(0)
361
+ }
362
+ selectedExamples = value
363
+ }
364
+
365
+ if (
366
+ selectedAddOns.length > 0 ||
367
+ selectedExamples.length > 0 ||
368
+ forcedAddOns.length > 0
369
+ ) {
370
+ options.chosenAddOns = await finalizeAddOns(
371
+ options.framework,
372
+ options.mode,
373
+ Array.from(
374
+ new Set([...selectedAddOns, ...selectedExamples, ...forcedAddOns]),
375
+ ),
376
+ )
377
+ options.tailwind = true
378
+ }
379
+ } else if (forcedAddOns.length > 0) {
380
+ options.chosenAddOns = await finalizeAddOns(
381
+ options.framework,
382
+ options.mode,
383
+ forcedAddOns,
384
+ )
385
+ }
386
+
387
+ // Collect variables
388
+ const variables: Array<Variable> = []
389
+ for (const addOn of options.chosenAddOns) {
390
+ for (const variable of addOn.variables ?? []) {
391
+ variables.push(variable)
392
+ }
393
+ }
394
+ options.variableValues = await collectVariables(variables)
395
+
396
+ // Git selection
397
+ if (cliOptions.git === undefined) {
398
+ const git = await confirm({
399
+ message: 'Would you like to initialize a new git repository?',
400
+ initialValue: true,
401
+ })
402
+ if (isCancel(git)) {
403
+ cancel('Operation cancelled.')
404
+ process.exit(0)
405
+ }
406
+ options.git = git
407
+ } else {
408
+ options.git = !!cliOptions.git
409
+ }
410
+
411
+ return options
11
412
  }