@fragments-sdk/cli 0.10.1 → 0.12.1

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 (223) hide show
  1. package/dist/ai-client-I6MDWNYA.js +21 -0
  2. package/dist/bin.js +292 -367
  3. package/dist/bin.js.map +1 -1
  4. package/dist/{chunk-PW7QTQA6.js → chunk-4OC7FTJB.js} +2 -2
  5. package/dist/{chunk-HRFUSSZI.js → chunk-AM4MRTMN.js} +2 -2
  6. package/dist/{chunk-5G3VZH43.js → chunk-GVDSFQ4E.js} +281 -351
  7. package/dist/chunk-GVDSFQ4E.js.map +1 -0
  8. package/dist/chunk-JJ2VRTBU.js +626 -0
  9. package/dist/chunk-JJ2VRTBU.js.map +1 -0
  10. package/dist/{chunk-D5PYOXEI.js → chunk-LVWFOLUZ.js} +148 -13
  11. package/dist/{chunk-D5PYOXEI.js.map → chunk-LVWFOLUZ.js.map} +1 -1
  12. package/dist/{chunk-WXSR2II7.js → chunk-OQKMEFOS.js} +58 -6
  13. package/dist/chunk-OQKMEFOS.js.map +1 -0
  14. package/dist/chunk-SXTKFDCR.js +104 -0
  15. package/dist/chunk-SXTKFDCR.js.map +1 -0
  16. package/dist/chunk-T5OMVL7E.js +443 -0
  17. package/dist/chunk-T5OMVL7E.js.map +1 -0
  18. package/dist/{chunk-ZM4ZQZWZ.js → chunk-TPWGL2XS.js} +39 -37
  19. package/dist/chunk-TPWGL2XS.js.map +1 -0
  20. package/dist/{chunk-OQO55NKV.js → chunk-WFS63PCW.js} +85 -11
  21. package/dist/chunk-WFS63PCW.js.map +1 -0
  22. package/dist/core/index.js +9 -1
  23. package/dist/{discovery-NEOY4MPN.js → discovery-ZJQSXF56.js} +3 -3
  24. package/dist/{generate-FBHSXR3D.js → generate-RJFS2JWA.js} +4 -4
  25. package/dist/index.js +7 -6
  26. package/dist/index.js.map +1 -1
  27. package/dist/init-ZSX3NRCZ.js +636 -0
  28. package/dist/init-ZSX3NRCZ.js.map +1 -0
  29. package/dist/mcp-bin.js +2 -2
  30. package/dist/{scan-CJF2DOQW.js → scan-3PMCJ4RB.js} +6 -6
  31. package/dist/scan-generate-SYU4PYZD.js +1115 -0
  32. package/dist/scan-generate-SYU4PYZD.js.map +1 -0
  33. package/dist/{service-TQYWY65E.js → service-VMGNJZ42.js} +3 -3
  34. package/dist/snapshot-XOISO2IS.js +139 -0
  35. package/dist/snapshot-XOISO2IS.js.map +1 -0
  36. package/dist/{static-viewer-NUBFPKWH.js → static-viewer-5GXH2MGE.js} +3 -3
  37. package/dist/static-viewer-5GXH2MGE.js.map +1 -0
  38. package/dist/{test-Z5LVO724.js → test-SI4NSHQX.js} +4 -4
  39. package/dist/{tokens-CE46OTMD.js → tokens-T6SIVUT5.js} +5 -5
  40. package/dist/{viewer-DNMNC5VS.js → viewer-7ZEAFBVN.js} +80 -58
  41. package/dist/viewer-7ZEAFBVN.js.map +1 -0
  42. package/package.json +6 -14
  43. package/src/ai-client.ts +156 -0
  44. package/src/bin.ts +74 -2
  45. package/src/build.ts +95 -33
  46. package/src/commands/__tests__/drift-sync.test.ts +252 -0
  47. package/src/commands/__tests__/scan-generate.test.ts +497 -45
  48. package/src/commands/enhance.ts +11 -35
  49. package/src/commands/init.ts +296 -193
  50. package/src/commands/scan-generate.ts +740 -139
  51. package/src/commands/scan.ts +37 -32
  52. package/src/commands/setup.ts +143 -52
  53. package/src/commands/snapshot.ts +197 -0
  54. package/src/commands/sync.ts +357 -0
  55. package/src/commands/validate.ts +43 -1
  56. package/src/core/component-extractor.test.ts +282 -0
  57. package/src/core/component-extractor.ts +1030 -0
  58. package/src/core/discovery.ts +93 -7
  59. package/src/service/enhance/props-extractor.ts +235 -13
  60. package/src/validators.ts +236 -0
  61. package/src/viewer/__tests__/viewer-integration.test.ts +85 -74
  62. package/src/viewer/server.ts +37 -22
  63. package/src/viewer/vite-plugin.ts +25 -9
  64. package/dist/chunk-5G3VZH43.js.map +0 -1
  65. package/dist/chunk-OQO55NKV.js.map +0 -1
  66. package/dist/chunk-WXSR2II7.js.map +0 -1
  67. package/dist/chunk-ZM4ZQZWZ.js.map +0 -1
  68. package/dist/init-NDQXUWDU.js +0 -796
  69. package/dist/init-NDQXUWDU.js.map +0 -1
  70. package/dist/scan-generate-SJAN5MVI.js +0 -691
  71. package/dist/scan-generate-SJAN5MVI.js.map +0 -1
  72. package/dist/viewer-DNMNC5VS.js.map +0 -1
  73. package/src/ai.ts +0 -266
  74. package/src/commands/init-framework.ts +0 -414
  75. package/src/mcp/bin.ts +0 -36
  76. package/src/migrate/bin.ts +0 -114
  77. package/src/theme/index.ts +0 -77
  78. package/src/viewer/__tests__/a11y-fixes.test.ts +0 -358
  79. package/src/viewer/__tests__/jsx-parser.test.ts +0 -502
  80. package/src/viewer/__tests__/render-utils.test.ts +0 -232
  81. package/src/viewer/__tests__/style-utils.test.ts +0 -404
  82. package/src/viewer/assets/fragments-logo.ts +0 -4
  83. package/src/viewer/assets/fragments_logo.png +0 -0
  84. package/src/viewer/bin.ts +0 -86
  85. package/src/viewer/cli/health.ts +0 -256
  86. package/src/viewer/cli/index.ts +0 -33
  87. package/src/viewer/cli/scan.ts +0 -124
  88. package/src/viewer/cli/utils.ts +0 -174
  89. package/src/viewer/components/AccessibilityPanel.tsx +0 -1457
  90. package/src/viewer/components/ActionCapture.tsx +0 -172
  91. package/src/viewer/components/ActionsPanel.tsx +0 -332
  92. package/src/viewer/components/AllVariantsPreview.tsx +0 -78
  93. package/src/viewer/components/App.tsx +0 -582
  94. package/src/viewer/components/BottomPanel.tsx +0 -288
  95. package/src/viewer/components/CodePanel.naming.test.tsx +0 -59
  96. package/src/viewer/components/CodePanel.tsx +0 -118
  97. package/src/viewer/components/CommandPalette.tsx +0 -392
  98. package/src/viewer/components/ComponentDocView.tsx +0 -164
  99. package/src/viewer/components/ComponentGraph.tsx +0 -380
  100. package/src/viewer/components/ComponentHeader.tsx +0 -88
  101. package/src/viewer/components/ContractPanel.tsx +0 -241
  102. package/src/viewer/components/EmptyVariantMessage.tsx +0 -54
  103. package/src/viewer/components/ErrorBoundary.tsx +0 -97
  104. package/src/viewer/components/FigmaEmbed.tsx +0 -238
  105. package/src/viewer/components/FragmentEditor.tsx +0 -525
  106. package/src/viewer/components/FragmentRenderer.tsx +0 -61
  107. package/src/viewer/components/HeaderSearch.tsx +0 -24
  108. package/src/viewer/components/HealthDashboard.tsx +0 -441
  109. package/src/viewer/components/HmrStatusIndicator.tsx +0 -61
  110. package/src/viewer/components/Icons.tsx +0 -479
  111. package/src/viewer/components/InteractionsPanel.tsx +0 -757
  112. package/src/viewer/components/IsolatedPreviewFrame.tsx +0 -346
  113. package/src/viewer/components/IsolatedRender.tsx +0 -113
  114. package/src/viewer/components/KeyboardShortcutsHelp.tsx +0 -53
  115. package/src/viewer/components/LandingPage.tsx +0 -421
  116. package/src/viewer/components/Layout.tsx +0 -27
  117. package/src/viewer/components/LeftSidebar.tsx +0 -472
  118. package/src/viewer/components/LoadErrorMessage.tsx +0 -102
  119. package/src/viewer/components/MultiViewportPreview.tsx +0 -522
  120. package/src/viewer/components/NoVariantsMessage.tsx +0 -59
  121. package/src/viewer/components/PanelShell.tsx +0 -161
  122. package/src/viewer/components/PerformancePanel.tsx +0 -304
  123. package/src/viewer/components/PreviewArea.tsx +0 -472
  124. package/src/viewer/components/PreviewAside.tsx +0 -168
  125. package/src/viewer/components/PreviewFrameHost.tsx +0 -303
  126. package/src/viewer/components/PreviewPane.tsx +0 -149
  127. package/src/viewer/components/PreviewToolbar.tsx +0 -80
  128. package/src/viewer/components/PropsEditor.tsx +0 -506
  129. package/src/viewer/components/PropsTable.tsx +0 -111
  130. package/src/viewer/components/RelationsSection.tsx +0 -88
  131. package/src/viewer/components/ResizablePanel.tsx +0 -271
  132. package/src/viewer/components/RightSidebar.tsx +0 -102
  133. package/src/viewer/components/RuntimeToolsRegistrar.tsx +0 -17
  134. package/src/viewer/components/ScreenshotButton.tsx +0 -90
  135. package/src/viewer/components/Sidebar.tsx +0 -169
  136. package/src/viewer/components/SkeletonLoader.tsx +0 -161
  137. package/src/viewer/components/ThemeProvider.tsx +0 -42
  138. package/src/viewer/components/Toast.tsx +0 -3
  139. package/src/viewer/components/TokenStylePanel.tsx +0 -699
  140. package/src/viewer/components/TopToolbar.tsx +0 -159
  141. package/src/viewer/components/UsageSection.tsx +0 -95
  142. package/src/viewer/components/VariantMatrix.tsx +0 -388
  143. package/src/viewer/components/VariantRenderer.tsx +0 -131
  144. package/src/viewer/components/VariantTabs.tsx +0 -40
  145. package/src/viewer/components/ViewerHeader.tsx +0 -69
  146. package/src/viewer/components/ViewerStateSync.tsx +0 -52
  147. package/src/viewer/components/ViewportSelector.tsx +0 -172
  148. package/src/viewer/components/WebMCPDevTools.tsx +0 -503
  149. package/src/viewer/components/WebMCPIntegration.tsx +0 -47
  150. package/src/viewer/components/WebMCPStatusIndicator.tsx +0 -60
  151. package/src/viewer/components/_future/CreatePage.tsx +0 -836
  152. package/src/viewer/components/viewer-utils.ts +0 -16
  153. package/src/viewer/composition-renderer.ts +0 -381
  154. package/src/viewer/constants/index.ts +0 -1
  155. package/src/viewer/constants/ui.ts +0 -166
  156. package/src/viewer/entry.tsx +0 -335
  157. package/src/viewer/hooks/index.ts +0 -2
  158. package/src/viewer/hooks/useA11yCache.ts +0 -383
  159. package/src/viewer/hooks/useA11yService.ts +0 -364
  160. package/src/viewer/hooks/useActions.ts +0 -138
  161. package/src/viewer/hooks/useAppState.ts +0 -147
  162. package/src/viewer/hooks/useCompiledFragments.ts +0 -42
  163. package/src/viewer/hooks/useFigmaIntegration.ts +0 -132
  164. package/src/viewer/hooks/useHmrStatus.ts +0 -109
  165. package/src/viewer/hooks/useKeyboardShortcuts.ts +0 -270
  166. package/src/viewer/hooks/usePreviewBridge.ts +0 -347
  167. package/src/viewer/hooks/useScrollSpy.ts +0 -78
  168. package/src/viewer/hooks/useUrlState.ts +0 -318
  169. package/src/viewer/hooks/useViewSettings.ts +0 -111
  170. package/src/viewer/index.html +0 -28
  171. package/src/viewer/intelligence/healthReport.ts +0 -505
  172. package/src/viewer/intelligence/styleDrift.ts +0 -340
  173. package/src/viewer/intelligence/usageScanner.ts +0 -309
  174. package/src/viewer/jsx-parser.ts +0 -486
  175. package/src/viewer/preview-frame-entry.tsx +0 -25
  176. package/src/viewer/preview-frame.html +0 -125
  177. package/src/viewer/public/favicon.ico +0 -0
  178. package/src/viewer/render-template.html +0 -68
  179. package/src/viewer/styles/globals.css +0 -278
  180. package/src/viewer/types/a11y.ts +0 -197
  181. package/src/viewer/utils/a11y-fixes.ts +0 -509
  182. package/src/viewer/utils/actionExport.ts +0 -372
  183. package/src/viewer/utils/colorSchemes.ts +0 -201
  184. package/src/viewer/utils/detectRelationships.ts +0 -256
  185. package/src/viewer/vendor/shared/src/ComponentDocContent.module.scss +0 -10
  186. package/src/viewer/vendor/shared/src/ComponentDocContent.module.scss.d.ts +0 -2
  187. package/src/viewer/vendor/shared/src/ComponentDocContent.tsx +0 -274
  188. package/src/viewer/vendor/shared/src/DocsHeaderBar.tsx +0 -129
  189. package/src/viewer/vendor/shared/src/DocsPageAsideHost.tsx +0 -89
  190. package/src/viewer/vendor/shared/src/DocsPageShell.tsx +0 -124
  191. package/src/viewer/vendor/shared/src/DocsSearchCommand.tsx +0 -99
  192. package/src/viewer/vendor/shared/src/DocsSidebarNav.tsx +0 -66
  193. package/src/viewer/vendor/shared/src/PropsTable.module.scss +0 -68
  194. package/src/viewer/vendor/shared/src/PropsTable.module.scss.d.ts +0 -2
  195. package/src/viewer/vendor/shared/src/PropsTable.tsx +0 -76
  196. package/src/viewer/vendor/shared/src/VariantPreviewCard.module.scss +0 -114
  197. package/src/viewer/vendor/shared/src/VariantPreviewCard.module.scss.d.ts +0 -2
  198. package/src/viewer/vendor/shared/src/VariantPreviewCard.tsx +0 -137
  199. package/src/viewer/vendor/shared/src/docs-data/index.ts +0 -32
  200. package/src/viewer/vendor/shared/src/docs-data/mcp-configs.ts +0 -72
  201. package/src/viewer/vendor/shared/src/docs-data/palettes.ts +0 -75
  202. package/src/viewer/vendor/shared/src/docs-data/setup-examples.ts +0 -55
  203. package/src/viewer/vendor/shared/src/docs-layout.scss +0 -28
  204. package/src/viewer/vendor/shared/src/docs-layout.scss.d.ts +0 -2
  205. package/src/viewer/vendor/shared/src/index.ts +0 -34
  206. package/src/viewer/vendor/shared/src/types.ts +0 -53
  207. package/src/viewer/webmcp/__tests__/analytics.test.ts +0 -108
  208. package/src/viewer/webmcp/analytics.ts +0 -165
  209. package/src/viewer/webmcp/index.ts +0 -3
  210. package/src/viewer/webmcp/posthog-bridge.ts +0 -39
  211. package/src/viewer/webmcp/runtime-tools.ts +0 -152
  212. package/src/viewer/webmcp/scan-utils.ts +0 -135
  213. package/src/viewer/webmcp/use-tool-analytics.ts +0 -69
  214. package/src/viewer/webmcp/viewer-state.ts +0 -45
  215. /package/dist/{discovery-NEOY4MPN.js.map → ai-client-I6MDWNYA.js.map} +0 -0
  216. /package/dist/{chunk-PW7QTQA6.js.map → chunk-4OC7FTJB.js.map} +0 -0
  217. /package/dist/{chunk-HRFUSSZI.js.map → chunk-AM4MRTMN.js.map} +0 -0
  218. /package/dist/{scan-CJF2DOQW.js.map → discovery-ZJQSXF56.js.map} +0 -0
  219. /package/dist/{generate-FBHSXR3D.js.map → generate-RJFS2JWA.js.map} +0 -0
  220. /package/dist/{service-TQYWY65E.js.map → scan-3PMCJ4RB.js.map} +0 -0
  221. /package/dist/{static-viewer-NUBFPKWH.js.map → service-VMGNJZ42.js.map} +0 -0
  222. /package/dist/{test-Z5LVO724.js.map → test-SI4NSHQX.js.map} +0 -0
  223. /package/dist/{tokens-CE46OTMD.js.map → tokens-T6SIVUT5.js.map} +0 -0
@@ -0,0 +1,443 @@
1
+ import { createRequire as __banner_createRequire } from 'module'; const require = __banner_createRequire(import.meta.url);
2
+ import {
3
+ BRAND
4
+ } from "./chunk-WFS63PCW.js";
5
+
6
+ // src/commands/setup.ts
7
+ import { readFile, writeFile, access, mkdir } from "fs/promises";
8
+ import { join, resolve, dirname } from "path";
9
+ import pc from "picocolors";
10
+ async function fileExists(path) {
11
+ try {
12
+ await access(path);
13
+ return true;
14
+ } catch {
15
+ return false;
16
+ }
17
+ }
18
+ async function detectSetupFramework(root) {
19
+ if (await fileExists(join(root, "app/layout.tsx")) || await fileExists(join(root, "src/app/layout.tsx"))) {
20
+ return "nextjs-app";
21
+ }
22
+ if (await fileExists(join(root, "pages/_app.tsx")) || await fileExists(join(root, "pages/_app.ts"))) {
23
+ return "nextjs-pages";
24
+ }
25
+ if (await fileExists(join(root, "next.config.ts")) || await fileExists(join(root, "next.config.js")) || await fileExists(join(root, "next.config.mjs"))) {
26
+ return "nextjs-app";
27
+ }
28
+ if (await fileExists(join(root, "app/root.tsx")) || await fileExists(join(root, "app/root.ts"))) {
29
+ return "remix";
30
+ }
31
+ if (await fileExists(join(root, "astro.config.mjs")) || await fileExists(join(root, "astro.config.ts"))) {
32
+ return "astro";
33
+ }
34
+ if (await fileExists(join(root, "vite.config.ts")) || await fileExists(join(root, "vite.config.js"))) {
35
+ return "vite";
36
+ }
37
+ try {
38
+ const pkgPath = join(root, "package.json");
39
+ const pkgContent = await readFile(pkgPath, "utf-8");
40
+ const pkg = JSON.parse(pkgContent);
41
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
42
+ if (allDeps["next"]) return "nextjs-app";
43
+ if (allDeps["@remix-run/react"]) return "remix";
44
+ if (allDeps["astro"]) return "astro";
45
+ if (allDeps["vite"]) return "vite";
46
+ } catch {
47
+ }
48
+ return "unknown";
49
+ }
50
+ async function findEntryFile(root, framework) {
51
+ const candidates = [];
52
+ switch (framework) {
53
+ case "nextjs-app":
54
+ candidates.push(
55
+ "src/app/layout.tsx",
56
+ "app/layout.tsx",
57
+ "src/app/layout.ts",
58
+ "app/layout.ts"
59
+ );
60
+ break;
61
+ case "nextjs-pages":
62
+ candidates.push("pages/_app.tsx", "pages/_app.ts");
63
+ break;
64
+ case "remix":
65
+ candidates.push("app/root.tsx", "app/root.ts");
66
+ break;
67
+ case "astro":
68
+ candidates.push(
69
+ "src/layouts/Layout.astro",
70
+ "src/layouts/BaseLayout.astro",
71
+ "src/pages/index.astro"
72
+ );
73
+ break;
74
+ case "vite":
75
+ candidates.push(
76
+ "src/main.tsx",
77
+ "src/main.ts",
78
+ "src/index.tsx",
79
+ "src/index.ts"
80
+ );
81
+ break;
82
+ default:
83
+ candidates.push(
84
+ "src/main.tsx",
85
+ "src/main.ts",
86
+ "src/index.tsx",
87
+ "src/index.ts",
88
+ "src/App.tsx",
89
+ "src/App.ts"
90
+ );
91
+ }
92
+ for (const candidate of candidates) {
93
+ if (await fileExists(join(root, candidate))) {
94
+ return candidate;
95
+ }
96
+ }
97
+ return null;
98
+ }
99
+ async function findNextConfig(root) {
100
+ const candidates = ["next.config.ts", "next.config.mjs", "next.config.js"];
101
+ for (const candidate of candidates) {
102
+ if (await fileExists(join(root, candidate))) {
103
+ return candidate;
104
+ }
105
+ }
106
+ return null;
107
+ }
108
+ async function addStylesImport(root, entryFile) {
109
+ const fullPath = join(root, entryFile);
110
+ const content = await readFile(fullPath, "utf-8");
111
+ if (content.includes("@fragments-sdk/ui/styles")) {
112
+ return { modified: false, message: `Styles already imported in ${entryFile}` };
113
+ }
114
+ const stylesImport = "import '@fragments-sdk/ui/styles';";
115
+ let newContent;
116
+ if (entryFile.endsWith(".astro")) {
117
+ const fenceStart = content.indexOf("---");
118
+ if (fenceStart !== -1) {
119
+ const insertPos = fenceStart + 4;
120
+ newContent = content.slice(0, insertPos) + stylesImport + "\n" + content.slice(insertPos);
121
+ } else {
122
+ newContent = `---
123
+ ${stylesImport}
124
+ ---
125
+ ${content}`;
126
+ }
127
+ } else {
128
+ const useClientMatch = content.match(/^(?:\uFEFF)?[ \t]*['"]use client['"]\s*;?[ \t]*$/m);
129
+ if (useClientMatch && useClientMatch.index != null) {
130
+ const directiveLineEnd = content.indexOf("\n", useClientMatch.index);
131
+ const directiveEnd = directiveLineEnd === -1 ? content.length : directiveLineEnd + 1;
132
+ const separator = directiveLineEnd === -1 ? "\n" : "";
133
+ newContent = content.slice(0, directiveEnd) + separator + stylesImport + "\n" + content.slice(directiveEnd);
134
+ } else {
135
+ newContent = stylesImport + "\n" + content;
136
+ }
137
+ }
138
+ await writeFile(fullPath, newContent, "utf-8");
139
+ return { modified: true, message: `Added styles import to ${entryFile}` };
140
+ }
141
+ async function addThemeProvider(root, entryFile, framework) {
142
+ const fullPath = join(root, entryFile);
143
+ const content = await readFile(fullPath, "utf-8");
144
+ if (content.includes("ThemeProvider")) {
145
+ return { modified: false, message: `ThemeProvider already present in ${entryFile}` };
146
+ }
147
+ if (framework === "astro") {
148
+ return { modified: false, message: "Add ThemeProvider in your React island \u2014 see https://usefragments.com/getting-started#astro" };
149
+ }
150
+ const providerImport = "import { ThemeProvider, TooltipProvider, ToastProvider } from '@fragments-sdk/ui';";
151
+ let newContent = content;
152
+ const lines = content.split("\n");
153
+ let insertIdx = -1;
154
+ for (let i = 0; i < lines.length; i++) {
155
+ if (lines[i].includes("@fragments-sdk/ui/styles")) {
156
+ insertIdx = i;
157
+ break;
158
+ }
159
+ }
160
+ if (insertIdx === -1) {
161
+ for (let i = 0; i < lines.length; i++) {
162
+ if (lines[i].startsWith("import ") || lines[i].startsWith("import '") || lines[i].startsWith('import "')) {
163
+ insertIdx = i;
164
+ }
165
+ }
166
+ }
167
+ if (insertIdx >= 0) {
168
+ lines.splice(insertIdx + 1, 0, providerImport);
169
+ newContent = lines.join("\n");
170
+ } else {
171
+ newContent = providerImport + "\n" + content;
172
+ }
173
+ await writeFile(fullPath, newContent, "utf-8");
174
+ if (framework === "nextjs-app") {
175
+ const hint = !content.includes("suppressHydrationWarning") ? `
176
+ Add suppressHydrationWarning to your <html> tag` : "";
177
+ return {
178
+ modified: true,
179
+ message: `Added provider imports to ${entryFile}. Wrap {children} with:
180
+ <ThemeProvider defaultMode="system"><TooltipProvider><ToastProvider>{children}</ToastProvider></TooltipProvider></ThemeProvider>${hint}`
181
+ };
182
+ }
183
+ if (framework === "nextjs-pages") {
184
+ return {
185
+ modified: true,
186
+ message: `Added provider imports to ${entryFile}. Wrap <Component {...pageProps} /> with:
187
+ <ThemeProvider defaultMode="system"><TooltipProvider><ToastProvider>...</ToastProvider></TooltipProvider></ThemeProvider>`
188
+ };
189
+ }
190
+ if (framework === "remix") {
191
+ return {
192
+ modified: true,
193
+ message: `Added provider imports to ${entryFile}. Wrap <Outlet /> with:
194
+ <ThemeProvider defaultMode="system"><TooltipProvider><ToastProvider>...</ToastProvider></TooltipProvider></ThemeProvider>`
195
+ };
196
+ }
197
+ return {
198
+ modified: true,
199
+ message: `Added provider imports to ${entryFile}. Wrap your app root with:
200
+ <ThemeProvider defaultMode="system"><TooltipProvider><ToastProvider>...</ToastProvider></TooltipProvider></ThemeProvider>`
201
+ };
202
+ }
203
+ async function addTranspilePackages(root) {
204
+ const configFile = await findNextConfig(root);
205
+ if (!configFile) {
206
+ return { modified: false, message: "No next.config found" };
207
+ }
208
+ const fullPath = join(root, configFile);
209
+ const content = await readFile(fullPath, "utf-8");
210
+ if (content.includes("transpilePackages") && content.includes("@fragments-sdk/ui")) {
211
+ return { modified: false, message: `transpilePackages already configured in ${configFile}` };
212
+ }
213
+ if (content.includes("transpilePackages")) {
214
+ return {
215
+ modified: false,
216
+ message: `transpilePackages found in ${configFile} but missing '@fragments-sdk/ui'. Please add it manually.`
217
+ };
218
+ }
219
+ const patterns = [
220
+ // const nextConfig: NextConfig = { ... } (with optional type annotation)
221
+ { search: /const\s+\w+\s*(?::\s*\w+)?\s*=\s*\{/, replacement: (match) => `${match}
222
+ transpilePackages: ['@fragments-sdk/ui'],` },
223
+ // module.exports = { ... }
224
+ { search: /module\.exports\s*=\s*\{/, replacement: (match) => `${match}
225
+ transpilePackages: ['@fragments-sdk/ui'],` },
226
+ // export default { ... }
227
+ { search: /export\s+default\s*\{/, replacement: (match) => `${match}
228
+ transpilePackages: ['@fragments-sdk/ui'],` }
229
+ ];
230
+ for (const pattern of patterns) {
231
+ if (pattern.search.test(content)) {
232
+ const newContent = content.replace(pattern.search, pattern.replacement);
233
+ await writeFile(fullPath, newContent, "utf-8");
234
+ return { modified: true, message: `Added transpilePackages to ${configFile}` };
235
+ }
236
+ }
237
+ return {
238
+ modified: false,
239
+ message: `Could not auto-modify ${configFile}. Add transpilePackages: ['@fragments-sdk/ui'] manually.`
240
+ };
241
+ }
242
+ async function createScssSeeds(root, brand) {
243
+ const scssLocations = [
244
+ "src/app/globals.scss",
245
+ "app/globals.scss",
246
+ "src/styles/globals.scss",
247
+ "src/globals.scss",
248
+ "styles/globals.scss"
249
+ ];
250
+ for (const loc of scssLocations) {
251
+ const fullPath2 = join(root, loc);
252
+ if (await fileExists(fullPath2)) {
253
+ const content = await readFile(fullPath2, "utf-8");
254
+ if (content.includes("@fragments-sdk/ui/styles")) {
255
+ return { modified: false, message: `SCSS seeds already configured in ${loc}` };
256
+ }
257
+ const seedContent = generateScssSeedImport(brand);
258
+ const newContent = seedContent + "\n" + content;
259
+ await writeFile(fullPath2, newContent, "utf-8");
260
+ return { modified: true, message: `Added SCSS seed import to ${loc}` };
261
+ }
262
+ }
263
+ const targetDir = await fileExists(join(root, "src/app")) ? "src/app" : await fileExists(join(root, "src")) ? "src/styles" : "styles";
264
+ const targetPath = join(targetDir, "globals.scss");
265
+ const fullPath = join(root, targetPath);
266
+ await mkdir(dirname(fullPath), { recursive: true });
267
+ await writeFile(fullPath, generateScssSeedImport(brand), "utf-8");
268
+ return { modified: true, message: `Created ${targetPath} with SCSS seed configuration` };
269
+ }
270
+ async function setupMcpConfig(root) {
271
+ const mcpConfigPaths = [
272
+ ".cursor/mcp.json",
273
+ ".vscode/mcp.json"
274
+ ];
275
+ for (const configPath of mcpConfigPaths) {
276
+ const fullPath = join(root, configPath);
277
+ if (await fileExists(fullPath)) {
278
+ try {
279
+ const content = await readFile(fullPath, "utf-8");
280
+ const config = JSON.parse(content);
281
+ const servers = config.mcpServers || {};
282
+ const hasFragments = Object.values(servers).some((server) => {
283
+ const s = server;
284
+ return s.args?.some((arg) => arg.includes("@fragments-sdk/mcp"));
285
+ });
286
+ if (hasFragments) {
287
+ return { modified: false, message: `MCP server already configured in ${configPath}` };
288
+ }
289
+ servers.fragments = {
290
+ command: "npx",
291
+ args: ["@fragments-sdk/mcp"]
292
+ };
293
+ config.mcpServers = servers;
294
+ await writeFile(fullPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
295
+ return { modified: true, message: `Added Fragments MCP server to ${configPath}` };
296
+ } catch {
297
+ return { modified: false, message: `Could not parse ${configPath}` };
298
+ }
299
+ }
300
+ }
301
+ const cursorDir = join(root, ".cursor");
302
+ const cursorMcpPath = join(cursorDir, "mcp.json");
303
+ await mkdir(cursorDir, { recursive: true });
304
+ const mcpConfig = {
305
+ mcpServers: {
306
+ fragments: {
307
+ command: "npx",
308
+ args: ["@fragments-sdk/mcp"]
309
+ }
310
+ }
311
+ };
312
+ await writeFile(cursorMcpPath, JSON.stringify(mcpConfig, null, 2) + "\n", "utf-8");
313
+ return { modified: true, message: "Created .cursor/mcp.json with Fragments MCP server" };
314
+ }
315
+ function generateScssSeedImport(brand) {
316
+ const brandColor = brand || "#0066ff";
317
+ return `@use '@fragments-sdk/ui/styles' with (
318
+ $fui-brand: ${brandColor},
319
+ $fui-neutral: "stone",
320
+ $fui-density: "default",
321
+ $fui-radius-style: "rounded"
322
+ );
323
+ `;
324
+ }
325
+ async function setup(options = {}) {
326
+ const root = resolve(options.root ?? process.cwd());
327
+ const actions = [];
328
+ const errors = [];
329
+ console.log(pc.cyan(`
330
+ ${BRAND.name} Setup
331
+ `));
332
+ const framework = await detectSetupFramework(root);
333
+ const frameworkLabels = {
334
+ "nextjs-app": "Next.js (App Router)",
335
+ "nextjs-pages": "Next.js (Pages Router)",
336
+ "vite": "Vite",
337
+ "remix": "Remix",
338
+ "astro": "Astro"
339
+ };
340
+ const frameworkLabel = frameworkLabels[framework] || "Unknown";
341
+ console.log(` ${pc.dim("Framework:")} ${frameworkLabel}`);
342
+ const entryFile = await findEntryFile(root, framework);
343
+ if (entryFile) {
344
+ console.log(` ${pc.dim("Entry:")} ${entryFile}`);
345
+ } else {
346
+ console.log(` ${pc.yellow("!")} Could not detect entry file`);
347
+ }
348
+ console.log();
349
+ if (entryFile) {
350
+ try {
351
+ const result = await addStylesImport(root, entryFile);
352
+ const icon = result.modified ? pc.green("+") : pc.dim("\xB7");
353
+ console.log(` ${icon} ${result.message}`);
354
+ if (result.modified) actions.push(result.message);
355
+ } catch (error) {
356
+ const msg = `Failed to add styles import: ${error instanceof Error ? error.message : error}`;
357
+ console.log(` ${pc.red("\u2717")} ${msg}`);
358
+ errors.push(msg);
359
+ }
360
+ }
361
+ if (entryFile) {
362
+ try {
363
+ const result = await addThemeProvider(root, entryFile, framework);
364
+ const icon = result.modified ? pc.green("+") : pc.dim("\xB7");
365
+ console.log(` ${icon} ${result.message}`);
366
+ if (result.modified) actions.push(result.message);
367
+ } catch (error) {
368
+ const msg = `Failed to add ThemeProvider: ${error instanceof Error ? error.message : error}`;
369
+ console.log(` ${pc.red("\u2717")} ${msg}`);
370
+ errors.push(msg);
371
+ }
372
+ }
373
+ if (framework === "nextjs-app" || framework === "nextjs-pages") {
374
+ try {
375
+ const result = await addTranspilePackages(root);
376
+ const icon = result.modified ? pc.green("+") : pc.dim("\xB7");
377
+ console.log(` ${icon} ${result.message}`);
378
+ if (result.modified) actions.push(result.message);
379
+ } catch (error) {
380
+ const msg = `Failed to update next.config: ${error instanceof Error ? error.message : error}`;
381
+ console.log(` ${pc.red("\u2717")} ${msg}`);
382
+ errors.push(msg);
383
+ }
384
+ }
385
+ if (options.scss || options.brand) {
386
+ try {
387
+ const result = await createScssSeeds(root, options.brand);
388
+ const icon = result.modified ? pc.green("+") : pc.dim("\xB7");
389
+ console.log(` ${icon} ${result.message}`);
390
+ if (result.modified) actions.push(result.message);
391
+ } catch (error) {
392
+ const msg = `Failed to create SCSS seeds: ${error instanceof Error ? error.message : error}`;
393
+ console.log(` ${pc.red("\u2717")} ${msg}`);
394
+ errors.push(msg);
395
+ }
396
+ }
397
+ if (options.mcp) {
398
+ try {
399
+ const result = await setupMcpConfig(root);
400
+ const icon = result.modified ? pc.green("+") : pc.dim("\xB7");
401
+ console.log(` ${icon} ${result.message}`);
402
+ if (result.modified) actions.push(result.message);
403
+ } catch (error) {
404
+ const msg = `Failed to configure MCP: ${error instanceof Error ? error.message : error}`;
405
+ console.log(` ${pc.red("\u2717")} ${msg}`);
406
+ errors.push(msg);
407
+ }
408
+ }
409
+ console.log();
410
+ if (errors.length > 0) {
411
+ console.log(pc.red(` ${errors.length} error(s) occurred during setup`));
412
+ } else if (actions.length > 0) {
413
+ console.log(pc.green(` \u2713 Setup complete \u2014 ${actions.length} file(s) modified`));
414
+ } else {
415
+ console.log(pc.green(" \u2713 Already configured \u2014 no changes needed"));
416
+ }
417
+ console.log();
418
+ console.log(pc.dim(" Next steps:"));
419
+ if (!options.scss && !options.brand) {
420
+ console.log(pc.dim(" \u2022 Run with --scss to add build-time theme seeds"));
421
+ }
422
+ if (!options.mcp) {
423
+ console.log(pc.dim(" \u2022 Run with --mcp to configure AI tooling (MCP server)"));
424
+ }
425
+ console.log(pc.dim(" \u2022 Run `fragments doctor` to verify your setup"));
426
+ console.log(pc.dim(" \u2022 Visit https://usefragments.com/getting-started"));
427
+ console.log();
428
+ return {
429
+ success: errors.length === 0,
430
+ actions,
431
+ errors
432
+ };
433
+ }
434
+
435
+ export {
436
+ detectSetupFramework,
437
+ findEntryFile,
438
+ addStylesImport,
439
+ addThemeProvider,
440
+ addTranspilePackages,
441
+ setup
442
+ };
443
+ //# sourceMappingURL=chunk-T5OMVL7E.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/setup.ts"],"sourcesContent":["/**\n * fragments setup - Configure @fragments-sdk/ui in a consumer project\n *\n * Auto-detects framework (Next.js, Vite, etc.) and scaffolds:\n * - Styles import in entry file\n * - ThemeProvider wrapper in layout/app\n * - transpilePackages for Next.js\n * - SCSS seeds file (optional)\n */\n\nimport { readFile, writeFile, access, mkdir } from 'node:fs/promises';\nimport { join, resolve, dirname } from 'node:path';\nimport pc from 'picocolors';\nimport { BRAND } from '../core/index.js';\n\n// ============================================\n// Types\n// ============================================\n\nexport interface SetupOptions {\n /** Project root directory (defaults to cwd) */\n root?: string;\n /** Skip interactive prompts */\n yes?: boolean;\n /** Brand color hex (e.g., #6366f1) */\n brand?: string;\n /** Include SCSS seed file */\n scss?: boolean;\n /** Configure MCP server for AI tooling */\n mcp?: boolean;\n}\n\nexport interface SetupResult {\n success: boolean;\n actions: string[];\n errors: string[];\n}\n\nexport type Framework = 'nextjs-app' | 'nextjs-pages' | 'vite' | 'remix' | 'astro' | 'unknown';\n\n// ============================================\n// Detection\n// ============================================\n\nexport async function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function detectSetupFramework(root: string): Promise<Framework> {\n // Next.js App Router\n if (\n await fileExists(join(root, 'app/layout.tsx')) ||\n await fileExists(join(root, 'src/app/layout.tsx'))\n ) {\n return 'nextjs-app';\n }\n\n // Next.js Pages Router\n if (\n await fileExists(join(root, 'pages/_app.tsx')) ||\n await fileExists(join(root, 'pages/_app.ts'))\n ) {\n return 'nextjs-pages';\n }\n\n // Next.js (config exists but no router detected yet)\n if (\n await fileExists(join(root, 'next.config.ts')) ||\n await fileExists(join(root, 'next.config.js')) ||\n await fileExists(join(root, 'next.config.mjs'))\n ) {\n return 'nextjs-app';\n }\n\n // Remix\n if (\n await fileExists(join(root, 'app/root.tsx')) ||\n await fileExists(join(root, 'app/root.ts'))\n ) {\n return 'remix';\n }\n\n // Astro\n if (\n await fileExists(join(root, 'astro.config.mjs')) ||\n await fileExists(join(root, 'astro.config.ts'))\n ) {\n return 'astro';\n }\n\n // Vite (check after Remix/Astro since they also use Vite under the hood)\n if (\n await fileExists(join(root, 'vite.config.ts')) ||\n await fileExists(join(root, 'vite.config.js'))\n ) {\n return 'vite';\n }\n\n // Fallback: check package.json for framework deps\n try {\n const pkgPath = join(root, 'package.json');\n const pkgContent = await readFile(pkgPath, 'utf-8');\n const pkg = JSON.parse(pkgContent);\n const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };\n\n if (allDeps['next']) return 'nextjs-app';\n if (allDeps['@remix-run/react']) return 'remix';\n if (allDeps['astro']) return 'astro';\n if (allDeps['vite']) return 'vite';\n } catch {\n // No package.json or parse error\n }\n\n return 'unknown';\n}\n\nexport async function findEntryFile(root: string, framework: Framework): Promise<string | null> {\n const candidates: string[] = [];\n\n switch (framework) {\n case 'nextjs-app':\n candidates.push(\n 'src/app/layout.tsx', 'app/layout.tsx',\n 'src/app/layout.ts', 'app/layout.ts'\n );\n break;\n case 'nextjs-pages':\n candidates.push('pages/_app.tsx', 'pages/_app.ts');\n break;\n case 'remix':\n candidates.push('app/root.tsx', 'app/root.ts');\n break;\n case 'astro':\n candidates.push(\n 'src/layouts/Layout.astro',\n 'src/layouts/BaseLayout.astro',\n 'src/pages/index.astro'\n );\n break;\n case 'vite':\n candidates.push(\n 'src/main.tsx', 'src/main.ts',\n 'src/index.tsx', 'src/index.ts'\n );\n break;\n default:\n candidates.push(\n 'src/main.tsx', 'src/main.ts',\n 'src/index.tsx', 'src/index.ts',\n 'src/App.tsx', 'src/App.ts'\n );\n }\n\n for (const candidate of candidates) {\n if (await fileExists(join(root, candidate))) {\n return candidate;\n }\n }\n\n return null;\n}\n\nasync function findNextConfig(root: string): Promise<string | null> {\n const candidates = ['next.config.ts', 'next.config.mjs', 'next.config.js'];\n for (const candidate of candidates) {\n if (await fileExists(join(root, candidate))) {\n return candidate;\n }\n }\n return null;\n}\n\n// ============================================\n// Actions\n// ============================================\n\nexport async function addStylesImport(root: string, entryFile: string): Promise<{ modified: boolean; message: string }> {\n const fullPath = join(root, entryFile);\n const content = await readFile(fullPath, 'utf-8');\n\n if (content.includes('@fragments-sdk/ui/styles')) {\n return { modified: false, message: `Styles already imported in ${entryFile}` };\n }\n\n const stylesImport = \"import '@fragments-sdk/ui/styles';\";\n let newContent: string;\n\n // Astro files: insert inside frontmatter block (between --- fences)\n if (entryFile.endsWith('.astro')) {\n const fenceStart = content.indexOf('---');\n if (fenceStart !== -1) {\n const insertPos = fenceStart + 4; // after \"---\\n\"\n newContent = content.slice(0, insertPos) + stylesImport + '\\n' + content.slice(insertPos);\n } else {\n // No frontmatter — add one\n newContent = `---\\n${stylesImport}\\n---\\n${content}`;\n }\n } else {\n const useClientMatch = content.match(/^(?:\\uFEFF)?[ \\t]*['\"]use client['\"]\\s*;?[ \\t]*$/m);\n\n if (useClientMatch && useClientMatch.index != null) {\n const directiveLineEnd = content.indexOf('\\n', useClientMatch.index);\n const directiveEnd = directiveLineEnd === -1 ? content.length : directiveLineEnd + 1;\n const separator = directiveLineEnd === -1 ? '\\n' : '';\n newContent = content.slice(0, directiveEnd) + separator + stylesImport + '\\n' + content.slice(directiveEnd);\n } else {\n newContent = stylesImport + '\\n' + content;\n }\n }\n\n await writeFile(fullPath, newContent, 'utf-8');\n return { modified: true, message: `Added styles import to ${entryFile}` };\n}\n\nexport async function addThemeProvider(root: string, entryFile: string, framework: Framework): Promise<{ modified: boolean; message: string }> {\n const fullPath = join(root, entryFile);\n const content = await readFile(fullPath, 'utf-8');\n\n if (content.includes('ThemeProvider')) {\n return { modified: false, message: `ThemeProvider already present in ${entryFile}` };\n }\n\n // Astro uses .astro files — can't inject React imports\n if (framework === 'astro') {\n return { modified: false, message: 'Add ThemeProvider in your React island — see https://usefragments.com/getting-started#astro' };\n }\n\n // Add provider import after the last import line\n const providerImport = \"import { ThemeProvider, TooltipProvider, ToastProvider } from '@fragments-sdk/ui';\";\n\n let newContent = content;\n const lines = content.split('\\n');\n\n // Prefer placing right after the @fragments-sdk/ui/styles import if it exists\n let insertIdx = -1;\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].includes('@fragments-sdk/ui/styles')) {\n insertIdx = i;\n break;\n }\n }\n\n // Otherwise, place after the last import line\n if (insertIdx === -1) {\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].startsWith('import ') || lines[i].startsWith(\"import '\") || lines[i].startsWith('import \"')) {\n insertIdx = i;\n }\n }\n }\n\n if (insertIdx >= 0) {\n lines.splice(insertIdx + 1, 0, providerImport);\n newContent = lines.join('\\n');\n } else {\n newContent = providerImport + '\\n' + content;\n }\n\n await writeFile(fullPath, newContent, 'utf-8');\n\n // Framework-specific wrap instructions\n if (framework === 'nextjs-app') {\n const hint = !content.includes('suppressHydrationWarning')\n ? `\\n Add suppressHydrationWarning to your <html> tag`\n : '';\n return {\n modified: true,\n message: `Added provider imports to ${entryFile}. Wrap {children} with:\\n` +\n ` <ThemeProvider defaultMode=\"system\"><TooltipProvider><ToastProvider>{children}</ToastProvider></TooltipProvider></ThemeProvider>${hint}`,\n };\n }\n\n if (framework === 'nextjs-pages') {\n return {\n modified: true,\n message: `Added provider imports to ${entryFile}. Wrap <Component {...pageProps} /> with:\\n` +\n ` <ThemeProvider defaultMode=\"system\"><TooltipProvider><ToastProvider>...</ToastProvider></TooltipProvider></ThemeProvider>`,\n };\n }\n\n if (framework === 'remix') {\n return {\n modified: true,\n message: `Added provider imports to ${entryFile}. Wrap <Outlet /> with:\\n` +\n ` <ThemeProvider defaultMode=\"system\"><TooltipProvider><ToastProvider>...</ToastProvider></TooltipProvider></ThemeProvider>`,\n };\n }\n\n // Vite and unknown — generic instruction\n return {\n modified: true,\n message: `Added provider imports to ${entryFile}. Wrap your app root with:\\n` +\n ` <ThemeProvider defaultMode=\"system\"><TooltipProvider><ToastProvider>...</ToastProvider></TooltipProvider></ThemeProvider>`,\n };\n}\n\nexport async function addTranspilePackages(root: string): Promise<{ modified: boolean; message: string }> {\n const configFile = await findNextConfig(root);\n if (!configFile) {\n return { modified: false, message: 'No next.config found' };\n }\n\n const fullPath = join(root, configFile);\n const content = await readFile(fullPath, 'utf-8');\n\n if (content.includes('transpilePackages') && content.includes('@fragments-sdk/ui')) {\n return { modified: false, message: `transpilePackages already configured in ${configFile}` };\n }\n\n if (content.includes('transpilePackages')) {\n // transpilePackages exists but without @fragments-sdk/ui — need manual addition\n return {\n modified: false,\n message: `transpilePackages found in ${configFile} but missing '@fragments-sdk/ui'. Please add it manually.`,\n };\n }\n\n // Add transpilePackages to the config\n // Try to find the config object and add the property\n const patterns = [\n // const nextConfig: NextConfig = { ... } (with optional type annotation)\n { search: /const\\s+\\w+\\s*(?::\\s*\\w+)?\\s*=\\s*\\{/, replacement: (match: string) => `${match}\\n transpilePackages: ['@fragments-sdk/ui'],` },\n // module.exports = { ... }\n { search: /module\\.exports\\s*=\\s*\\{/, replacement: (match: string) => `${match}\\n transpilePackages: ['@fragments-sdk/ui'],` },\n // export default { ... }\n { search: /export\\s+default\\s*\\{/, replacement: (match: string) => `${match}\\n transpilePackages: ['@fragments-sdk/ui'],` },\n ];\n\n for (const pattern of patterns) {\n if (pattern.search.test(content)) {\n const newContent = content.replace(pattern.search, pattern.replacement);\n await writeFile(fullPath, newContent, 'utf-8');\n return { modified: true, message: `Added transpilePackages to ${configFile}` };\n }\n }\n\n return {\n modified: false,\n message: `Could not auto-modify ${configFile}. Add transpilePackages: ['@fragments-sdk/ui'] manually.`,\n };\n}\n\nasync function createScssSeeds(root: string, brand?: string): Promise<{ modified: boolean; message: string }> {\n // Try common SCSS locations\n const scssLocations = [\n 'src/app/globals.scss',\n 'app/globals.scss',\n 'src/styles/globals.scss',\n 'src/globals.scss',\n 'styles/globals.scss',\n ];\n\n // Check if any exists already\n for (const loc of scssLocations) {\n const fullPath = join(root, loc);\n if (await fileExists(fullPath)) {\n const content = await readFile(fullPath, 'utf-8');\n if (content.includes('@fragments-sdk/ui/styles')) {\n return { modified: false, message: `SCSS seeds already configured in ${loc}` };\n }\n\n // Prepend @use to existing file\n const seedContent = generateScssSeedImport(brand);\n const newContent = seedContent + '\\n' + content;\n await writeFile(fullPath, newContent, 'utf-8');\n return { modified: true, message: `Added SCSS seed import to ${loc}` };\n }\n }\n\n // Create new globals.scss in the most common location\n const targetDir = await fileExists(join(root, 'src/app'))\n ? 'src/app'\n : await fileExists(join(root, 'src'))\n ? 'src/styles'\n : 'styles';\n\n const targetPath = join(targetDir, 'globals.scss');\n const fullPath = join(root, targetPath);\n\n await mkdir(dirname(fullPath), { recursive: true });\n await writeFile(fullPath, generateScssSeedImport(brand), 'utf-8');\n return { modified: true, message: `Created ${targetPath} with SCSS seed configuration` };\n}\n\nasync function setupMcpConfig(root: string): Promise<{ modified: boolean; message: string }> {\n // Check common MCP config locations\n const mcpConfigPaths = [\n '.cursor/mcp.json',\n '.vscode/mcp.json',\n ];\n\n for (const configPath of mcpConfigPaths) {\n const fullPath = join(root, configPath);\n if (await fileExists(fullPath)) {\n try {\n const content = await readFile(fullPath, 'utf-8');\n const config = JSON.parse(content);\n const servers = config.mcpServers || {};\n\n // Check if fragments is already configured\n const hasFragments = Object.values(servers).some((server: unknown) => {\n const s = server as { command?: string; args?: string[] };\n return s.args?.some((arg: string) => arg.includes('@fragments-sdk/mcp'));\n });\n\n if (hasFragments) {\n return { modified: false, message: `MCP server already configured in ${configPath}` };\n }\n\n // Add fragments MCP server\n servers.fragments = {\n command: 'npx',\n args: ['@fragments-sdk/mcp'],\n };\n config.mcpServers = servers;\n\n await writeFile(fullPath, JSON.stringify(config, null, 2) + '\\n', 'utf-8');\n return { modified: true, message: `Added Fragments MCP server to ${configPath}` };\n } catch {\n return { modified: false, message: `Could not parse ${configPath}` };\n }\n }\n }\n\n // No existing MCP config — create one for Cursor (most common)\n const cursorDir = join(root, '.cursor');\n const cursorMcpPath = join(cursorDir, 'mcp.json');\n\n await mkdir(cursorDir, { recursive: true });\n const mcpConfig = {\n mcpServers: {\n fragments: {\n command: 'npx',\n args: ['@fragments-sdk/mcp'],\n },\n },\n };\n\n await writeFile(cursorMcpPath, JSON.stringify(mcpConfig, null, 2) + '\\n', 'utf-8');\n return { modified: true, message: 'Created .cursor/mcp.json with Fragments MCP server' };\n}\n\nfunction generateScssSeedImport(brand?: string): string {\n const brandColor = brand || '#0066ff';\n return `@use '@fragments-sdk/ui/styles' with (\n $fui-brand: ${brandColor},\n $fui-neutral: \"stone\",\n $fui-density: \"default\",\n $fui-radius-style: \"rounded\"\n);\n`;\n}\n\n// ============================================\n// Main Setup Function\n// ============================================\n\nexport async function setup(options: SetupOptions = {}): Promise<SetupResult> {\n const root = resolve(options.root ?? process.cwd());\n const actions: string[] = [];\n const errors: string[] = [];\n\n console.log(pc.cyan(`\\n${BRAND.name} Setup\\n`));\n\n // 1. Detect framework\n const framework = await detectSetupFramework(root);\n const frameworkLabels: Record<string, string> = {\n 'nextjs-app': 'Next.js (App Router)',\n 'nextjs-pages': 'Next.js (Pages Router)',\n 'vite': 'Vite',\n 'remix': 'Remix',\n 'astro': 'Astro',\n };\n const frameworkLabel = frameworkLabels[framework] || 'Unknown';\n\n console.log(` ${pc.dim('Framework:')} ${frameworkLabel}`);\n\n // 2. Find entry file\n const entryFile = await findEntryFile(root, framework);\n if (entryFile) {\n console.log(` ${pc.dim('Entry:')} ${entryFile}`);\n } else {\n console.log(` ${pc.yellow('!')} Could not detect entry file`);\n }\n console.log();\n\n // 3. Add styles import\n if (entryFile) {\n try {\n const result = await addStylesImport(root, entryFile);\n const icon = result.modified ? pc.green('+') : pc.dim('·');\n console.log(` ${icon} ${result.message}`);\n if (result.modified) actions.push(result.message);\n } catch (error) {\n const msg = `Failed to add styles import: ${error instanceof Error ? error.message : error}`;\n console.log(` ${pc.red('✗')} ${msg}`);\n errors.push(msg);\n }\n }\n\n // 4. Add ThemeProvider imports\n if (entryFile) {\n try {\n const result = await addThemeProvider(root, entryFile, framework);\n const icon = result.modified ? pc.green('+') : pc.dim('·');\n console.log(` ${icon} ${result.message}`);\n if (result.modified) actions.push(result.message);\n } catch (error) {\n const msg = `Failed to add ThemeProvider: ${error instanceof Error ? error.message : error}`;\n console.log(` ${pc.red('✗')} ${msg}`);\n errors.push(msg);\n }\n }\n\n // 5. Next.js: add transpilePackages\n if (framework === 'nextjs-app' || framework === 'nextjs-pages') {\n try {\n const result = await addTranspilePackages(root);\n const icon = result.modified ? pc.green('+') : pc.dim('·');\n console.log(` ${icon} ${result.message}`);\n if (result.modified) actions.push(result.message);\n } catch (error) {\n const msg = `Failed to update next.config: ${error instanceof Error ? error.message : error}`;\n console.log(` ${pc.red('✗')} ${msg}`);\n errors.push(msg);\n }\n }\n\n // 6. Create SCSS seeds file (if --scss flag or brand color specified)\n if (options.scss || options.brand) {\n try {\n const result = await createScssSeeds(root, options.brand);\n const icon = result.modified ? pc.green('+') : pc.dim('·');\n console.log(` ${icon} ${result.message}`);\n if (result.modified) actions.push(result.message);\n } catch (error) {\n const msg = `Failed to create SCSS seeds: ${error instanceof Error ? error.message : error}`;\n console.log(` ${pc.red('✗')} ${msg}`);\n errors.push(msg);\n }\n }\n\n // 7. Configure MCP server (if --mcp flag)\n if (options.mcp) {\n try {\n const result = await setupMcpConfig(root);\n const icon = result.modified ? pc.green('+') : pc.dim('·');\n console.log(` ${icon} ${result.message}`);\n if (result.modified) actions.push(result.message);\n } catch (error) {\n const msg = `Failed to configure MCP: ${error instanceof Error ? error.message : error}`;\n console.log(` ${pc.red('✗')} ${msg}`);\n errors.push(msg);\n }\n }\n\n // Summary\n console.log();\n if (errors.length > 0) {\n console.log(pc.red(` ${errors.length} error(s) occurred during setup`));\n } else if (actions.length > 0) {\n console.log(pc.green(` ✓ Setup complete — ${actions.length} file(s) modified`));\n } else {\n console.log(pc.green(' ✓ Already configured — no changes needed'));\n }\n\n // Next steps\n console.log();\n console.log(pc.dim(' Next steps:'));\n if (!options.scss && !options.brand) {\n console.log(pc.dim(' • Run with --scss to add build-time theme seeds'));\n }\n if (!options.mcp) {\n console.log(pc.dim(' • Run with --mcp to configure AI tooling (MCP server)'));\n }\n console.log(pc.dim(' • Run `fragments doctor` to verify your setup'));\n console.log(pc.dim(' • Visit https://usefragments.com/getting-started'));\n console.log();\n\n return {\n success: errors.length === 0,\n actions,\n errors,\n };\n}\n"],"mappings":"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","names":["fullPath"]}