@react-spa-scaffold/mcp 1.1.3 → 1.2.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 (217) hide show
  1. package/README.md +19 -15
  2. package/dist/features/definitions/api.d.ts +3 -0
  3. package/dist/features/definitions/api.d.ts.map +1 -0
  4. package/dist/features/definitions/api.js +20 -0
  5. package/dist/features/definitions/api.js.map +1 -0
  6. package/dist/features/definitions/ci.d.ts +3 -0
  7. package/dist/features/definitions/ci.d.ts.map +1 -0
  8. package/dist/features/definitions/ci.js +25 -0
  9. package/dist/features/definitions/ci.js.map +1 -0
  10. package/dist/features/definitions/core.d.ts +3 -0
  11. package/dist/features/definitions/core.d.ts.map +1 -0
  12. package/dist/features/definitions/core.js +76 -0
  13. package/dist/features/definitions/core.js.map +1 -0
  14. package/dist/features/definitions/devtools.d.ts +3 -0
  15. package/dist/features/definitions/devtools.d.ts.map +1 -0
  16. package/dist/features/definitions/devtools.js +53 -0
  17. package/dist/features/definitions/devtools.js.map +1 -0
  18. package/dist/features/definitions/forms.d.ts +3 -0
  19. package/dist/features/definitions/forms.d.ts.map +1 -0
  20. package/dist/features/definitions/forms.js +32 -0
  21. package/dist/features/definitions/forms.js.map +1 -0
  22. package/dist/features/definitions/i18n.d.ts +3 -0
  23. package/dist/features/definitions/i18n.d.ts.map +1 -0
  24. package/dist/features/definitions/i18n.js +50 -0
  25. package/dist/features/definitions/i18n.js.map +1 -0
  26. package/dist/features/definitions/index.d.ts +15 -0
  27. package/dist/features/definitions/index.d.ts.map +1 -0
  28. package/dist/features/definitions/index.js +15 -0
  29. package/dist/features/definitions/index.js.map +1 -0
  30. package/dist/features/definitions/mobile.d.ts +3 -0
  31. package/dist/features/definitions/mobile.d.ts.map +1 -0
  32. package/dist/features/definitions/mobile.js +19 -0
  33. package/dist/features/definitions/mobile.js.map +1 -0
  34. package/dist/features/definitions/observability.d.ts +3 -0
  35. package/dist/features/definitions/observability.d.ts.map +1 -0
  36. package/dist/features/definitions/observability.js +21 -0
  37. package/dist/features/definitions/observability.js.map +1 -0
  38. package/dist/features/definitions/performance.d.ts +3 -0
  39. package/dist/features/definitions/performance.d.ts.map +1 -0
  40. package/dist/features/definitions/performance.js +28 -0
  41. package/dist/features/definitions/performance.js.map +1 -0
  42. package/dist/features/definitions/routing.d.ts +3 -0
  43. package/dist/features/definitions/routing.d.ts.map +1 -0
  44. package/dist/features/definitions/routing.js +25 -0
  45. package/dist/features/definitions/routing.js.map +1 -0
  46. package/dist/features/definitions/state.d.ts +3 -0
  47. package/dist/features/definitions/state.d.ts.map +1 -0
  48. package/dist/features/definitions/state.js +27 -0
  49. package/dist/features/definitions/state.js.map +1 -0
  50. package/dist/features/definitions/testing.d.ts +3 -0
  51. package/dist/features/definitions/testing.d.ts.map +1 -0
  52. package/dist/features/definitions/testing.js +56 -0
  53. package/dist/features/definitions/testing.js.map +1 -0
  54. package/dist/features/definitions/theming.d.ts +3 -0
  55. package/dist/features/definitions/theming.d.ts.map +1 -0
  56. package/dist/features/definitions/theming.js +26 -0
  57. package/dist/features/definitions/theming.js.map +1 -0
  58. package/dist/features/definitions/ui.d.ts +3 -0
  59. package/dist/features/definitions/ui.d.ts.map +1 -0
  60. package/dist/features/definitions/ui.js +44 -0
  61. package/dist/features/definitions/ui.js.map +1 -0
  62. package/dist/features/index.d.ts +3 -2
  63. package/dist/features/index.d.ts.map +1 -1
  64. package/dist/features/index.js +2 -1
  65. package/dist/features/index.js.map +1 -1
  66. package/dist/features/registry.d.ts +3 -9
  67. package/dist/features/registry.d.ts.map +1 -1
  68. package/dist/features/registry.js +3 -554
  69. package/dist/features/registry.js.map +1 -1
  70. package/dist/features/types.d.ts +11 -9
  71. package/dist/features/types.d.ts.map +1 -1
  72. package/dist/features/types.js +24 -1
  73. package/dist/features/types.js.map +1 -1
  74. package/dist/server.d.ts +2 -7
  75. package/dist/server.d.ts.map +1 -1
  76. package/dist/server.js +22 -56
  77. package/dist/server.js.map +1 -1
  78. package/dist/server.test.d.ts +2 -0
  79. package/dist/server.test.d.ts.map +1 -0
  80. package/dist/server.test.js +14 -0
  81. package/dist/server.test.js.map +1 -0
  82. package/dist/tools/get-example.test.d.ts +5 -0
  83. package/dist/tools/get-example.test.d.ts.map +1 -0
  84. package/dist/tools/get-example.test.js +63 -0
  85. package/dist/tools/get-example.test.js.map +1 -0
  86. package/dist/tools/get-features.d.ts +0 -5
  87. package/dist/tools/get-features.d.ts.map +1 -1
  88. package/dist/tools/get-features.js +0 -2
  89. package/dist/tools/get-features.js.map +1 -1
  90. package/dist/tools/get-features.test.d.ts +5 -0
  91. package/dist/tools/get-features.test.d.ts.map +1 -0
  92. package/dist/tools/get-features.test.js +45 -0
  93. package/dist/tools/get-features.test.js.map +1 -0
  94. package/dist/tools/get-scaffold.d.ts +2 -2
  95. package/dist/tools/get-scaffold.test.d.ts +5 -0
  96. package/dist/tools/get-scaffold.test.d.ts.map +1 -0
  97. package/dist/tools/get-scaffold.test.js +194 -0
  98. package/dist/tools/get-scaffold.test.js.map +1 -0
  99. package/dist/tools/index.d.ts +2 -0
  100. package/dist/tools/index.d.ts.map +1 -1
  101. package/dist/tools/index.js +1 -0
  102. package/dist/tools/index.js.map +1 -1
  103. package/dist/tools/registry.d.ts +9 -0
  104. package/dist/tools/registry.d.ts.map +1 -0
  105. package/dist/tools/registry.js +29 -0
  106. package/dist/tools/registry.js.map +1 -0
  107. package/dist/tools/types.d.ts +23 -0
  108. package/dist/tools/types.d.ts.map +1 -0
  109. package/dist/tools/types.js +5 -0
  110. package/dist/tools/types.js.map +1 -0
  111. package/dist/utils/cache.d.ts +21 -0
  112. package/dist/utils/cache.d.ts.map +1 -0
  113. package/dist/utils/cache.js +45 -0
  114. package/dist/utils/cache.js.map +1 -0
  115. package/dist/utils/docs.test.d.ts +5 -0
  116. package/dist/utils/docs.test.d.ts.map +1 -0
  117. package/dist/utils/docs.test.js +37 -0
  118. package/dist/utils/docs.test.js.map +1 -0
  119. package/dist/utils/errors.d.ts +8 -0
  120. package/dist/utils/errors.d.ts.map +1 -0
  121. package/dist/utils/errors.js +19 -0
  122. package/dist/utils/errors.js.map +1 -0
  123. package/dist/utils/examples/api-patterns.d.ts +3 -0
  124. package/dist/utils/examples/api-patterns.d.ts.map +1 -0
  125. package/dist/utils/examples/api-patterns.js +19 -0
  126. package/dist/utils/examples/api-patterns.js.map +1 -0
  127. package/dist/utils/examples/component-patterns.d.ts +3 -0
  128. package/dist/utils/examples/component-patterns.d.ts.map +1 -0
  129. package/dist/utils/examples/component-patterns.js +71 -0
  130. package/dist/utils/examples/component-patterns.js.map +1 -0
  131. package/dist/utils/examples/context-patterns.d.ts +3 -0
  132. package/dist/utils/examples/context-patterns.d.ts.map +1 -0
  133. package/dist/utils/examples/context-patterns.js +32 -0
  134. package/dist/utils/examples/context-patterns.js.map +1 -0
  135. package/dist/utils/examples/hook-patterns.d.ts +3 -0
  136. package/dist/utils/examples/hook-patterns.d.ts.map +1 -0
  137. package/dist/utils/examples/hook-patterns.js +55 -0
  138. package/dist/utils/examples/hook-patterns.js.map +1 -0
  139. package/dist/utils/examples/i18n-patterns.d.ts +3 -0
  140. package/dist/utils/examples/i18n-patterns.d.ts.map +1 -0
  141. package/dist/utils/examples/i18n-patterns.js +43 -0
  142. package/dist/utils/examples/i18n-patterns.js.map +1 -0
  143. package/dist/utils/examples/index.d.ts +12 -0
  144. package/dist/utils/examples/index.d.ts.map +1 -0
  145. package/dist/utils/examples/index.js +69 -0
  146. package/dist/utils/examples/index.js.map +1 -0
  147. package/dist/utils/examples/mobile-patterns.d.ts +3 -0
  148. package/dist/utils/examples/mobile-patterns.d.ts.map +1 -0
  149. package/dist/utils/examples/mobile-patterns.js +38 -0
  150. package/dist/utils/examples/mobile-patterns.js.map +1 -0
  151. package/dist/utils/examples/page-patterns.d.ts +3 -0
  152. package/dist/utils/examples/page-patterns.d.ts.map +1 -0
  153. package/dist/utils/examples/page-patterns.js +34 -0
  154. package/dist/utils/examples/page-patterns.js.map +1 -0
  155. package/dist/utils/examples/store-patterns.d.ts +3 -0
  156. package/dist/utils/examples/store-patterns.d.ts.map +1 -0
  157. package/dist/utils/examples/store-patterns.js +40 -0
  158. package/dist/utils/examples/store-patterns.js.map +1 -0
  159. package/dist/utils/examples/test-patterns.d.ts +3 -0
  160. package/dist/utils/examples/test-patterns.d.ts.map +1 -0
  161. package/dist/utils/examples/test-patterns.js +58 -0
  162. package/dist/utils/examples/test-patterns.js.map +1 -0
  163. package/dist/utils/examples/types.d.ts +17 -0
  164. package/dist/utils/examples/types.d.ts.map +1 -0
  165. package/dist/utils/examples/types.js +2 -0
  166. package/dist/utils/examples/types.js.map +1 -0
  167. package/dist/utils/examples/utility-patterns.d.ts +3 -0
  168. package/dist/utils/examples/utility-patterns.d.ts.map +1 -0
  169. package/dist/utils/examples/utility-patterns.js +77 -0
  170. package/dist/utils/examples/utility-patterns.js.map +1 -0
  171. package/dist/utils/index.d.ts +5 -3
  172. package/dist/utils/index.d.ts.map +1 -1
  173. package/dist/utils/index.js +5 -3
  174. package/dist/utils/index.js.map +1 -1
  175. package/dist/utils/paths.d.ts +6 -25
  176. package/dist/utils/paths.d.ts.map +1 -1
  177. package/dist/utils/paths.js +11 -40
  178. package/dist/utils/paths.js.map +1 -1
  179. package/dist/utils/paths.test.d.ts +2 -0
  180. package/dist/utils/paths.test.d.ts.map +1 -0
  181. package/dist/utils/paths.test.js +17 -0
  182. package/dist/utils/paths.test.js.map +1 -0
  183. package/dist/utils/scaffold/commands.d.ts +11 -0
  184. package/dist/utils/scaffold/commands.d.ts.map +1 -0
  185. package/dist/utils/scaffold/commands.js +22 -0
  186. package/dist/utils/scaffold/commands.js.map +1 -0
  187. package/dist/utils/scaffold/compute.d.ts +18 -0
  188. package/dist/utils/scaffold/compute.d.ts.map +1 -0
  189. package/dist/utils/scaffold/compute.js +78 -0
  190. package/dist/utils/scaffold/compute.js.map +1 -0
  191. package/dist/utils/scaffold/dependencies.d.ts +32 -0
  192. package/dist/utils/scaffold/dependencies.d.ts.map +1 -0
  193. package/dist/utils/scaffold/dependencies.js +107 -0
  194. package/dist/utils/scaffold/dependencies.js.map +1 -0
  195. package/dist/utils/scaffold/file-structure.d.ts +23 -0
  196. package/dist/utils/scaffold/file-structure.d.ts.map +1 -0
  197. package/dist/utils/scaffold/file-structure.js +62 -0
  198. package/dist/utils/scaffold/file-structure.js.map +1 -0
  199. package/dist/utils/scaffold/generators.d.ts +17 -0
  200. package/dist/utils/scaffold/generators.d.ts.map +1 -0
  201. package/dist/utils/{scaffold.js → scaffold/generators.js} +6 -254
  202. package/dist/utils/scaffold/generators.js.map +1 -0
  203. package/dist/utils/scaffold/index.d.ts +11 -0
  204. package/dist/utils/scaffold/index.d.ts.map +1 -0
  205. package/dist/utils/scaffold/index.js +11 -0
  206. package/dist/utils/scaffold/index.js.map +1 -0
  207. package/package.json +1 -1
  208. package/templates/.github/workflows/release.yml +1 -1
  209. package/templates/e2e/tests/home.spec.ts +2 -2
  210. package/templates/e2e/tests/language.spec.ts +7 -3
  211. package/dist/utils/examples.d.ts +0 -27
  212. package/dist/utils/examples.d.ts.map +0 -1
  213. package/dist/utils/examples.js +0 -438
  214. package/dist/utils/examples.js.map +0 -1
  215. package/dist/utils/scaffold.d.ts +0 -59
  216. package/dist/utils/scaffold.d.ts.map +0 -1
  217. package/dist/utils/scaffold.js.map +0 -1
@@ -1,5 +1,28 @@
1
1
  /**
2
2
  * Type definitions for feature modules
3
3
  */
4
- export {};
4
+ /**
5
+ * All valid feature IDs as a const tuple.
6
+ * Used for compile-time type safety when referencing features.
7
+ */
8
+ export const FEATURE_IDS = [
9
+ 'core',
10
+ 'mobile',
11
+ 'routing',
12
+ 'ui',
13
+ 'forms',
14
+ 'state',
15
+ 'api',
16
+ 'i18n',
17
+ 'testing',
18
+ 'performance',
19
+ 'devtools',
20
+ 'ci',
21
+ 'observability',
22
+ 'theming',
23
+ ];
24
+ /** Type guard to check if a string is a valid FeatureId */
25
+ export function isFeatureId(value) {
26
+ return FEATURE_IDS.includes(value);
27
+ }
5
28
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/features/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/features/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,MAAM;IACN,QAAQ;IACR,SAAS;IACT,IAAI;IACJ,OAAO;IACP,OAAO;IACP,KAAK;IACL,MAAM;IACN,SAAS;IACT,aAAa;IACb,UAAU;IACV,IAAI;IACJ,eAAe;IACf,SAAS;CACD,CAAC;AAKX,2DAA2D;AAC3D,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,WAAW,CAAC,QAAQ,CAAC,KAAkB,CAAC,CAAC;AAClD,CAAC"}
package/dist/server.d.ts CHANGED
@@ -1,12 +1,7 @@
1
1
  /**
2
- * MCP Server for react-spa-scaffold scaffolding
3
- *
4
- * This server provides tools and resources for AI agents to scaffold
5
- * new projects based on the react-spa-scaffold template.
2
+ * MCP Server for react-spa-scaffold scaffolding.
6
3
  */
7
4
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
8
- /**
9
- * Create and configure the MCP server
10
- */
5
+ /** Creates and configures the MCP server. */
11
6
  export declare function createServer(): Server;
12
7
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AA2DnE;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAoFrC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAyCnE,6CAA6C;AAC7C,wBAAgB,YAAY,IAAI,MAAM,CA0DrC"}
package/dist/server.js CHANGED
@@ -1,17 +1,11 @@
1
1
  /**
2
- * MCP Server for react-spa-scaffold scaffolding
3
- *
4
- * This server provides tools and resources for AI agents to scaffold
5
- * new projects based on the react-spa-scaffold template.
2
+ * MCP Server for react-spa-scaffold scaffolding.
6
3
  */
7
4
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
8
5
  import { CallToolRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
9
- import { getFeatures, getFeaturesToolDefinition, getScaffold, getScaffoldSchema, getScaffoldToolDefinition, getExample, getExampleSchema, getExampleToolDefinition, } from './tools/index.js';
6
+ import { TOOL_REGISTRY, getToolDefinitions } from './tools/index.js';
10
7
  import { getDocumentationResources, readDocumentation, isValidDocumentationUri } from './resources/index.js';
11
8
  import { VERSION } from './version.js';
12
- // ═══════════════════════════════════════════════════════════════════════════
13
- // Response Helpers
14
- // ═══════════════════════════════════════════════════════════════════════════
15
9
  function jsonResponse(data) {
16
10
  return {
17
11
  content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
@@ -23,9 +17,6 @@ function errorResponse(message) {
23
17
  isError: true,
24
18
  };
25
19
  }
26
- // ═══════════════════════════════════════════════════════════════════════════
27
- // Server Instructions
28
- // ═══════════════════════════════════════════════════════════════════════════
29
20
  const SERVER_INSTRUCTIONS = `
30
21
  react-spa-scaffold MCP Server - Project Scaffolding Assistant
31
22
 
@@ -41,63 +32,38 @@ Tips:
41
32
  - Theming feature automatically includes state (requires Zustand)
42
33
  - Check docs://conventions before generating code
43
34
  `.trim();
44
- /**
45
- * Create and configure the MCP server
46
- */
35
+ /** Creates and configures the MCP server. */
47
36
  export function createServer() {
48
- const server = new Server({
49
- name: 'react-spa-scaffold-mcp',
50
- version: VERSION,
51
- }, {
52
- capabilities: {
53
- tools: {},
54
- resources: {},
55
- },
56
- instructions: SERVER_INSTRUCTIONS,
57
- });
58
- // ═══════════════════════════════════════════════════════════════════════
59
- // TOOLS
60
- // ═══════════════════════════════════════════════════════════════════════
61
- server.setRequestHandler(ListToolsRequestSchema, async () => {
62
- return {
63
- tools: [getFeaturesToolDefinition, getScaffoldToolDefinition, getExampleToolDefinition],
64
- };
65
- });
37
+ const server = new Server({ name: 'react-spa-scaffold-mcp', version: VERSION }, { capabilities: { tools: {}, resources: {} }, instructions: SERVER_INSTRUCTIONS });
38
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
39
+ tools: getToolDefinitions(),
40
+ }));
66
41
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
67
42
  const { name, arguments: args } = request.params;
43
+ const toolConfig = TOOL_REGISTRY[name];
44
+ if (!toolConfig) {
45
+ return errorResponse(`Unknown tool: ${name}`);
46
+ }
68
47
  try {
69
- switch (name) {
70
- case 'get_features':
71
- return jsonResponse(getFeatures());
72
- case 'get_scaffold': {
73
- const parsed = getScaffoldSchema.safeParse(args);
74
- if (!parsed.success) {
75
- return errorResponse(`Invalid input: ${parsed.error.message}`);
76
- }
77
- return jsonResponse(await getScaffold(parsed.data));
48
+ if (toolConfig.schema) {
49
+ const parsed = toolConfig.schema.safeParse(args);
50
+ if (!parsed.success) {
51
+ return errorResponse(`Invalid input: ${parsed.error.message}`);
78
52
  }
79
- case 'get_example': {
80
- const parsed = getExampleSchema.safeParse(args);
81
- if (!parsed.success) {
82
- return errorResponse(`Invalid input: ${parsed.error.message}`);
83
- }
84
- return jsonResponse(await getExample(parsed.data));
85
- }
86
- default:
87
- return errorResponse(`Unknown tool: ${name}`);
53
+ const result = await toolConfig.handler(parsed.data);
54
+ return jsonResponse(result);
88
55
  }
56
+ const result = await toolConfig.handler();
57
+ return jsonResponse(result);
89
58
  }
90
59
  catch (error) {
91
60
  const message = error instanceof Error ? error.message : String(error);
92
61
  return errorResponse(`Error executing ${name}: ${message}`);
93
62
  }
94
63
  });
95
- // ═══════════════════════════════════════════════════════════════════════
96
- // RESOURCES
97
- // ═══════════════════════════════════════════════════════════════════════
98
- server.setRequestHandler(ListResourcesRequestSchema, async () => {
99
- return { resources: getDocumentationResources() };
100
- });
64
+ server.setRequestHandler(ListResourcesRequestSchema, async () => ({
65
+ resources: getDocumentationResources(),
66
+ }));
101
67
  server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
102
68
  const { uri } = request.params;
103
69
  if (!isValidDocumentationUri(uri)) {
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=server.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.test.d.ts","sourceRoot":"","sources":["../src/server.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { createServer } from './server.js';
3
+ describe('MCP server', () => {
4
+ it('creates server instance', () => {
5
+ const server = createServer();
6
+ expect(server).toBeDefined();
7
+ });
8
+ it('has correct server name and version', () => {
9
+ const server = createServer();
10
+ // @ts-expect-error - accessing internal server info
11
+ expect(server._serverInfo?.name).toBe('react-spa-scaffold-mcp');
12
+ });
13
+ });
14
+ //# sourceMappingURL=server.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.test.js","sourceRoot":"","sources":["../src/server.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;QAC9B,oDAAoD;QACpD,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for get_example tool
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=get-example.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-example.test.d.ts","sourceRoot":"","sources":["../../src/tools/get-example.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Tests for get_example tool
3
+ */
4
+ import { describe, it, expect } from 'vitest';
5
+ import { getExample, getExampleSchema } from './get-example.js';
6
+ describe('get_example tool', () => {
7
+ it('rejects unknown pattern via schema', () => {
8
+ const result = getExampleSchema.safeParse({ pattern: 'unknown-pattern' });
9
+ expect(result.success).toBe(false);
10
+ if (!result.success) {
11
+ expect(result.error.message).toContain('Invalid pattern');
12
+ }
13
+ });
14
+ it('returns code for valid pattern', async () => {
15
+ const result = await getExample({ pattern: 'zustand-store' });
16
+ expect(result).not.toHaveProperty('error');
17
+ expect(result).toHaveProperty('code');
18
+ expect(result).toHaveProperty('filePath');
19
+ expect(result).toHaveProperty('description');
20
+ expect(result).toHaveProperty('keyPoints');
21
+ });
22
+ it('returns usage hint', async () => {
23
+ const result = await getExample({ pattern: 'zustand-store' });
24
+ expect(result).toHaveProperty('usage');
25
+ expect(typeof result.usage).toBe('string');
26
+ });
27
+ it('returns actual code content', async () => {
28
+ const result = await getExample({ pattern: 'hook-state' });
29
+ expect(result.code).toBeTruthy();
30
+ expect(result.code?.length).toBeGreaterThan(50);
31
+ });
32
+ it('works for component patterns', async () => {
33
+ const result = await getExample({ pattern: 'component-ui' });
34
+ expect(result).not.toHaveProperty('error');
35
+ expect(result.code).toContain('export');
36
+ });
37
+ it('works for test patterns', async () => {
38
+ const result = await getExample({ pattern: 'test-component' });
39
+ expect(result).not.toHaveProperty('error');
40
+ expect(result.code).toContain('describe');
41
+ });
42
+ it('works for mobile-context pattern', async () => {
43
+ const result = await getExample({ pattern: 'mobile-context' });
44
+ expect(result).not.toHaveProperty('error');
45
+ expect(result.code).toContain('MobileProvider');
46
+ expect(result.code).toContain('useMobileContext');
47
+ expect(result.filePath).toBe('src/contexts/mobileContext.tsx');
48
+ });
49
+ it('works for use-media-query pattern', async () => {
50
+ const result = await getExample({ pattern: 'use-media-query' });
51
+ expect(result).not.toHaveProperty('error');
52
+ expect(result.code).toContain('BREAKPOINTS');
53
+ expect(result.code).toContain('useMediaQuery');
54
+ expect(result.filePath).toBe('src/hooks/useMediaQuery.ts');
55
+ });
56
+ it('works for use-touch-sizes pattern', async () => {
57
+ const result = await getExample({ pattern: 'use-touch-sizes' });
58
+ expect(result).not.toHaveProperty('error');
59
+ expect(result.code).toContain('useTouchSizes');
60
+ expect(result.filePath).toBe('src/hooks/useTouchSizes.ts');
61
+ });
62
+ });
63
+ //# sourceMappingURL=get-example.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-example.test.js","sourceRoot":"","sources":["../../src/tools/get-example.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEhE,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,MAAM,GAAG,gBAAgB,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAE1E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;QAE9D,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oBAAoB,EAAE,KAAK,IAAI,EAAE;QAClC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;QAE9D,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,CAAC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;QAE3D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;QAE7D,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAE/D,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAE/D,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAEhE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAEhE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -11,11 +11,6 @@ export interface FeatureSummary {
11
11
  description: string;
12
12
  required: boolean;
13
13
  includes: string[];
14
- hasOptions: boolean;
15
- options?: Record<string, {
16
- description: string;
17
- default: boolean;
18
- }>;
19
14
  }
20
15
  export declare function getFeatures(): FeatureSummary[];
21
16
  export declare const getFeaturesToolDefinition: {
@@ -1 +1 @@
1
- {"version":3,"file":"get-features.d.ts","sourceRoot":"","sources":["../../src/tools/get-features.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACrE;AAED,wBAAgB,WAAW,IAAI,cAAc,EAAE,CAa9C;AAED,eAAO,MAAM,yBAAyB;;;;;;kBAqBlB,MAAM,EAAE;;CAE3B,CAAC"}
1
+ {"version":3,"file":"get-features.d.ts","sourceRoot":"","sources":["../../src/tools/get-features.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAgB,WAAW,IAAI,cAAc,EAAE,CAW9C;AAED,eAAO,MAAM,yBAAyB;;;;;;kBAqBlB,MAAM,EAAE;;CAE3B,CAAC"}
@@ -15,8 +15,6 @@ export function getFeatures() {
15
15
  description: feature.description,
16
16
  required: feature.required,
17
17
  includes: feature.includes,
18
- hasOptions: !!feature.options,
19
- options: feature.options,
20
18
  };
21
19
  });
22
20
  }
@@ -1 +1 @@
1
- {"version":3,"file":"get-features.js","sourceRoot":"","sources":["../../src/tools/get-features.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAY7D,MAAM,UAAU,WAAW;IACzB,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAkB,EAAE;QAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC7B,OAAO;YACL,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC;YACd,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO;YAC7B,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE;;;;;;;;;;;;;;;uEAewD;IACrE,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE,EAAE;QACd,QAAQ,EAAE,EAAc;KACzB;CACF,CAAC"}
1
+ {"version":3,"file":"get-features.js","sourceRoot":"","sources":["../../src/tools/get-features.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAU7D,MAAM,UAAU,WAAW;IACzB,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAkB,EAAE;QAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC7B,OAAO;YACL,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC;YACd,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;SAC3B,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE;;;;;;;;;;;;;;;uEAewD;IACrE,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE,EAAE;QACd,QAAQ,EAAE,EAAc;KACzB;CACF,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for get_features tool
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=get-features.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-features.test.d.ts","sourceRoot":"","sources":["../../src/tools/get-features.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Tests for get_features tool
3
+ */
4
+ import { describe, it, expect } from 'vitest';
5
+ import { getFeatures } from './get-features.js';
6
+ import { FEATURE_IDS } from '../features/index.js';
7
+ describe('get_features tool', () => {
8
+ it('returns all feature IDs', () => {
9
+ const features = getFeatures();
10
+ expect(features).toHaveLength(FEATURE_IDS.length);
11
+ expect(features.map((f) => f.id)).toEqual(expect.arrayContaining([...FEATURE_IDS]));
12
+ });
13
+ it('returns core as required', () => {
14
+ const features = getFeatures();
15
+ const core = features.find((f) => f.id === 'core');
16
+ expect(core).toBeDefined();
17
+ expect(core?.required).toBe(true);
18
+ });
19
+ it('returns proper structure for each feature', () => {
20
+ const features = getFeatures();
21
+ for (const feature of features) {
22
+ expect(feature).toHaveProperty('id');
23
+ expect(feature).toHaveProperty('name');
24
+ expect(feature).toHaveProperty('description');
25
+ expect(feature).toHaveProperty('required');
26
+ expect(feature).toHaveProperty('includes');
27
+ expect(Array.isArray(feature.includes)).toBe(true);
28
+ }
29
+ });
30
+ it('mobile feature exists and is not required', () => {
31
+ const features = getFeatures();
32
+ const mobile = features.find((f) => f.id === 'mobile');
33
+ expect(mobile).toBeDefined();
34
+ expect(mobile?.required).toBe(false);
35
+ expect(mobile?.name).toBe('Mobile Support');
36
+ });
37
+ it('theming feature exists and is not required', () => {
38
+ const features = getFeatures();
39
+ const theming = features.find((f) => f.id === 'theming');
40
+ expect(theming).toBeDefined();
41
+ expect(theming?.required).toBe(false);
42
+ expect(theming?.name).toBe('Theming');
43
+ });
44
+ });
45
+ //# sourceMappingURL=get-features.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-features.test.js","sourceRoot":"","sources":["../../src/tools/get-features.test.ts"],"names":[],"mappings":"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"}
@@ -16,9 +16,9 @@ export type GetScaffoldInput = z.infer<typeof getScaffoldSchema>;
16
16
  export declare function getScaffold(input: GetScaffoldInput): Promise<{
17
17
  projectName: string;
18
18
  selectedFeatures: string[];
19
- resolvedFeatures: string[];
19
+ resolvedFeatures: ("core" | "mobile" | "routing" | "ui" | "forms" | "state" | "api" | "i18n" | "testing" | "performance" | "devtools" | "ci" | "observability" | "theming")[];
20
20
  featureDetails: {
21
- id: string;
21
+ id: "core" | "mobile" | "routing" | "ui" | "forms" | "state" | "api" | "i18n" | "testing" | "performance" | "devtools" | "ci" | "observability" | "theming";
22
22
  name: string;
23
23
  wasExplicitlySelected: boolean;
24
24
  wasAutoIncluded: boolean;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for get_scaffold tool
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=get-scaffold.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-scaffold.test.d.ts","sourceRoot":"","sources":["../../src/tools/get-scaffold.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Tests for get_scaffold tool
3
+ */
4
+ import { describe, it, expect } from 'vitest';
5
+ import { getScaffold, getScaffoldSchema } from './get-scaffold.js';
6
+ describe('get_scaffold tool', () => {
7
+ it('always includes core feature', async () => {
8
+ const result = await getScaffold({ features: ['routing'] });
9
+ expect(result.resolvedFeatures).toContain('core');
10
+ });
11
+ it('rejects invalid features via schema', () => {
12
+ const result = getScaffoldSchema.safeParse({
13
+ features: ['invalid-feature'],
14
+ });
15
+ expect(result.success).toBe(false);
16
+ if (!result.success) {
17
+ expect(result.error.message).toContain('Invalid features');
18
+ }
19
+ });
20
+ it('only includes explicitly selected features (plus core)', async () => {
21
+ const result = await getScaffold({ features: ['ui'] });
22
+ expect(result.resolvedFeatures).not.toContain('state');
23
+ expect(result.resolvedFeatures).not.toContain('mobile');
24
+ expect(result.resolvedFeatures).toContain('ui');
25
+ expect(result.resolvedFeatures).toContain('core');
26
+ });
27
+ it('theming feature auto-includes state feature', async () => {
28
+ const result = await getScaffold({ features: ['theming'] });
29
+ expect(result.resolvedFeatures).toContain('theming');
30
+ expect(result.resolvedFeatures).toContain('state');
31
+ expect(result.resolvedFeatures).toContain('core');
32
+ });
33
+ it('marks auto-included features correctly', async () => {
34
+ const result = await getScaffold({ features: ['theming'] });
35
+ const themingDetail = result.featureDetails.find((f) => f.id === 'theming');
36
+ const stateDetail = result.featureDetails.find((f) => f.id === 'state');
37
+ const coreDetail = result.featureDetails.find((f) => f.id === 'core');
38
+ // Theming was explicitly selected
39
+ expect(themingDetail?.wasExplicitlySelected).toBe(true);
40
+ expect(themingDetail?.wasAutoIncluded).toBe(false);
41
+ // State was auto-included (dependency of theming)
42
+ expect(stateDetail?.wasExplicitlySelected).toBe(false);
43
+ expect(stateDetail?.wasAutoIncluded).toBe(true);
44
+ // Core is always auto-included
45
+ expect(coreDetail?.wasExplicitlySelected).toBe(false);
46
+ expect(coreDetail?.wasAutoIncluded).toBe(true);
47
+ });
48
+ it('includes theming files when theming feature is selected', async () => {
49
+ const result = await getScaffold({ features: ['theming'] });
50
+ expect(result.fileStructure).toContain('src/hooks/useThemeEffect.ts');
51
+ expect(result.fileStructure).toContain('src/components/shared/ThemeToggle/ThemeToggle.tsx');
52
+ });
53
+ it('excludes theming files when only ui is selected', async () => {
54
+ const result = await getScaffold({ features: ['ui'] });
55
+ expect(result.fileStructure).not.toContain('src/hooks/useThemeEffect.ts');
56
+ expect(result.fileStructure).not.toContain('src/components/shared/ThemeToggle/ThemeToggle.tsx');
57
+ });
58
+ it('includes mobile files when mobile feature is selected', async () => {
59
+ const result = await getScaffold({ features: ['mobile'] });
60
+ expect(result.fileStructure).toContain('src/contexts/mobileContext.tsx');
61
+ expect(result.fileStructure).toContain('src/hooks/useMediaQuery.ts');
62
+ expect(result.fileStructure).toContain('src/hooks/useTouchSizes.ts');
63
+ });
64
+ it('excludes mobile files when only core is selected', async () => {
65
+ const result = await getScaffold({ features: [] });
66
+ expect(result.fileStructure).not.toContain('src/contexts/mobileContext.tsx');
67
+ expect(result.fileStructure).not.toContain('src/hooks/useMediaQuery.ts');
68
+ });
69
+ it('returns valid package.json structure', async () => {
70
+ const result = await getScaffold({ features: ['routing'], projectName: 'test-app' });
71
+ expect(result.packageJson).toBeDefined();
72
+ expect(result.packageJson.name).toBe('test-app');
73
+ expect(result.packageJson.dependencies).toBeDefined();
74
+ expect(result.packageJson.devDependencies).toBeDefined();
75
+ expect(result.packageJson.scripts).toBeDefined();
76
+ });
77
+ it('includes react in core dependencies', async () => {
78
+ const result = await getScaffold({ features: [] });
79
+ expect(result.packageJson.dependencies).toHaveProperty('react');
80
+ expect(result.packageJson.dependencies).toHaveProperty('react-dom');
81
+ });
82
+ it('includes routing dependencies when routing feature selected', async () => {
83
+ const result = await getScaffold({ features: ['routing'] });
84
+ expect(result.packageJson.dependencies).toHaveProperty('react-router');
85
+ });
86
+ it('returns file structure', async () => {
87
+ const result = await getScaffold({ features: ['routing'] });
88
+ expect(Array.isArray(result.fileStructure)).toBe(true);
89
+ expect(result.fileStructure.length).toBeGreaterThan(0);
90
+ });
91
+ it('returns setup commands', async () => {
92
+ const result = await getScaffold({ features: ['routing'] });
93
+ expect(Array.isArray(result.setupCommands)).toBe(true);
94
+ expect(result.setupCommands).toContain('npm install');
95
+ });
96
+ it('uses default project name when not provided', async () => {
97
+ const result = await getScaffold({ features: [] });
98
+ expect(result.projectName).toBe('my-app');
99
+ });
100
+ it('marks explicitly selected features correctly', async () => {
101
+ const result = await getScaffold({ features: ['ui', 'state'] });
102
+ const stateDetail = result.featureDetails.find((f) => f.id === 'state');
103
+ const uiDetail = result.featureDetails.find((f) => f.id === 'ui');
104
+ expect(stateDetail?.wasExplicitlySelected).toBe(true);
105
+ expect(stateDetail?.wasAutoIncluded).toBe(false);
106
+ expect(uiDetail?.wasExplicitlySelected).toBe(true);
107
+ expect(uiDetail?.wasAutoIncluded).toBe(false);
108
+ });
109
+ it('includes CLAUDE.md in file structure', async () => {
110
+ const result = await getScaffold({ features: [] });
111
+ expect(result.fileStructure).toContain('CLAUDE.md');
112
+ });
113
+ it('returns claudeMd content', async () => {
114
+ const result = await getScaffold({ features: [], projectName: 'test-project' });
115
+ expect(result.claudeMd).toBeDefined();
116
+ expect(typeof result.claudeMd).toBe('string');
117
+ expect(result.claudeMd).toContain('# CLAUDE.md');
118
+ expect(result.claudeMd).toContain('test-project');
119
+ });
120
+ it('claudeMd includes testing section when testing feature selected', async () => {
121
+ const result = await getScaffold({ features: ['testing'] });
122
+ expect(result.claudeMd).toContain('## Testing');
123
+ expect(result.claudeMd).toContain('Vitest');
124
+ });
125
+ it('claudeMd excludes testing section when testing feature not selected', async () => {
126
+ const result = await getScaffold({ features: [] });
127
+ expect(result.claudeMd).not.toContain('## Testing');
128
+ });
129
+ it('claudeMd includes UI section only when ui feature selected', async () => {
130
+ const withUi = await getScaffold({ features: ['ui'] });
131
+ const withoutUi = await getScaffold({ features: [] });
132
+ expect(withUi.claudeMd).toContain('## UI Components');
133
+ expect(withoutUi.claudeMd).not.toContain('## UI Components');
134
+ });
135
+ it('claudeMd includes i18n section only when i18n feature selected', async () => {
136
+ const withI18n = await getScaffold({ features: ['i18n'] });
137
+ const withoutI18n = await getScaffold({ features: [] });
138
+ expect(withI18n.claudeMd).toContain('## Translations');
139
+ expect(withoutI18n.claudeMd).not.toContain('## Translations');
140
+ });
141
+ it('claudeMd includes mobile section only when mobile feature selected', async () => {
142
+ const withMobile = await getScaffold({ features: ['mobile'] });
143
+ const withoutMobile = await getScaffold({ features: [] });
144
+ expect(withMobile.claudeMd).toContain('## Mobile & Responsive Design');
145
+ expect(withMobile.claudeMd).toContain('MobileProvider');
146
+ expect(withoutMobile.claudeMd).not.toContain('## Mobile & Responsive Design');
147
+ });
148
+ it('claudeMd includes theming section only when theming feature selected', async () => {
149
+ const withTheming = await getScaffold({ features: ['theming'] });
150
+ const withoutTheming = await getScaffold({ features: [] });
151
+ expect(withTheming.claudeMd).toContain('## Theming');
152
+ expect(withTheming.claudeMd).toContain('usePreferencesStore');
153
+ expect(withoutTheming.claudeMd).not.toContain('## Theming');
154
+ });
155
+ it('claudeMd project structure shows contexts when mobile is selected', async () => {
156
+ const withMobile = await getScaffold({ features: ['mobile'] });
157
+ const withoutMobile = await getScaffold({ features: [] });
158
+ expect(withMobile.claudeMd).toContain('contexts/');
159
+ expect(withoutMobile.claudeMd).not.toContain('contexts/');
160
+ });
161
+ it('returns config files with content', async () => {
162
+ const result = await getScaffold({ features: ['ui'] });
163
+ expect(typeof result.configFiles).toBe('object');
164
+ expect(result.configFiles).toHaveProperty('components.json');
165
+ });
166
+ it('includes radix-nova style in components.json', async () => {
167
+ const result = await getScaffold({ features: ['ui'] });
168
+ const componentsJson = JSON.parse(result.configFiles['components.json']);
169
+ expect(componentsJson.style).toBe('radix-nova');
170
+ });
171
+ it('always includes .gitignore in fileStructure (core feature)', async () => {
172
+ const result = await getScaffold({ features: [] });
173
+ expect(result.fileStructure).toContain('.gitignore');
174
+ });
175
+ it('always includes .gitignore content in configFiles', async () => {
176
+ const result = await getScaffold({ features: [] });
177
+ expect(result.configFiles).toHaveProperty('.gitignore');
178
+ expect(result.configFiles['.gitignore']).toContain('node_modules');
179
+ expect(result.configFiles['.gitignore']).toContain('dist/');
180
+ });
181
+ it('includes docs in structure and content', async () => {
182
+ const result = await getScaffold({ features: [] });
183
+ expect(result.fileStructure).toContain('docs/ARCHITECTURE.md');
184
+ expect(result.fileStructure).not.toContain('docs/TESTING.md');
185
+ expect(result.docs['docs/ARCHITECTURE.md']).toBeDefined();
186
+ expect(result.docs['docs/TESTING.md']).toBeUndefined();
187
+ });
188
+ it('adds feature-specific docs when feature selected', async () => {
189
+ const result = await getScaffold({ features: ['testing'] });
190
+ expect(result.fileStructure).toContain('docs/TESTING.md');
191
+ expect(result.docs['docs/TESTING.md']).toContain('# Testing Guidelines');
192
+ });
193
+ });
194
+ //# sourceMappingURL=get-scaffold.test.js.map