@teispace/next-maker 1.15.0 → 1.16.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 (73) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +418 -281
  3. package/dist/index.js +372 -136
  4. package/dist/index.js.map +4 -4
  5. package/dist/src/commands/doctor.d.ts +3 -0
  6. package/dist/src/commands/doctor.d.ts.map +1 -0
  7. package/dist/src/commands/env.d.ts +3 -0
  8. package/dist/src/commands/env.d.ts.map +1 -0
  9. package/dist/src/commands/index.d.ts.map +1 -1
  10. package/dist/src/commands/layout.d.ts +3 -0
  11. package/dist/src/commands/layout.d.ts.map +1 -0
  12. package/dist/src/commands/provider.d.ts +3 -0
  13. package/dist/src/commands/provider.d.ts.map +1 -0
  14. package/dist/src/commands/remove.d.ts +3 -0
  15. package/dist/src/commands/remove.d.ts.map +1 -0
  16. package/dist/src/commands/setup.d.ts.map +1 -1
  17. package/dist/src/generators/index.d.ts +4 -0
  18. package/dist/src/generators/index.d.ts.map +1 -1
  19. package/dist/src/generators/layout.generator.d.ts +22 -0
  20. package/dist/src/generators/layout.generator.d.ts.map +1 -0
  21. package/dist/src/generators/provider.generator.d.ts +14 -0
  22. package/dist/src/generators/provider.generator.d.ts.map +1 -0
  23. package/dist/src/generators/templates/layout.template.d.ts +13 -0
  24. package/dist/src/generators/templates/layout.template.d.ts.map +1 -0
  25. package/dist/src/generators/templates/provider.template.d.ts +12 -0
  26. package/dist/src/generators/templates/provider.template.d.ts.map +1 -0
  27. package/dist/src/manifests/bundle-analyzer.manifest.d.ts +3 -0
  28. package/dist/src/manifests/bundle-analyzer.manifest.d.ts.map +1 -0
  29. package/dist/src/manifests/commitizen.manifest.d.ts +3 -0
  30. package/dist/src/manifests/commitizen.manifest.d.ts.map +1 -0
  31. package/dist/src/manifests/dark-theme.manifest.d.ts +3 -0
  32. package/dist/src/manifests/dark-theme.manifest.d.ts.map +1 -0
  33. package/dist/src/manifests/http-client.manifest.d.ts +3 -0
  34. package/dist/src/manifests/http-client.manifest.d.ts.map +1 -0
  35. package/dist/src/manifests/i18n.manifest.d.ts +3 -0
  36. package/dist/src/manifests/i18n.manifest.d.ts.map +1 -0
  37. package/dist/src/manifests/index.d.ts +23 -0
  38. package/dist/src/manifests/index.d.ts.map +1 -0
  39. package/dist/src/manifests/react-compiler.manifest.d.ts +3 -0
  40. package/dist/src/manifests/react-compiler.manifest.d.ts.map +1 -0
  41. package/dist/src/manifests/redux.manifest.d.ts +9 -0
  42. package/dist/src/manifests/redux.manifest.d.ts.map +1 -0
  43. package/dist/src/manifests/runner.d.ts +37 -0
  44. package/dist/src/manifests/runner.d.ts.map +1 -0
  45. package/dist/src/manifests/security-headers.manifest.d.ts +3 -0
  46. package/dist/src/manifests/security-headers.manifest.d.ts.map +1 -0
  47. package/dist/src/manifests/tests.manifest.d.ts +3 -0
  48. package/dist/src/manifests/tests.manifest.d.ts.map +1 -0
  49. package/dist/src/manifests/types.d.ts +105 -0
  50. package/dist/src/manifests/types.d.ts.map +1 -0
  51. package/dist/src/manifests/validate-scripts.manifest.d.ts +3 -0
  52. package/dist/src/manifests/validate-scripts.manifest.d.ts.map +1 -0
  53. package/dist/src/modifiers/env-var.modifier.d.ts +60 -0
  54. package/dist/src/modifiers/env-var.modifier.d.ts.map +1 -0
  55. package/dist/src/modifiers/index.d.ts +2 -0
  56. package/dist/src/modifiers/index.d.ts.map +1 -1
  57. package/dist/src/modifiers/root-provider.modifier.d.ts +26 -0
  58. package/dist/src/modifiers/root-provider.modifier.d.ts.map +1 -0
  59. package/dist/src/services/setup/commitizen/index.d.ts +3 -0
  60. package/dist/src/services/setup/commitizen/index.d.ts.map +1 -0
  61. package/dist/src/services/setup/commitizen/package-modifier.d.ts +17 -0
  62. package/dist/src/services/setup/commitizen/package-modifier.d.ts.map +1 -0
  63. package/dist/src/services/setup/security-headers/headers.d.ts +29 -0
  64. package/dist/src/services/setup/security-headers/headers.d.ts.map +1 -0
  65. package/dist/src/services/setup/security-headers/index.d.ts +3 -0
  66. package/dist/src/services/setup/security-headers/index.d.ts.map +1 -0
  67. package/dist/src/services/setup/validate-scripts/index.d.ts +4 -0
  68. package/dist/src/services/setup/validate-scripts/index.d.ts.map +1 -0
  69. package/dist/src/services/setup/validate-scripts/package-modifier.d.ts +19 -0
  70. package/dist/src/services/setup/validate-scripts/package-modifier.d.ts.map +1 -0
  71. package/dist/src/services/setup/validate-scripts/scripts.d.ts +12 -0
  72. package/dist/src/services/setup/validate-scripts/scripts.d.ts.map +1 -0
  73. package/package.json +3 -3
package/README.md CHANGED
@@ -1,151 +1,281 @@
1
1
  # @teispace/next-maker
2
2
 
3
- A CLI that scaffolds Next.js 16+ applications (TypeScript, Tailwind v4, Biome, Pino, Zod, Redux Toolkit, next-intl, Vitest) and co-generates feature-based architecture — pages, components, hooks, Redux slices, API services, locales, and tests.
3
+ A CLI that scaffolds Next.js 16+ applications (TypeScript, Tailwind v4, Biome, Pino, Zod, Redux Toolkit, next-intl, Vitest) and co-generates feature-based architecture — pages, layouts, components, hooks, Redux slices, API services, locales, providers, env vars, and tests. Ships a manifest-driven `doctor` and `remove` for ongoing maintenance.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ### Using npx (Recommended)
8
8
 
9
9
  ```bash
10
- npx @teispace/next-maker <command> [name] [options]
10
+ npx @teispace/next-maker <command> [args] [options]
11
11
  ```
12
12
 
13
13
  ### Global Installation
14
14
 
15
15
  ```bash
16
16
  npm install -g @teispace/next-maker
17
- next-maker <command> [name] [options]
17
+ next-maker <command> [args] [options]
18
18
  ```
19
19
 
20
- ## Commands
20
+ ---
21
+
22
+ ## Commands at a glance
23
+
24
+ | Category | Command | Purpose |
25
+ | --- | --- | --- |
26
+ | Lifecycle | `init [name]` | Create a new Next.js application |
27
+ | Lifecycle | `setup [options]` | Add features to an existing project (retrofit) |
28
+ | Lifecycle | `doctor [options]` | Diagnose drift against known feature manifests |
29
+ | Lifecycle | `remove <feature>` | Reverse a feature install (uses the manifest) |
30
+ | Routing | `page <name>` | Generate a page/route |
31
+ | Routing | `layout <segment>` | Generate a nested layout.tsx |
32
+ | UI | `component <name>` | Shared component with auto-wired barrel exports |
33
+ | State | `feature <name>` | Full feature module (DDD) |
34
+ | State | `slice <name>` | Redux Toolkit slice (auto-registers in rootReducer) |
35
+ | State | `service <name>` | API service (axios/fetch, optional CRUD) |
36
+ | State | `provider <name>` | Context provider with RootProvider auto-wiring |
37
+ | Config | `env <NAME>` | Add an env var (schema + .env.example + .env) |
38
+ | Config | `locale [code]` | Add a new language/locale |
39
+ | Code | `hook <name>` | Custom React hook |
40
+ | Code | `test <file>` | Sibling test stub for a component/hook/slice |
41
+
42
+ Run `npx @teispace/next-maker <command> --help` for the full option list of any command.
21
43
 
22
- ### 1. Create a New App
44
+ ---
23
45
 
24
- Generate a complete Next.js application with production-ready configuration.
46
+ ## Lifecycle commands
47
+
48
+ ### `init` — Create a New App
25
49
 
26
50
  ```bash
27
51
  npx @teispace/next-maker init [project-name]
28
52
  ```
29
53
 
30
- **Interactive Setup:**
54
+ The starter at [`teispace/nextjs-starter`](https://github.com/teispace/nextjs-starter) is cloned via `degit` and trimmed to match your prompt answers. The `cleanup` step strips opted-out features so the generated project compiles end-to-end on first install.
31
55
 
32
- During initialization, you'll be prompted to configure:
56
+ **Interactive prompts:**
33
57
 
34
- - **Package Manager** (npm, yarn, pnpm, bun)
35
- - **GitHub Repository** (optional - configures remote origin)
36
- - **HTTP Client** (axios, fetch, both, or none)
37
- - **Dark Mode** (@teispace/next-themes integration)
38
- - **Redux Toolkit** (with redux-persist)
39
- - **Internationalization** (next-intl)
40
- - **Testing** (Vitest + React Testing Library)
41
- - **React Compiler** (experimental — on by default)
42
- - **Bundle Analyzer** (@next/bundle-analyzer — off by default)
43
- - **Community Files** (CODE_OF_CONDUCT, CONTRIBUTING, etc.)
44
- - **Docker** support
45
- - **CI/CD** configuration
46
- - **Pre-commit hooks** (Husky)
58
+ | Section | Prompts |
59
+ | --- | --- |
60
+ | Identity | project name, description, author, version, support email, package manager, GitHub repo / issues / homepage |
61
+ | Architecture | HTTP client (axios / fetch / both / none), dark mode, Redux Toolkit, i18n, testing, React Compiler, Bundle Analyzer |
62
+ | Tooling | community files (CODE_OF_CONDUCT, CONTRIBUTING, SECURITY), README, Docker, CI/CD, pre-commit hooks (Husky/Commitlint/Lint-staged), Commitizen, copy `.env.example` → `.env` |
63
+ | Templates | keep GitHub issue/PR templates? include `react-secure-storage`? |
47
64
 
48
- **Core Features (always shipped):**
65
+ **Always shipped:**
49
66
 
50
67
  - Next.js 16+ with App Router
51
68
  - TypeScript (strict mode)
52
69
  - Tailwind CSS v4
53
- - Biome (single-tool lint + format; replaces ESLint + Prettier)
70
+ - Biome (single-tool lint + format)
54
71
  - Pino structured logger with redaction
55
- - Zod-validated env schema
72
+ - Zod-validated env schema in `src/lib/env/`
56
73
  - Feature-based DDD architecture
57
- - Result-based HTTP clients (axios / fetch)
74
+ - Result-based HTTP clients (when enabled)
75
+ - Hardened security headers in `next.config.ts`
76
+ - `scripts/sync-env.ts` and `scripts/check-deprecated.ts` (used by the `validate` chain)
58
77
 
59
78
  ---
60
79
 
61
- ### 2. Setup Additional Features
80
+ ### `setup` Retrofit a feature
62
81
 
63
- Add features to your existing Next.js project after initialization.
82
+ Add a feature to an existing project (one that wasn't generated by `init`, or one created before a feature existed).
64
83
 
65
84
  ```bash
66
85
  npx @teispace/next-maker setup [options]
67
86
  ```
68
87
 
69
- **Options:**
70
-
71
- - `--http-client` - Setup HTTP client (Interactive: axios|fetch|both)
72
- - `--dark-theme` - Setup dark theme support (@teispace/next-themes)
73
- - `--redux` - Setup Redux Toolkit with persistence
74
- - `--i18n` - Setup next-intl for internationalization
75
- - `--tests` - Setup testing (Vitest + React Testing Library)
76
- - `--react-compiler` - Enable the React Compiler
77
- - `--bundle-analyzer` - Add @next/bundle-analyzer
88
+ | Flag | What it does |
89
+ | --- | --- |
90
+ | `--http-client` | Adds the axios and/or fetch Result-based clients under `src/lib/utils/http/` |
91
+ | `--dark-theme` | Installs `@teispace/next-themes` and adds `CustomThemeProvider` |
92
+ | `--redux` | Redux Toolkit + `react-redux` + `redux-persist`, `StoreProvider`, `src/store` |
93
+ | `--i18n` | `next-intl` + `[locale]` routing + `proxy.ts` + `RootProvider` wiring |
94
+ | `--tests` | Vitest + React Testing Library + jsdom + `test/test-utils.tsx` |
95
+ | `--react-compiler` | `reactCompiler: true` in `next.config.ts` + `babel-plugin-react-compiler` |
96
+ | `--bundle-analyzer` | Wraps the default export with `withBundleAnalyzer` and adds the `analyze` script |
97
+ | `--security-headers` | Injects the hardened headers block into `next.config.ts` (DNS prefetch, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, X-XSS-Protection) |
98
+ | `--validate-scripts` | Drops in `scripts/sync-env.ts` + `scripts/check-deprecated.ts` and wires `env:sync`, `check:deprecated`, `type-check`, and the `validate` chain (PM-aware) |
99
+ | `--commitizen` | Writes `.czrc`, adds `commit` script, installs `commitizen` + `cz-conventional-changelog` |
78
100
 
79
- **Examples:**
101
+ Run `setup` without flags for an interactive picker.
80
102
 
81
103
  ```bash
82
- # Interactive menu
104
+ # Interactive
83
105
  npx @teispace/next-maker setup
84
106
 
85
- # Add specific features
86
- npx @teispace/next-maker setup --http-client
87
- npx @teispace/next-maker setup --dark-theme
107
+ # Specific feature
88
108
  npx @teispace/next-maker setup --redux
89
- npx @teispace/next-maker setup --i18n
90
- npx @teispace/next-maker setup --tests
91
- npx @teispace/next-maker setup --react-compiler
92
- npx @teispace/next-maker setup --bundle-analyzer
109
+ npx @teispace/next-maker setup --security-headers
110
+ npx @teispace/next-maker setup --validate-scripts
93
111
  ```
94
112
 
113
+ Every `setup` operation is **idempotent** — re-running is a no-op on already-installed parts and a fix-up on missing parts.
114
+
95
115
  ---
96
116
 
97
- ### 3. Generate a Page
117
+ ### `doctor` Drift detection
98
118
 
99
- Create a new page/route with locale-aware boilerplate, SEO metadata, and optional loading/error states.
119
+ `doctor` walks every feature manifest, asks "is this installed?" and (if yes) "are all of its parts present?". Drift is reported per feature.
100
120
 
101
121
  ```bash
102
- npx @teispace/next-maker page <name> [options]
122
+ npx @teispace/next-maker doctor [options]
103
123
  ```
104
124
 
105
- **Options:**
125
+ | Flag | Behaviour |
126
+ | --- | --- |
127
+ | `--fix` | Re-runs `apply()` for every drifted feature (idempotent — safe to retry) |
128
+ | `--feature <id>` | Only check one manifest (e.g. `redux`, `security-headers`) |
129
+ | `--json` | Machine-readable output for CI |
106
130
 
107
- - `--dynamic <param>` - Create dynamic route (e.g., `--dynamic id` creates `[id]/page.tsx`)
108
- - `--loading` - Generate `loading.tsx`
109
- - `--error` - Generate `error.tsx`
131
+ Exit code is `0` on a clean report and `1` when drift is found — `next-maker doctor --json` makes a useful CI gate.
110
132
 
111
- **What it generates:**
133
+ ```bash
134
+ # Human report
135
+ npx @teispace/next-maker doctor
112
136
 
113
- - `page.tsx` with full locale support (if i18n is set up), `generateMetadata`, `setRequestLocale`
114
- - Registers route in `src/lib/config/app-paths.ts`
115
- - Adds translation namespace to `en.json` (if i18n)
116
- - Optional `loading.tsx` and `error.tsx`
137
+ # Fix everything that drifted
138
+ npx @teispace/next-maker doctor --fix
139
+
140
+ # CI
141
+ npx @teispace/next-maker doctor --json > health.json
142
+ ```
143
+
144
+ **Sample output:**
145
+
146
+ ```
147
+ 🩺 Project Doctor
148
+
149
+ ✓ Security Headers
150
+ ! Validation Scripts (2 issues)
151
+ • missing file: scripts/sync-env.ts
152
+ • missing script: validate
153
+ — Redux Toolkit (not installed)
154
+ ✓ Internationalization
155
+
156
+ 1 clean, 1 drifted, 1 not installed
157
+
158
+ Run with --fix to re-apply drifted features.
159
+ ```
160
+
161
+ Manifests live under `src/manifests/`; each one declares the files, packages, scripts, and code blocks the feature consists of. Adding a manifest for a new feature is a single file — `doctor` and `remove` automatically pick it up.
117
162
 
118
- **Examples:**
163
+ ---
164
+
165
+ ### `remove` — Reverse an install
166
+
167
+ Symmetric to `setup`. Uses the feature manifest to compute the reversal: deletes generated files, strips code blocks (when a `removePattern` is recorded), removes scripts, uninstalls packages.
119
168
 
120
169
  ```bash
121
- # Simple page
122
- npx @teispace/next-maker page about
170
+ npx @teispace/next-maker remove <feature> [options]
171
+ ```
123
172
 
124
- # Page with loading and error states
125
- npx @teispace/next-maker page dashboard --loading --error
173
+ | Flag | Behaviour |
174
+ | --- | --- |
175
+ | `--dry-run` | Print the planned changes without writing |
176
+ | `-y, --yes` | Skip the confirmation prompt |
177
+
178
+ Anything the manifest can't safely undo (e.g. unwrapping an outer JSX wrap with multiple sibling providers) is reported as `manual cleanup` rather than guessed.
179
+
180
+ ```bash
181
+ # Preview the effect
182
+ npx @teispace/next-maker remove redux --dry-run
183
+
184
+ # Apply with confirmation
185
+ npx @teispace/next-maker remove security-headers
186
+
187
+ # Non-interactive
188
+ npx @teispace/next-maker remove validate-scripts --yes
189
+ ```
190
+
191
+ **Sample plan:**
192
+
193
+ ```
194
+ 🗑 Remove Validation Scripts
195
+
196
+ Planned changes:
197
+ - delete file: scripts/sync-env.ts
198
+ - delete file: scripts/check-deprecated.ts
199
+ - remove script: env:sync
200
+ - remove script: check:deprecated
201
+ - remove script: validate
202
+ - uninstall: tsx
203
+ ```
204
+
205
+ ---
126
206
 
127
- # Dynamic route (e.g., /products/[id])
207
+ ## Code generators
208
+
209
+ ### `page` — Generate a page/route
210
+
211
+ ```bash
212
+ npx @teispace/next-maker page <name> [options]
213
+ ```
214
+
215
+ | Flag | Effect |
216
+ | --- | --- |
217
+ | `--dynamic <param>` | Dynamic segment (e.g. `--dynamic id` produces `[id]/page.tsx`) |
218
+ | `--loading` | Generate `loading.tsx` |
219
+ | `--error` | Generate `error.tsx` |
220
+
221
+ **What it does:**
222
+
223
+ - Writes `page.tsx` under `src/app/[locale]/<name>/` (i18n) or `src/app/<name>/`
224
+ - When i18n is detected: `generateMetadata`, `setRequestLocale`, `getTranslations`
225
+ - Registers route in `src/lib/config/app-paths.ts`
226
+ - Adds translation namespace to `en.json`
227
+
228
+ ```bash
229
+ npx @teispace/next-maker page about
230
+ npx @teispace/next-maker page dashboard --loading --error
128
231
  npx @teispace/next-maker page products --dynamic id --loading --error
129
232
  ```
130
233
 
131
234
  ---
132
235
 
133
- ### 4. Generate a Component
236
+ ### `layout` Generate a nested layout
134
237
 
135
- Create a shared component with automatic barrel export wiring across all index files.
238
+ ```bash
239
+ npx @teispace/next-maker layout <segment> [options]
240
+ ```
241
+
242
+ | Flag | Effect |
243
+ | --- | --- |
244
+ | `--group` | Wraps the segment in parens for a route group, e.g. `(marketing)` |
245
+ | `--at <path>` | Places the layout under a nested path (kebab-case, slash-separated) |
246
+ | `--no-locale` | Skip the locale wrapper even when i18n is detected |
247
+
248
+ When i18n is detected the generated layout consumes `params: Promise<{ locale: string }>` and calls `setRequestLocale`. Otherwise it's a plain `({ children }) => <>{children}</>` shell.
136
249
 
137
250
  ```bash
138
- npx @teispace/next-maker component <name> [options]
251
+ # /[locale]/dashboard/layout.tsx
252
+ npx @teispace/next-maker layout dashboard
253
+
254
+ # Route group: /[locale]/(marketing)/layout.tsx
255
+ npx @teispace/next-maker layout marketing --group
256
+
257
+ # Nested: /[locale]/dashboard/settings/preferences/layout.tsx
258
+ npx @teispace/next-maker layout preferences --at dashboard/settings
139
259
  ```
140
260
 
141
- **Options:**
261
+ Refuses to overwrite an existing `layout.tsx` — explicit error rather than silent loss.
262
+
263
+ ---
264
+
265
+ ### `component` — Shared component
266
+
267
+ ```bash
268
+ npx @teispace/next-maker component <name> [options]
269
+ ```
142
270
 
143
- - `--client` - Add `'use client'` directive
144
- - `--i18n` - Add `useTranslations` hook
145
- - `--feature <path>` - Generate inside a feature directory
146
- - `--test` / `--no-test` - Co-generate a sibling `*.test.tsx` (default: on when tests are installed)
271
+ | Flag | Effect |
272
+ | --- | --- |
273
+ | `--client` | Adds `'use client'` directive |
274
+ | `--i18n` | Imports `useTranslations` |
275
+ | `--feature <path>` | Generate inside a feature directory |
276
+ | `--test` / `--no-test` | Co-generate a sibling `*.test.tsx` (default: on when Vitest is installed) |
147
277
 
148
- **Generated structure (shared):**
278
+ **Generated structure:**
149
279
 
150
280
  ```
151
281
  src/components/common/MyButton/
@@ -155,347 +285,338 @@ src/components/common/MyButton/
155
285
 
156
286
  Auto-updates `src/components/common/index.ts` and `src/components/index.ts`.
157
287
 
158
- **Examples:**
159
-
160
288
  ```bash
161
- # Shared component
162
289
  npx @teispace/next-maker component data-table --client
163
-
164
- # Component with i18n
165
290
  npx @teispace/next-maker component nav-bar --client --i18n
166
-
167
- # Feature-specific component
168
291
  npx @teispace/next-maker component user-card --client --feature src/features/auth
169
292
  ```
170
293
 
171
294
  ---
172
295
 
173
- ### 5. Generate a Feature Module
174
-
175
- Create a complete feature module following Domain-Driven Design principles.
296
+ ### `feature` Full feature module
176
297
 
177
298
  ```bash
178
299
  npx @teispace/next-maker feature <name> [options]
179
300
  ```
180
301
 
181
- **Options:**
182
-
183
- - `--store <type>` - Generate Redux store (persist|no-persist)
184
- - `--skip-store` - Skip Redux store generation
185
- - `--service <client>` - Generate API service (axios|fetch)
186
- - `--skip-service` - Skip API service generation
187
- - `--path <path>` - Custom path (default: src/features)
302
+ | Flag | Effect |
303
+ | --- | --- |
304
+ | `--store <type>` | Generate Redux store: `persist` or `no-persist` |
305
+ | `--skip-store` | Skip Redux store |
306
+ | `--service <client>` | API service: `axios` or `fetch` |
307
+ | `--skip-service` | Skip API service |
308
+ | `--path <path>` | Custom path (default `src/features`) |
188
309
 
189
310
  **Generated structure:**
190
311
 
191
312
  ```
192
313
  src/features/user-dashboard/
193
- ├── components/
194
- │ └── UserDashboard.tsx
195
- ├── hooks/
196
- │ └── useUserDashboard.ts
197
- ├── types/
198
- │ └── user-dashboard.types.ts
199
- ├── store/ (optional)
200
- │ ├── user-dashboard.slice.ts
201
- │ ├── user-dashboard.selectors.ts
202
- │ ├── persist.ts (optional)
203
- │ └── index.ts
204
- ├── services/ (optional)
205
- │ └── user-dashboard.service.ts
314
+ ├── components/UserDashboard.tsx
315
+ ├── hooks/useUserDashboard.ts
316
+ ├── types/user-dashboard.types.ts
317
+ ├── store/ (optional)
318
+ ├── services/ (optional)
206
319
  └── index.ts
207
320
  ```
208
321
 
209
- **Examples:**
210
-
211
322
  ```bash
212
- # Full feature with Redux and API service
213
323
  npx @teispace/next-maker feature user-profile --store persist --service axios
214
-
215
- # Feature with Redux only
216
324
  npx @teispace/next-maker feature shopping-cart --store no-persist --skip-service
217
-
218
- # Feature in custom location
219
325
  npx @teispace/next-maker feature auth --store persist --service fetch --path src/modules
220
326
  ```
221
327
 
222
328
  ---
223
329
 
224
- ### 6. Generate a Redux Slice
225
-
226
- Create a Redux Toolkit slice with persistence support.
330
+ ### `slice` Redux slice
227
331
 
228
332
  ```bash
229
333
  npx @teispace/next-maker slice <name> [options]
230
334
  ```
231
335
 
232
- **Options:**
233
-
234
- - `--persist` - Enable redux-persist for this slice
235
- - `--no-persist` - Disable persistence
236
- - `--path <path>` - Custom path (default: create new feature)
237
- - `--test` / `--no-test` - Co-generate a sibling `*.slice.test.ts` (default: on when tests are installed)
238
-
239
- **Auto-registers in rootReducer** with correct imports.
336
+ | Flag | Effect |
337
+ | --- | --- |
338
+ | `--persist` / `--no-persist` | Toggle redux-persist for this slice |
339
+ | `--path <path>` | Custom path (default: new feature) |
340
+ | `--test` / `--no-test` | Co-generate `*.slice.test.ts` (default: on when Vitest is installed) |
240
341
 
241
- **Examples:**
342
+ Auto-registers in `rootReducer` with correct imports and persist config.
242
343
 
243
344
  ```bash
244
- # Create new feature with slice
245
345
  npx @teispace/next-maker slice auth --persist
246
-
247
- # Add slice to existing feature
248
346
  npx @teispace/next-maker slice user-settings --path features/auth/store
249
347
  ```
250
348
 
251
349
  ---
252
350
 
253
- ### 7. Generate an API Service
254
-
255
- Create an API service with HTTP client integration. Supports both simple and full CRUD generation.
351
+ ### `service` API service
256
352
 
257
353
  ```bash
258
354
  npx @teispace/next-maker service <name> [options]
259
355
  ```
260
356
 
261
- **Options:**
357
+ | Flag | Effect |
358
+ | --- | --- |
359
+ | `--axios` / `--fetch` | Pick the HTTP client |
360
+ | `--crud` | Generate full CRUD (`getAll`, `getById`, `create`, `update`, `delete`) |
361
+ | `--path <path>` | Custom path |
262
362
 
263
- - `--axios` - Use AxiosClient
264
- - `--fetch` - Use FetchClient
265
- - `--crud` - Generate full CRUD service (getAll, getById, create, update, delete)
266
- - `--path <path>` - Custom path (default: create new feature)
363
+ CRUD mode also generates `<Name>Summary` (list view) and `<Name>Detail` (detail view) types, `Create<Name>Dto`, `Update<Name>Dto`, and registers the endpoints in `app-apis.ts`.
267
364
 
268
- **CRUD mode** generates:
365
+ ```bash
366
+ npx @teispace/next-maker service payment --axios
367
+ npx @teispace/next-maker service users --fetch --crud
368
+ npx @teispace/next-maker service orders --axios --crud --path features/products/services
369
+ ```
269
370
 
270
- - Service with 5 methods: `getAll`, `getById`, `create`, `update`, `delete`
271
- - `<Name>Summary` type for list responses (cards, tables) and `<Name>Detail` type for single-item responses (detail pages)
272
- - DTO types: `Create<Name>Dto`, `Update<Name>Dto`
273
- - Full API config with dynamic routes (`getById(id)`, `update(id)`, `delete(id)`)
371
+ ---
274
372
 
275
- **Examples:**
373
+ ### `provider` — Context provider
276
374
 
277
375
  ```bash
278
- # Simple service
279
- npx @teispace/next-maker service payment --axios
376
+ npx @teispace/next-maker provider <name>
377
+ ```
280
378
 
281
- # Full CRUD service with types and endpoints
282
- npx @teispace/next-maker service users --fetch --crud
379
+ Generates `src/providers/<Name>Provider.tsx` with:
283
380
 
284
- # CRUD service in existing feature
285
- npx @teispace/next-maker service orders --axios --crud --path features/products/services
381
+ - `'use client'` directive
382
+ - `createContext` + typed context value
383
+ - `useX()` hook with non-null guard
384
+ - `<XProvider>` component memoising the value with `useMemo`
385
+
386
+ Then **two-tier auto-wiring**:
387
+
388
+ 1. Locates `RootProvider.tsx` — canonical path first (`src/providers/RootProvider.tsx`), heuristic scan as fallback (looks for the deepest `{children}` chain in `src/providers/*.tsx`).
389
+ 2. Wraps `{children}` with `<XProvider>` inside that chain, preserving indentation.
390
+ 3. Updates `src/providers/index.ts` barrel (re-exports kept sorted).
391
+
392
+ If no candidate is found, the generator prints the snippet to wire manually rather than failing silently.
393
+
394
+ ```bash
395
+ npx @teispace/next-maker provider auth # → AuthProvider, useAuth
396
+ npx @teispace/next-maker provider session # → SessionProvider, useSession
397
+ npx @teispace/next-maker provider analytics-provider # already-suffixed names work
286
398
  ```
287
399
 
400
+ The wrap is **idempotent** — running twice is a no-op.
401
+
288
402
  ---
289
403
 
290
- ### 8. Add a Locale
404
+ ### `env` Declare an env var
405
+
406
+ Adds a new variable across the four files the starter keeps in sync, atomically and idempotently:
291
407
 
292
- Add a new language/locale to your internationalized project.
408
+ 1. `src/lib/env/schema.ts` Zod entry with the right wrapper (`preprocess(emptyStringToUndefined, …)` for non-enum types)
409
+ 2. `.env.example` — `KEY=` placeholder with optional description comment and `# -public` marker
410
+ 3. `.env` — `KEY=<default>` line when the file exists
293
411
 
294
412
  ```bash
295
- npx @teispace/next-maker locale [code] [options]
413
+ npx @teispace/next-maker env <NAME> [options]
296
414
  ```
297
415
 
298
- **Options:**
416
+ | Flag | Effect |
417
+ | --- | --- |
418
+ | `--type <type>` | `string` (default), `url`, `number`, `boolean`, `enum` |
419
+ | `--required` | Skips `.optional()` and `.default()` |
420
+ | `--default <value>` | Adds `.default(value)` (mutually exclusive with `--required`) |
421
+ | `--public` | Auto-prefixes `NEXT_PUBLIC_` if missing and tags `.env.example` with `# -public` |
422
+ | `--describe <text>` | Adds `.describe()` and a comment line in `.env.example` |
423
+ | `--enum <list>` | Comma-separated values, required when `--type=enum` |
299
424
 
300
- - `--copy-translations` - Copy English translations instead of empty values
425
+ ```bash
426
+ # Optional URL
427
+ npx @teispace/next-maker env SENTRY_DSN --type url --describe "Sentry endpoint"
301
428
 
302
- **What it does:**
429
+ # Public default
430
+ npx @teispace/next-maker env API_URL --type url --public --default "http://localhost:3000"
431
+
432
+ # Required string (no default, no .optional)
433
+ npx @teispace/next-maker env DATABASE_URL --type url --required
434
+
435
+ # Enum
436
+ npx @teispace/next-maker env LOG_LEVEL --type enum --enum debug,info,warn,error --default info
437
+
438
+ # Coerced number
439
+ npx @teispace/next-maker env PORT --type number --default 3000
440
+ ```
441
+
442
+ The generator quote-escapes defaults and descriptions, mirrors the starter's house style, and is fully covered by tests against the `schema.ts`/`.env.example`/`.env` shapes.
303
443
 
304
- - Creates `src/i18n/translations/<code>.json` (empty or copied from English)
305
- - Updates `SupportedLocale` type in `src/types/i18n.ts`
306
- - Adds entry to `src/lib/config/app-locales.ts` with name, flag, country
444
+ ---
307
445
 
308
- **Examples:**
446
+ ### `locale` — Add a locale
309
447
 
310
448
  ```bash
311
- # Add Spanish (interactive prompts for name, country, flag)
312
- npx @teispace/next-maker locale es
449
+ npx @teispace/next-maker locale [code] [options]
450
+ ```
451
+
452
+ | Flag | Effect |
453
+ | --- | --- |
454
+ | `--copy-translations` | Copy English translations as the starting point |
313
455
 
314
- # Add French with English translations as starting point
456
+ Creates `src/i18n/translations/<code>.json`, updates `SupportedLocale`, and adds the entry to `src/lib/config/app-locales.ts` (name, flag, country).
457
+
458
+ ```bash
459
+ npx @teispace/next-maker locale es
315
460
  npx @teispace/next-maker locale fr --copy-translations
316
461
  ```
317
462
 
318
463
  ---
319
464
 
320
- ### 9. Generate a Hook
321
-
322
- Create a custom React hook with loading/error state boilerplate.
465
+ ### `hook` Custom React hook
323
466
 
324
467
  ```bash
325
468
  npx @teispace/next-maker hook <name> [options]
326
469
  ```
327
470
 
328
- **Options:**
329
-
330
- - `--client` - Add `'use client'` directive (default: true)
331
- - `--feature <path>` - Generate in feature directory
332
- - `--test` / `--no-test` - Co-generate a sibling `*.test.ts` (default: on when tests are installed)
333
-
334
- **Examples:**
471
+ | Flag | Effect |
472
+ | --- | --- |
473
+ | `--client` | Add `'use client'` directive (default true) |
474
+ | `--feature <path>` | Generate inside a feature directory |
475
+ | `--test` / `--no-test` | Co-generate `*.test.ts` |
335
476
 
336
477
  ```bash
337
- # Shared hook in src/hooks/
338
478
  npx @teispace/next-maker hook auth-session
339
-
340
- # Hook inside a feature
341
479
  npx @teispace/next-maker hook user-profile --feature src/features/auth
342
480
  ```
343
481
 
344
482
  ---
345
483
 
346
- ### 10. Generate a Test
484
+ ### `test` Retrofit a sibling test
347
485
 
348
- Scaffold a sibling `*.test.{ts,tsx}` next to an existing component, hook, or slice. Handy for retrofitting tests onto code that pre-dates the `--with-test` flag.
486
+ Adds a `*.test.{ts,tsx}` next to existing code that pre-dates the `--test` flag.
349
487
 
350
488
  ```bash
351
489
  npx @teispace/next-maker test <file> [options]
352
490
  ```
353
491
 
354
- **Options:**
492
+ | Flag | Effect |
493
+ | --- | --- |
494
+ | `--kind <kind>` | Override inferred kind: `component` / `hook` / `slice` |
495
+ | `--force` | Overwrite an existing test file |
355
496
 
356
- - `--kind <kind>` - Override inferred kind: `component` | `hook` | `slice`
357
- - `--force` - Overwrite an existing test file
497
+ Inference rules:
358
498
 
359
- **Inference rules:**
360
-
361
- - `*.slice.ts` → slice reducer test
362
- - `use*.ts` / content starts with `export function useX` → hook test (`renderHook`)
499
+ - `*.slice.ts` → reducer test
500
+ - `use*.ts` (or content starting with `export function useX`) → hook test (`renderHook`)
363
501
  - `*.tsx` → component test (`renderWithProviders`)
364
502
 
365
- The generated file imports `renderWithProviders` / `TestProviders` from `test/test-utils` using a path resolved relative to the source file, so tests work whether they're under `src/features/*/components/`, `src/hooks/`, or anywhere else in the tree.
366
-
367
- **Examples:**
368
-
369
503
  ```bash
370
504
  npx @teispace/next-maker test src/features/auth/components/LoginForm.tsx
371
- npx @teispace/next-maker test src/features/auth/hooks/useLogin.ts
372
505
  npx @teispace/next-maker test src/features/auth/store/auth.slice.ts
373
506
  npx @teispace/next-maker test src/hooks/use-debounce.ts --kind hook --force
374
507
  ```
375
508
 
376
- Requires testing to be installed (`next-maker setup --tests` if not).
509
+ Requires `setup --tests` first.
377
510
 
378
511
  ---
379
512
 
380
- ## Usage Examples
513
+ ## End-to-end examples
381
514
 
382
- ### Quick Start - New Project
515
+ ### Quick start
383
516
 
384
517
  ```bash
385
- # Create a new Next.js app with interactive setup
386
518
  npx @teispace/next-maker init my-project
387
519
  cd my-project
388
520
 
389
- # Generate pages
521
+ # Routes & layouts
390
522
  npx @teispace/next-maker page dashboard --loading --error
391
- npx @teispace/next-maker page settings --loading
523
+ npx @teispace/next-maker layout dashboard
524
+ npx @teispace/next-maker page products --dynamic id --loading --error
392
525
 
393
- # Generate features with CRUD
526
+ # State + data
394
527
  npx @teispace/next-maker feature users --store persist --service fetch
395
528
  npx @teispace/next-maker service users --fetch --crud --path features/users/services
396
529
 
397
- # Add a locale
530
+ # Providers & env
531
+ npx @teispace/next-maker provider auth
532
+ npx @teispace/next-maker env SENTRY_DSN --type url --describe "Sentry endpoint"
533
+
534
+ # i18n
398
535
  npx @teispace/next-maker locale es
399
536
 
400
- # Start development
537
+ # Health check before commit
538
+ npx @teispace/next-maker doctor
539
+
401
540
  npm run dev
402
541
  ```
403
542
 
404
- ### Feature-Based Development
543
+ ### Feature-driven workflow
405
544
 
406
545
  ```bash
407
- # E-commerce example
408
546
  npx @teispace/next-maker feature products --store persist --service axios
409
547
  npx @teispace/next-maker service products --axios --crud --path features/products/services
410
548
  npx @teispace/next-maker page products --dynamic id --loading --error
411
549
  npx @teispace/next-maker component product-card --client --feature src/features/products
550
+ npx @teispace/next-maker layout products
412
551
 
413
552
  npx @teispace/next-maker feature cart --store persist --skip-service
414
553
  npx @teispace/next-maker page checkout --loading --error
415
554
  ```
416
555
 
417
- ### Get Help
556
+ ### Maintenance — re-applying drifted features
418
557
 
419
558
  ```bash
420
- npx @teispace/next-maker --help
421
- npx @teispace/next-maker page --help
422
- npx @teispace/next-maker component --help
423
- npx @teispace/next-maker locale --help
424
- ```
425
-
426
- ---
427
-
428
- ## Key Features
429
-
430
- ### Pages with Full Locale Support
431
-
432
- Auto-generates `generateMetadata`, `setRequestLocale`, typed Props, SEO metadata, and translation namespace. Supports dynamic routes with `--dynamic`.
433
-
434
- ### Shared Components with Auto-Wiring
435
-
436
- Creates component in `src/components/common/<Name>/` and auto-updates all barrel exports so you can immediately `import { MyComponent } from '@/components'`.
559
+ # What's drifted?
560
+ npx @teispace/next-maker doctor
437
561
 
438
- ### CRUD Service Generation
562
+ # Fix in place
563
+ npx @teispace/next-maker doctor --fix
439
564
 
440
- `--crud` flag generates a complete service with 5 REST methods, separate `Summary` and `Detail` response types (list vs detail views), typed DTOs, and full API config with dynamic route helpers.
441
-
442
- ### Locale Management
443
-
444
- One command adds a new language: translation file, type update, and config entry. No manual file editing.
445
-
446
- ### Feature-First Architecture
447
-
448
- All generators follow a feature-based DDD approach, organizing code by business domain rather than technical layers.
565
+ # Pull a feature out cleanly
566
+ npx @teispace/next-maker remove i18n --dry-run
567
+ npx @teispace/next-maker remove i18n
568
+ ```
449
569
 
450
- ### Smart Redux Integration
570
+ ---
451
571
 
452
- Auto-registers slices in `rootReducer` with correct import paths and optional redux-persist configuration.
572
+ ## Architecture
453
573
 
454
- ### HTTP Client Support
574
+ ### Layers
455
575
 
456
- - **AxiosClient**: Result-based error handling
457
- - **FetchClient**: Same Result pattern with native fetch
458
- - Auto-detects available clients
576
+ ```
577
+ src/
578
+ ├── commands/ # Commander definitions (one file per CLI command)
579
+ ├── prompts/ # Enquirer flows (one per command needing interactivity)
580
+ ├── generators/ # generate<X>(): writes files for a single artifact
581
+ │ └── templates/ # Pure string-template functions (testable in isolation)
582
+ ├── modifiers/ # Pure functions that surgically edit existing files
583
+ ├── pipelines/ # PipelineStep[] composers for multi-step generators
584
+ ├── services/setup/ # Retrofit installers, one per feature
585
+ ├── manifests/ # Declarative feature footprints (drives doctor + remove)
586
+ ├── detection/ # "Is feature X installed?" detectors
587
+ ├── core/ # File I/O + package-manager helpers (yarn/npm/pnpm/bun)
588
+ └── config/ # PROJECT_PATHS, PACKAGES, spinner, output, error handlers
589
+ ```
459
590
 
460
- ### Intelligent Path Handling
591
+ ### The manifest pattern
461
592
 
462
- All commands support `--path` for custom locations. Relative paths like `features/auth` are resolved to `src/features/auth`.
593
+ Each feature has a manifest in `src/manifests/<feature>.manifest.ts` describing:
463
594
 
464
- ### Built-in Validations
595
+ - **detect** — high-level "is this installed?"
596
+ - **files** — paths the feature owns (with `generated: true/false` to control deletion safety)
597
+ - **packages** — runtime/dev dependencies
598
+ - **scripts** — `package.json` script entries (with optional exact-value match)
599
+ - **injections** — code blocks in shared files (with `presence` and optional `removePattern`)
600
+ - **apply** — the existing `setup<X>()` function (for `setup` and `doctor --fix`)
601
+ - **remove** — optional custom remover (defaults to the generic reverser)
465
602
 
466
- - Checks for required dependencies (Redux, HTTP clients, i18n)
467
- - Prevents duplicate generation
468
- - Validates naming conventions (kebab-case)
603
+ The manifest registry is consumed by:
469
604
 
470
- ### Test Generation
605
+ - `setup` — calls `apply()` directly
606
+ - `doctor` — walks every manifest, reports drift via `checkManifest`
607
+ - `remove` — runs `reverseManifest` (or a custom `remove`) and prints the plan
471
608
 
472
- - `component`, `hook`, and `slice` generators accept `--test` / `--no-test`; the default is **on** when Vitest is installed in the target project (detected via `vitest.config.ts` or the `vitest` dep).
473
- - Component tests use `renderWithProviders` and forward `messages: {}` / `preloadedState: {}` based on detected i18n / Redux.
474
- - Hook tests use `renderHook`; wrap with `TestProviders` when a Redux store is detected and the hook lives inside a feature.
475
- - Slice tests exercise the reducer directly (`setLoading`, `setError`, `resetState`, initial-state invariants) — no providers needed.
476
- - Standalone `test <file>` retrofits tests onto existing code, inferring kind from filename (`*.slice.ts`, `use*.ts`, `*.tsx`) and source content.
477
- - Import paths to `test/test-utils` are resolved relative to the source file, so co-generated tests compile no matter how deep in the tree they live.
609
+ Adding a manifest for a new feature is a single file. The CLI commands don't need to know about it.
478
610
 
479
- ---
611
+ ### Modifier conventions
480
612
 
481
- ## Command Reference
482
-
483
- | Command | Description |
484
- | ------------------ | -------------------------------------------------------- |
485
- | `init [name]` | Create a new Next.js application |
486
- | `setup` | Add features to an existing project |
487
- | `page <name>` | Generate a new page/route |
488
- | `component <name>` | Generate a shared component (optional sibling test) |
489
- | `feature <name>` | Generate a feature module |
490
- | `slice <name>` | Generate a Redux slice (optional sibling test) |
491
- | `service <name>` | Generate an API service |
492
- | `locale [code]` | Add a new locale/language |
493
- | `hook <name>` | Generate a custom React hook (optional sibling test) |
494
- | `test <file>` | Generate a sibling test for a component/hook/slice |
613
+ - **Pure transformation modules** (e.g. `headers.ts`, `package-modifier.ts`, `env-var.modifier.ts`) take strings or JSON and return strings or JSON. No filesystem.
614
+ - **Thin async wrappers** (`index.ts` per setup service, the modifier orchestrators) handle I/O and spinners.
615
+ - **Idempotency** is required: re-running anything is a no-op when the target state is already reached. This is what makes `doctor --fix` safe.
495
616
 
496
617
  ---
497
618
 
498
- ## Project Structure
619
+ ## Project structure (generated app)
499
620
 
500
621
  The full shape of a scaffolded app (branches marked `(opt)` are stripped when the matching prompt is declined during `init`):
501
622
 
@@ -526,11 +647,11 @@ my-project/
526
647
  │ │ ├── common/ # Shared UI (auto-wired barrel exports)
527
648
  │ │ └── index.ts
528
649
  │ ├── providers/
529
- │ │ ├── RootProvider.tsx # Composes Store → Theme → Intl
650
+ │ │ ├── RootProvider.tsx # Composes Store → Theme → Intl → custom
530
651
  │ │ ├── StoreProvider.tsx # (opt, redux) useRef + PersistGate
531
652
  │ │ ├── CustomThemeProvider.tsx # (opt, dark-mode) @teispace/next-themes
532
- │ │ └── index.ts
533
- │ ├── store/ # (opt, redux) makeStore, rootReducer, typed hooks, SSR-safe storage
653
+ │ │ └── index.ts # Barrel — `next-maker provider <name>` keeps it sorted
654
+ │ ├── store/ # (opt, redux) makeStore, rootReducer, typed hooks
534
655
  │ ├── services/
535
656
  │ │ ├── api/ # API service barrel
536
657
  │ │ └── storage/ # react-secure-storage wrapper
@@ -558,11 +679,12 @@ my-project/
558
679
  │ └── check-deprecated.ts # fails build if @deprecated APIs are referenced
559
680
  ├── public/
560
681
  ├── biome.json # single-tool lint + format
561
- ├── next.config.ts # headers, reactCompiler (opt), bundleAnalyzer (opt), withNextIntl (opt, i18n)
682
+ ├── next.config.ts # security headers, reactCompiler (opt), bundleAnalyzer (opt), withNextIntl (opt, i18n)
562
683
  ├── vitest.config.ts # (opt, tests)
563
684
  ├── postcss.config.mjs # @tailwindcss/postcss
564
685
  ├── tsconfig.json
565
686
  ├── .env.example
687
+ ├── .czrc # (opt, commitizen)
566
688
  ├── .husky/ # (opt, pre-commit hooks)
567
689
  ├── .lintstagedrc.mjs # (opt, pre-commit hooks) runs `biome check --write`
568
690
  ├── commitlint.config.mjs # (opt, pre-commit hooks)
@@ -573,19 +695,15 @@ my-project/
573
695
  └── package.json
574
696
  ```
575
697
 
576
- Features that have first-class opt-out prompts during `init`: `httpClient`, `darkMode`, `redux`, `i18n`, `tests`, `reactCompiler`, `bundleAnalyzer`, `docker`, `ci`, `preCommitHooks`, `commitizen`, `communityFiles`, `readme`. Each has a matching `setup --<feature>` command to re-add it later.
698
+ Features that have first-class opt-out prompts during `init`: `httpClient`, `darkMode`, `redux`, `i18n`, `tests`, `reactCompiler`, `bundleAnalyzer`, `docker`, `ci`, `preCommitHooks`, `commitizen`, `communityFiles`, `readme`, `copyEnv`. Each opt-out has a matching `setup --<feature>` to re-add later. `doctor` and `remove` cover the whole installed footprint via manifests.
577
699
 
578
700
  ---
579
701
 
580
702
  ## Tech Stack
581
703
 
582
- **CLI:**
583
-
584
- - TypeScript, esbuild, Commander.js, Enquirer, Vitest
585
-
586
- **Generated Apps:**
704
+ **CLI:** TypeScript, esbuild, Commander.js, Enquirer, Vitest, degit.
587
705
 
588
- - Next.js 16+, TypeScript, Tailwind CSS v4, Biome, Pino, Zod, Redux Toolkit, @teispace/next-themes, next-intl, Axios, Vitest + RTL, React Compiler
706
+ **Generated apps:** Next.js 16+, TypeScript, Tailwind CSS v4, Biome, Pino, Zod, Redux Toolkit, `@teispace/next-themes`, next-intl, Axios, Vitest + RTL, React Compiler.
589
707
 
590
708
  ---
591
709
 
@@ -596,37 +714,56 @@ Features that have first-class opt-out prompts during `init`: `httpClient`, `dar
596
714
  ```bash
597
715
  git clone <repository-url>
598
716
  cd npm-packages/packages/next-maker
599
- npm install
717
+ yarn install
600
718
  ```
601
719
 
602
720
  ### Build
603
721
 
604
722
  ```bash
605
- npm run build
723
+ yarn build # esbuild bundle + tsc --emitDeclarationOnly
606
724
  ```
607
725
 
608
726
  ### Test
609
727
 
610
728
  ```bash
611
- npm test
612
- npm run test:watch
729
+ yarn test # one-shot
730
+ yarn test:watch
613
731
  ```
614
732
 
615
- ### Test Locally
733
+ The test suite covers every modifier, generator template, and manifest runner with deterministic string/JSON inputs. Generators that touch the filesystem are tested against `os.tmpdir()` directories.
734
+
735
+ ### Smoke-test the built CLI
616
736
 
617
737
  ```bash
618
738
  node dist/index.js init test-project
619
739
  cd test-project
740
+
741
+ # Generators
620
742
  node ../dist/index.js page dashboard --loading --error
621
- node ../dist/index.js component sidebar --client # co-generates Sidebar.test.tsx if tests installed
622
- node ../dist/index.js hook debounce # co-generates useDebounce.test.ts
623
- node ../dist/index.js slice filters --persist # co-generates filters.slice.test.ts
624
- node ../dist/index.js feature auth --store persist --service axios
743
+ node ../dist/index.js layout dashboard
744
+ node ../dist/index.js component sidebar --client
745
+ node ../dist/index.js hook debounce
746
+ node ../dist/index.js provider auth
747
+ node ../dist/index.js slice filters --persist
748
+ node ../dist/index.js feature users --store persist --service axios
625
749
  node ../dist/index.js service users --fetch --crud
626
- node ../dist/index.js test src/hooks/useDebounce.ts --force # retrofit sibling test
750
+ node ../dist/index.js env SENTRY_DSN --type url --describe "Sentry"
627
751
  node ../dist/index.js locale es
752
+ node ../dist/index.js test src/hooks/useDebounce.ts --force
753
+
754
+ # Maintenance
755
+ node ../dist/index.js doctor
756
+ node ../dist/index.js remove redux --dry-run
628
757
  ```
629
758
 
759
+ ### Adding a new feature manifest
760
+
761
+ 1. Drop a file under `src/manifests/<feature>.manifest.ts` exporting a `FeatureManifest`.
762
+ 2. Append it to the `MANIFESTS` array in `src/manifests/index.ts`.
763
+ 3. (Optional) Add a `setup --<feature>` flag if you want a flag-based retrofit.
764
+
765
+ `doctor` and `remove` will pick it up automatically.
766
+
630
767
  ---
631
768
 
632
769
  ## License
@@ -637,11 +774,11 @@ MIT
637
774
 
638
775
  ## Contributing
639
776
 
640
- Contributions are welcome! Please feel free to submit a Pull Request.
777
+ Contributions are welcome. Please open a PR.
641
778
 
642
779
  1. Fork the repository
643
780
  2. Create your feature branch (`git checkout -b feature/amazing-feature`)
644
- 3. Commit your changes (`git commit -m 'Add amazing feature'`)
781
+ 3. Commit your changes (`git commit -m 'feat: add amazing feature'`)
645
782
  4. Push to the branch (`git push origin feature/amazing-feature`)
646
783
  5. Open a Pull Request
647
784