virastack 0.0.1 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (447) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +94 -18
  3. package/bin/virastack.js +7 -0
  4. package/package.json +43 -9
  5. package/src/commands/add.js +64 -0
  6. package/src/commands/init.js +286 -0
  7. package/src/i18n.js +231 -0
  8. package/src/index.js +64 -0
  9. package/src/utils/args.js +60 -0
  10. package/src/utils/copy-template.js +81 -0
  11. package/src/utils/exec.js +29 -0
  12. package/src/utils/git.js +38 -0
  13. package/src/utils/is-online.js +14 -0
  14. package/src/utils/package-info.js +12 -0
  15. package/src/utils/package-manager.js +33 -0
  16. package/src/utils/setup-env.js +25 -0
  17. package/src/utils/telemetry.js +86 -0
  18. package/src/utils/tools.js +48 -0
  19. package/src/utils/update-package-json.js +44 -0
  20. package/src/utils/update-readme.js +25 -0
  21. package/src/utils/validate-project-name.js +26 -0
  22. package/templates/nextjs/.changeset/README.md +8 -0
  23. package/templates/nextjs/.changeset/config.json +11 -0
  24. package/templates/nextjs/.env.example +6 -0
  25. package/templates/nextjs/.env.local +6 -0
  26. package/templates/nextjs/.eslintcache +1 -0
  27. package/templates/nextjs/.github/workflows/ci.yml +41 -0
  28. package/templates/nextjs/.husky/commit-msg +1 -0
  29. package/templates/nextjs/.husky/pre-commit +1 -0
  30. package/templates/nextjs/.husky/pre-push +1 -0
  31. package/templates/nextjs/.prettierignore +6 -0
  32. package/templates/nextjs/.prettierrc +42 -0
  33. package/templates/nextjs/.vscode/extensions.json +7 -0
  34. package/templates/nextjs/.vscode/settings.json +20 -0
  35. package/templates/nextjs/LICENSE +21 -0
  36. package/templates/nextjs/README.md +202 -0
  37. package/templates/nextjs/_gitignore +45 -0
  38. package/templates/nextjs/commitlint.config.js +6 -0
  39. package/templates/nextjs/eslint.config.mjs +27 -0
  40. package/templates/nextjs/knip.config.js +25 -0
  41. package/templates/nextjs/next-env.d.ts +6 -0
  42. package/templates/nextjs/next.config.ts +39 -0
  43. package/templates/nextjs/package.json +115 -0
  44. package/templates/nextjs/pnpm-lock.yaml +6467 -0
  45. package/templates/nextjs/pnpm-workspace.yaml +3 -0
  46. package/templates/nextjs/postcss.config.mjs +7 -0
  47. package/templates/nextjs/public/favicon.ico +0 -0
  48. package/templates/nextjs/public/llms.txt +96 -0
  49. package/templates/nextjs/public/logo.png +0 -0
  50. package/templates/nextjs/public/logo.webp +0 -0
  51. package/templates/nextjs/public/og.png +0 -0
  52. package/templates/nextjs/src/app/error.tsx +34 -0
  53. package/templates/nextjs/src/app/favicon.ico +0 -0
  54. package/templates/nextjs/src/app/global-error.tsx +32 -0
  55. package/templates/nextjs/src/app/layout.tsx +37 -0
  56. package/templates/nextjs/src/app/loading.tsx +12 -0
  57. package/templates/nextjs/src/app/manifest.ts +22 -0
  58. package/templates/nextjs/src/app/not-found.tsx +18 -0
  59. package/templates/nextjs/src/app/page.tsx +5 -0
  60. package/templates/nextjs/src/app/robots.ts +13 -0
  61. package/templates/nextjs/src/app/sitemap.ts +14 -0
  62. package/templates/nextjs/src/components/shared/ThemeToggle.tsx +30 -0
  63. package/templates/nextjs/src/components/ui/avatar.tsx +54 -0
  64. package/templates/nextjs/src/components/ui/button.tsx +46 -0
  65. package/templates/nextjs/src/components/ui/dialog.tsx +107 -0
  66. package/templates/nextjs/src/components/ui/field.tsx +24 -0
  67. package/templates/nextjs/src/components/ui/index.ts +27 -0
  68. package/templates/nextjs/src/components/ui/input.tsx +23 -0
  69. package/templates/nextjs/src/components/ui/label.tsx +17 -0
  70. package/templates/nextjs/src/components/ui/skeleton.tsx +13 -0
  71. package/templates/nextjs/src/components/ui/table.tsx +94 -0
  72. package/templates/nextjs/src/components/ui/tabs.tsx +46 -0
  73. package/templates/nextjs/src/config/seo.config.ts +37 -0
  74. package/templates/nextjs/src/config/site.config.ts +15 -0
  75. package/templates/nextjs/src/constants/index.ts +5 -0
  76. package/templates/nextjs/src/env.ts +41 -0
  77. package/templates/nextjs/src/features/landing/api/get-users.api.ts +7 -0
  78. package/templates/nextjs/src/features/landing/api/index.ts +2 -0
  79. package/templates/nextjs/src/features/landing/api/query-keys.ts +7 -0
  80. package/templates/nextjs/src/features/landing/components/CartDemo.tsx +66 -0
  81. package/templates/nextjs/src/features/landing/components/Features.tsx +39 -0
  82. package/templates/nextjs/src/features/landing/components/Hero.tsx +65 -0
  83. package/templates/nextjs/src/features/landing/components/LandingPage.tsx +17 -0
  84. package/templates/nextjs/src/features/landing/components/ProjectFormDemo.tsx +62 -0
  85. package/templates/nextjs/src/features/landing/components/Reveal.tsx +83 -0
  86. package/templates/nextjs/src/features/landing/components/Showcase.tsx +66 -0
  87. package/templates/nextjs/src/features/landing/components/UsersDemo.tsx +188 -0
  88. package/templates/nextjs/src/features/landing/data/features.data.tsx +47 -0
  89. package/templates/nextjs/src/features/landing/data/index.ts +1 -0
  90. package/templates/nextjs/src/features/landing/helpers/get-initials.ts +15 -0
  91. package/templates/nextjs/src/features/landing/helpers/index.ts +7 -0
  92. package/templates/nextjs/src/features/landing/helpers/motion.ts +21 -0
  93. package/templates/nextjs/src/features/landing/hooks/index.ts +1 -0
  94. package/templates/nextjs/src/features/landing/hooks/use-users.ts +16 -0
  95. package/templates/nextjs/src/features/landing/icons/index.ts +6 -0
  96. package/templates/nextjs/src/features/landing/icons/nextjs.tsx +68 -0
  97. package/templates/nextjs/src/features/landing/icons/react-hook-form.tsx +18 -0
  98. package/templates/nextjs/src/features/landing/icons/react.tsx +20 -0
  99. package/templates/nextjs/src/features/landing/icons/tailwind.tsx +14 -0
  100. package/templates/nextjs/src/features/landing/icons/tanstack.tsx +321 -0
  101. package/templates/nextjs/src/features/landing/icons/typescript.tsx +16 -0
  102. package/templates/nextjs/src/features/landing/index.ts +1 -0
  103. package/templates/nextjs/src/features/landing/schemas/index.ts +1 -0
  104. package/templates/nextjs/src/features/landing/schemas/project.schema.ts +7 -0
  105. package/templates/nextjs/src/features/landing/stores/counter.store.ts +18 -0
  106. package/templates/nextjs/src/features/landing/stores/index.ts +1 -0
  107. package/templates/nextjs/src/features/landing/types/index.ts +1 -0
  108. package/templates/nextjs/src/features/landing/types/user.types.ts +9 -0
  109. package/templates/nextjs/src/helpers/format-date.ts +13 -0
  110. package/templates/nextjs/src/helpers/index.ts +1 -0
  111. package/templates/nextjs/src/hooks/index.ts +5 -0
  112. package/templates/nextjs/src/lib/api.ts +97 -0
  113. package/templates/nextjs/src/lib/query-client.ts +18 -0
  114. package/templates/nextjs/src/lib/utils.ts +12 -0
  115. package/templates/nextjs/src/providers/Providers.tsx +15 -0
  116. package/templates/nextjs/src/providers/QueryProvider.tsx +19 -0
  117. package/templates/nextjs/src/providers/ThemeProvider.tsx +9 -0
  118. package/templates/nextjs/src/providers/index.ts +1 -0
  119. package/templates/nextjs/src/proxy.ts +6 -0
  120. package/templates/nextjs/src/schemas/index.ts +5 -0
  121. package/templates/nextjs/src/stores/index.ts +5 -0
  122. package/templates/nextjs/src/styles/tailwind.css +122 -0
  123. package/templates/nextjs/src/types/site-config.types.ts +10 -0
  124. package/templates/nextjs/tsconfig.json +45 -0
  125. package/templates/nextjs/tsconfig.tsbuildinfo +1 -0
  126. package/templates/tanstack/.changeset/README.md +8 -0
  127. package/templates/tanstack/.changeset/config.json +11 -0
  128. package/templates/tanstack/.env.example +6 -0
  129. package/templates/tanstack/.env.local +6 -0
  130. package/templates/tanstack/.eslintcache +1 -0
  131. package/templates/tanstack/.github/workflows/ci.yml +41 -0
  132. package/templates/tanstack/.husky/commit-msg +1 -0
  133. package/templates/tanstack/.husky/pre-commit +1 -0
  134. package/templates/tanstack/.husky/pre-push +1 -0
  135. package/templates/tanstack/.prettierignore +7 -0
  136. package/templates/tanstack/.prettierrc +41 -0
  137. package/templates/tanstack/.vscode/extensions.json +7 -0
  138. package/templates/tanstack/.vscode/settings.json +22 -0
  139. package/templates/tanstack/LICENSE +21 -0
  140. package/templates/tanstack/README.md +204 -0
  141. package/templates/tanstack/_gitignore +52 -0
  142. package/templates/tanstack/commitlint.config.js +6 -0
  143. package/templates/tanstack/eslint.config.js +28 -0
  144. package/templates/tanstack/knip.config.js +22 -0
  145. package/templates/tanstack/package.json +130 -0
  146. package/templates/tanstack/pnpm-lock.yaml +5835 -0
  147. package/templates/tanstack/pnpm-workspace.yaml +3 -0
  148. package/templates/tanstack/public/favicon.ico +0 -0
  149. package/templates/tanstack/public/llms.txt +86 -0
  150. package/templates/tanstack/public/logo.png +0 -0
  151. package/templates/tanstack/public/logo.webp +0 -0
  152. package/templates/tanstack/public/og.png +0 -0
  153. package/templates/tanstack/src/components/shared/DefaultCatchBoundary.tsx +36 -0
  154. package/templates/tanstack/src/components/shared/NotFound.tsx +18 -0
  155. package/templates/tanstack/src/components/shared/Pending.tsx +13 -0
  156. package/templates/tanstack/src/components/shared/ThemeToggle.tsx +31 -0
  157. package/templates/tanstack/src/components/ui/avatar.tsx +52 -0
  158. package/templates/tanstack/src/components/ui/button.tsx +47 -0
  159. package/templates/tanstack/src/components/ui/dialog.tsx +107 -0
  160. package/templates/tanstack/src/components/ui/field.tsx +24 -0
  161. package/templates/tanstack/src/components/ui/index.ts +27 -0
  162. package/templates/tanstack/src/components/ui/input.tsx +23 -0
  163. package/templates/tanstack/src/components/ui/label.tsx +17 -0
  164. package/templates/tanstack/src/components/ui/skeleton.tsx +13 -0
  165. package/templates/tanstack/src/components/ui/table.tsx +94 -0
  166. package/templates/tanstack/src/components/ui/tabs.tsx +46 -0
  167. package/templates/tanstack/src/config/seo.config.ts +52 -0
  168. package/templates/tanstack/src/config/site.config.ts +15 -0
  169. package/templates/tanstack/src/constants/index.ts +5 -0
  170. package/templates/tanstack/src/env.ts +47 -0
  171. package/templates/tanstack/src/features/landing/api/get-users.api.ts +7 -0
  172. package/templates/tanstack/src/features/landing/api/index.ts +2 -0
  173. package/templates/tanstack/src/features/landing/api/query-keys.ts +7 -0
  174. package/templates/tanstack/src/features/landing/components/CartDemo.tsx +66 -0
  175. package/templates/tanstack/src/features/landing/components/Features.tsx +39 -0
  176. package/templates/tanstack/src/features/landing/components/Hero.tsx +63 -0
  177. package/templates/tanstack/src/features/landing/components/LandingPage.tsx +17 -0
  178. package/templates/tanstack/src/features/landing/components/ProjectFormDemo.tsx +63 -0
  179. package/templates/tanstack/src/features/landing/components/Reveal.tsx +83 -0
  180. package/templates/tanstack/src/features/landing/components/Showcase.tsx +66 -0
  181. package/templates/tanstack/src/features/landing/components/UsersDemo.tsx +191 -0
  182. package/templates/tanstack/src/features/landing/data/features.data.tsx +45 -0
  183. package/templates/tanstack/src/features/landing/data/index.ts +1 -0
  184. package/templates/tanstack/src/features/landing/helpers/get-initials.ts +15 -0
  185. package/templates/tanstack/src/features/landing/helpers/index.ts +7 -0
  186. package/templates/tanstack/src/features/landing/helpers/motion.ts +21 -0
  187. package/templates/tanstack/src/features/landing/hooks/index.ts +1 -0
  188. package/templates/tanstack/src/features/landing/hooks/use-users.ts +19 -0
  189. package/templates/tanstack/src/features/landing/icons/index.ts +5 -0
  190. package/templates/tanstack/src/features/landing/icons/react-hook-form.tsx +18 -0
  191. package/templates/tanstack/src/features/landing/icons/react.tsx +20 -0
  192. package/templates/tanstack/src/features/landing/icons/tailwind.tsx +14 -0
  193. package/templates/tanstack/src/features/landing/icons/tanstack.tsx +321 -0
  194. package/templates/tanstack/src/features/landing/icons/typescript.tsx +16 -0
  195. package/templates/tanstack/src/features/landing/index.ts +1 -0
  196. package/templates/tanstack/src/features/landing/schemas/index.ts +1 -0
  197. package/templates/tanstack/src/features/landing/schemas/project.schema.ts +7 -0
  198. package/templates/tanstack/src/features/landing/stores/counter.store.ts +18 -0
  199. package/templates/tanstack/src/features/landing/stores/index.ts +1 -0
  200. package/templates/tanstack/src/features/landing/types/index.ts +1 -0
  201. package/templates/tanstack/src/features/landing/types/user.types.ts +9 -0
  202. package/templates/tanstack/src/helpers/format-date.ts +13 -0
  203. package/templates/tanstack/src/helpers/index.ts +1 -0
  204. package/templates/tanstack/src/hooks/index.ts +5 -0
  205. package/templates/tanstack/src/lib/api.ts +97 -0
  206. package/templates/tanstack/src/lib/query-client.ts +18 -0
  207. package/templates/tanstack/src/lib/utils.ts +13 -0
  208. package/templates/tanstack/src/providers/Providers.tsx +12 -0
  209. package/templates/tanstack/src/providers/ThemeProvider.tsx +98 -0
  210. package/templates/tanstack/src/providers/devtools.tsx +6 -0
  211. package/templates/tanstack/src/providers/index.ts +1 -0
  212. package/templates/tanstack/src/providers/root-provider.ts +9 -0
  213. package/templates/tanstack/src/routeTree.gen.ts +123 -0
  214. package/templates/tanstack/src/router.tsx +27 -0
  215. package/templates/tanstack/src/routes/__root.tsx +78 -0
  216. package/templates/tanstack/src/routes/index.tsx +13 -0
  217. package/templates/tanstack/src/routes/robots[.]txt.ts +21 -0
  218. package/templates/tanstack/src/routes/site[.]webmanifest.ts +32 -0
  219. package/templates/tanstack/src/routes/sitemap[.]xml.ts +27 -0
  220. package/templates/tanstack/src/schemas/index.ts +5 -0
  221. package/templates/tanstack/src/start.ts +20 -0
  222. package/templates/tanstack/src/stores/index.ts +5 -0
  223. package/templates/tanstack/src/styles/tailwind.css +123 -0
  224. package/templates/tanstack/src/types/site-config.types.ts +10 -0
  225. package/templates/tanstack/tsconfig.json +25 -0
  226. package/templates/tanstack/tsr.config.json +3 -0
  227. package/templates/tanstack/vite.config.ts +12 -0
  228. package/templates-i18n/nextjs/.changeset/README.md +8 -0
  229. package/templates-i18n/nextjs/.changeset/config.json +11 -0
  230. package/templates-i18n/nextjs/.env.example +6 -0
  231. package/templates-i18n/nextjs/.eslintcache +1 -0
  232. package/templates-i18n/nextjs/.github/workflows/ci.yml +41 -0
  233. package/templates-i18n/nextjs/.husky/commit-msg +1 -0
  234. package/templates-i18n/nextjs/.husky/pre-commit +1 -0
  235. package/templates-i18n/nextjs/.husky/pre-push +1 -0
  236. package/templates-i18n/nextjs/.prettierignore +6 -0
  237. package/templates-i18n/nextjs/.prettierrc +42 -0
  238. package/templates-i18n/nextjs/.vscode/extensions.json +7 -0
  239. package/templates-i18n/nextjs/.vscode/settings.json +20 -0
  240. package/templates-i18n/nextjs/LICENSE +21 -0
  241. package/templates-i18n/nextjs/README.md +202 -0
  242. package/templates-i18n/nextjs/_gitignore +45 -0
  243. package/templates-i18n/nextjs/commitlint.config.js +6 -0
  244. package/templates-i18n/nextjs/eslint.config.mjs +27 -0
  245. package/templates-i18n/nextjs/knip.config.js +29 -0
  246. package/templates-i18n/nextjs/next-env.d.ts +6 -0
  247. package/templates-i18n/nextjs/next.config.ts +42 -0
  248. package/templates-i18n/nextjs/package.json +117 -0
  249. package/templates-i18n/nextjs/pnpm-lock.yaml +6854 -0
  250. package/templates-i18n/nextjs/pnpm-workspace.yaml +3 -0
  251. package/templates-i18n/nextjs/postcss.config.mjs +7 -0
  252. package/templates-i18n/nextjs/public/favicon.ico +0 -0
  253. package/templates-i18n/nextjs/public/llms.txt +96 -0
  254. package/templates-i18n/nextjs/public/logo.png +0 -0
  255. package/templates-i18n/nextjs/public/logo.webp +0 -0
  256. package/templates-i18n/nextjs/public/og.png +0 -0
  257. package/templates-i18n/nextjs/src/app/[locale]/error.tsx +34 -0
  258. package/templates-i18n/nextjs/src/app/[locale]/layout.tsx +60 -0
  259. package/templates-i18n/nextjs/src/app/[locale]/loading.tsx +12 -0
  260. package/templates-i18n/nextjs/src/app/[locale]/not-found.tsx +18 -0
  261. package/templates-i18n/nextjs/src/app/[locale]/page.tsx +10 -0
  262. package/templates-i18n/nextjs/src/app/favicon.ico +0 -0
  263. package/templates-i18n/nextjs/src/app/global-error.tsx +32 -0
  264. package/templates-i18n/nextjs/src/app/manifest.ts +22 -0
  265. package/templates-i18n/nextjs/src/app/robots.ts +13 -0
  266. package/templates-i18n/nextjs/src/app/sitemap.ts +14 -0
  267. package/templates-i18n/nextjs/src/components/shared/LanguageSwitcher.tsx +48 -0
  268. package/templates-i18n/nextjs/src/components/shared/ThemeToggle.tsx +30 -0
  269. package/templates-i18n/nextjs/src/components/ui/avatar.tsx +54 -0
  270. package/templates-i18n/nextjs/src/components/ui/button.tsx +46 -0
  271. package/templates-i18n/nextjs/src/components/ui/dialog.tsx +107 -0
  272. package/templates-i18n/nextjs/src/components/ui/field.tsx +24 -0
  273. package/templates-i18n/nextjs/src/components/ui/index.ts +27 -0
  274. package/templates-i18n/nextjs/src/components/ui/input.tsx +23 -0
  275. package/templates-i18n/nextjs/src/components/ui/label.tsx +17 -0
  276. package/templates-i18n/nextjs/src/components/ui/skeleton.tsx +13 -0
  277. package/templates-i18n/nextjs/src/components/ui/table.tsx +94 -0
  278. package/templates-i18n/nextjs/src/components/ui/tabs.tsx +46 -0
  279. package/templates-i18n/nextjs/src/config/seo.config.ts +37 -0
  280. package/templates-i18n/nextjs/src/config/site.config.ts +15 -0
  281. package/templates-i18n/nextjs/src/constants/index.ts +5 -0
  282. package/templates-i18n/nextjs/src/env.ts +41 -0
  283. package/templates-i18n/nextjs/src/features/landing/api/get-users.api.ts +7 -0
  284. package/templates-i18n/nextjs/src/features/landing/api/index.ts +2 -0
  285. package/templates-i18n/nextjs/src/features/landing/api/query-keys.ts +7 -0
  286. package/templates-i18n/nextjs/src/features/landing/components/CartDemo.tsx +68 -0
  287. package/templates-i18n/nextjs/src/features/landing/components/Features.tsx +84 -0
  288. package/templates-i18n/nextjs/src/features/landing/components/Hero.tsx +76 -0
  289. package/templates-i18n/nextjs/src/features/landing/components/LandingPage.tsx +17 -0
  290. package/templates-i18n/nextjs/src/features/landing/components/ProjectFormDemo.tsx +64 -0
  291. package/templates-i18n/nextjs/src/features/landing/components/Reveal.tsx +83 -0
  292. package/templates-i18n/nextjs/src/features/landing/components/Showcase.tsx +83 -0
  293. package/templates-i18n/nextjs/src/features/landing/components/UsersDemo.tsx +191 -0
  294. package/templates-i18n/nextjs/src/features/landing/data/features.data.tsx +47 -0
  295. package/templates-i18n/nextjs/src/features/landing/data/index.ts +1 -0
  296. package/templates-i18n/nextjs/src/features/landing/helpers/get-initials.ts +15 -0
  297. package/templates-i18n/nextjs/src/features/landing/helpers/index.ts +7 -0
  298. package/templates-i18n/nextjs/src/features/landing/helpers/motion.ts +21 -0
  299. package/templates-i18n/nextjs/src/features/landing/hooks/index.ts +1 -0
  300. package/templates-i18n/nextjs/src/features/landing/hooks/use-users.ts +16 -0
  301. package/templates-i18n/nextjs/src/features/landing/icons/index.ts +6 -0
  302. package/templates-i18n/nextjs/src/features/landing/icons/nextjs.tsx +68 -0
  303. package/templates-i18n/nextjs/src/features/landing/icons/react-hook-form.tsx +18 -0
  304. package/templates-i18n/nextjs/src/features/landing/icons/react.tsx +20 -0
  305. package/templates-i18n/nextjs/src/features/landing/icons/tailwind.tsx +14 -0
  306. package/templates-i18n/nextjs/src/features/landing/icons/tanstack.tsx +321 -0
  307. package/templates-i18n/nextjs/src/features/landing/icons/typescript.tsx +16 -0
  308. package/templates-i18n/nextjs/src/features/landing/index.ts +1 -0
  309. package/templates-i18n/nextjs/src/features/landing/schemas/index.ts +1 -0
  310. package/templates-i18n/nextjs/src/features/landing/schemas/project.schema.ts +9 -0
  311. package/templates-i18n/nextjs/src/features/landing/stores/counter.store.ts +18 -0
  312. package/templates-i18n/nextjs/src/features/landing/stores/index.ts +1 -0
  313. package/templates-i18n/nextjs/src/features/landing/types/index.ts +1 -0
  314. package/templates-i18n/nextjs/src/features/landing/types/user.types.ts +9 -0
  315. package/templates-i18n/nextjs/src/helpers/format-date.ts +13 -0
  316. package/templates-i18n/nextjs/src/helpers/index.ts +1 -0
  317. package/templates-i18n/nextjs/src/hooks/index.ts +5 -0
  318. package/templates-i18n/nextjs/src/i18n/request.ts +16 -0
  319. package/templates-i18n/nextjs/src/i18n/routing.ts +11 -0
  320. package/templates-i18n/nextjs/src/lib/api.ts +97 -0
  321. package/templates-i18n/nextjs/src/lib/query-client.ts +18 -0
  322. package/templates-i18n/nextjs/src/lib/utils.ts +12 -0
  323. package/templates-i18n/nextjs/src/messages/en.json +55 -0
  324. package/templates-i18n/nextjs/src/messages/tr.json +55 -0
  325. package/templates-i18n/nextjs/src/providers/Providers.tsx +15 -0
  326. package/templates-i18n/nextjs/src/providers/QueryProvider.tsx +19 -0
  327. package/templates-i18n/nextjs/src/providers/ThemeProvider.tsx +9 -0
  328. package/templates-i18n/nextjs/src/providers/index.ts +1 -0
  329. package/templates-i18n/nextjs/src/proxy.ts +16 -0
  330. package/templates-i18n/nextjs/src/schemas/index.ts +5 -0
  331. package/templates-i18n/nextjs/src/stores/index.ts +5 -0
  332. package/templates-i18n/nextjs/src/styles/tailwind.css +122 -0
  333. package/templates-i18n/nextjs/src/types/site-config.types.ts +10 -0
  334. package/templates-i18n/nextjs/tsconfig.json +45 -0
  335. package/templates-i18n/nextjs/tsconfig.tsbuildinfo +1 -0
  336. package/templates-i18n/tanstack/.changeset/README.md +8 -0
  337. package/templates-i18n/tanstack/.changeset/config.json +11 -0
  338. package/templates-i18n/tanstack/.env.example +6 -0
  339. package/templates-i18n/tanstack/.eslintcache +1 -0
  340. package/templates-i18n/tanstack/.github/workflows/ci.yml +41 -0
  341. package/templates-i18n/tanstack/.husky/commit-msg +1 -0
  342. package/templates-i18n/tanstack/.husky/pre-commit +1 -0
  343. package/templates-i18n/tanstack/.husky/pre-push +1 -0
  344. package/templates-i18n/tanstack/.prettierignore +7 -0
  345. package/templates-i18n/tanstack/.prettierrc +41 -0
  346. package/templates-i18n/tanstack/.vscode/extensions.json +7 -0
  347. package/templates-i18n/tanstack/.vscode/settings.json +22 -0
  348. package/templates-i18n/tanstack/LICENSE +21 -0
  349. package/templates-i18n/tanstack/README.md +204 -0
  350. package/templates-i18n/tanstack/_gitignore +52 -0
  351. package/templates-i18n/tanstack/commitlint.config.js +6 -0
  352. package/templates-i18n/tanstack/eslint.config.js +29 -0
  353. package/templates-i18n/tanstack/knip.config.js +26 -0
  354. package/templates-i18n/tanstack/messages/en.json +65 -0
  355. package/templates-i18n/tanstack/messages/tr.json +65 -0
  356. package/templates-i18n/tanstack/package.json +132 -0
  357. package/templates-i18n/tanstack/pnpm-lock.yaml +5998 -0
  358. package/templates-i18n/tanstack/pnpm-workspace.yaml +3 -0
  359. package/templates-i18n/tanstack/project.inlang/README.md +157 -0
  360. package/templates-i18n/tanstack/project.inlang/settings.json +9 -0
  361. package/templates-i18n/tanstack/public/favicon.ico +0 -0
  362. package/templates-i18n/tanstack/public/llms.txt +86 -0
  363. package/templates-i18n/tanstack/public/logo.png +0 -0
  364. package/templates-i18n/tanstack/public/logo.webp +0 -0
  365. package/templates-i18n/tanstack/public/og.png +0 -0
  366. package/templates-i18n/tanstack/src/components/shared/DefaultCatchBoundary.tsx +36 -0
  367. package/templates-i18n/tanstack/src/components/shared/LanguageSwitcher.tsx +57 -0
  368. package/templates-i18n/tanstack/src/components/shared/NotFound.tsx +18 -0
  369. package/templates-i18n/tanstack/src/components/shared/Pending.tsx +13 -0
  370. package/templates-i18n/tanstack/src/components/shared/ThemeToggle.tsx +31 -0
  371. package/templates-i18n/tanstack/src/components/ui/avatar.tsx +52 -0
  372. package/templates-i18n/tanstack/src/components/ui/button.tsx +47 -0
  373. package/templates-i18n/tanstack/src/components/ui/dialog.tsx +107 -0
  374. package/templates-i18n/tanstack/src/components/ui/field.tsx +24 -0
  375. package/templates-i18n/tanstack/src/components/ui/index.ts +27 -0
  376. package/templates-i18n/tanstack/src/components/ui/input.tsx +23 -0
  377. package/templates-i18n/tanstack/src/components/ui/label.tsx +17 -0
  378. package/templates-i18n/tanstack/src/components/ui/skeleton.tsx +13 -0
  379. package/templates-i18n/tanstack/src/components/ui/table.tsx +94 -0
  380. package/templates-i18n/tanstack/src/components/ui/tabs.tsx +46 -0
  381. package/templates-i18n/tanstack/src/config/seo.config.ts +52 -0
  382. package/templates-i18n/tanstack/src/config/site.config.ts +15 -0
  383. package/templates-i18n/tanstack/src/constants/index.ts +5 -0
  384. package/templates-i18n/tanstack/src/env.ts +47 -0
  385. package/templates-i18n/tanstack/src/features/landing/api/get-users.api.ts +7 -0
  386. package/templates-i18n/tanstack/src/features/landing/api/index.ts +2 -0
  387. package/templates-i18n/tanstack/src/features/landing/api/query-keys.ts +7 -0
  388. package/templates-i18n/tanstack/src/features/landing/components/CartDemo.tsx +67 -0
  389. package/templates-i18n/tanstack/src/features/landing/components/Features.tsx +79 -0
  390. package/templates-i18n/tanstack/src/features/landing/components/Hero.tsx +68 -0
  391. package/templates-i18n/tanstack/src/features/landing/components/LandingPage.tsx +17 -0
  392. package/templates-i18n/tanstack/src/features/landing/components/ProjectFormDemo.tsx +64 -0
  393. package/templates-i18n/tanstack/src/features/landing/components/Reveal.tsx +83 -0
  394. package/templates-i18n/tanstack/src/features/landing/components/Showcase.tsx +81 -0
  395. package/templates-i18n/tanstack/src/features/landing/components/UsersDemo.tsx +191 -0
  396. package/templates-i18n/tanstack/src/features/landing/data/features.data.tsx +45 -0
  397. package/templates-i18n/tanstack/src/features/landing/data/index.ts +1 -0
  398. package/templates-i18n/tanstack/src/features/landing/helpers/get-initials.ts +15 -0
  399. package/templates-i18n/tanstack/src/features/landing/helpers/index.ts +7 -0
  400. package/templates-i18n/tanstack/src/features/landing/helpers/motion.ts +21 -0
  401. package/templates-i18n/tanstack/src/features/landing/hooks/index.ts +1 -0
  402. package/templates-i18n/tanstack/src/features/landing/hooks/use-users.ts +19 -0
  403. package/templates-i18n/tanstack/src/features/landing/icons/index.ts +5 -0
  404. package/templates-i18n/tanstack/src/features/landing/icons/react-hook-form.tsx +18 -0
  405. package/templates-i18n/tanstack/src/features/landing/icons/react.tsx +20 -0
  406. package/templates-i18n/tanstack/src/features/landing/icons/tailwind.tsx +14 -0
  407. package/templates-i18n/tanstack/src/features/landing/icons/tanstack.tsx +321 -0
  408. package/templates-i18n/tanstack/src/features/landing/icons/typescript.tsx +16 -0
  409. package/templates-i18n/tanstack/src/features/landing/index.ts +1 -0
  410. package/templates-i18n/tanstack/src/features/landing/schemas/index.ts +1 -0
  411. package/templates-i18n/tanstack/src/features/landing/schemas/project.schema.ts +10 -0
  412. package/templates-i18n/tanstack/src/features/landing/stores/counter.store.ts +18 -0
  413. package/templates-i18n/tanstack/src/features/landing/stores/index.ts +1 -0
  414. package/templates-i18n/tanstack/src/features/landing/types/index.ts +1 -0
  415. package/templates-i18n/tanstack/src/features/landing/types/user.types.ts +9 -0
  416. package/templates-i18n/tanstack/src/helpers/format-date.ts +13 -0
  417. package/templates-i18n/tanstack/src/helpers/index.ts +1 -0
  418. package/templates-i18n/tanstack/src/hooks/index.ts +5 -0
  419. package/templates-i18n/tanstack/src/lib/api.ts +97 -0
  420. package/templates-i18n/tanstack/src/lib/query-client.ts +18 -0
  421. package/templates-i18n/tanstack/src/lib/utils.ts +13 -0
  422. package/templates-i18n/tanstack/src/paraglide/README.md +162 -0
  423. package/templates-i18n/tanstack/src/providers/Providers.tsx +12 -0
  424. package/templates-i18n/tanstack/src/providers/ThemeProvider.tsx +98 -0
  425. package/templates-i18n/tanstack/src/providers/devtools.tsx +6 -0
  426. package/templates-i18n/tanstack/src/providers/index.ts +1 -0
  427. package/templates-i18n/tanstack/src/providers/root-provider.ts +9 -0
  428. package/templates-i18n/tanstack/src/routeTree.gen.ts +179 -0
  429. package/templates-i18n/tanstack/src/router.tsx +27 -0
  430. package/templates-i18n/tanstack/src/routes/$lang/index.tsx +13 -0
  431. package/templates-i18n/tanstack/src/routes/$lang.tsx +22 -0
  432. package/templates-i18n/tanstack/src/routes/__root.tsx +80 -0
  433. package/templates-i18n/tanstack/src/routes/index.tsx +13 -0
  434. package/templates-i18n/tanstack/src/routes/robots[.]txt.ts +21 -0
  435. package/templates-i18n/tanstack/src/routes/site[.]webmanifest.ts +32 -0
  436. package/templates-i18n/tanstack/src/routes/sitemap[.]xml.ts +27 -0
  437. package/templates-i18n/tanstack/src/schemas/index.ts +5 -0
  438. package/templates-i18n/tanstack/src/server.ts +10 -0
  439. package/templates-i18n/tanstack/src/start.ts +20 -0
  440. package/templates-i18n/tanstack/src/stores/index.ts +5 -0
  441. package/templates-i18n/tanstack/src/styles/tailwind.css +123 -0
  442. package/templates-i18n/tanstack/src/types/site-config.types.ts +10 -0
  443. package/templates-i18n/tanstack/tsconfig.json +26 -0
  444. package/templates-i18n/tanstack/tsr.config.json +3 -0
  445. package/templates-i18n/tanstack/vite.config.ts +31 -0
  446. package/index.js +0 -3
  447. package/public/start.jpg +0 -0
package/LICENSE CHANGED
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,35 +1,111 @@
1
1
  <div align="center">
2
- <img src="./public/start.jpg" alt="Vira Stack CLI" />
2
+
3
+ <a href="https://github.com/virastack/start" target="_blank" rel="noreferrer">
4
+ <picture>
5
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/virastack/start/main/assets/logo-dark.png">
6
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/virastack/start/main/assets/logo-light.png">
7
+ <img src="https://raw.githubusercontent.com/virastack/start/main/assets/logo-light.png" alt="ViraStack Start" height="120" style="max-width: 100%;" />
8
+ </picture>
9
+ </a>
10
+
11
+ *Production-grade scaffolding CLI for modern React — integrate ecosystem tools in one command.*
12
+
13
+ [![ViraStack Start](https://img.shields.io/badge/ViraStack-Start-%2300bba7)](https://virastack.com/start/)
14
+ [![npm version](https://img.shields.io/npm/v/virastack?color=blue)](https://www.npmjs.com/package/virastack)
15
+ [![npm downloads](https://img.shields.io/npm/dt/virastack)](https://www.npmjs.com/package/virastack)
16
+ [![Node](https://img.shields.io/badge/node-%3E%3D20.9-339933?logo=node.js&logoColor=white)](package.json)
17
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
18
+ [![@virastack](https://img.shields.io/badge/-%40virastack-black?logo=x&logoColor=white)](https://x.com/virastack)
19
+
3
20
  </div>
4
21
 
5
- <br />
22
+ ---
6
23
 
7
- # ViraStack CLI
24
+ ### [Read the full documentation →](https://virastack.com/start/)
8
25
 
9
- Automated scaffolding tool to initialize and scale high-discipline ViraStack architectures.
26
+ ## Why ViraStack Start?
10
27
 
11
- ## Explore the ViraStack Ecosystem
28
+ - **Interactive CLI:** Interactive prompts for template selection, project naming, and ecosystem tool integration.
29
+ - **Production-Ready Foundations:** Scaffolds Next.js or TanStack Start projects with pre-configured feature-sliced architecture.
30
+ - **Built-in AI Protocols:** Integrates [**ViraStack AI**](https://github.com/virastack/ai) automatically — architecture rules, `AGENTS.md`, and design skills from [**Emil Kowalski**](https://github.com/emilkowalski/skills) and [**Jakub Krehel**](https://github.com/jakubkrehel/make-interfaces-feel-better) — giving your coding agents a strict "constitution" from day one.
31
+ - **End-to-End Type Safety:** Strict TypeScript rules, Zod validation, and native package manager alignment (pnpm, npm, yarn, bun).
32
+ - **Ecosystem Integration:** Add optional ViraStack tools (`@virastack/mask`, `@virastack/password`) seamlessly.
33
+
34
+ ## Quick Start
35
+
36
+ **Recommended (pnpm):**
37
+ ```bash
38
+ pnpm dlx virastack
39
+ ```
40
+
41
+ **Alternatives:**
42
+ ```bash
43
+ npx virastack
44
+ # or
45
+ yarn dlx virastack
46
+ # or
47
+ bunx virastack
48
+ ```
49
+
50
+ ## What it asks
51
+
52
+ ```text
53
+ What is your project named?
54
+ virastack-app
12
55
 
13
- ### Projects
56
+ Which template would you like to use?
57
+ › Next.js App Router
58
+ TanStack Start
14
59
 
15
- - [**Next.js Boilerplate**](https://github.com/virastack/nextjs-boilerplate) - Production-ready Next.js 16+ starter template built with Tailwind CSS 4 and TypeScript.
16
- - [**AI Rules**](https://github.com/virastack/ai-rules) - AI-native architecture kit and high-discipline protocols for modern React applications.
17
- - [**Input Mask**](https://github.com/virastack/input-mask) - Lightweight, zero-dependency input masking library optimized for React Hook Form.
18
- - [**Password Toggle**](https://github.com/virastack/password-toggle) - Fully accessible and highly customizable password visibility hook for React.
19
- - [**Modern Web in 3 Minutes**](https://github.com/virastack/modern-web-in-3-minutes) - Master modern web development standards in just 3 minutes.
60
+ Would you like multi-language (i18n) support?
61
+ Yes
62
+ No
20
63
 
21
- ### 🚧 Coming Soon
64
+ Which ViraStack tools would you like to include?
65
+ [ ] @virastack/mask
66
+ [ ] @virastack/password
67
+ ```
22
68
 
23
- - [**Start (CLI)**](https://github.com/virastack/cli) - Automated scaffolding tool to initialize and scale high-discipline ViraStack architectures.
24
- - [**TanStack Boilerplate**](https://github.com/virastack/tanstack-boilerplate) - Production-ready TanStack Start starter template built with Tailwind CSS 4 and TypeScript.
25
- - [**Standards**](https://github.com/virastack/standards) - A unified suite of ESLint, Prettier, and architectural rules to enforce absolute code integrity.
26
- - [**Error Guard**](https://github.com/virastack/error-guard) - Pro-grade error handling and smart recovery protocols for zero-friction React environments.
69
+ ## Tools
70
+
71
+ | Tool | Description |
72
+ | :--- | :--- |
73
+ | `@virastack/ai` | Pre-configured AI layer and coding rules for modern AI assistants (included in templates by default) |
74
+ | `@virastack/mask` | Input masking and formatting (Phone, IBAN, etc.) |
75
+ | `@virastack/password` | Password visibility toggle with customizable icons and text |
76
+
77
+ ## Options
78
+
79
+ | Flag | Description |
80
+ | :--- | :--- |
81
+ | `--name <name>` | Project name (or pass as positional / `.`) |
82
+ | `--template <name>` | `nextjs` or `tanstack` |
83
+ | `--tools <list>` | Comma-separated tools (`mask,password`) |
84
+ | `--i18n` / `--no-i18n` | Enable or disable the i18n template |
85
+ | `--yes`, `-y` | Non-interactive mode (flags + defaults) |
86
+ | `--skip-install` | Scaffold files only; skip install + AI setup |
87
+ | `--tr` | Turkish prompts |
88
+ | `--telemetry-disable` | Permanently disable anonymous usage tracking |
89
+ | `-v`, `--version` | Print CLI version |
90
+ | `-h`, `--help` | Show usage |
91
+
92
+ ## Telemetry
93
+
94
+ To understand which tools and templates are preferred by the community, ViraStack collects strictly anonymous usage data (template, i18n choice, selected tools, package manager, and CLI version). Absolutely no personal data, project names, or file paths are collected.
95
+
96
+ Opt out anytime: `pnpm dlx virastack --telemetry-disable`
97
+
98
+ ## Contributing
99
+
100
+ Ideas and bug reports are welcome — open an [issue](https://github.com/virastack/start/issues).
101
+
102
+ ## Explore the ViraStack Ecosystem
27
103
 
28
- ... and more at [**virastack.com**](https://virastack.com)
104
+ Discover all ViraStack tools, libraries, and boilerplates at [**virastack.com**](https://virastack.com).
29
105
 
30
106
  ## License
31
107
 
32
- Licensed under the <a href="https://github.com/virastack/cli/blob/main/LICENSE">MIT License</a>.
108
+ Licensed under the [MIT License](LICENSE).
33
109
 
34
110
  ## Maintainer
35
111
 
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import { main } from "../src/index.js";
3
+
4
+ main().catch((error) => {
5
+ console.error(error?.stack ?? error);
6
+ process.exitCode = 1;
7
+ });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "virastack",
3
- "version": "0.0.1",
4
- "description": "Virastack CLI",
3
+ "version": "1.0.1",
4
+ "description": "Scaffold new projects and add tools from the ViraStack ecosystem with a single command.",
5
5
  "author": {
6
6
  "name": "Ömer Gülçiçek (ViraStack)",
7
7
  "email": "iletisim@omergulcicek.com",
@@ -11,18 +11,52 @@
11
11
  "homepage": "https://virastack.com",
12
12
  "repository": {
13
13
  "type": "git",
14
- "url": "git+https://github.com/virastack/cli.git"
14
+ "url": "git+https://github.com/virastack/start.git"
15
15
  },
16
16
  "bugs": {
17
- "url": "https://github.com/virastack/cli/issues"
17
+ "url": "https://github.com/virastack/start/issues"
18
+ },
19
+ "type": "module",
20
+ "engines": {
21
+ "node": ">=20.9.0"
22
+ },
23
+ "publishConfig": {
24
+ "access": "public"
18
25
  },
19
- "main": "index.js",
20
26
  "bin": {
21
- "virastack": "./index.js"
27
+ "virastack": "./bin/virastack.js"
22
28
  },
29
+ "files": [
30
+ "bin",
31
+ "src",
32
+ "templates",
33
+ "templates-i18n",
34
+ "!src/**/*.test.js"
35
+ ],
23
36
  "keywords": [
24
37
  "virastack",
38
+ "start",
25
39
  "cli",
26
- "init"
27
- ]
28
- }
40
+ "create-virastack",
41
+ "scaffolding",
42
+ "boilerplate",
43
+ "nextjs",
44
+ "tanstack",
45
+ "react",
46
+ "typescript",
47
+ "dx"
48
+ ],
49
+ "dependencies": {
50
+ "@clack/prompts": "^1.7.0",
51
+ "cross-spawn": "^7.0.6",
52
+ "picocolors": "^1.1.1"
53
+ },
54
+ "devDependencies": {
55
+ "vitest": "^3.2.7"
56
+ },
57
+ "scripts": {
58
+ "start": "node ./bin/virastack.js",
59
+ "test": "vitest run",
60
+ "test:watch": "vitest"
61
+ }
62
+ }
@@ -0,0 +1,64 @@
1
+ import path from "node:path";
2
+ import { promises as fs } from "node:fs";
3
+ import * as p from "@clack/prompts";
4
+ import pc from "picocolors";
5
+
6
+ import { t, getLocale } from "../i18n.js";
7
+ import { runCommand } from "../utils/exec.js";
8
+ import { detectPackageManager, getAddArgs } from "../utils/package-manager.js";
9
+ import { trackEvent } from "../utils/telemetry.js";
10
+ import { findTool, TOOLS } from "../utils/tools.js";
11
+
12
+ async function fileExists(filePath) {
13
+ try {
14
+ await fs.access(filePath);
15
+ return true;
16
+ } catch {
17
+ return false;
18
+ }
19
+ }
20
+
21
+ export async function runAdd(toolId) {
22
+ console.log();
23
+ p.intro(pc.bgMagenta(pc.black(" ViraStack ")));
24
+
25
+ const toolList = TOOLS.map((tool) => tool.id).join(", ");
26
+
27
+ if (!toolId) {
28
+ p.log.error(t("add.toolMissing", { list: toolList }));
29
+ process.exit(1);
30
+ }
31
+
32
+ const tool = findTool(toolId);
33
+ if (!tool) {
34
+ p.log.error(t("add.toolInvalid", { tool: toolId, list: toolList }));
35
+ process.exit(1);
36
+ }
37
+
38
+ const cwd = process.cwd();
39
+ if (!(await fileExists(path.join(cwd, "package.json")))) {
40
+ p.log.error(t("add.notAProject"));
41
+ process.exit(1);
42
+ }
43
+
44
+ const packageManager = detectPackageManager();
45
+ const spinner = p.spinner();
46
+ spinner.start(t("add.installing", { pkg: tool.package }));
47
+
48
+ try {
49
+ if (tool.kind === "dependency") {
50
+ await runCommand(packageManager, getAddArgs(packageManager, [tool.package]), { cwd });
51
+ } else {
52
+ const args = ["--yes", tool.package, "init", "--force"];
53
+ if (getLocale() === "tr") args.push("--tr");
54
+ await runCommand("npx", args, { cwd });
55
+ }
56
+ spinner.stop(t("add.done", { pkg: tool.package }));
57
+ } catch (error) {
58
+ spinner.stop(t("add.installFailed", { pkg: tool.package }));
59
+ p.log.error(String(error?.message ?? error));
60
+ process.exit(1);
61
+ }
62
+
63
+ await trackEvent("add", { tool: tool.id, packageManager });
64
+ }
@@ -0,0 +1,286 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ import * as p from "@clack/prompts";
4
+ import pc from "picocolors";
5
+
6
+ import { t, getLocale } from "../i18n.js";
7
+ import { copyTemplate, dirHasFiles, isDirEmpty } from "../utils/copy-template.js";
8
+ import { runCommand } from "../utils/exec.js";
9
+ import { initGitRepo } from "../utils/git.js";
10
+ import { isOnline } from "../utils/is-online.js";
11
+ import {
12
+ detectPackageManager,
13
+ getAiInitCommand,
14
+ getInstallArgs,
15
+ getInstallCommand,
16
+ getRunDevCommand,
17
+ } from "../utils/package-manager.js";
18
+ import { trackEvent, isTelemetryDisabled, hasSeenTelemetryNotice, markTelemetryNoticeShown } from "../utils/telemetry.js";
19
+ import { TOOLS, parseToolsFlag } from "../utils/tools.js";
20
+ import { setupEnvFile } from "../utils/setup-env.js";
21
+ import { updatePackageJson } from "../utils/update-package-json.js";
22
+ import { updateReadme } from "../utils/update-readme.js";
23
+ import { validateProjectName } from "../utils/validate-project-name.js";
24
+
25
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
26
+ const TEMPLATES_DIR = path.resolve(__dirname, "../../templates");
27
+ const TEMPLATES_I18N_DIR = path.resolve(__dirname, "../../templates-i18n");
28
+ const VALID_TEMPLATES = new Set(["nextjs", "tanstack"]);
29
+
30
+ function cancelAndExit() {
31
+ p.cancel(t("cancel"));
32
+ process.exit(0);
33
+ }
34
+
35
+ function failAndExit(message) {
36
+ p.log.error(message);
37
+ process.exit(1);
38
+ }
39
+
40
+ /**
41
+ * @param {{
42
+ * name?: string,
43
+ * template?: string,
44
+ * i18n?: boolean,
45
+ * tools?: string[] | string | true,
46
+ * yes?: boolean,
47
+ * skipInstall?: boolean,
48
+ * }} [options]
49
+ */
50
+ export async function runInit(options = {}) {
51
+ const yes = Boolean(options.yes);
52
+ const skipInstall = Boolean(options.skipInstall);
53
+
54
+ console.clear();
55
+ p.intro(pc.bgMagenta(pc.black(" ViraStack ")));
56
+
57
+ if (!(await isTelemetryDisabled()) && !(await hasSeenTelemetryNotice())) {
58
+ p.log.info(t("telemetry.notice"));
59
+ await markTelemetryNoticeShown();
60
+ }
61
+
62
+ let projectNameInput = options.name;
63
+
64
+ if (projectNameInput == null) {
65
+ if (yes) {
66
+ failAndExit(t("projectName.errorNonInteractive"));
67
+ }
68
+
69
+ projectNameInput = await p.text({
70
+ message: t("projectName.message"),
71
+ placeholder: t("projectName.placeholder"),
72
+ validate: (value) => {
73
+ const error = validateProjectName(value);
74
+ if (error === "empty") return t("projectName.errorEmpty");
75
+ if (error === "invalid") return t("projectName.errorInvalid");
76
+ },
77
+ });
78
+ if (p.isCancel(projectNameInput)) return cancelAndExit();
79
+ } else {
80
+ const error = validateProjectName(projectNameInput);
81
+ if (error === "empty") failAndExit(t("projectName.errorEmpty"));
82
+ if (error === "invalid") failAndExit(t("projectName.errorInvalid"));
83
+ }
84
+
85
+ const useCurrentDir = projectNameInput === ".";
86
+ const targetDir = useCurrentDir
87
+ ? process.cwd()
88
+ : path.resolve(process.cwd(), projectNameInput);
89
+ const projectName = useCurrentDir ? path.basename(targetDir) : projectNameInput;
90
+
91
+ if (!(await isDirEmpty(targetDir))) {
92
+ if (yes) {
93
+ p.log.warn(
94
+ t("projectName.confirmNonEmptyDir", {
95
+ dir: useCurrentDir ? "." : projectNameInput,
96
+ }),
97
+ );
98
+ } else {
99
+ const proceed = await p.confirm({
100
+ message: t("projectName.confirmNonEmptyDir", {
101
+ dir: useCurrentDir ? "." : projectNameInput,
102
+ }),
103
+ initialValue: false,
104
+ });
105
+ if (p.isCancel(proceed) || !proceed) return cancelAndExit();
106
+ }
107
+ }
108
+
109
+ let template = options.template;
110
+ if (template != null && !VALID_TEMPLATES.has(template)) {
111
+ failAndExit(t("template.errorInvalid", { template }));
112
+ }
113
+
114
+ if (template == null) {
115
+ if (yes) {
116
+ template = "nextjs";
117
+ } else {
118
+ template = await p.select({
119
+ message: t("template.message"),
120
+ options: [
121
+ {
122
+ value: "nextjs",
123
+ label: t("template.nextjs.label"),
124
+ hint: t("template.nextjs.hint"),
125
+ },
126
+ {
127
+ value: "tanstack",
128
+ label: t("template.tanstack.label"),
129
+ hint: t("template.tanstack.hint"),
130
+ },
131
+ ],
132
+ });
133
+ if (p.isCancel(template)) return cancelAndExit();
134
+ }
135
+ }
136
+
137
+ if (template === "tanstack" && !(await dirHasFiles(path.join(TEMPLATES_DIR, "tanstack")))) {
138
+ p.log.warn(t("template.tanstack.notReady"));
139
+ template = "nextjs";
140
+ }
141
+
142
+ let wantsI18n = options.i18n;
143
+ if (wantsI18n == null) {
144
+ if (yes) {
145
+ wantsI18n = false;
146
+ } else {
147
+ wantsI18n = await p.confirm({
148
+ message: t("i18n.message"),
149
+ active: t("i18n.active"),
150
+ inactive: t("i18n.inactive"),
151
+ initialValue: false,
152
+ });
153
+ if (p.isCancel(wantsI18n)) return cancelAndExit();
154
+ }
155
+ }
156
+
157
+ if (wantsI18n && !(await dirHasFiles(path.join(TEMPLATES_I18N_DIR, template)))) {
158
+ p.log.warn(t("i18n.notReady"));
159
+ wantsI18n = false;
160
+ }
161
+
162
+ let tools = options.tools;
163
+ if (tools == null) {
164
+ if (yes) {
165
+ tools = [];
166
+ } else {
167
+ tools = await p.multiselect({
168
+ message: t("tools.message"),
169
+ required: false,
170
+ options: TOOLS.filter((tool) => !tool.hiddenFromInit).map((tool) => ({
171
+ value: tool.id,
172
+ label: t(`tools.${tool.id}.label`),
173
+ hint: t(`tools.${tool.id}.hint`),
174
+ })),
175
+ });
176
+ if (p.isCancel(tools)) return cancelAndExit();
177
+ }
178
+ } else {
179
+ tools = Array.isArray(tools) ? tools : parseToolsFlag(tools);
180
+ }
181
+
182
+ const packageManager = detectPackageManager();
183
+ const templateSourceDir = path.join(
184
+ wantsI18n ? TEMPLATES_I18N_DIR : TEMPLATES_DIR,
185
+ template,
186
+ );
187
+
188
+ const scaffoldSpinner = p.spinner();
189
+ scaffoldSpinner.start(t("scaffold.copying"));
190
+ await copyTemplate(templateSourceDir, targetDir);
191
+ await updatePackageJson(targetDir, { projectName, tools });
192
+ await updateReadme(targetDir, projectName);
193
+ await setupEnvFile(targetDir);
194
+ scaffoldSpinner.stop(t("scaffold.copyDone"));
195
+
196
+ const gitSpinner = p.spinner();
197
+ gitSpinner.start(t("scaffold.gitInit"));
198
+ const gitInitialized = await initGitRepo(targetDir);
199
+ gitSpinner.stop(
200
+ gitInitialized ? t("scaffold.gitInitDone") : t("scaffold.gitInitSkipped"),
201
+ );
202
+
203
+ const online = await isOnline();
204
+ let installOk = false;
205
+ let aiOk = false;
206
+ let offline = false;
207
+
208
+ if (skipInstall) {
209
+ p.log.info(t("scaffold.skipInstall"));
210
+ } else if (!online) {
211
+ offline = true;
212
+ p.log.warn(t("scaffold.offline"));
213
+ } else {
214
+ const installSpinner = p.spinner();
215
+ installSpinner.start(t("scaffold.installing", { pm: packageManager }));
216
+ try {
217
+ await runCommand(packageManager, getInstallArgs(packageManager), { cwd: targetDir });
218
+ installSpinner.stop(t("scaffold.installDone"));
219
+ installOk = true;
220
+ } catch (error) {
221
+ installSpinner.stop(t("scaffold.installFailed"));
222
+ p.log.error(String(error?.message ?? error));
223
+ }
224
+
225
+ if (installOk) {
226
+ const aiSpinner = p.spinner();
227
+ aiSpinner.start(t("scaffold.aiInit"));
228
+ try {
229
+ const args = ["--yes", "@virastack/ai", "init", "--force"];
230
+ if (getLocale() === "tr") args.push("--tr");
231
+ await runCommand("npx", args, { cwd: targetDir });
232
+ aiSpinner.stop(t("scaffold.aiInitDone"));
233
+ aiOk = true;
234
+ } catch {
235
+ aiSpinner.stop(t("scaffold.aiInitFailed"));
236
+ }
237
+
238
+ if (aiOk) {
239
+ try {
240
+ await runCommand("npx", ["--yes", "skills@latest", "add", "emilkowalski/skills", "--skill", "emil-design-eng", "-y"], { cwd: targetDir });
241
+ await runCommand("npx", ["--yes", "skills@latest", "add", "jakubkrehel/make-interfaces-feel-better", "-y"], { cwd: targetDir });
242
+ } catch {
243
+ p.log.warn(t("scaffold.skillsInitFailed"));
244
+ }
245
+ }
246
+ } else {
247
+ p.log.warn(t("scaffold.aiInitSkipped"));
248
+ }
249
+ }
250
+
251
+ await trackEvent("create", {
252
+ template,
253
+ i18n: wantsI18n,
254
+ tools,
255
+ packageManager,
256
+ installOk,
257
+ skipInstall,
258
+ });
259
+
260
+ const cdHint = useCurrentDir ? null : t("done.cd", { dir: projectName });
261
+ const installCmd = getInstallCommand(packageManager);
262
+ const aiCmd = getAiInitCommand();
263
+ const devCmd = getRunDevCommand(packageManager);
264
+
265
+ if (skipInstall || offline || !installOk) {
266
+ const outroLines = [t("done.partialTitle")];
267
+ if (cdHint) outroLines.push(cdHint);
268
+ outroLines.push(t("done.manualInstall", { cmd: installCmd }));
269
+ outroLines.push(t("done.manualAi", { cmd: aiCmd }));
270
+ outroLines.push(t("done.dev", { cmd: devCmd }));
271
+ if (!installOk && !offline && !skipInstall) {
272
+ p.log.error(t("done.installFailedNote"));
273
+ }
274
+ p.outro(outroLines.join("\n"));
275
+ if (!installOk && !offline && !skipInstall) {
276
+ process.exitCode = 1;
277
+ }
278
+ return;
279
+ }
280
+
281
+ const outroLines = [t("done.title")];
282
+ if (cdHint) outroLines.push(cdHint);
283
+ if (!aiOk) outroLines.push(t("done.manualAi", { cmd: aiCmd }));
284
+ outroLines.push(t("done.dev", { cmd: devCmd }));
285
+ p.outro(outroLines.join("\n"));
286
+ }