@react-spa-scaffold/mcp 1.2.1 → 2.1.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 (161) hide show
  1. package/README.md +39 -127
  2. package/dist/features/definitions/api.d.ts.map +1 -1
  3. package/dist/features/definitions/api.js +1 -11
  4. package/dist/features/definitions/api.js.map +1 -1
  5. package/dist/features/definitions/ci.d.ts.map +1 -1
  6. package/dist/features/definitions/ci.js +0 -11
  7. package/dist/features/definitions/ci.js.map +1 -1
  8. package/dist/features/definitions/core.d.ts.map +1 -1
  9. package/dist/features/definitions/core.js +2 -15
  10. package/dist/features/definitions/core.js.map +1 -1
  11. package/dist/features/definitions/devtools.d.ts.map +1 -1
  12. package/dist/features/definitions/devtools.js +1 -15
  13. package/dist/features/definitions/devtools.js.map +1 -1
  14. package/dist/features/definitions/forms.d.ts.map +1 -1
  15. package/dist/features/definitions/forms.js +1 -10
  16. package/dist/features/definitions/forms.js.map +1 -1
  17. package/dist/features/definitions/i18n.d.ts.map +1 -1
  18. package/dist/features/definitions/i18n.js +2 -15
  19. package/dist/features/definitions/i18n.js.map +1 -1
  20. package/dist/features/definitions/mobile.d.ts.map +1 -1
  21. package/dist/features/definitions/mobile.js +0 -10
  22. package/dist/features/definitions/mobile.js.map +1 -1
  23. package/dist/features/definitions/observability.d.ts.map +1 -1
  24. package/dist/features/definitions/observability.js +2 -13
  25. package/dist/features/definitions/observability.js.map +1 -1
  26. package/dist/features/definitions/performance.d.ts.map +1 -1
  27. package/dist/features/definitions/performance.js +2 -14
  28. package/dist/features/definitions/performance.js.map +1 -1
  29. package/dist/features/definitions/routing.d.ts.map +1 -1
  30. package/dist/features/definitions/routing.js +1 -10
  31. package/dist/features/definitions/routing.js.map +1 -1
  32. package/dist/features/definitions/state.d.ts.map +1 -1
  33. package/dist/features/definitions/state.js +1 -12
  34. package/dist/features/definitions/state.js.map +1 -1
  35. package/dist/features/definitions/testing.d.ts.map +1 -1
  36. package/dist/features/definitions/testing.js +1 -17
  37. package/dist/features/definitions/testing.js.map +1 -1
  38. package/dist/features/definitions/theming.d.ts.map +1 -1
  39. package/dist/features/definitions/theming.js +0 -9
  40. package/dist/features/definitions/theming.js.map +1 -1
  41. package/dist/features/definitions/ui.d.ts.map +1 -1
  42. package/dist/features/definitions/ui.js +2 -16
  43. package/dist/features/definitions/ui.js.map +1 -1
  44. package/dist/features/types.d.ts +2 -4
  45. package/dist/features/types.d.ts.map +1 -1
  46. package/dist/server.js +6 -6
  47. package/dist/tools/add-features.d.ts +44 -0
  48. package/dist/tools/add-features.d.ts.map +1 -0
  49. package/dist/tools/add-features.js +157 -0
  50. package/dist/tools/add-features.js.map +1 -0
  51. package/dist/tools/add-features.test.d.ts +5 -0
  52. package/dist/tools/add-features.test.d.ts.map +1 -0
  53. package/dist/tools/add-features.test.js +170 -0
  54. package/dist/tools/add-features.test.js.map +1 -0
  55. package/dist/tools/get-features.d.ts +1 -2
  56. package/dist/tools/get-features.d.ts.map +1 -1
  57. package/dist/tools/get-features.js +1 -2
  58. package/dist/tools/get-features.js.map +1 -1
  59. package/dist/tools/get-features.test.js +6 -2
  60. package/dist/tools/get-features.test.js.map +1 -1
  61. package/dist/tools/get-file.d.ts +1 -1
  62. package/dist/tools/get-file.d.ts.map +1 -1
  63. package/dist/tools/get-file.js +12 -8
  64. package/dist/tools/get-file.js.map +1 -1
  65. package/dist/tools/get-scaffold.d.ts +3 -4
  66. package/dist/tools/get-scaffold.d.ts.map +1 -1
  67. package/dist/tools/get-scaffold.js +58 -29
  68. package/dist/tools/get-scaffold.js.map +1 -1
  69. package/dist/tools/get-scaffold.test.js +25 -10
  70. package/dist/tools/get-scaffold.test.js.map +1 -1
  71. package/dist/tools/index.d.ts +2 -1
  72. package/dist/tools/index.d.ts.map +1 -1
  73. package/dist/tools/index.js +2 -1
  74. package/dist/tools/index.js.map +1 -1
  75. package/dist/tools/registry.js +8 -8
  76. package/dist/tools/registry.js.map +1 -1
  77. package/dist/utils/index.d.ts +0 -1
  78. package/dist/utils/index.d.ts.map +1 -1
  79. package/dist/utils/index.js +0 -1
  80. package/dist/utils/index.js.map +1 -1
  81. package/dist/utils/scaffold/compute.js +1 -1
  82. package/dist/utils/scaffold/compute.js.map +1 -1
  83. package/dist/utils/scaffold/dependencies.d.ts +15 -2
  84. package/dist/utils/scaffold/dependencies.d.ts.map +1 -1
  85. package/dist/utils/scaffold/dependencies.js +15 -8
  86. package/dist/utils/scaffold/dependencies.js.map +1 -1
  87. package/dist/utils/scaffold/file-structure.d.ts +12 -0
  88. package/dist/utils/scaffold/file-structure.d.ts.map +1 -1
  89. package/dist/utils/scaffold/file-structure.js +23 -0
  90. package/dist/utils/scaffold/file-structure.js.map +1 -1
  91. package/dist/utils/scaffold/generators.d.ts.map +1 -1
  92. package/dist/utils/scaffold/generators.js +10 -0
  93. package/dist/utils/scaffold/generators.js.map +1 -1
  94. package/dist/utils/scaffold/index.d.ts +3 -2
  95. package/dist/utils/scaffold/index.d.ts.map +1 -1
  96. package/dist/utils/scaffold/index.js +1 -1
  97. package/dist/utils/scaffold/index.js.map +1 -1
  98. package/package.json +1 -1
  99. package/templates/e2e/tests/language.spec.ts +2 -1
  100. package/templates/src/contexts/queryContext.tsx +1 -2
  101. package/templates/src/lib/storage.ts +1 -1
  102. package/dist/tools/get-example.d.ts +0 -38
  103. package/dist/tools/get-example.d.ts.map +0 -1
  104. package/dist/tools/get-example.js +0 -83
  105. package/dist/tools/get-example.js.map +0 -1
  106. package/dist/tools/get-example.test.d.ts +0 -5
  107. package/dist/tools/get-example.test.d.ts.map +0 -1
  108. package/dist/tools/get-example.test.js +0 -63
  109. package/dist/tools/get-example.test.js.map +0 -1
  110. package/dist/utils/examples/api-patterns.d.ts +0 -3
  111. package/dist/utils/examples/api-patterns.d.ts.map +0 -1
  112. package/dist/utils/examples/api-patterns.js +0 -19
  113. package/dist/utils/examples/api-patterns.js.map +0 -1
  114. package/dist/utils/examples/component-patterns.d.ts +0 -3
  115. package/dist/utils/examples/component-patterns.d.ts.map +0 -1
  116. package/dist/utils/examples/component-patterns.js +0 -71
  117. package/dist/utils/examples/component-patterns.js.map +0 -1
  118. package/dist/utils/examples/context-patterns.d.ts +0 -3
  119. package/dist/utils/examples/context-patterns.d.ts.map +0 -1
  120. package/dist/utils/examples/context-patterns.js +0 -32
  121. package/dist/utils/examples/context-patterns.js.map +0 -1
  122. package/dist/utils/examples/hook-patterns.d.ts +0 -3
  123. package/dist/utils/examples/hook-patterns.d.ts.map +0 -1
  124. package/dist/utils/examples/hook-patterns.js +0 -55
  125. package/dist/utils/examples/hook-patterns.js.map +0 -1
  126. package/dist/utils/examples/i18n-patterns.d.ts +0 -3
  127. package/dist/utils/examples/i18n-patterns.d.ts.map +0 -1
  128. package/dist/utils/examples/i18n-patterns.js +0 -43
  129. package/dist/utils/examples/i18n-patterns.js.map +0 -1
  130. package/dist/utils/examples/index.d.ts +0 -12
  131. package/dist/utils/examples/index.d.ts.map +0 -1
  132. package/dist/utils/examples/index.js +0 -65
  133. package/dist/utils/examples/index.js.map +0 -1
  134. package/dist/utils/examples/mobile-patterns.d.ts +0 -3
  135. package/dist/utils/examples/mobile-patterns.d.ts.map +0 -1
  136. package/dist/utils/examples/mobile-patterns.js +0 -38
  137. package/dist/utils/examples/mobile-patterns.js.map +0 -1
  138. package/dist/utils/examples/page-patterns.d.ts +0 -3
  139. package/dist/utils/examples/page-patterns.d.ts.map +0 -1
  140. package/dist/utils/examples/page-patterns.js +0 -34
  141. package/dist/utils/examples/page-patterns.js.map +0 -1
  142. package/dist/utils/examples/patterns.test.d.ts +0 -6
  143. package/dist/utils/examples/patterns.test.d.ts.map +0 -1
  144. package/dist/utils/examples/patterns.test.js +0 -75
  145. package/dist/utils/examples/patterns.test.js.map +0 -1
  146. package/dist/utils/examples/store-patterns.d.ts +0 -3
  147. package/dist/utils/examples/store-patterns.d.ts.map +0 -1
  148. package/dist/utils/examples/store-patterns.js +0 -40
  149. package/dist/utils/examples/store-patterns.js.map +0 -1
  150. package/dist/utils/examples/test-patterns.d.ts +0 -3
  151. package/dist/utils/examples/test-patterns.d.ts.map +0 -1
  152. package/dist/utils/examples/test-patterns.js +0 -58
  153. package/dist/utils/examples/test-patterns.js.map +0 -1
  154. package/dist/utils/examples/types.d.ts +0 -17
  155. package/dist/utils/examples/types.d.ts.map +0 -1
  156. package/dist/utils/examples/types.js +0 -2
  157. package/dist/utils/examples/types.js.map +0 -1
  158. package/dist/utils/examples/utility-patterns.d.ts +0 -3
  159. package/dist/utils/examples/utility-patterns.d.ts.map +0 -1
  160. package/dist/utils/examples/utility-patterns.js +0 -77
  161. package/dist/utils/examples/utility-patterns.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"routing.js","sourceRoot":"","sources":["../../../src/features/definitions/routing.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,OAAO,GAAY;IAC9B,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,sDAAsD;IACnE,QAAQ,EAAE,KAAK;IACf,QAAQ,EAAE;QACR,gBAAgB;QAChB,qCAAqC;QACrC,qEAAqE;QACrE,oBAAoB;QACpB,gCAAgC;QAChC,uCAAuC;KACxC;IACD,eAAe,EAAE,CAAC,cAAc,CAAC;IACjC,KAAK,EAAE;QACL,oBAAoB;QACpB,wBAAwB;QACxB,oBAAoB;QACpB,+BAA+B;QAC/B,uCAAuC;KACxC;IACD,SAAS,EAAE,CAAC,8BAA8B,CAAC;IAC3C,QAAQ,EAAE,CAAC,WAAW,EAAE,iBAAiB,EAAE,gBAAgB,CAAC;IAC5D,OAAO,EAAE,EAAE;CACZ,CAAC"}
1
+ {"version":3,"file":"routing.js","sourceRoot":"","sources":["../../../src/features/definitions/routing.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,OAAO,GAAY;IAC9B,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,sDAAsD;IACnE,QAAQ,EAAE,KAAK;IACf,YAAY,EAAE,CAAC,cAAc,CAAC;IAC9B,KAAK,EAAE;QACL,oBAAoB;QACpB,wBAAwB;QACxB,oBAAoB;QACpB,+BAA+B;QAC/B,uCAAuC;KACxC;IACD,SAAS,EAAE,CAAC,8BAA8B,CAAC;IAC3C,OAAO,EAAE,EAAE;CACZ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/features/definitions/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,eAAO,MAAM,KAAK,EAAE,OAyBnB,CAAC"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/features/definitions/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,eAAO,MAAM,KAAK,EAAE,OAcnB,CAAC"}
@@ -2,17 +2,7 @@ export const state = {
2
2
  name: 'State Management',
3
3
  description: 'Zustand with persistence, devtools, and multi-tab sync',
4
4
  required: false,
5
- includes: [
6
- 'Zustand store',
7
- 'Persist middleware (localStorage)',
8
- 'Devtools middleware',
9
- 'Multi-tab sync utility (initPreferencesSync)',
10
- 'Storage utilities (get/set/remove/clear)',
11
- 'Prefixed storage keys',
12
- 'Example preferences store (theme)',
13
- 'Type-safe store selectors',
14
- ],
15
- dependencyNames: ['zustand'],
5
+ dependencies: ['zustand'],
16
6
  files: [
17
7
  'src/stores/preferencesStore.ts',
18
8
  'src/stores/index.ts',
@@ -21,7 +11,6 @@ export const state = {
21
11
  'src/types/preferences.ts',
22
12
  ],
23
13
  testFiles: ['src/lib/storage.test.ts', 'src/stores/preferencesStore.test.ts'],
24
- patterns: ['zustand-store', 'store-persistence', 'multi-tab-sync', 'storage-utility'],
25
14
  scripts: {},
26
15
  };
27
16
  //# sourceMappingURL=state.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/features/definitions/state.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,KAAK,GAAY;IAC5B,IAAI,EAAE,kBAAkB;IACxB,WAAW,EAAE,wDAAwD;IACrE,QAAQ,EAAE,KAAK;IACf,QAAQ,EAAE;QACR,eAAe;QACf,mCAAmC;QACnC,qBAAqB;QACrB,8CAA8C;QAC9C,0CAA0C;QAC1C,uBAAuB;QACvB,mCAAmC;QACnC,2BAA2B;KAC5B;IACD,eAAe,EAAE,CAAC,SAAS,CAAC;IAC5B,KAAK,EAAE;QACL,gCAAgC;QAChC,qBAAqB;QACrB,oBAAoB;QACpB,wBAAwB;QACxB,0BAA0B;KAC3B;IACD,SAAS,EAAE,CAAC,yBAAyB,EAAE,qCAAqC,CAAC;IAC7E,QAAQ,EAAE,CAAC,eAAe,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,iBAAiB,CAAC;IACrF,OAAO,EAAE,EAAE;CACZ,CAAC"}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/features/definitions/state.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,KAAK,GAAY;IAC5B,IAAI,EAAE,kBAAkB;IACxB,WAAW,EAAE,wDAAwD;IACrE,QAAQ,EAAE,KAAK;IACf,YAAY,EAAE,CAAC,SAAS,CAAC;IACzB,KAAK,EAAE;QACL,gCAAgC;QAChC,qBAAqB;QACrB,oBAAoB;QACpB,wBAAwB;QACxB,0BAA0B;KAC3B;IACD,SAAS,EAAE,CAAC,yBAAyB,EAAE,qCAAqC,CAAC;IAC7E,OAAO,EAAE,EAAE;CACZ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../../src/features/definitions/testing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,eAAO,MAAM,OAAO,EAAE,OAsDrB,CAAC"}
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../../src/features/definitions/testing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,eAAO,MAAM,OAAO,EAAE,OAsCrB,CAAC"}
@@ -2,20 +2,7 @@ export const testing = {
2
2
  name: 'Testing',
3
3
  description: 'Vitest + Testing Library + Playwright + MSW',
4
4
  required: false,
5
- includes: [
6
- 'Vitest for unit testing',
7
- 'React Testing Library',
8
- '@testing-library/user-event for interactions',
9
- 'Playwright for E2E testing (Chromium)',
10
- 'MSW (Mock Service Worker) for API mocking',
11
- 'Test utilities (render, providers, mocks)',
12
- '80% coverage threshold (lines, functions, statements, branches)',
13
- 'jsdom environment',
14
- 'Example tests for components, hooks, stores, utilities',
15
- 'MSW handlers for API endpoints',
16
- 'Test fixtures for mock data',
17
- ],
18
- devDependencyNames: [
5
+ devDependencies: [
19
6
  '@playwright/test',
20
7
  '@testing-library/jest-dom',
21
8
  '@testing-library/react',
@@ -40,10 +27,7 @@ export const testing = {
40
27
  'e2e/tests/',
41
28
  'vitest.config.ts',
42
29
  'playwright.config.ts',
43
- 'docs/TESTING.md',
44
- 'docs/E2E_TESTING.md',
45
30
  ],
46
- patterns: ['test-component', 'test-hook', 'test-store', 'test-utility', 'msw-handler', 'test-fixture'],
47
31
  scripts: {
48
32
  test: 'vitest run',
49
33
  'test:watch': 'vitest',
@@ -1 +1 @@
1
- {"version":3,"file":"testing.js","sourceRoot":"","sources":["../../../src/features/definitions/testing.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,OAAO,GAAY;IAC9B,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,6CAA6C;IAC1D,QAAQ,EAAE,KAAK;IACf,QAAQ,EAAE;QACR,yBAAyB;QACzB,uBAAuB;QACvB,8CAA8C;QAC9C,uCAAuC;QACvC,2CAA2C;QAC3C,2CAA2C;QAC3C,iEAAiE;QACjE,mBAAmB;QACnB,wDAAwD;QACxD,gCAAgC;QAChC,6BAA6B;KAC9B;IACD,kBAAkB,EAAE;QAClB,kBAAkB;QAClB,2BAA2B;QAC3B,wBAAwB;QACxB,6BAA6B;QAC7B,qBAAqB;QACrB,OAAO;QACP,KAAK;QACL,QAAQ;KACT;IACD,KAAK,EAAE;QACL,mBAAmB;QACnB,mBAAmB;QACnB,wBAAwB;QACxB,mBAAmB;QACnB,6BAA6B;QAC7B,6BAA6B;QAC7B,6BAA6B;QAC7B,6BAA6B;QAC7B,mBAAmB;QACnB,oBAAoB;QACpB,eAAe;QACf,YAAY;QACZ,kBAAkB;QAClB,sBAAsB;QACtB,iBAAiB;QACjB,qBAAqB;KACtB;IACD,QAAQ,EAAE,CAAC,gBAAgB,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,CAAC;IACtG,OAAO,EAAE;QACP,IAAI,EAAE,YAAY;QAClB,YAAY,EAAE,QAAQ;QACtB,eAAe,EAAE,uBAAuB;QACxC,GAAG,EAAE,sCAAsC;QAC3C,QAAQ,EAAE,2CAA2C;KACtD;IACD,WAAW,EAAE,CAAC,kBAAkB,EAAE,sBAAsB,EAAE,mBAAmB,CAAC;CAC/E,CAAC"}
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../../../src/features/definitions/testing.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,OAAO,GAAY;IAC9B,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,6CAA6C;IAC1D,QAAQ,EAAE,KAAK;IACf,eAAe,EAAE;QACf,kBAAkB;QAClB,2BAA2B;QAC3B,wBAAwB;QACxB,6BAA6B;QAC7B,qBAAqB;QACrB,OAAO;QACP,KAAK;QACL,QAAQ;KACT;IACD,KAAK,EAAE;QACL,mBAAmB;QACnB,mBAAmB;QACnB,wBAAwB;QACxB,mBAAmB;QACnB,6BAA6B;QAC7B,6BAA6B;QAC7B,6BAA6B;QAC7B,6BAA6B;QAC7B,mBAAmB;QACnB,oBAAoB;QACpB,eAAe;QACf,YAAY;QACZ,kBAAkB;QAClB,sBAAsB;KACvB;IACD,OAAO,EAAE;QACP,IAAI,EAAE,YAAY;QAClB,YAAY,EAAE,QAAQ;QACtB,eAAe,EAAE,uBAAuB;QACxC,GAAG,EAAE,sCAAsC;QAC3C,QAAQ,EAAE,2CAA2C;KACtD;IACD,WAAW,EAAE,CAAC,kBAAkB,EAAE,sBAAsB,EAAE,mBAAmB,CAAC;CAC/E,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"theming.d.ts","sourceRoot":"","sources":["../../../src/features/definitions/theming.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,eAAO,MAAM,OAAO,EAAE,OAyBrB,CAAC"}
1
+ {"version":3,"file":"theming.d.ts","sourceRoot":"","sources":["../../../src/features/definitions/theming.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,eAAO,MAAM,OAAO,EAAE,OAgBrB,CAAC"}
@@ -3,14 +3,6 @@ export const theming = {
3
3
  description: 'Light/dark/system theme toggle with CSS variables',
4
4
  required: false,
5
5
  requires: ['state'], // Needs Zustand for persistence
6
- includes: [
7
- 'Light/dark/system theme modes',
8
- 'useThemeEffect hook (applies .dark class to document)',
9
- 'ThemeToggle component',
10
- 'System preference detection (prefers-color-scheme)',
11
- 'Zustand persistence via preferencesStore',
12
- 'Multi-tab sync via storage events',
13
- ],
14
6
  files: [
15
7
  'src/hooks/useThemeEffect.ts',
16
8
  'src/components/shared/ThemeToggle/ThemeToggle.tsx',
@@ -21,7 +13,6 @@ export const theming = {
21
13
  'src/components/shared/ThemeToggle/ThemeToggle.test.tsx',
22
14
  'e2e/tests/theme.spec.ts',
23
15
  ],
24
- patterns: ['theme-toggle', 'hook-effect'],
25
16
  scripts: {},
26
17
  };
27
18
  //# sourceMappingURL=theming.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"theming.js","sourceRoot":"","sources":["../../../src/features/definitions/theming.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,OAAO,GAAY;IAC9B,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,mDAAmD;IAChE,QAAQ,EAAE,KAAK;IACf,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,gCAAgC;IACrD,QAAQ,EAAE;QACR,+BAA+B;QAC/B,uDAAuD;QACvD,uBAAuB;QACvB,oDAAoD;QACpD,0CAA0C;QAC1C,mCAAmC;KACpC;IACD,KAAK,EAAE;QACL,6BAA6B;QAC7B,mDAAmD;QACnD,4CAA4C;KAC7C;IACD,SAAS,EAAE;QACT,kCAAkC;QAClC,wDAAwD;QACxD,yBAAyB;KAC1B;IACD,QAAQ,EAAE,CAAC,cAAc,EAAE,aAAa,CAAC;IACzC,OAAO,EAAE,EAAE;CACZ,CAAC"}
1
+ {"version":3,"file":"theming.js","sourceRoot":"","sources":["../../../src/features/definitions/theming.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,OAAO,GAAY;IAC9B,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,mDAAmD;IAChE,QAAQ,EAAE,KAAK;IACf,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,gCAAgC;IACrD,KAAK,EAAE;QACL,6BAA6B;QAC7B,mDAAmD;QACnD,4CAA4C;KAC7C;IACD,SAAS,EAAE;QACT,kCAAkC;QAClC,wDAAwD;QACxD,yBAAyB;KAC1B;IACD,OAAO,EAAE,EAAE;CACZ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../../src/features/definitions/ui.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,eAAO,MAAM,EAAE,EAAE,OA0ChB,CAAC"}
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../../src/features/definitions/ui.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,eAAO,MAAM,EAAE,EAAE,OA4BhB,CAAC"}
@@ -2,20 +2,7 @@ export const ui = {
2
2
  name: 'UI Components',
3
3
  description: 'Shadcn/UI + icons + animations + toasts',
4
4
  required: false,
5
- includes: [
6
- 'Shadcn/UI component system (radix-nova style)',
7
- 'Radix UI primitives',
8
- 'CVA (class-variance-authority) for variants',
9
- 'Lucide React icons',
10
- 'tw-animate-css for animations',
11
- 'Sonner toast notifications',
12
- 'Button with variants (default, destructive, outline, etc.)',
13
- 'DropdownMenu component',
14
- 'Loading, Skeleton, Spinner components',
15
- 'VisuallyHidden and SkipLink (accessibility)',
16
- 'components.json for shadcn CLI',
17
- ],
18
- dependencyNames: [
5
+ dependencies: [
19
6
  '@radix-ui/react-slot',
20
7
  'class-variance-authority',
21
8
  'lucide-react',
@@ -23,7 +10,7 @@ export const ui = {
23
10
  'sonner',
24
11
  'tw-animate-css',
25
12
  ],
26
- devDependencyNames: ['shadcn'],
13
+ devDependencies: ['shadcn'],
27
14
  files: [
28
15
  'src/components/ui/button.tsx',
29
16
  'src/components/ui/dropdown-menu.tsx',
@@ -37,7 +24,6 @@ export const ui = {
37
24
  'components.json',
38
25
  ],
39
26
  testFiles: ['src/components/ui/loading.test.tsx', 'src/components/layout/Header.test.tsx'],
40
- patterns: ['component-ui', 'button-variants', 'forward-ref-component'],
41
27
  scripts: {},
42
28
  configFiles: ['components.json'],
43
29
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../src/features/definitions/ui.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,EAAE,GAAY;IACzB,IAAI,EAAE,eAAe;IACrB,WAAW,EAAE,yCAAyC;IACtD,QAAQ,EAAE,KAAK;IACf,QAAQ,EAAE;QACR,+CAA+C;QAC/C,qBAAqB;QACrB,6CAA6C;QAC7C,oBAAoB;QACpB,+BAA+B;QAC/B,4BAA4B;QAC5B,4DAA4D;QAC5D,wBAAwB;QACxB,uCAAuC;QACvC,6CAA6C;QAC7C,gCAAgC;KACjC;IACD,eAAe,EAAE;QACf,sBAAsB;QACtB,0BAA0B;QAC1B,cAAc;QACd,UAAU;QACV,QAAQ;QACR,gBAAgB;KACjB;IACD,kBAAkB,EAAE,CAAC,QAAQ,CAAC;IAC9B,KAAK,EAAE;QACL,8BAA8B;QAC9B,qCAAqC;QACrC,+BAA+B;QAC/B,gCAAgC;QAChC,+BAA+B;QAC/B,8BAA8B;QAC9B,uCAAuC;QACvC,kCAAkC;QAClC,gCAAgC;QAChC,iBAAiB;KAClB;IACD,SAAS,EAAE,CAAC,oCAAoC,EAAE,uCAAuC,CAAC;IAC1F,QAAQ,EAAE,CAAC,cAAc,EAAE,iBAAiB,EAAE,uBAAuB,CAAC;IACtE,OAAO,EAAE,EAAE;IACX,WAAW,EAAE,CAAC,iBAAiB,CAAC;CACjC,CAAC"}
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../src/features/definitions/ui.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,EAAE,GAAY;IACzB,IAAI,EAAE,eAAe;IACrB,WAAW,EAAE,yCAAyC;IACtD,QAAQ,EAAE,KAAK;IACf,YAAY,EAAE;QACZ,sBAAsB;QACtB,0BAA0B;QAC1B,cAAc;QACd,UAAU;QACV,QAAQ;QACR,gBAAgB;KACjB;IACD,eAAe,EAAE,CAAC,QAAQ,CAAC;IAC3B,KAAK,EAAE;QACL,8BAA8B;QAC9B,qCAAqC;QACrC,+BAA+B;QAC/B,gCAAgC;QAChC,+BAA+B;QAC/B,8BAA8B;QAC9B,uCAAuC;QACvC,kCAAkC;QAClC,gCAAgC;QAChC,iBAAiB;KAClB;IACD,SAAS,EAAE,CAAC,oCAAoC,EAAE,uCAAuC,CAAC;IAC1F,OAAO,EAAE,EAAE;IACX,WAAW,EAAE,CAAC,iBAAiB,CAAC;CACjC,CAAC"}
@@ -12,16 +12,14 @@ export interface Feature {
12
12
  name: string;
13
13
  description: string;
14
14
  required: boolean;
15
- includes: string[];
16
15
  /** Other features this feature depends on (auto-included when this feature is selected). */
17
16
  requires?: FeatureId[];
18
17
  /** Dependency package names - versions resolved from package.json at runtime. */
19
- dependencyNames?: string[];
20
- devDependencyNames?: string[];
18
+ dependencies?: string[];
19
+ devDependencies?: string[];
21
20
  files: string[];
22
21
  /** Test files - only included when 'testing' feature is also selected. */
23
22
  testFiles?: string[];
24
- patterns: string[];
25
23
  scripts?: Record<string, string>;
26
24
  configFiles?: string[];
27
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/features/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,oFAAoF;AACpF,eAAO,MAAM,WAAW,EAA6B,SAAS,SAAS,EAAE,CAAC;AAE1E,oCAAoC;AACpC,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,OAAO,OAAO,CAAC,CAAC;AAE/D,4DAA4D;AAC5D,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,SAAS,CAE7D;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAC;IACvB,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,8DAA8D;AAC9D,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACxC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACjC,CAAC;IACF,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,wDAAwD;IACxD,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/features/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,oFAAoF;AACpF,eAAO,MAAM,WAAW,EAA6B,SAAS,SAAS,EAAE,CAAC;AAE1E,oCAAoC;AACpC,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,OAAO,OAAO,CAAC,CAAC;AAE/D,4DAA4D;AAC5D,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,SAAS,CAE7D;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAC;IACvB,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,8DAA8D;AAC9D,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACxC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACjC,CAAC;IACF,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,wDAAwD;IACxD,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB"}
package/dist/server.js CHANGED
@@ -22,16 +22,16 @@ const SERVER_INSTRUCTIONS = `
22
22
  react-spa-scaffold MCP Server - Project Scaffolding Assistant
23
23
 
24
24
  Usage:
25
- 1. Call get_features to see available feature modules
26
- 2. Call get_scaffold with desired features to get project structure
27
- 3. Call get_example to get code patterns for specific file types
28
- 4. Read docs:// resources for conventions and best practices
25
+ 1. get_features - list available feature modules
26
+ 2. get_scaffold - get project structure (paths only)
27
+ 3. get_file - fetch content for EACH file
28
+
29
+ CRITICAL: Do not generate files. Fetch via get_file, then strip unselected features.
29
30
 
30
31
  Tips:
31
32
  - Core feature is always included automatically
32
- - Features are mostly independent - select only what you need
33
33
  - Theming feature automatically includes state (requires Zustand)
34
- - Check docs://conventions before generating code
34
+ - Read docs:// resources for conventions and best practices
35
35
  `.trim();
36
36
  /** Creates and configures the MCP server. */
37
37
  export function createServer() {
@@ -0,0 +1,44 @@
1
+ /**
2
+ * add_features tool
3
+ *
4
+ * Get files and dependencies for adding features to an existing project.
5
+ * Unlike get_scaffold, this tool does NOT auto-include the `core` feature,
6
+ * as it assumes the project already has core scaffolded.
7
+ */
8
+ import { z } from 'zod';
9
+ import type { FeatureId } from '../features/types.js';
10
+ import type { ToolDefinition } from './types.js';
11
+ /** Zod schema for add_features input */
12
+ export declare const addFeaturesSchema: z.ZodObject<{
13
+ features: z.ZodArray<z.ZodString>;
14
+ }, z.core.$strip>;
15
+ export type AddFeaturesInput = z.infer<typeof addFeaturesSchema>;
16
+ /** Handler function */
17
+ export declare function addFeatures(input: AddFeaturesInput): Promise<{
18
+ selectedFeatures: string[];
19
+ resolvedFeatures: FeatureId[];
20
+ featureDetails: {
21
+ id: FeatureId;
22
+ name: string;
23
+ description: string;
24
+ wasExplicitlySelected: boolean;
25
+ wasAutoIncluded: boolean;
26
+ }[];
27
+ dependencies: Record<string, string>;
28
+ devDependencies: Record<string, string>;
29
+ scripts: Record<string, string>;
30
+ files: string[];
31
+ testFiles: string[];
32
+ configFiles: string[];
33
+ docs: string[];
34
+ regenerated: {
35
+ routesTs?: string;
36
+ envTs?: string;
37
+ viteEnvDts?: string;
38
+ };
39
+ warnings: string[];
40
+ instructions: string;
41
+ }>;
42
+ /** Tool definition */
43
+ export declare const addFeaturesToolDefinition: ToolDefinition;
44
+ //# sourceMappingURL=add-features.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-features.d.ts","sourceRoot":"","sources":["../../src/tools/add-features.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAUtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,wCAAwC;AACxC,eAAO,MAAM,iBAAiB;;iBAiB5B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEjE,uBAAuB;AACvB,wBAAsB,WAAW,CAAC,KAAK,EAAE,gBAAgB;;;;;;;;;;;;;;;;;;mBAwB1C,MAAM;gBACT,MAAM;qBACD,MAAM;;;;GAyDtB;AA8BD,sBAAsB;AACtB,eAAO,MAAM,yBAAyB,EAAE,cAmCvC,CAAC"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * add_features tool
3
+ *
4
+ * Get files and dependencies for adding features to an existing project.
5
+ * Unlike get_scaffold, this tool does NOT auto-include the `core` feature,
6
+ * as it assumes the project already has core scaffolded.
7
+ */
8
+ import { z } from 'zod';
9
+ import { FEATURE_IDS, FEATURES } from '../features/index.js';
10
+ import { computeDocsForFeatures } from '../utils/docs.js';
11
+ import { collectFeatureFiles, getConfigFiles, mergeDependencies, mergeScripts, resolveFeatureDependencies, } from '../utils/scaffold/index.js';
12
+ import { generateEnvTs, generateRoutesTs, generateViteEnvDts } from '../utils/scaffold/generators.js';
13
+ /** Zod schema for add_features input */
14
+ export const addFeaturesSchema = z.object({
15
+ features: z
16
+ .array(z.string())
17
+ .min(1, 'At least one feature required')
18
+ .max(15, 'Maximum 15 features allowed')
19
+ .check((ctx) => {
20
+ const invalidFeatures = ctx.value.filter((f) => !(f in FEATURES));
21
+ if (invalidFeatures.length > 0) {
22
+ ctx.issues.push({
23
+ code: 'custom',
24
+ message: `Invalid features: ${invalidFeatures.join(', ')}. Valid: ${FEATURE_IDS.join(', ')}`,
25
+ input: ctx.value,
26
+ path: [],
27
+ });
28
+ }
29
+ })
30
+ .describe('List of feature IDs to add (e.g., ["routing", "state", "forms"])'),
31
+ });
32
+ /** Handler function */
33
+ export async function addFeatures(input) {
34
+ const { features } = input;
35
+ // 1. Resolve feature dependencies WITHOUT auto-including core
36
+ // (existing projects already have core scaffolded)
37
+ const resolvedFeatureIds = resolveFeatureDependencies(features, { includeCore: false });
38
+ // 2. Merge dependencies from all features
39
+ const { dependencies, devDependencies, warnings } = await mergeDependencies(resolvedFeatureIds);
40
+ // 3. Merge scripts
41
+ const scripts = mergeScripts(resolvedFeatureIds);
42
+ // 4. Collect file paths from all features
43
+ const { files, testFiles } = collectFeatureFiles(resolvedFeatureIds);
44
+ // 5. Get config files that may need updates
45
+ const configFiles = getConfigFiles(resolvedFeatureIds);
46
+ // 6. Get relevant documentation
47
+ const docs = computeDocsForFeatures(resolvedFeatureIds);
48
+ // 7. Generate code if routing/api/observability included
49
+ const regenerated = {};
50
+ if (resolvedFeatureIds.includes('routing')) {
51
+ regenerated.routesTs = generateRoutesTs();
52
+ }
53
+ // Always generate env files if api or observability is added
54
+ if (resolvedFeatureIds.includes('api') || resolvedFeatureIds.includes('observability')) {
55
+ regenerated.envTs = generateEnvTs(resolvedFeatureIds);
56
+ regenerated.viteEnvDts = generateViteEnvDts(resolvedFeatureIds);
57
+ }
58
+ // 8. Build feature details
59
+ const featureDetails = resolvedFeatureIds.map((id) => {
60
+ const feature = FEATURES[id];
61
+ return {
62
+ id,
63
+ name: feature.name,
64
+ description: feature.description,
65
+ wasExplicitlySelected: features.includes(id),
66
+ wasAutoIncluded: !features.includes(id),
67
+ };
68
+ });
69
+ return {
70
+ // Selected and resolved features
71
+ selectedFeatures: features,
72
+ resolvedFeatures: resolvedFeatureIds,
73
+ featureDetails,
74
+ // Dependencies to install
75
+ dependencies,
76
+ devDependencies,
77
+ // Scripts to add to package.json
78
+ scripts,
79
+ // Files to create (fetch via get_file)
80
+ files,
81
+ testFiles,
82
+ // Config files that may need updates
83
+ configFiles,
84
+ // Documentation files (fetch via get_file)
85
+ docs,
86
+ // Generated code (write directly, no need for get_file)
87
+ regenerated,
88
+ // Warnings (e.g., missing deps in source package.json)
89
+ warnings,
90
+ // Usage instructions
91
+ instructions: generateInstructions(resolvedFeatureIds),
92
+ };
93
+ }
94
+ function generateInstructions(features) {
95
+ const hasRouting = features.includes('routing');
96
+ const hasEnvChanges = features.includes('api') || features.includes('observability');
97
+ return `## Integration Instructions
98
+
99
+ 1. Install dependencies:
100
+ \`npm install <dependencies>\`
101
+ \`npm install -D <devDependencies>\`
102
+
103
+ 2. Add scripts to package.json
104
+
105
+ 3. Write generated content (if any):${hasRouting ? '\n - `src/lib/routes.ts` ← from `regenerated.routesTs`' : ''}${hasEnvChanges ? '\n - `src/lib/env.ts` ← from `regenerated.envTs`\n - `src/vite-env.d.ts` ← from `regenerated.viteEnvDts`' : ''}
106
+
107
+ 4. For EACH file in \`files\` and \`testFiles\`:
108
+ - Fetch content via \`get_file({ path: "..." })\`
109
+ - Create file in project
110
+ - Integrate with existing code as needed
111
+
112
+ 5. Review and update config files:
113
+ - Check each file in \`configFiles\`
114
+ - Merge any feature-specific configurations
115
+
116
+ 6. Update existing files to use new features:
117
+ - Import and use new stores/hooks/components
118
+ - Add providers to App.tsx if needed`;
119
+ }
120
+ /** Tool definition */
121
+ export const addFeaturesToolDefinition = {
122
+ name: 'add_features',
123
+ description: `Get files and dependencies for adding features to an existing project.
124
+
125
+ Returns metadata for incrementally adding features without scaffolding entire project.
126
+ Does NOT auto-include \`core\` feature (assumes project already has core).
127
+
128
+ **Returns:**
129
+ - \`resolvedFeatures\`: Features including auto-resolved dependencies
130
+ - \`featureDetails\`: Details with wasExplicitlySelected/wasAutoIncluded flags
131
+ - \`dependencies\`: npm packages to install (production)
132
+ - \`devDependencies\`: npm packages to install (dev)
133
+ - \`scripts\`: npm scripts to add
134
+ - \`files\`: Source files to create (fetch via get_file)
135
+ - \`testFiles\`: Test files to create (fetch via get_file)
136
+ - \`configFiles\`: Config files that may need updates
137
+ - \`docs\`: Documentation files (fetch via get_file)
138
+ - \`regenerated\`: Generated code (routesTs, envTs, viteEnvDts)
139
+ - \`warnings\`: Any issues encountered
140
+ - \`instructions\`: Integration guidance
141
+
142
+ **Feature Dependencies:**
143
+ - theming → state (auto-included)
144
+
145
+ **Usage Pattern:**
146
+ 1. Call add_features with feature list
147
+ 2. Install dependencies
148
+ 3. Add scripts to package.json
149
+ 4. Write generated content from \`regenerated\`
150
+ 5. Fetch each file via \`get_file({ path: "..." })\`
151
+ 6. Integrate files into existing project
152
+ 7. Update config files as needed
153
+
154
+ **Example:** features: ["theming"] → resolvedFeatures: ["theming", "state"]`,
155
+ inputSchema: z.toJSONSchema(addFeaturesSchema),
156
+ };
157
+ //# sourceMappingURL=add-features.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-features.js","sourceRoot":"","sources":["../../src/tools/add-features.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,0BAA0B,GAC3B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAGtG,wCAAwC;AACxC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,QAAQ,EAAE,CAAC;SACR,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,GAAG,CAAC,CAAC,EAAE,+BAA+B,CAAC;SACvC,GAAG,CAAC,EAAE,EAAE,6BAA6B,CAAC;SACtC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACb,MAAM,eAAe,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC;QAC1E,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,qBAAqB,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBAC5F,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,IAAI,EAAE,EAAE;aACT,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;SACD,QAAQ,CAAC,kEAAkE,CAAC;CAChF,CAAC,CAAC;AAIH,uBAAuB;AACvB,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAuB;IACvD,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAE3B,8DAA8D;IAC9D,mDAAmD;IACnD,MAAM,kBAAkB,GAAG,0BAA0B,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;IAExF,0CAA0C;IAC1C,MAAM,EAAE,YAAY,EAAE,eAAe,EAAE,QAAQ,EAAE,GAAG,MAAM,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;IAEhG,mBAAmB;IACnB,MAAM,OAAO,GAAG,YAAY,CAAC,kBAAkB,CAAC,CAAC;IAEjD,0CAA0C;IAC1C,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,mBAAmB,CAAC,kBAAkB,CAAC,CAAC;IAErE,4CAA4C;IAC5C,MAAM,WAAW,GAAG,cAAc,CAAC,kBAAkB,CAAC,CAAC;IAEvD,gCAAgC;IAChC,MAAM,IAAI,GAAG,sBAAsB,CAAC,kBAAkB,CAAC,CAAC;IAExD,yDAAyD;IACzD,MAAM,WAAW,GAIb,EAAE,CAAC;IAEP,IAAI,kBAAkB,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3C,WAAW,CAAC,QAAQ,GAAG,gBAAgB,EAAE,CAAC;IAC5C,CAAC;IAED,6DAA6D;IAC7D,IAAI,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,kBAAkB,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QACvF,WAAW,CAAC,KAAK,GAAG,aAAa,CAAC,kBAAkB,CAAC,CAAC;QACtD,WAAW,CAAC,UAAU,GAAG,kBAAkB,CAAC,kBAAkB,CAAC,CAAC;IAClE,CAAC;IAED,2BAA2B;IAC3B,MAAM,cAAc,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;QACnD,MAAM,OAAO,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC7B,OAAO;YACL,EAAE;YACF,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,qBAAqB,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5C,eAAe,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;SACxC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,iCAAiC;QACjC,gBAAgB,EAAE,QAAQ;QAC1B,gBAAgB,EAAE,kBAAkB;QACpC,cAAc;QAEd,0BAA0B;QAC1B,YAAY;QACZ,eAAe;QAEf,iCAAiC;QACjC,OAAO;QAEP,uCAAuC;QACvC,KAAK;QACL,SAAS;QAET,qCAAqC;QACrC,WAAW;QAEX,2CAA2C;QAC3C,IAAI;QAEJ,wDAAwD;QACxD,WAAW;QAEX,uDAAuD;QACvD,QAAQ;QAER,qBAAqB;QACrB,YAAY,EAAE,oBAAoB,CAAC,kBAAkB,CAAC;KACvD,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,QAAqB;IACjD,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAChD,MAAM,aAAa,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;IAErF,OAAO;;;;;;;;sCAQ6B,UAAU,CAAC,CAAC,CAAC,0DAA0D,CAAC,CAAC,CAAC,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,8GAA8G,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;wCAahN,CAAC;AACzC,CAAC;AAED,sBAAsB;AACtB,MAAM,CAAC,MAAM,yBAAyB,GAAmB;IACvD,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4EA+B6D;IAC1E,WAAW,EAAE,CAAC,CAAC,YAAY,CAAC,iBAAiB,CAAkC;CAChF,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for add_features tool
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=add-features.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-features.test.d.ts","sourceRoot":"","sources":["../../src/tools/add-features.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Tests for add_features tool
3
+ */
4
+ import { describe, it, expect } from 'vitest';
5
+ import { addFeatures, addFeaturesSchema } from './add-features.js';
6
+ describe('add_features tool', () => {
7
+ describe('schema validation', () => {
8
+ it('requires at least one feature', () => {
9
+ const result = addFeaturesSchema.safeParse({ features: [] });
10
+ expect(result.success).toBe(false);
11
+ if (!result.success) {
12
+ expect(result.error.message).toContain('At least one feature required');
13
+ }
14
+ });
15
+ it('rejects invalid features via schema', () => {
16
+ const result = addFeaturesSchema.safeParse({
17
+ features: ['invalid-feature'],
18
+ });
19
+ expect(result.success).toBe(false);
20
+ if (!result.success) {
21
+ expect(result.error.message).toContain('Invalid features');
22
+ }
23
+ });
24
+ it('accepts valid features', () => {
25
+ const result = addFeaturesSchema.safeParse({
26
+ features: ['state', 'routing'],
27
+ });
28
+ expect(result.success).toBe(true);
29
+ });
30
+ it('rejects more than 15 features', () => {
31
+ const result = addFeaturesSchema.safeParse({
32
+ features: Array(16).fill('state'),
33
+ });
34
+ expect(result.success).toBe(false);
35
+ if (!result.success) {
36
+ expect(result.error.message).toContain('Maximum 15 features');
37
+ }
38
+ });
39
+ });
40
+ describe('feature resolution', () => {
41
+ it('does NOT auto-include core feature', async () => {
42
+ const result = await addFeatures({ features: ['state'] });
43
+ expect(result.resolvedFeatures).not.toContain('core');
44
+ expect(result.resolvedFeatures).toContain('state');
45
+ });
46
+ it('auto-includes feature dependencies (theming → state)', async () => {
47
+ const result = await addFeatures({ features: ['theming'] });
48
+ expect(result.resolvedFeatures).toContain('theming');
49
+ expect(result.resolvedFeatures).toContain('state');
50
+ expect(result.resolvedFeatures).not.toContain('core');
51
+ });
52
+ it('marks auto-included features correctly', async () => {
53
+ const result = await addFeatures({ features: ['theming'] });
54
+ const themingDetail = result.featureDetails.find((f) => f.id === 'theming');
55
+ const stateDetail = result.featureDetails.find((f) => f.id === 'state');
56
+ // Theming was explicitly selected
57
+ expect(themingDetail?.wasExplicitlySelected).toBe(true);
58
+ expect(themingDetail?.wasAutoIncluded).toBe(false);
59
+ // State was auto-included (dependency of theming)
60
+ expect(stateDetail?.wasExplicitlySelected).toBe(false);
61
+ expect(stateDetail?.wasAutoIncluded).toBe(true);
62
+ });
63
+ it('returns only selected features when no dependencies', async () => {
64
+ const result = await addFeatures({ features: ['ui'] });
65
+ expect(result.resolvedFeatures).toEqual(['ui']);
66
+ });
67
+ });
68
+ describe('dependencies', () => {
69
+ it('returns dependencies for selected features', async () => {
70
+ const result = await addFeatures({ features: ['state'] });
71
+ expect(result.dependencies).toHaveProperty('zustand');
72
+ });
73
+ it('returns routing dependencies when routing selected', async () => {
74
+ const result = await addFeatures({ features: ['routing'] });
75
+ expect(result.dependencies).toHaveProperty('react-router');
76
+ });
77
+ it('does NOT include core dependencies', async () => {
78
+ const result = await addFeatures({ features: ['state'] });
79
+ // Core deps like react/react-dom should not be included
80
+ expect(result.dependencies).not.toHaveProperty('react');
81
+ expect(result.dependencies).not.toHaveProperty('react-dom');
82
+ });
83
+ });
84
+ describe('files', () => {
85
+ it('returns files for selected features', async () => {
86
+ const result = await addFeatures({ features: ['state'] });
87
+ expect(result.files).toContain('src/stores/preferencesStore.ts');
88
+ expect(result.files).toContain('src/stores/index.ts');
89
+ });
90
+ it('returns testFiles for selected features', async () => {
91
+ const result = await addFeatures({ features: ['state'] });
92
+ expect(result.testFiles).toContain('src/stores/preferencesStore.test.ts');
93
+ });
94
+ it('includes files from auto-included dependencies', async () => {
95
+ const result = await addFeatures({ features: ['theming'] });
96
+ // Theming files
97
+ expect(result.files).toContain('src/hooks/useThemeEffect.ts');
98
+ // State files (auto-included dependency)
99
+ expect(result.files).toContain('src/stores/preferencesStore.ts');
100
+ });
101
+ it('returns configFiles that may need updates', async () => {
102
+ // Use 'ui' feature which has configFiles defined (components.json)
103
+ const result = await addFeatures({ features: ['ui'] });
104
+ expect(Array.isArray(result.configFiles)).toBe(true);
105
+ expect(result.configFiles).toContain('components.json');
106
+ });
107
+ it('returns empty configFiles when feature has none', async () => {
108
+ // 'state' feature has no configFiles
109
+ const result = await addFeatures({ features: ['state'] });
110
+ expect(Array.isArray(result.configFiles)).toBe(true);
111
+ expect(result.configFiles.length).toBe(0);
112
+ });
113
+ });
114
+ describe('docs', () => {
115
+ it('returns relevant documentation files', async () => {
116
+ const result = await addFeatures({ features: ['testing'] });
117
+ expect(result.docs).toContain('docs/TESTING.md');
118
+ });
119
+ it('includes universal docs', async () => {
120
+ const result = await addFeatures({ features: ['state'] });
121
+ expect(result.docs).toContain('docs/ARCHITECTURE.md');
122
+ });
123
+ });
124
+ describe('regenerated content', () => {
125
+ it('generates routesTs when routing is selected', async () => {
126
+ const result = await addFeatures({ features: ['routing'] });
127
+ expect(result.regenerated.routesTs).toBeDefined();
128
+ expect(result.regenerated.routesTs).toContain('ROUTES');
129
+ });
130
+ it('does NOT generate routesTs when routing is not selected', async () => {
131
+ const result = await addFeatures({ features: ['state'] });
132
+ expect(result.regenerated.routesTs).toBeUndefined();
133
+ });
134
+ it('generates envTs when api is selected', async () => {
135
+ const result = await addFeatures({ features: ['api'] });
136
+ expect(result.regenerated.envTs).toBeDefined();
137
+ expect(result.regenerated.viteEnvDts).toBeDefined();
138
+ });
139
+ });
140
+ describe('instructions', () => {
141
+ it('returns integration instructions', async () => {
142
+ const result = await addFeatures({ features: ['state'] });
143
+ expect(result.instructions).toContain('Integration Instructions');
144
+ expect(result.instructions).toContain('npm install');
145
+ expect(result.instructions).toContain('get_file');
146
+ });
147
+ });
148
+ describe('difference from get_scaffold', () => {
149
+ it('does NOT include core feature or its files', async () => {
150
+ const result = await addFeatures({ features: ['ui'] });
151
+ // Core files should NOT be included
152
+ expect(result.files).not.toContain('src/App.tsx');
153
+ expect(result.files).not.toContain('src/main.tsx');
154
+ // Only UI files
155
+ expect(result.resolvedFeatures).toEqual(['ui']);
156
+ });
157
+ it('does NOT include package.json template', async () => {
158
+ const result = await addFeatures({ features: ['state'] });
159
+ // Should NOT have full packageJson, just deps
160
+ expect(result).not.toHaveProperty('packageJson');
161
+ expect(result).toHaveProperty('dependencies');
162
+ expect(result).toHaveProperty('devDependencies');
163
+ });
164
+ it('does NOT include claudeMd', async () => {
165
+ const result = await addFeatures({ features: ['state'] });
166
+ expect(result).not.toHaveProperty('claudeMd');
167
+ });
168
+ });
169
+ });
170
+ //# sourceMappingURL=add-features.test.js.map