@react-spa-scaffold/mcp 0.3.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 (173) hide show
  1. package/README.md +423 -0
  2. package/dist/features/index.d.ts +5 -0
  3. package/dist/features/index.d.ts.map +1 -0
  4. package/dist/features/index.js +3 -0
  5. package/dist/features/index.js.map +1 -0
  6. package/dist/features/registry.d.ts +10 -0
  7. package/dist/features/registry.d.ts.map +1 -0
  8. package/dist/features/registry.js +508 -0
  9. package/dist/features/registry.js.map +1 -0
  10. package/dist/features/types.d.ts +45 -0
  11. package/dist/features/types.d.ts.map +1 -0
  12. package/dist/features/types.js +5 -0
  13. package/dist/features/types.js.map +1 -0
  14. package/dist/features/versions.d.ts +16 -0
  15. package/dist/features/versions.d.ts.map +1 -0
  16. package/dist/features/versions.js +46 -0
  17. package/dist/features/versions.js.map +1 -0
  18. package/dist/features/versions.json +5 -0
  19. package/dist/index.d.ts +22 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +43 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/resources/docs.d.ts +29 -0
  24. package/dist/resources/docs.d.ts.map +1 -0
  25. package/dist/resources/docs.js +105 -0
  26. package/dist/resources/docs.js.map +1 -0
  27. package/dist/resources/index.d.ts +2 -0
  28. package/dist/resources/index.d.ts.map +1 -0
  29. package/dist/resources/index.js +2 -0
  30. package/dist/resources/index.js.map +1 -0
  31. package/dist/server.d.ts +12 -0
  32. package/dist/server.d.ts.map +1 -0
  33. package/dist/server.js +115 -0
  34. package/dist/server.js.map +1 -0
  35. package/dist/tools/get-example.d.ts +51 -0
  36. package/dist/tools/get-example.d.ts.map +1 -0
  37. package/dist/tools/get-example.js +90 -0
  38. package/dist/tools/get-example.js.map +1 -0
  39. package/dist/tools/get-features.d.ts +30 -0
  40. package/dist/tools/get-features.d.ts.map +1 -0
  41. package/dist/tools/get-features.js +46 -0
  42. package/dist/tools/get-features.js.map +1 -0
  43. package/dist/tools/get-scaffold.d.ts +77 -0
  44. package/dist/tools/get-scaffold.d.ts.map +1 -0
  45. package/dist/tools/get-scaffold.js +153 -0
  46. package/dist/tools/get-scaffold.js.map +1 -0
  47. package/dist/tools/index.d.ts +4 -0
  48. package/dist/tools/index.d.ts.map +1 -0
  49. package/dist/tools/index.js +4 -0
  50. package/dist/tools/index.js.map +1 -0
  51. package/dist/utils/docs.d.ts +14 -0
  52. package/dist/utils/docs.d.ts.map +1 -0
  53. package/dist/utils/docs.js +64 -0
  54. package/dist/utils/docs.js.map +1 -0
  55. package/dist/utils/examples.d.ts +27 -0
  56. package/dist/utils/examples.d.ts.map +1 -0
  57. package/dist/utils/examples.js +399 -0
  58. package/dist/utils/examples.js.map +1 -0
  59. package/dist/utils/index.d.ts +5 -0
  60. package/dist/utils/index.d.ts.map +1 -0
  61. package/dist/utils/index.js +5 -0
  62. package/dist/utils/index.js.map +1 -0
  63. package/dist/utils/paths.d.ts +28 -0
  64. package/dist/utils/paths.d.ts.map +1 -0
  65. package/dist/utils/paths.js +40 -0
  66. package/dist/utils/paths.js.map +1 -0
  67. package/dist/utils/scaffold.d.ts +50 -0
  68. package/dist/utils/scaffold.d.ts.map +1 -0
  69. package/dist/utils/scaffold.js +500 -0
  70. package/dist/utils/scaffold.js.map +1 -0
  71. package/dist/version.d.ts +5 -0
  72. package/dist/version.d.ts.map +1 -0
  73. package/dist/version.js +19 -0
  74. package/dist/version.js.map +1 -0
  75. package/package.json +63 -0
  76. package/templates/.bundled +0 -0
  77. package/templates/CLAUDE.md +145 -0
  78. package/templates/docs/API_REFERENCE.md +58 -0
  79. package/templates/docs/ARCHITECTURE.md +185 -0
  80. package/templates/docs/CODING_STANDARDS.md +53 -0
  81. package/templates/docs/COMPONENT_GUIDELINES.md +301 -0
  82. package/templates/docs/E2E_TESTING.md +116 -0
  83. package/templates/docs/INTERNATIONALIZATION.md +67 -0
  84. package/templates/docs/TESTING.md +259 -0
  85. package/templates/docs/WORKFLOW.md +170 -0
  86. package/templates/src/App.tsx +42 -0
  87. package/templates/src/components/layout/Header.tsx +19 -0
  88. package/templates/src/components/layout/index.ts +1 -0
  89. package/templates/src/components/shared/ErrorBoundary/ErrorBoundary.tsx +104 -0
  90. package/templates/src/components/shared/ErrorBoundary/index.ts +1 -0
  91. package/templates/src/components/shared/LanguageSwitcher/LanguageSwitcher.tsx +45 -0
  92. package/templates/src/components/shared/LanguageSwitcher/index.ts +1 -0
  93. package/templates/src/components/shared/SEO/SEO.tsx +55 -0
  94. package/templates/src/components/shared/SEO/index.ts +1 -0
  95. package/templates/src/components/shared/ThemeToggle/ThemeToggle.tsx +41 -0
  96. package/templates/src/components/shared/ThemeToggle/index.ts +1 -0
  97. package/templates/src/components/shared/index.ts +4 -0
  98. package/templates/src/components/ui/button.tsx +48 -0
  99. package/templates/src/components/ui/dropdown-menu.tsx +228 -0
  100. package/templates/src/components/ui/form-error.tsx +95 -0
  101. package/templates/src/components/ui/loading.tsx +58 -0
  102. package/templates/src/components/ui/skeleton.tsx +52 -0
  103. package/templates/src/components/ui/sonner.tsx +34 -0
  104. package/templates/src/components/ui/spinner.tsx +40 -0
  105. package/templates/src/components/ui/visually-hidden.tsx +51 -0
  106. package/templates/src/contexts/mobileContext.tsx +66 -0
  107. package/templates/src/contexts/queryContext.tsx +28 -0
  108. package/templates/src/hooks/index.ts +7 -0
  109. package/templates/src/hooks/useContactForm.ts +33 -0
  110. package/templates/src/hooks/useExampleQuery.ts +20 -0
  111. package/templates/src/hooks/useLanguage.ts +23 -0
  112. package/templates/src/hooks/useMediaQuery.ts +53 -0
  113. package/templates/src/hooks/useThemeEffect.ts +31 -0
  114. package/templates/src/hooks/useTouchSizes.ts +16 -0
  115. package/templates/src/i18n/config.ts +11 -0
  116. package/templates/src/i18n/detectLanguage.ts +57 -0
  117. package/templates/src/i18n/index.ts +20 -0
  118. package/templates/src/i18n/loadCatalog.ts +30 -0
  119. package/templates/src/index.css +98 -0
  120. package/templates/src/lib/api.ts +142 -0
  121. package/templates/src/lib/config.ts +15 -0
  122. package/templates/src/lib/constants.ts +8 -0
  123. package/templates/src/lib/env.ts +53 -0
  124. package/templates/src/lib/format.ts +119 -0
  125. package/templates/src/lib/index.ts +24 -0
  126. package/templates/src/lib/routes.ts +11 -0
  127. package/templates/src/lib/storage.ts +91 -0
  128. package/templates/src/lib/storageKeys.ts +10 -0
  129. package/templates/src/lib/utils.ts +6 -0
  130. package/templates/src/lib/validations.ts +39 -0
  131. package/templates/src/locales/de.po +65 -0
  132. package/templates/src/locales/en.po +65 -0
  133. package/templates/src/locales/es.po +65 -0
  134. package/templates/src/main.tsx +107 -0
  135. package/templates/src/mocks/fixtures/index.ts +1 -0
  136. package/templates/src/mocks/fixtures/todos.ts +40 -0
  137. package/templates/src/mocks/handlers/index.ts +7 -0
  138. package/templates/src/mocks/handlers/todos.ts +59 -0
  139. package/templates/src/mocks/index.ts +3 -0
  140. package/templates/src/mocks/node.ts +9 -0
  141. package/templates/src/pages/Home.tsx +27 -0
  142. package/templates/src/pages/NotFound.tsx +28 -0
  143. package/templates/src/pages/index.ts +2 -0
  144. package/templates/src/stores/index.ts +2 -0
  145. package/templates/src/stores/preferencesStore.ts +85 -0
  146. package/templates/src/test/index.ts +8 -0
  147. package/templates/src/test/mocks.ts +17 -0
  148. package/templates/src/test/providers.tsx +54 -0
  149. package/templates/src/test-setup.ts +54 -0
  150. package/templates/src/types/api.ts +31 -0
  151. package/templates/src/types/index.ts +2 -0
  152. package/templates/src/types/preferences.ts +5 -0
  153. package/templates/src/vite-env.d.ts +10 -0
  154. package/templates/tests/unit/components/ErrorBoundary.test.tsx +193 -0
  155. package/templates/tests/unit/components/Header.test.tsx +33 -0
  156. package/templates/tests/unit/components/LanguageSwitcher.test.tsx +40 -0
  157. package/templates/tests/unit/components/Loading.test.tsx +76 -0
  158. package/templates/tests/unit/components/SEO.test.tsx +80 -0
  159. package/templates/tests/unit/components/ThemeToggle.test.tsx +62 -0
  160. package/templates/tests/unit/contexts/mobileContext.test.tsx +54 -0
  161. package/templates/tests/unit/hooks/useContactForm.test.ts +60 -0
  162. package/templates/tests/unit/hooks/useExampleQuery.test.tsx +94 -0
  163. package/templates/tests/unit/hooks/useLanguage.test.tsx +75 -0
  164. package/templates/tests/unit/hooks/useMediaQuery.test.ts +57 -0
  165. package/templates/tests/unit/hooks/useThemeEffect.test.ts +42 -0
  166. package/templates/tests/unit/i18n/detectLanguage.test.ts +40 -0
  167. package/templates/tests/unit/i18n/loadCatalog.test.ts +70 -0
  168. package/templates/tests/unit/lib/api.test.ts +142 -0
  169. package/templates/tests/unit/lib/format.test.ts +100 -0
  170. package/templates/tests/unit/lib/storage.test.ts +90 -0
  171. package/templates/tests/unit/lib/utils.test.ts +19 -0
  172. package/templates/tests/unit/lib/validations.test.ts +56 -0
  173. package/templates/tests/unit/stores/preferencesStore.test.ts +75 -0
@@ -0,0 +1,500 @@
1
+ /**
2
+ * Scaffold computation utilities
3
+ */
4
+ import { readFile } from 'fs/promises';
5
+ import { FEATURES } from '../features/index.js';
6
+ import { computeDocsContent, computeDocsForFeatures } from './docs.js';
7
+ import { resolveTemplatePath } from './paths.js';
8
+ /**
9
+ * Resolve selected features (always includes core)
10
+ *
11
+ * Features are independent - only explicitly selected features are included.
12
+ */
13
+ export function resolveFeatureDependencies(selectedFeatures) {
14
+ const resolved = new Set();
15
+ // Always include core
16
+ resolved.add('core');
17
+ // Add all selected features (no recursive dependency resolution)
18
+ for (const featureId of selectedFeatures) {
19
+ const feature = FEATURES[featureId];
20
+ if (feature) {
21
+ resolved.add(featureId);
22
+ }
23
+ }
24
+ return Array.from(resolved);
25
+ }
26
+ /**
27
+ * Merge dependencies from multiple features
28
+ */
29
+ export function mergeDependencies(featureIds) {
30
+ const dependencies = {};
31
+ const devDependencies = {};
32
+ for (const featureId of featureIds) {
33
+ const feature = FEATURES[featureId];
34
+ if (!feature)
35
+ continue;
36
+ if (feature.dependencies) {
37
+ Object.assign(dependencies, feature.dependencies);
38
+ }
39
+ if (feature.devDependencies) {
40
+ Object.assign(devDependencies, feature.devDependencies);
41
+ }
42
+ }
43
+ // Sort alphabetically
44
+ const sortObject = (obj) => Object.fromEntries(Object.entries(obj).sort(([a], [b]) => a.localeCompare(b)));
45
+ return {
46
+ dependencies: sortObject(dependencies),
47
+ devDependencies: sortObject(devDependencies),
48
+ };
49
+ }
50
+ /**
51
+ * Merge scripts from multiple features
52
+ */
53
+ export function mergeScripts(featureIds) {
54
+ const scripts = {};
55
+ for (const featureId of featureIds) {
56
+ const feature = FEATURES[featureId];
57
+ if (!feature?.scripts)
58
+ continue;
59
+ Object.assign(scripts, feature.scripts);
60
+ }
61
+ return scripts;
62
+ }
63
+ /**
64
+ * Compute file structure for selected features
65
+ */
66
+ export function computeFileStructure(featureIds) {
67
+ const files = new Set();
68
+ for (const featureId of featureIds) {
69
+ const feature = FEATURES[featureId];
70
+ if (!feature?.files)
71
+ continue;
72
+ for (const file of feature.files) {
73
+ files.add(file);
74
+ }
75
+ }
76
+ return Array.from(files).sort();
77
+ }
78
+ /**
79
+ * Get config files needed for selected features
80
+ */
81
+ export function getConfigFiles(featureIds) {
82
+ const configs = new Set();
83
+ for (const featureId of featureIds) {
84
+ const feature = FEATURES[featureId];
85
+ if (!feature?.configFiles)
86
+ continue;
87
+ for (const config of feature.configFiles) {
88
+ configs.add(config);
89
+ }
90
+ }
91
+ return Array.from(configs).sort();
92
+ }
93
+ /**
94
+ * Read config file content from template
95
+ */
96
+ async function readConfigFileContent(configPath) {
97
+ const fullPath = resolveTemplatePath(configPath);
98
+ try {
99
+ return await readFile(fullPath, 'utf-8');
100
+ }
101
+ catch {
102
+ // File might not exist if running outside react-spa-scaffold
103
+ return `// File not found: ${configPath}\n// Run MCP server from within react-spa-scaffold repository`;
104
+ }
105
+ }
106
+ /**
107
+ * Generate setup commands based on selected features
108
+ */
109
+ export function getSetupCommands(featureIds) {
110
+ const commands = ['npm install'];
111
+ if (featureIds.includes('devtools')) {
112
+ commands.push('npm run prepare'); // Initialize husky
113
+ }
114
+ if (featureIds.includes('testing')) {
115
+ commands.push('npx playwright install chromium'); // Install Playwright browser
116
+ }
117
+ if (featureIds.includes('i18n')) {
118
+ commands.push('npm run i18n:extract'); // Extract initial translations
119
+ }
120
+ return commands;
121
+ }
122
+ /**
123
+ * Generate CLAUDE.md content based on selected features
124
+ */
125
+ export function generateClaudeMd(featureIds, projectName, scripts) {
126
+ const sections = [];
127
+ // Header
128
+ sections.push(`# CLAUDE.md
129
+
130
+ AI assistant guidance for **${projectName}** - a React 19 + TypeScript + Vite 7 codebase.`);
131
+ // Commands section - based on actual scripts
132
+ const commandLines = [];
133
+ const scriptDescriptions = {
134
+ dev: 'Dev server at localhost:5173',
135
+ build: 'Production build (typecheck + bundle)',
136
+ preview: 'Preview production build',
137
+ typecheck: 'TypeScript only',
138
+ lint: 'ESLint check',
139
+ 'lint:fix': 'ESLint auto-fix',
140
+ format: 'Prettier format',
141
+ 'format:check': 'Prettier check',
142
+ test: 'Vitest once',
143
+ 'test:watch': 'Vitest watch mode',
144
+ 'test:coverage': 'Coverage (80% threshold)',
145
+ e2e: 'Playwright E2E',
146
+ 'e2e:ui': 'Playwright UI mode',
147
+ 'i18n:extract': 'Extract translations to .po',
148
+ prepare: 'Initialize Husky hooks',
149
+ };
150
+ for (const script of Object.keys(scripts).sort()) {
151
+ const desc = scriptDescriptions[script] || '';
152
+ const padding = ' '.repeat(Math.max(1, 20 - script.length));
153
+ commandLines.push(`npm run ${script}${padding}# ${desc}`);
154
+ }
155
+ sections.push(`
156
+ ## Commands
157
+
158
+ \`\`\`bash
159
+ ${commandLines.join('\n')}
160
+ \`\`\``);
161
+ // Project Structure - dynamic based on features
162
+ const structureParts = ['src/', '├── components/ # ui/ (primitives), layout/, shared/ (features)'];
163
+ if (featureIds.includes('api') || featureIds.includes('i18n') || featureIds.includes('mobile')) {
164
+ structureParts.push('├── contexts/ # React Context providers');
165
+ }
166
+ structureParts.push('├── hooks/ # Custom hooks');
167
+ structureParts.push('├── lib/ # config, utils, format' +
168
+ (featureIds.includes('api') ? ', api' : '') +
169
+ (featureIds.includes('routing') ? ', routes' : '') +
170
+ (featureIds.includes('state') ? ', storage' : ''));
171
+ if (featureIds.includes('routing')) {
172
+ structureParts.push('├── pages/ # Lazy-loaded route components');
173
+ }
174
+ if (featureIds.includes('state')) {
175
+ structureParts.push('├── stores/ # Zustand stores');
176
+ }
177
+ if (featureIds.includes('i18n')) {
178
+ structureParts.push('├── i18n/ # LinguiJS config and catalogs');
179
+ structureParts.push('├── locales/ # Translation files (.po)');
180
+ }
181
+ structureParts.push('└── types/ # TypeScript definitions');
182
+ if (featureIds.includes('testing')) {
183
+ structureParts.push('');
184
+ structureParts.push('tests/unit/ # Vitest (mirrors src/)');
185
+ structureParts.push('e2e/ # Playwright tests');
186
+ }
187
+ sections.push(`
188
+ ## Project Structure
189
+
190
+ \`\`\`
191
+ ${structureParts.join('\n')}
192
+ \`\`\``);
193
+ // Code Patterns - always included
194
+ const stateHierarchy = [];
195
+ if (featureIds.includes('state'))
196
+ stateHierarchy.push('Zustand (persisted)');
197
+ if (featureIds.includes('api'))
198
+ stateHierarchy.push('TanStack Query (server)');
199
+ stateHierarchy.push('Context (UI)', 'useState (local)');
200
+ sections.push(`
201
+ ## Code Patterns
202
+
203
+ **Imports**: Always use \`@/\` path alias
204
+
205
+ **Components**: Named exports + \`Props\` interface. Pages use default exports for lazy loading.
206
+
207
+ **TypeScript**: \`type\` for unions, \`interface\` for objects
208
+
209
+ **State hierarchy**: ${stateHierarchy.join(' → ')}`);
210
+ // UI Components section - only if ui feature
211
+ if (featureIds.includes('ui')) {
212
+ sections.push(`
213
+ ## UI Components (Shadcn/UI)
214
+
215
+ This project uses **Shadcn/UI** with radix-nova style. Components live in \`src/components/ui/\`.
216
+
217
+ ### Adding New Components
218
+
219
+ \`\`\`bash
220
+ npx shadcn@latest add button # Single component
221
+ npx shadcn@latest add dialog card input # Multiple components
222
+ \`\`\`
223
+
224
+ **Pattern**: Import directly (no barrel exports for UI):
225
+
226
+ \`\`\`tsx
227
+ import { Button } from '@/components/ui/button';
228
+ import { cn } from '@/lib/utils';
229
+ \`\`\``);
230
+ }
231
+ // Mobile section - only if mobile feature
232
+ if (featureIds.includes('mobile')) {
233
+ sections.push(`
234
+ ## Mobile & Responsive Design
235
+
236
+ This project includes mobile-first responsive utilities.
237
+
238
+ ### Viewport Detection
239
+
240
+ \`\`\`tsx
241
+ import { MobileProvider, useMobileContext } from '@/contexts/mobileContext';
242
+
243
+ // Wrap app with MobileProvider
244
+ <MobileProvider>{children}</MobileProvider>
245
+
246
+ // Use in components
247
+ const { isMobile, isTablet, isDesktop, width } = useMobileContext();
248
+ \`\`\`
249
+
250
+ ### Breakpoints
251
+
252
+ \`\`\`tsx
253
+ import { BREAKPOINTS, useIsMobile, useIsDesktop } from '@/hooks/useMediaQuery';
254
+
255
+ // BREAKPOINTS: sm (640), md (768), lg (1024), xl (1280)
256
+ const isMobile = useIsMobile(); // width < 768px
257
+ const isDesktop = useIsDesktop(); // width >= 1024px
258
+ \`\`\`
259
+
260
+ ### Touch-Aware Sizing
261
+
262
+ \`\`\`tsx
263
+ import { useTouchSizes } from '@/hooks/useTouchSizes';
264
+
265
+ const sizes = useTouchSizes();
266
+ <Button size={sizes.button}>Click</Button> // 'touch' on mobile, 'default' on desktop
267
+ \`\`\``);
268
+ }
269
+ // MCP Servers section - always helpful
270
+ sections.push(`
271
+ ## MCP Servers (PREFER OVER WebSearch)
272
+
273
+ Use MCP servers for documentation lookup. They provide **structured, version-accurate data** directly from source.
274
+
275
+ ### Context7 MCP (All Libraries)
276
+
277
+ Use for **any npm package** documentation:
278
+
279
+ \`\`\`
280
+ resolve-library-id → get-library-docs
281
+ \`\`\`
282
+
283
+ **Examples**: react-hook-form, @tanstack/react-query, zustand, zod, date-fns`);
284
+ if (featureIds.includes('ui')) {
285
+ sections.push(`
286
+ ### Shadcn MCP (UI Components)
287
+
288
+ | Need | Tool |
289
+ | ------------------- | ------------------------------------------------ |
290
+ | Find component | \`mcp__shadcn__search_items_in_registries\` |
291
+ | View component code | \`mcp__shadcn__view_items_in_registries\` |
292
+ | Usage examples | \`mcp__shadcn__get_item_examples_from_registries\` |`);
293
+ }
294
+ // Translations section - only if i18n feature
295
+ if (featureIds.includes('i18n')) {
296
+ sections.push(`
297
+ ## Translations (CRITICAL)
298
+
299
+ All user-facing text MUST have translator comments. ESLint enforces this.
300
+
301
+ \`\`\`tsx
302
+ <Trans comment="Dashboard heading">Welcome back</Trans>
303
+ t({ message: 'Close', comment: 'Close button' })
304
+ \`\`\``);
305
+ }
306
+ // Testing section - only if testing feature
307
+ if (featureIds.includes('testing')) {
308
+ sections.push(`
309
+ ## Testing
310
+
311
+ Tests in \`tests/unit/\` mirror \`src/\` structure. 80% coverage required.
312
+
313
+ \`\`\`typescript
314
+ import { describe, it, expect, vi } from 'vitest';
315
+ import { screen, renderHook } from '@testing-library/react';
316
+ import { render, mockMatchMedia, server } from '@/test';
317
+ \`\`\`
318
+
319
+ MSW handlers auto-reset after each test.`);
320
+ }
321
+ // Common Gotchas - filtered by features
322
+ const gotchas = [];
323
+ if (featureIds.includes('devtools')) {
324
+ gotchas.push('**Node.js >= 22.0.0** required (check `.nvmrc`)');
325
+ gotchas.push('**Conventional commits** enforced by commitlint');
326
+ }
327
+ if (featureIds.includes('mobile')) {
328
+ gotchas.push('**Context hooks throw** outside provider (e.g., `useMobileContext()`)');
329
+ }
330
+ gotchas.push('**Barrel exports** in each directory via `index.ts`');
331
+ if (featureIds.includes('ui')) {
332
+ gotchas.push('**UI components** import directly: `@/components/ui/button` (no barrel)');
333
+ }
334
+ sections.push(`
335
+ ## Common Gotchas
336
+
337
+ ${gotchas.map((g, i) => `${i + 1}. ${g}`).join('\n')}
338
+ `);
339
+ return sections.join('\n');
340
+ }
341
+ /**
342
+ * Generate vite-env.d.ts content based on selected features
343
+ */
344
+ export function generateViteEnvDts(featureIds) {
345
+ const envVars = [];
346
+ // Core env vars (always included)
347
+ envVars.push(' readonly VITE_APP_NAME: string;');
348
+ envVars.push(' readonly VITE_APP_URL: string;');
349
+ // API feature env vars
350
+ if (featureIds.includes('api')) {
351
+ envVars.push(' readonly VITE_API_URL: string;');
352
+ }
353
+ // Observability feature env vars
354
+ if (featureIds.includes('observability')) {
355
+ envVars.push(' readonly VITE_SENTRY_DSN: string;');
356
+ envVars.push(' readonly VITE_SENTRY_ENABLED: string;');
357
+ }
358
+ return `/// <reference types="vite/client" />
359
+
360
+ interface ImportMetaEnv {
361
+ ${envVars.join('\n')}
362
+ }
363
+
364
+ interface ImportMeta {
365
+ readonly env: ImportMetaEnv;
366
+ }
367
+ `;
368
+ }
369
+ /**
370
+ * Generate env.ts content based on selected features
371
+ */
372
+ export function generateEnvTs(featureIds) {
373
+ const schemaFields = [];
374
+ const envFields = [];
375
+ // Core env vars (always included)
376
+ schemaFields.push(' VITE_APP_NAME: z.string().min(1).optional(),');
377
+ schemaFields.push(' VITE_APP_URL: z.string().url().optional(),');
378
+ envFields.push(' VITE_APP_NAME: import.meta.env.VITE_APP_NAME,');
379
+ envFields.push(' VITE_APP_URL: import.meta.env.VITE_APP_URL,');
380
+ // API feature env vars
381
+ if (featureIds.includes('api')) {
382
+ schemaFields.push(' VITE_API_URL: z.string().url().optional(),');
383
+ envFields.push(' VITE_API_URL: import.meta.env.VITE_API_URL,');
384
+ }
385
+ // Observability feature env vars
386
+ if (featureIds.includes('observability')) {
387
+ schemaFields.push(' VITE_SENTRY_DSN: z.string().url().optional(),');
388
+ schemaFields.push(' VITE_SENTRY_ENABLED: z.string().optional(),');
389
+ envFields.push(' VITE_SENTRY_DSN: import.meta.env.VITE_SENTRY_DSN,');
390
+ envFields.push(' VITE_SENTRY_ENABLED: import.meta.env.VITE_SENTRY_ENABLED,');
391
+ }
392
+ // Vite built-in env vars (always included)
393
+ schemaFields.push(" MODE: z.enum(['development', 'production', 'test']).default('development'),");
394
+ schemaFields.push(' DEV: z.boolean().default(false),');
395
+ schemaFields.push(' PROD: z.boolean().default(false),');
396
+ envFields.push(' MODE: import.meta.env.MODE,');
397
+ envFields.push(' DEV: import.meta.env.DEV,');
398
+ envFields.push(' PROD: import.meta.env.PROD,');
399
+ return `/**
400
+ * Environment variable validation using Zod.
401
+ * Validates at runtime to catch missing/invalid env vars early.
402
+ */
403
+
404
+ import { z } from 'zod';
405
+
406
+ const envSchema = z.object({
407
+ ${schemaFields.join('\n')}
408
+ });
409
+
410
+ export type Env = z.infer<typeof envSchema>;
411
+
412
+ /**
413
+ * Validate environment variables and return typed env object.
414
+ * Throws if validation fails in production.
415
+ */
416
+ export function validateEnv(): Env {
417
+ const env = {
418
+ ${envFields.join('\n')}
419
+ };
420
+
421
+ const result = envSchema.safeParse(env);
422
+
423
+ if (!result.success) {
424
+ const errors = result.error.format();
425
+ console.error('Environment validation failed:', errors);
426
+
427
+ if (import.meta.env.PROD) {
428
+ throw new Error('Invalid environment configuration');
429
+ }
430
+ }
431
+
432
+ return result.success ? result.data : (env as Env);
433
+ }
434
+
435
+ /**
436
+ * Validated environment variables.
437
+ * Access this instead of import.meta.env for type safety.
438
+ */
439
+ export const env = validateEnv();
440
+ `;
441
+ }
442
+ /**
443
+ * Read and parse the source package.json
444
+ */
445
+ async function readSourcePackageJson() {
446
+ const path = resolveTemplatePath('package.json');
447
+ const content = await readFile(path, 'utf-8');
448
+ return JSON.parse(content);
449
+ }
450
+ /**
451
+ * Compute complete scaffold for selected features
452
+ */
453
+ export async function computeScaffold(selectedFeatures, projectName = 'my-app') {
454
+ // Resolve all dependencies
455
+ const resolvedFeatures = resolveFeatureDependencies(selectedFeatures);
456
+ // Read engines from source package.json
457
+ const sourcePackageJson = await readSourcePackageJson();
458
+ const engines = sourcePackageJson.engines || {};
459
+ // Merge all dependencies
460
+ const { dependencies, devDependencies } = mergeDependencies(resolvedFeatures);
461
+ // Merge all scripts
462
+ const scripts = mergeScripts(resolvedFeatures);
463
+ // Get file structure (add CLAUDE.md which is generated, not from patterns)
464
+ // Also add docs based on selected features
465
+ const docPaths = computeDocsForFeatures(resolvedFeatures);
466
+ const structure = [...computeFileStructure(resolvedFeatures), 'CLAUDE.md', ...docPaths];
467
+ // Get config files with actual content read from templates
468
+ const configFiles = {};
469
+ const configPaths = getConfigFiles(resolvedFeatures);
470
+ for (const config of configPaths) {
471
+ configFiles[config] = await readConfigFileContent(config);
472
+ }
473
+ // Get setup commands
474
+ const setupCommands = getSetupCommands(resolvedFeatures);
475
+ // Generate CLAUDE.md content
476
+ const claudeMd = generateClaudeMd(resolvedFeatures, projectName, scripts);
477
+ // Generate vite-env.d.ts content
478
+ const viteEnvDts = generateViteEnvDts(resolvedFeatures);
479
+ // Generate env.ts content
480
+ const envTs = generateEnvTs(resolvedFeatures);
481
+ // Get docs with content filtered by features
482
+ const docs = await computeDocsContent(resolvedFeatures);
483
+ return {
484
+ packageJson: {
485
+ name: projectName,
486
+ dependencies,
487
+ devDependencies,
488
+ scripts,
489
+ engines,
490
+ },
491
+ structure,
492
+ configFiles,
493
+ setupCommands,
494
+ claudeMd,
495
+ viteEnvDts,
496
+ envTs,
497
+ docs,
498
+ };
499
+ }
500
+ //# sourceMappingURL=scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../src/utils/scaffold.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Package version - read from package.json
3
+ */
4
+ export declare const VERSION: string;
5
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkBH,eAAO,MAAM,OAAO,QAAe,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Package version - read from package.json
3
+ */
4
+ import { readFileSync } from 'fs';
5
+ import { dirname, join } from 'path';
6
+ import { fileURLToPath } from 'url';
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ function getVersion() {
9
+ try {
10
+ const packagePath = join(__dirname, '..', 'package.json');
11
+ const pkg = JSON.parse(readFileSync(packagePath, 'utf-8'));
12
+ return pkg.version;
13
+ }
14
+ catch {
15
+ return '1.0.0'; // Fallback
16
+ }
17
+ }
18
+ export const VERSION = getVersion();
19
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;QAC3D,OAAO,GAAG,CAAC,OAAO,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC,CAAC,WAAW;IAC7B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@react-spa-scaffold/mcp",
3
+ "version": "0.3.0",
4
+ "description": "MCP server for scaffolding projects based on react-spa-scaffold template",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "react-spa-scaffold-mcp": "dist/index.js"
10
+ },
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "dev": "tsc --watch",
14
+ "start": "node dist/index.js",
15
+ "typecheck": "tsc --noEmit",
16
+ "test": "vitest run",
17
+ "test:watch": "vitest",
18
+ "inspect": "npx @modelcontextprotocol/inspector node dist/index.js",
19
+ "bundle": "node scripts/bundle-templates.js",
20
+ "prepublishOnly": "npm run bundle && npm run build"
21
+ },
22
+ "keywords": [
23
+ "mcp",
24
+ "model-context-protocol",
25
+ "react-spa-scaffold",
26
+ "scaffolding",
27
+ "react",
28
+ "typescript"
29
+ ],
30
+ "author": "Mariusz Kaczkowski",
31
+ "license": "MIT",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/mkaczkowski/react-spa-scaffold.git",
35
+ "directory": "packages/mcp"
36
+ },
37
+ "homepage": "https://github.com/mkaczkowski/react-spa-scaffold/tree/main/packages/mcp#readme",
38
+ "bugs": {
39
+ "url": "https://github.com/mkaczkowski/react-spa-scaffold/issues"
40
+ },
41
+ "dependencies": {
42
+ "@modelcontextprotocol/sdk": "^1.0.0",
43
+ "zod": "^3.25.64"
44
+ },
45
+ "devDependencies": {
46
+ "@types/node": "^22.15.0",
47
+ "@react-spa-scaffold/tsconfig": "*",
48
+ "typescript": "~5.9.0",
49
+ "vitest": "^4.0.16"
50
+ },
51
+ "engines": {
52
+ "node": ">=22.0.0"
53
+ },
54
+ "files": [
55
+ "dist",
56
+ "templates",
57
+ "README.md"
58
+ ],
59
+ "publishConfig": {
60
+ "access": "public",
61
+ "registry": "https://registry.npmjs.org/"
62
+ }
63
+ }
File without changes