muscle-config 1.0.0

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 (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +430 -0
  3. package/dist/commands/create.command.js +104 -0
  4. package/dist/config/projectConfig.js +1 -0
  5. package/dist/features/architecture.feature.js +49 -0
  6. package/dist/features/css.feature.js +107 -0
  7. package/dist/features/feature.interface.js +1 -0
  8. package/dist/features/git.feature.js +52 -0
  9. package/dist/features/mui.feature.js +138 -0
  10. package/dist/features/prettier.feature.js +73 -0
  11. package/dist/features/tailwind.feature.js +116 -0
  12. package/dist/generators/architecture.generator.js +75 -0
  13. package/dist/generators/css-plain.generator.js +215 -0
  14. package/dist/generators/css.generator.js +45 -0
  15. package/dist/generators/mui.generator.js +176 -0
  16. package/dist/generators/react.generator.js +38 -0
  17. package/dist/generators/tailwind.config.generator.js +17 -0
  18. package/dist/generators/toggle.generator.js +26 -0
  19. package/dist/index.js +11 -0
  20. package/dist/prompts/architecture.prompt.js +131 -0
  21. package/dist/prompts/css.prompt.js +217 -0
  22. package/dist/prompts/directory.prompt.js +16 -0
  23. package/dist/prompts/framework.prompt.js +15 -0
  24. package/dist/prompts/git.prompt.js +23 -0
  25. package/dist/prompts/mui.prompt.js +104 -0
  26. package/dist/prompts/prettier.prompt.js +42 -0
  27. package/dist/prompts/projectName.prompt.js +13 -0
  28. package/dist/prompts/styling.prompt.js +17 -0
  29. package/dist/prompts/tailwind.prompt.js +175 -0
  30. package/dist/templates/react/css/App.jsx +41 -0
  31. package/dist/templates/react/css/App.tsx +41 -0
  32. package/dist/templates/react/mui/App.jsx +42 -0
  33. package/dist/templates/react/mui/App.tsx +42 -0
  34. package/dist/templates/react/tailwind-v4/index.css +20 -0
  35. package/dist/templates/react/tailwind-v4/vite.config.js +7 -0
  36. package/dist/templates/react/tailwind-v4/vite.config.ts +7 -0
  37. package/dist/utils/directory.js +43 -0
  38. package/dist/utils/install.js +7 -0
  39. package/dist/utils/logger.js +10 -0
  40. package/dist/utils/rollback.js +63 -0
  41. package/dist/utils/spinner.js +13 -0
  42. package/dist/utils/welcome.js +46 -0
  43. package/package.json +57 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Cat-Div7
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,430 @@
1
+ # muscle-config
2
+
3
+ > Frontend scaffolding done right, every time.
4
+
5
+ <p align="center">
6
+ <img alt="npm version" src="https://img.shields.io/npm/v/muscle-config?style=for-the-badge&color=CB3837&logo=npm&logoColor=white" />
7
+ <img alt="npm downloads" src="https://img.shields.io/npm/dm/muscle-config?style=for-the-badge&color=2ea043&logo=npm&logoColor=white" />
8
+ <img alt="license" src="https://img.shields.io/github/license/Cat-Div7/muscle-config?style=for-the-badge&color=blue" />
9
+ <img alt="last commit" src="https://img.shields.io/github/last-commit/Cat-Div7/muscle-config?style=for-the-badge&color=6e40c9&logo=github&logoColor=white" />
10
+ <img alt="PRs welcome" src="https://img.shields.io/badge/PRs-welcome-brightgreen?style=for-the-badge&logo=github&logoColor=white" />
11
+ </p>
12
+
13
+ `muscle-config` is a CLI tool that scaffolds production-ready frontend projects with a clean, opinionated folder structure — picking your framework, language, styling, routing, state management, and architecture in one guided setup.
14
+
15
+ ---
16
+
17
+ ## Quick Start
18
+
19
+ ```bash
20
+ npx muscle-config
21
+ ```
22
+
23
+ > No installation required.
24
+
25
+ ---
26
+
27
+ ## What It Does
28
+
29
+ Instead of spending hours setting up a new project from scratch, `muscle-config` walks you through a series of prompts and generates a complete, ready-to-code frontend project with:
30
+
31
+ - The right folder structure for your chosen architecture
32
+ - All necessary dependencies installed
33
+ - Config files pre-configured (TypeScript, Prettier, etc.)
34
+ - Component library setup (MUI, Tailwind, Normal CSS)
35
+ - Git repository initialized with an initial commit
36
+
37
+ ---
38
+
39
+ ## Safe by Design
40
+
41
+ If anything fails mid-installation, `muscle-config` automatically rolls back and cleans up. No half-scaffolded projects left behind.
42
+
43
+ ---
44
+
45
+ ## How It Works
46
+
47
+ `muscle-config` asks you a series of questions and generates a complete, ready-to-code frontend project in seconds.
48
+
49
+ ```
50
+ 1. Where to create → new folder or current directory
51
+ 2. Project name → only if new folder
52
+ 3. Framework → React + TypeScript or JavaScript
53
+ 4. Styling → Tailwind CSS v4 / MUI / Plain CSS / None
54
+ 5. Styling config → options specific to chosen styling solution
55
+ 6. Architecture → Feature-based / Layered / Skip
56
+ 7. Prettier → formatting config, merges with Tailwind plugin if present
57
+ 8. Git → optional git init + initial commit
58
+ 9. Done → project is ready
59
+ ```
60
+
61
+ Each choice builds on the previous one. When done, you get a fully scaffolded project with the right folder structure, dependencies installed, and config files ready — no manual setup needed.
62
+
63
+ ---
64
+
65
+ ## CLI Flow (For More Details)
66
+
67
+ ```
68
+ Welcome screen
69
+
70
+ ├── Q: Where would you like to create the project?
71
+ │ ❯ Create in a new folder
72
+ │ Use current directory
73
+
74
+ │ └── [ if current directory is not empty ]
75
+ │ ⚠ Files detected: file1, file2 ...
76
+
77
+ │ Q: Creating a project here will overwrite existing files.
78
+ │ What would you like to do?
79
+ │ ❯ Cancel (recommended)
80
+ │ Continue anyway (deletes existing files)
81
+
82
+ ├── Q: Project name? ← only if "new folder"
83
+ │ ❯ my-app
84
+
85
+ ├── Q: Choose your React setup:
86
+ │ ❯ React + TypeScript
87
+ │ React + JavaScript
88
+
89
+ └── Q: Choose your styling solution:
90
+ ❯ Tailwind CSS v4
91
+ MUI (Material UI)
92
+ None (plain CSS)
93
+ Skip
94
+
95
+
96
+ ── If Tailwind ────────────────────────────────────────────────
97
+
98
+ ├── Q: Tailwind configuration mode?
99
+ │ ❯ Beginner (recommended)
100
+ │ Advanced (full control)
101
+
102
+ ├── [ Beginner ]
103
+ │ │
104
+ │ ├── Q: Enable Dark Mode?
105
+ │ │ ❯ Yes → class strategy + ThemeToggle auto included
106
+ │ │ No
107
+ │ │
108
+ │ └── Q: Choose a primary color:
109
+ │ ❯ Indigo / Emerald / Neutral / Custom HEX / Skip
110
+
111
+ ├── [ Advanced ]
112
+ │ │
113
+ │ ├── Q: Enable Dark Mode?
114
+ │ │ ❯ Yes
115
+ │ │ No
116
+ │ │
117
+ │ │ └── Q: Dark Mode strategy:
118
+ │ │ ❯ Manual toggle (class) (recommended)
119
+ │ │ System preference (media)
120
+ │ │
121
+ │ │ └── Q: Add ThemeToggle component? ← only if "class"
122
+ │ │ ❯ Yes
123
+ │ │ No
124
+ │ │
125
+ │ ├── Q: Choose a primary color:
126
+ │ │ ❯ Indigo / Emerald / Neutral / Custom HEX / Skip
127
+ │ │
128
+ │ └── Q: Choose default font:
129
+ │ ❯ Inter — clean, modern, readable
130
+ │ Poppins — rounded, great for dashboards
131
+ │ Cairo — elegant, great for bilingual apps
132
+ │ Skip
133
+
134
+ └── Q: Add Prettier plugin for Tailwind class sorting? (recommended)
135
+ ❯ Yes ← fires for both Beginner and Advanced
136
+ No
137
+
138
+
139
+ ── If MUI ─────────────────────────────────────────────────────
140
+
141
+ ├── Q: Default theme mode:
142
+ │ ❯ Light
143
+ │ Dark
144
+ │ System preference
145
+
146
+ ├── Q: Add dark mode toggle component? (recommended — required for demo)
147
+ │ ❯ Yes
148
+ │ No
149
+
150
+ ├── Q: Choose a primary color:
151
+ │ ❯ Blue / Purple / Green / Custom HEX
152
+
153
+ ├── Q: Add MUI Icons package? (@mui/icons-material)
154
+ │ ❯ Yes
155
+ │ No
156
+ ├── Q: Choose a default font:
157
+ │ ❯ Inter — clean, modern, readable
158
+ │ Poppins — rounded, great for dashboards
159
+ │ Cairo — elegant, great for bilingual apps
160
+ │ Skip
161
+
162
+ └── Q: Override App.jsx with a MUI demo template? ← only if toggle = Yes
163
+ ❯ Yes
164
+ No
165
+
166
+ ── If CSS ─────────────────────────────────────────────────────
167
+
168
+ ├── Q: CSS configuration mode?
169
+ │ ❯ Beginner (recommended)
170
+ │ Advanced (full control)
171
+ │ Skip (use Vite default)
172
+
173
+ ├── [ Beginner ]
174
+ │ │
175
+ │ ├── Q: Add a CSS reset?
176
+ │ │ ❯ Yes / No
177
+ │ │
178
+ │ ├── Q: Choose a primary color:
179
+ │ │ ❯ Indigo / Emerald / Neutral / Custom HEX / Skip
180
+ │ │
181
+ │ └── Q: Enable dark mode?
182
+ │ ❯ Yes → media strategy (automatic)
183
+ │ No
184
+
185
+ └── [ Advanced ]
186
+
187
+ ├── Q: Add a CSS reset?
188
+ │ ❯ Yes / No
189
+
190
+ ├── Q: Choose a primary color:
191
+ │ ❯ Indigo / Emerald / Neutral / Custom HEX / Skip
192
+
193
+ ├── Q: Enable dark mode?
194
+ │ ❯ Yes
195
+ │ No
196
+
197
+ │ └── Q: Dark mode strategy:
198
+ │ ❯ Manual toggle (class) (recommended)
199
+ │ System preference (media)
200
+
201
+ │ └── Q: Add ThemeToggle component? ← only if "class"
202
+ │ ❯ Yes
203
+ │ No
204
+
205
+ ├── Q: Choose a default font:
206
+ │ ❯ Inter / Poppins / Cairo / Skip
207
+
208
+ ├── Q: Generate separate CSS files? (variables, reset, typography)
209
+ │ ❯ Yes → creates src/styles/ folder
210
+ │ No → everything in one index.css
211
+ └── Q: Override App.jsx with a CSS demo template? ← only if toggle = Yes
212
+ ❯ Yes
213
+ No
214
+
215
+ ── If None ────────────────────────────────────────────────────
216
+
217
+ └── → No extra steps, plain Vite CSS stays as-is
218
+
219
+
220
+ ── Architecture ───────────────────────────────────────────────
221
+
222
+ ├── Q: Choose architecture style:
223
+ │ ❯ Layered (recommended for small/mid apps) - more popular
224
+ │ Feature-based (recommended for large apps)
225
+ │ Skip
226
+
227
+ ├── [ Feature-based ]
228
+ │ │
229
+ │ ├── Q: Select features to generate:
230
+ │ │ ❯ ◉ auth ○ dashboard ○ profile
231
+ │ │ ○ settings ○ home ○ products
232
+ │ │ ○ cart ○ checkout
233
+ │ │
234
+ │ ├── Q: Select folders inside each feature:
235
+ │ │ ❯ ◉ components ◉ hooks ◉ services
236
+ │ │ ○ utils ○ types ○ validators ○ api
237
+ │ │
238
+ │ ├── Q: Select shared folders in src/:
239
+ │ │ ❯ ◉ components ◉ hooks ◉ layouts ◉ pages
240
+ │ │ ○ services ○ utils ○ types ○ assets
241
+ │ │ ○ api ○ validators ○ templates
242
+ │ │ ○ themes ○ lib
243
+ │ │
244
+ │ └── Q: Select folders to add an index file to:
245
+ │ ❯ ○ components ○ hooks ○ services ...
246
+
247
+ └── [ Layered ]
248
+
249
+ ├── Q: Select folders in src/:
250
+ │ ❯ ◉ components ◉ hooks ◉ pages ◉ layouts
251
+ │ ○ services ○ utils ○ types ○ assets
252
+ │ ○ api ○ validators ○ templates
253
+
254
+ └── Q: Select folders to add an index file to:
255
+ ❯ ○ components ○ hooks ○ pages ...
256
+
257
+ ── Prettier ───────────────────────────────────────────────────
258
+
259
+ ├── Q: Add Prettier?
260
+ │ ❯ Yes
261
+ │ No
262
+
263
+ ├── Q: Use single quotes?
264
+ │ ❯ Yes / No
265
+
266
+ ├── Q: Use semicolons?
267
+ │ ❯ Yes / No
268
+
269
+ └── Q: Tab width:
270
+ ❯ 2 spaces (recommended)
271
+ 4 spaces
272
+
273
+ [ if Tailwind + prettierTailwind was selected ]
274
+ → .prettierrc already exists with plugin config
275
+ → formatting prefs are merged in, plugin is preserved
276
+
277
+ ── Git ────────────────────────────────────────────────────────
278
+
279
+ ├── Q: Initialize a Git repository?
280
+ │ ❯ Yes
281
+ │ No
282
+
283
+ └── [ if Yes ]
284
+
285
+ ├── Q: Create an initial commit?
286
+ │ ❯ Yes
287
+ │ No
288
+
289
+ └── [ if Yes ]
290
+ → commit message: "chore: initial commit"
291
+
292
+ ```
293
+
294
+ ---
295
+
296
+ ## 🛠 Supported Options
297
+
298
+ | Category | Available Now | Coming Soon |
299
+ | ------------------ | -------------------------------------- | ----------------------------------------- |
300
+ | Framework | React + TypeScript, React + JavaScript | Next.js, Vue, Svelte |
301
+ | Styling | Tailwind CSS v4, MUI, Plain CSS, None | — |
302
+ | Architecture | Feature-based, Layered, Skip | — |
303
+ | Formatter | Prettier (with Tailwind plugin merge) | ESLint config (if needed) |
304
+ | Version Control | Git init, Initial commit | — |
305
+ | Path Aliases | — | @components, @hooks, @pages, etc.. |
306
+ | Optional Libraries | — | axios, lucide-react, framer-motion, etc.. |
307
+ | State Management | — | Zustand, Context API boilerplate |
308
+ | Routing | — | React Router DOM |
309
+ | Templates | — | Custom template support |
310
+
311
+ ---
312
+
313
+ ## 🗂 Example Output Structure
314
+
315
+ ```
316
+ my-app/
317
+ ├── src/
318
+ │ ├── features/
319
+ │ │ └── auth/
320
+ │ │ ├── components/
321
+ │ │ ├── hooks/
322
+ │ │ └── services/
323
+ │ ├── components/
324
+ │ ├── hooks/
325
+ │ ├── layouts/
326
+ │ ├── pages/
327
+ │ ├── types/
328
+ │ ├── utils/
329
+ │ ├── index.css
330
+ │ ├── App.tsx
331
+ │ └── main.tsx
332
+ ├── public/
333
+ ├── tsconfig.json
334
+ ├── .eslintrc.json
335
+ ├── tailwind.config.ts
336
+ ├── .prettierrc
337
+ ├── .prettierignore
338
+ └── package.json
339
+ ```
340
+
341
+ ---
342
+
343
+ ## Roadmap
344
+
345
+ - [x] React + TypeScript/JavaScript
346
+ - [x] Tailwind CSS v4
347
+ - [x] MUI (Material UI)
348
+ - [x] Normal CSS utilities
349
+ - [x] Rollback on failure
350
+ - [x] Feature-based and Layered architecture
351
+ - [x] Prettier pre-configured
352
+ - [x] Git init + initial commit
353
+ - [ ] Path aliases (@context, @themes, @root)
354
+ - [ ] Optional libraries (axios, lucide-react, framer-motion, react-query, etc..)
355
+ - [ ] Zustand + React Query setup
356
+ - [ ] Custom template support
357
+ - [ ] Next.js support
358
+ - [ ] Vue / Svelte support (future)
359
+
360
+ ---
361
+
362
+ ## Project Structure (This Repo)
363
+
364
+ ```
365
+ muscle-config/
366
+ ├── src/
367
+ │ ├── commands/
368
+ │ │ └── create.command.ts # Main create command orchestration
369
+ │ ├── config/
370
+ │ │ └── projectConfig.ts # Project configuration types & defaults
371
+ │ ├── features/
372
+ │ │ ├── feature.interface.ts # Feature contract interface
373
+ │ │ ├── tailwind.feature.ts # Tailwind v4 setup orchestration
374
+ │ │ ├── mui.feature.ts # MUI setup orchestration
375
+ │ │ ├── css.feature.ts # Plain CSS setup orchestration
376
+ │ │ ├── architecture.feature.ts # Architecture folder generation
377
+ │ │ ├── prettier.feature.ts # Prettier setup + .prettierrc merge
378
+ │ │ └── git.feature.ts # Git init + initial commit
379
+ │ ├── generators/
380
+ │ │ ├── react.generator.ts # React + Vite scaffolding
381
+ │ │ ├── css.generator.ts # Tailwind index.css generator
382
+ │ │ ├── css-plain.generator.ts # Plain CSS generator (reset, variables, typography)
383
+ │ │ ├── tailwind.config.generator.ts # tailwind.config.ts/js generator
384
+ │ │ ├── toggle.generator.ts # Tailwind ThemeToggle generator
385
+ │ │ ├── mui.generator.ts # MUI files generator (theme, context, providers)
386
+ │ │ └── architecture.generator.ts # Folder structure generator
387
+ │ ├── prompts/
388
+ │ │ ├── directory.prompt.ts # Output directory prompt
389
+ │ │ ├── projectName.prompt.ts # Project name prompt
390
+ │ │ ├── framework.prompt.ts # Framework selection prompt
391
+ │ │ ├── styling.prompt.ts # Styling solution prompt
392
+ │ │ ├── tailwind.prompt.ts # Tailwind configuration prompts
393
+ │ │ ├── mui.prompt.ts # MUI configuration prompts
394
+ │ │ ├── css.prompt.ts # Plain CSS configuration prompts
395
+ │ │ ├── architecture.prompt.ts # Architecture configuration prompts
396
+ │ │ ├── prettier.prompt.ts # Prettier configuration prompts
397
+ │ │ └── git.prompt.ts # Git configuration prompts
398
+ │ ├── templates/
399
+ │ │ ├── react/
400
+ │ │ │ ├── tailwind-v4/
401
+ │ │ │ │ ├── vite.config.ts # Vite config with Tailwind plugin (TS)
402
+ │ │ │ │ ├── vite.config.js # Vite config with Tailwind plugin (JS)
403
+ │ │ │ │ └── index.css # Base Tailwind CSS template
404
+ │ │ │ ├── mui/
405
+ │ │ │ │ ├── App.tsx # MUI demo template (TS)
406
+ │ │ │ │ └── App.jsx # MUI demo template (JS)
407
+ │ │ │ └── css/
408
+ │ │ │ ├── App.tsx # CSS demo template (TS)
409
+ │ │ │ └── App.jsx # CSS demo template (JS)
410
+ │ │ ├── nextjs/ # (coming soon)
411
+ │ │ └── shared/ # Shared static templates (coming soon)
412
+ │ ├── utils/
413
+ │ │ ├── welcome.ts # CLI welcome screen
414
+ │ │ ├── logger.ts # Colored console output
415
+ │ │ ├── spinner.ts # Loading spinner helper
416
+ │ │ ├── directory.ts # Directory check and cleanup helpers
417
+ │ │ ├── rollback.ts # Project and feature rollback utilities
418
+ │ │ ├── files.ts # File/folder helpers (Not Available for now)
419
+ │ │ └── install.ts # Dependency installer
420
+ │ └── index.ts # Entry point
421
+ ├── package.json
422
+ ├── tsconfig.json
423
+ └── README.md
424
+ ```
425
+
426
+ ---
427
+
428
+ ## License
429
+
430
+ MIT © [Cat-Div7](https://github.com/Cat-Div7)
@@ -0,0 +1,104 @@
1
+ import path from "path";
2
+ // Prompts
3
+ import { askDirectoryMode } from "../prompts/directory.prompt.js";
4
+ import { askProjectName } from "../prompts/projectName.prompt.js";
5
+ import { askFramework } from "../prompts/framework.prompt.js";
6
+ import { askStyling } from "../prompts/styling.prompt.js";
7
+ import { askTailwindConfig } from "../prompts/tailwind.prompt.js";
8
+ import { askMuiConfig } from "../prompts/mui.prompt.js";
9
+ import { askCssConfig } from "../prompts/css.prompt.js";
10
+ import { askArchitecture } from "../prompts/architecture.prompt.js";
11
+ // Generators
12
+ import { generateReactProject } from "../generators/react.generator.js";
13
+ // Features
14
+ import { tailwindFeature } from "../features/tailwind.feature.js";
15
+ import { muiFeature } from "../features/mui.feature.js";
16
+ import { cssFeature } from "../features/css.feature.js";
17
+ import { createArchitectureFeature } from "../features/architecture.feature.js";
18
+ // Utils
19
+ import { checkCurrentDirectory } from "../utils/directory.js";
20
+ import { rollbackProject } from "../utils/rollback.js";
21
+ import { logger } from "../utils/logger.js";
22
+ import { askPrettierConfig } from "../prompts/prettier.prompt.js";
23
+ import { prettierFeature } from "../features/prettier.feature.js";
24
+ import { askGitConfig } from "../prompts/git.prompt.js";
25
+ import { gitFeature } from "../features/git.feature.js";
26
+ export async function createProject() {
27
+ // Step 1: Directory mode
28
+ const directoryMode = await askDirectoryMode();
29
+ if (directoryMode === "current")
30
+ await checkCurrentDirectory();
31
+ // Step 2: Project name (skipped if using current directory)
32
+ let projectName = "";
33
+ if (directoryMode === "new")
34
+ projectName = await askProjectName();
35
+ // Step 3: Framework (React TS / React JS)
36
+ const framework = await askFramework();
37
+ // Step 4: Styling choice + config (collected upfront, before scaffolding)
38
+ const styling = await askStyling();
39
+ let tailwindConfig;
40
+ let muiConfig;
41
+ let cssConfig;
42
+ if (styling === "tailwind")
43
+ tailwindConfig = await askTailwindConfig();
44
+ if (styling === "mui")
45
+ muiConfig = await askMuiConfig();
46
+ if (styling === "css")
47
+ cssConfig = await askCssConfig();
48
+ // Step 5: Architecture layout
49
+ const architecture = await askArchitecture();
50
+ // Step 6: Prettier config
51
+ const prettierConfig = await askPrettierConfig();
52
+ // Step 7: Git initialize
53
+ const gitConfig = await askGitConfig();
54
+ // Build config object
55
+ const config = {
56
+ projectName,
57
+ framework,
58
+ directoryMode,
59
+ styling,
60
+ architecture,
61
+ prettier: prettierConfig,
62
+ git: gitConfig,
63
+ };
64
+ const projectPath = config.directoryMode === "current"
65
+ ? process.cwd()
66
+ : path.join(process.cwd(), config.projectName);
67
+ try {
68
+ // Scaffold base React + Vite project
69
+ await generateReactProject(config);
70
+ console.log("");
71
+ // Queue features based on user choices
72
+ // Each factory receives its config and returns a Feature with run()
73
+ const features = [];
74
+ if (styling === "tailwind" && tailwindConfig)
75
+ features.push(tailwindFeature(tailwindConfig));
76
+ if (styling === "mui" && muiConfig)
77
+ features.push(muiFeature(muiConfig));
78
+ if (styling === "css" && cssConfig)
79
+ features.push(cssFeature(cssConfig));
80
+ if (architecture.style !== "skip")
81
+ features.push(createArchitectureFeature(architecture));
82
+ if (prettierConfig.enabled)
83
+ features.push(prettierFeature(prettierConfig));
84
+ // Ask the git init in the end
85
+ features.push(gitFeature(config.git));
86
+ // Run each feature sequentially
87
+ for (const feature of features) {
88
+ await feature.run(projectPath);
89
+ }
90
+ // Done
91
+ const runCommand = config.directoryMode === "current" ? "" : `cd ${config.projectName} && `;
92
+ console.log("");
93
+ logger.success("Project created successfully!");
94
+ logger.dim(" Get started:");
95
+ logger.dim(` ${runCommand}npm run dev`);
96
+ console.log("\n");
97
+ }
98
+ catch (error) {
99
+ // Full rollback if anything fails post-scaffolding
100
+ logger.error("Something went wrong during project creation.");
101
+ await rollbackProject(projectPath, config.directoryMode);
102
+ process.exit(1);
103
+ }
104
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,49 @@
1
+ import fs from "fs/promises";
2
+ import path from "path";
3
+ import { spinner } from "../utils/spinner.js";
4
+ import { logger } from "../utils/logger.js";
5
+ import { generateArchitecture } from "../generators/architecture.generator.js";
6
+ import { rollbackFeature } from "../utils/rollback.js";
7
+ export function createArchitectureFeature(config) {
8
+ return {
9
+ name: "architecture",
10
+ async run(projectPath) {
11
+ try {
12
+ if (config.style === "skip") {
13
+ logger.info("Skipping architecture setup.");
14
+ return;
15
+ }
16
+ /**
17
+ * STEP 1
18
+ * Detect TypeScript or JavaScript
19
+ */
20
+ const tsConfigPath = path.join(projectPath, "vite.config.ts");
21
+ let isTypeScript = false;
22
+ try {
23
+ await fs.access(tsConfigPath);
24
+ isTypeScript = true;
25
+ }
26
+ catch { }
27
+ /**
28
+ * STEP 2
29
+ * Generate folder structure
30
+ */
31
+ spinner.start("Generating folder structure...");
32
+ await generateArchitecture(config, projectPath, isTypeScript);
33
+ spinner.succeed("Folder structure generated!");
34
+ /**
35
+ * FINAL SUCCESS MESSAGE
36
+ */
37
+ logger.success("Architecture setup complete!");
38
+ }
39
+ catch (error) {
40
+ spinner.fail("Failed to setup architecture.");
41
+ await rollbackFeature([
42
+ path.join(projectPath, "src/features"),
43
+ ...config.sharedFolders.map((f) => path.join(projectPath, "src", f)),
44
+ ]);
45
+ throw error;
46
+ }
47
+ },
48
+ };
49
+ }